From f5e46c9bf2f50d66a953fa133161fc829cecff06 Mon Sep 17 00:00:00 2001 From: Matt Mastracci Date: Sat, 10 Feb 2024 13:22:13 -0700 Subject: chore: move cli/tests/ -> tests/ (#22369) This looks like a massive PR, but it's only a move from cli/tests -> tests, and updates of relative paths for files. This is the first step towards aggregate all of the integration test files under tests/, which will lead to a set of integration tests that can run without the CLI binary being built. While we could leave these tests under `cli`, it would require us to keep a more complex directory structure for the various test runners. In addition, we have a lot of complexity to ignore various test files in the `cli` project itself (cargo publish exclusion rules, autotests = false, etc). And finally, the `tests/` folder will eventually house the `test_ffi`, `test_napi` and other testing code, reducing the size of the root repo directory. For easier review, the extremely large and noisy "move" is in the first commit (with no changes -- just a move), while the remainder of the changes to actual files is in the second commit. --- tests/Cargo.toml | 52 + tests/config/deno.json | 5 + tests/integration/bench_tests.rs | 285 + tests/integration/bundle_tests.rs | 482 + tests/integration/cache_tests.rs | 186 + tests/integration/cert_tests.rs | 299 + tests/integration/check_tests.rs | 419 + tests/integration/compile_tests.rs | 1180 + tests/integration/coverage_tests.rs | 638 + tests/integration/doc_tests.rs | 152 + tests/integration/eval_tests.rs | 89 + tests/integration/flags_tests.rs | 86 + tests/integration/fmt_tests.rs | 352 + tests/integration/info_tests.rs | 162 + tests/integration/init_tests.rs | 171 + tests/integration/inspector_tests.rs | 1440 + tests/integration/install_tests.rs | 250 + tests/integration/js_unit_tests.rs | 201 + tests/integration/jsr_tests.rs | 183 + tests/integration/jupyter_tests.rs | 8 + tests/integration/lint_tests.rs | 211 + tests/integration/lsp_tests.rs | 11240 ++++ tests/integration/mod.rs | 158 + tests/integration/node_compat_tests.rs | 31 + tests/integration/node_unit_tests.rs | 207 + tests/integration/npm_tests.rs | 2750 + tests/integration/publish_tests.rs | 277 + tests/integration/repl_tests.rs | 1121 + tests/integration/run_tests.rs | 5142 ++ tests/integration/shared_library_tests.rs | 85 + tests/integration/task_tests.rs | 357 + tests/integration/test_tests.rs | 671 + tests/integration/upgrade_tests.rs | 259 + tests/integration/vendor_tests.rs | 704 + tests/integration/watcher_tests.rs | 1864 + tests/integration/worker_tests.rs | 111 + tests/integration_tests.rs | 7 + tests/integration_tests_runner.rs | 18 + tests/lib.rs | 1 + tests/node_compat/common.ts | 64 + tests/node_compat/config.jsonc | 736 + tests/node_compat/deno.json | 5 + tests/node_compat/polyfill_globals.js | 25 + tests/node_compat/runner.ts | 14 + tests/node_compat/test.ts | 168 + tests/node_compat/test/common/child_process.js | 56 + tests/node_compat/test/common/countdown.js | 35 + tests/node_compat/test/common/dns.js | 327 + tests/node_compat/test/common/duplexpair.js | 55 + tests/node_compat/test/common/fixtures.js | 45 + tests/node_compat/test/common/hijackstdio.js | 39 + tests/node_compat/test/common/index.js | 496 + tests/node_compat/test/common/index.mjs | 115 + tests/node_compat/test/common/internet.js | 68 + tests/node_compat/test/common/package.json | 1 + tests/node_compat/test/common/tmpdir.js | 79 + tests/node_compat/test/fixtures/GH-1899-output.js | 30 + tests/node_compat/test/fixtures/a.js | 53 + .../test/fixtures/child-process-spawn-node.js | 14 + .../fixtures/child_process_should_emit_error.js | 36 + tests/node_compat/test/fixtures/echo.js | 41 + tests/node_compat/test/fixtures/elipses.txt | 1 + tests/node_compat/test/fixtures/empty.txt | 0 tests/node_compat/test/fixtures/exit.js | 31 + .../node_compat/test/fixtures/keys/agent1-cert.pem | 23 + .../node_compat/test/fixtures/keys/agent1-key.pem | 27 + tests/node_compat/test/fixtures/keys/ca1-cert.pem | 22 + tests/node_compat/test/fixtures/loop.js | 17 + tests/node_compat/test/fixtures/package.json | 1 + tests/node_compat/test/fixtures/print-chars.js | 35 + tests/node_compat/test/fixtures/x.txt | 1 + tests/node_compat/test/internet/package.json | 1 + tests/node_compat/test/internet/test-dns-any.js | 194 + .../node_compat/test/internet/test-dns-idna2008.js | 76 + tests/node_compat/test/internet/test-dns-ipv4.js | 257 + tests/node_compat/test/internet/test-dns-ipv6.js | 250 + tests/node_compat/test/internet/test-dns-lookup.js | 61 + .../test/internet/test-dns-promises-resolve.js | 49 + .../test/internet/test-dns-regress-6244.js | 35 + .../test-dns-setserver-in-callback-of-resolve4.js | 25 + tests/node_compat/test/internet/test-dns.js | 766 + .../test/internet/test-http-https-default-ports.js | 46 + tests/node_compat/test/parallel/package.json | 1 + .../node_compat/test/parallel/test-assert-async.js | 244 + .../node_compat/test/parallel/test-assert-fail.js | 51 + .../test/parallel/test-assert-strict-exists.js | 13 + tests/node_compat/test/parallel/test-assert.js | 1615 + .../node_compat/test/parallel/test-bad-unicode.js | 40 + tests/node_compat/test/parallel/test-btoa-atob.js | 46 + .../node_compat/test/parallel/test-buffer-alloc.js | 1200 + .../test/parallel/test-buffer-arraybuffer.js | 159 + .../node_compat/test/parallel/test-buffer-ascii.js | 53 + .../test/parallel/test-buffer-badhex.js | 55 + .../test/parallel/test-buffer-bigint64.js | 62 + .../test/parallel/test-buffer-bytelength.js | 139 + .../test/parallel/test-buffer-compare-offset.js | 101 + .../test/parallel/test-buffer-concat.js | 107 + .../test/parallel/test-buffer-constants.js | 25 + .../node_compat/test/parallel/test-buffer-copy.js | 243 + .../test/parallel/test-buffer-equals.js | 32 + .../test-buffer-failed-alloc-typed-arrays.js | 40 + .../node_compat/test/parallel/test-buffer-fakes.js | 61 + .../node_compat/test/parallel/test-buffer-from.js | 73 + .../test/parallel/test-buffer-includes.js | 317 + .../test/parallel/test-buffer-indexof.js | 646 + .../test/parallel/test-buffer-inheritance.js | 46 + .../test/parallel/test-buffer-isencoding.js | 45 + .../test/parallel/test-buffer-iterator.js | 69 + tests/node_compat/test/parallel/test-buffer-new.js | 18 + .../parallel/test-buffer-no-negative-allocation.js | 45 + .../test/parallel/test-buffer-nopendingdep-map.js | 20 + .../test/parallel/test-buffer-of-no-deprecation.js | 14 + .../test/parallel/test-buffer-over-max-length.js | 37 + .../test/parallel/test-buffer-parent-property.js | 28 + .../node_compat/test/parallel/test-buffer-read.js | 113 + .../test/parallel/test-buffer-readdouble.js | 151 + .../test/parallel/test-buffer-readfloat.js | 113 + .../test/parallel/test-buffer-readint.js | 204 + .../test/parallel/test-buffer-readuint.js | 172 + .../test/parallel/test-buffer-safe-unsafe.js | 31 + .../node_compat/test/parallel/test-buffer-slice.js | 136 + .../node_compat/test/parallel/test-buffer-slow.js | 69 + .../node_compat/test/parallel/test-buffer-swap.js | 159 + .../test/parallel/test-buffer-tojson.js | 42 + .../test/parallel/test-buffer-tostring-range.js | 107 + .../parallel/test-buffer-tostring-rangeerror.js | 28 + .../test/parallel/test-buffer-tostring.js | 44 + .../test/parallel/test-buffer-writedouble.js | 140 + .../test/parallel/test-buffer-writefloat.js | 124 + .../test/parallel/test-buffer-writeint.js | 277 + .../test/parallel/test-buffer-writeuint.js | 237 + .../test/parallel/test-buffer-zero-fill-cli.js | 39 + .../test/parallel/test-buffer-zero-fill-reset.js | 26 + .../test/parallel/test-buffer-zero-fill.js | 21 + .../parallel/test-child-process-default-options.js | 58 + .../parallel/test-child-process-double-pipe.js | 129 + ...ild-process-exec-abortcontroller-promisified.js | 54 + .../test/parallel/test-child-process-exec-cwd.js | 46 + .../parallel/test-child-process-exec-encoding.js | 59 + .../test/parallel/test-child-process-exec-env.js | 71 + .../test/parallel/test-child-process-exec-error.js | 51 + .../test-child-process-exec-kill-throws.js | 42 + .../parallel/test-child-process-exec-maxbuf.js | 161 + .../test-child-process-exec-std-encoding.js | 33 + ...child-process-exec-stdout-stderr-data-string.js | 20 + .../test-child-process-exec-timeout-not-expired.js | 45 + .../parallel/test-child-process-execfile-maxbuf.js | 99 + .../test/parallel/test-child-process-execfile.js | 135 + .../test-child-process-execfilesync-maxbuf.js | 60 + .../parallel/test-child-process-execsync-maxbuf.js | 76 + .../test/parallel/test-child-process-exit-code.js | 51 + .../parallel/test-child-process-flush-stdio.js | 40 + .../test/parallel/test-child-process-fork-ref.js | 72 + .../test/parallel/test-child-process-fork-ref2.js | 63 + .../parallel/test-child-process-ipc-next-tick.js | 52 + .../test/parallel/test-child-process-ipc.js | 73 + .../test/parallel/test-child-process-kill.js | 48 + .../parallel/test-child-process-set-blocking.js | 43 + .../test/parallel/test-child-process-spawn-args.js | 62 + .../parallel/test-child-process-spawn-event.js | 34 + .../parallel/test-child-process-spawnsync-args.js | 55 + .../parallel/test-child-process-spawnsync-env.js | 47 + .../test-child-process-spawnsync-maxbuf.js | 65 + ...st-child-process-spawnsync-validation-errors.js | 223 + .../test/parallel/test-child-process-spawnsync.js | 74 + .../parallel/test-child-process-stdio-inherit.js | 66 + .../test-child-process-stdout-flush-exit.js | 67 + .../parallel/test-child-process-stdout-flush.js | 58 + .../parallel/test-console-async-write-error.js | 22 + .../test/parallel/test-console-group.js | 248 + .../test/parallel/test-console-instance.js | 156 + .../parallel/test-console-log-stdio-broken-dest.js | 31 + .../parallel/test-console-log-throw-primitive.js | 21 + .../test-console-no-swallow-stack-overflow.js | 26 + .../test/parallel/test-console-sync-write-error.js | 46 + .../test/parallel/test-console-table.js | 300 + .../test/parallel/test-console-tty-colors.js | 102 + .../test/parallel/test-crypto-dh-shared.js | 22 + tests/node_compat/test/parallel/test-crypto-dh.js | 214 + .../node_compat/test/parallel/test-crypto-hkdf.js | 203 + .../node_compat/test/parallel/test-crypto-hmac.js | 483 + .../node_compat/test/parallel/test-crypto-prime.js | 302 + .../test/parallel/test-crypto-secret-keygen.js | 144 + .../test/parallel/test-crypto-stream.js | 96 + .../test/parallel/test-crypto-update-encoding.js | 29 + .../node_compat/test/parallel/test-crypto-x509.js | 109 + .../test/parallel/test-dgram-close-during-bind.js | 26 + .../test/parallel/test-dgram-close-signal.js | 38 + .../test/parallel/test-dgram-custom-lookup.js | 56 + .../test/parallel/test-dgram-ipv6only.js | 44 + .../parallel/test-dgram-send-cb-quelches-error.js | 47 + .../test/parallel/test-dgram-socket-buffer-size.js | 178 + .../parallel/test-dgram-udp6-link-local-address.js | 61 + .../test-diagnostics-channel-has-subscribers.js | 17 + ...t-diagnostics-channel-object-channel-pub-sub.js | 53 + .../parallel/test-diagnostics-channel-pub-sub.js | 51 + .../test-diagnostics-channel-symbol-named.js | 35 + .../test/parallel/test-diagnostics-channel-udp.js | 22 + tests/node_compat/test/parallel/test-dns-lookup.js | 179 + .../test/parallel/test-dns-memory-error.js | 23 + .../test/parallel/test-dns-promises-exists.js | 40 + .../test/parallel/test-dns-resolveany.js | 78 + .../test/parallel/test-dns-resolvens-typeerror.js | 62 + .../parallel/test-dns-setservers-type-check.js | 127 + tests/node_compat/test/parallel/test-dns.js | 471 + .../parallel/test-eval-strict-referenceerror.js | 34 + tests/node_compat/test/parallel/test-eval.js | 14 + .../parallel/test-event-emitter-add-listeners.js | 93 + .../parallel/test-event-emitter-emit-context.js | 25 + .../parallel/test-event-emitter-error-monitor.js | 39 + .../test/parallel/test-event-emitter-errors.js | 44 + .../test-event-emitter-get-max-listeners.js | 26 + .../test-event-emitter-invalid-listener.js | 27 + .../parallel/test-event-emitter-listener-count.js | 25 + .../test-event-emitter-listeners-side-effects.js | 67 + .../test/parallel/test-event-emitter-listeners.js | 131 + .../parallel/test-event-emitter-max-listeners.js | 80 + .../parallel/test-event-emitter-method-names.js | 42 + .../parallel/test-event-emitter-modify-in-emit.js | 87 + ...ent-emitter-no-error-provided-to-error-event.js | 65 + .../test/parallel/test-event-emitter-num-args.js | 61 + .../test/parallel/test-event-emitter-once.js | 77 + .../test/parallel/test-event-emitter-prepend.js | 50 + .../test-event-emitter-remove-all-listeners.js | 130 + .../test-event-emitter-remove-listeners.js | 177 + ...event-emitter-set-max-listeners-side-effects.js | 39 + .../test-event-emitter-special-event-names.js | 44 + .../test/parallel/test-event-emitter-subclass.js | 74 + .../test/parallel/test-event-emitter-symbols.js | 30 + .../node_compat/test/parallel/test-events-list.js | 26 + .../test/parallel/test-events-on-async-iterator.js | 399 + .../node_compat/test/parallel/test-events-once.js | 272 + .../test-events-uncaught-exception-stack.js | 23 + .../test/parallel/test-eventtarget-brandcheck.js | 104 + .../test/parallel/test-exception-handler.js | 47 + .../test/parallel/test-exception-handler2.js | 43 + .../test/parallel/test-file-read-noexist.js | 39 + .../test/parallel/test-file-write-stream.js | 91 + .../test/parallel/test-file-write-stream2.js | 116 + .../test/parallel/test-file-write-stream3.js | 221 + .../test/parallel/test-file-write-stream4.js | 28 + tests/node_compat/test/parallel/test-fs-access.js | 242 + .../test/parallel/test-fs-append-file-sync.js | 115 + .../test/parallel/test-fs-append-file.js | 202 + .../test/parallel/test-fs-chmod-mask.js | 106 + tests/node_compat/test/parallel/test-fs-chmod.js | 167 + .../test/parallel/test-fs-chown-type-check.js | 60 + .../node_compat/test/parallel/test-fs-copyfile.js | 174 + .../test/parallel/test-fs-empty-readStream.js | 57 + tests/node_compat/test/parallel/test-fs-mkdir.js | 379 + .../test/parallel/test-fs-open-flags.js | 101 + .../test/parallel/test-fs-open-mode-mask.js | 48 + .../test/parallel/test-fs-open-no-close.js | 38 + .../test/parallel/test-fs-open-numeric-flags.js | 23 + tests/node_compat/test/parallel/test-fs-open.js | 128 + tests/node_compat/test/parallel/test-fs-opendir.js | 300 + .../test/parallel/test-fs-read-stream-autoClose.js | 23 + .../test-fs-read-stream-concurrent-reads.js | 54 + .../parallel/test-fs-read-stream-double-close.js | 26 + .../test/parallel/test-fs-read-stream-encoding.js | 24 + .../test/parallel/test-fs-read-stream-fd.js | 53 + .../test/parallel/test-fs-read-stream-inherit.js | 212 + .../parallel/test-fs-read-stream-patch-open.js | 24 + .../test/parallel/test-fs-read-stream-resume.js | 59 + .../test-fs-read-stream-throw-type-error.js | 84 + .../test/parallel/test-fs-read-stream.js | 284 + .../node_compat/test/parallel/test-fs-read-type.js | 250 + .../test/parallel/test-fs-read-zero-length.js | 25 + tests/node_compat/test/parallel/test-fs-read.js | 109 + .../parallel/test-fs-readdir-stack-overflow.js | 26 + tests/node_compat/test/parallel/test-fs-readdir.js | 60 + .../test/parallel/test-fs-readfile-empty.js | 52 + .../test/parallel/test-fs-realpath-native.js | 25 + ...test-fs-rmdir-recursive-sync-warns-not-found.js | 30 + .../test-fs-rmdir-recursive-sync-warns-on-file.js | 30 + .../test-fs-rmdir-recursive-throws-not-found.js | 43 + .../test-fs-rmdir-recursive-throws-on-file.js | 36 + .../test-fs-rmdir-recursive-warns-not-found.js | 29 + .../test-fs-rmdir-recursive-warns-on-file.js | 29 + .../test/parallel/test-fs-rmdir-recursive.js | 252 + .../test/parallel/test-fs-rmdir-type-check.js | 29 + .../node_compat/test/parallel/test-fs-watchfile.js | 112 + .../test/parallel/test-fs-write-buffer.js | 172 + .../test/parallel/test-fs-write-file-buffer.js | 62 + .../parallel/test-fs-write-file-invalid-path.js | 53 + .../test/parallel/test-fs-write-file-sync.js | 128 + .../test/parallel/test-fs-write-file.js | 115 + .../test/parallel/test-fs-write-no-fd.js | 19 + .../test-fs-write-stream-autoclose-option.js | 66 + .../test-fs-write-stream-close-without-callback.js | 20 + .../parallel/test-fs-write-stream-double-close.js | 53 + .../test/parallel/test-fs-write-stream-end.js | 67 + .../test/parallel/test-fs-write-stream-fs.js | 45 + .../test-fs-write-stream-throw-type-error.js | 39 + .../test/parallel/test-fs-write-stream.js | 74 + .../test/parallel/test-fs-write-sync.js | 63 + tests/node_compat/test/parallel/test-fs-write.js | 212 + .../test/parallel/test-fs-writev-sync.js | 104 + .../test/parallel/test-handle-wrap-close-abort.js | 44 + .../test/parallel/test-http-agent-getname.js | 63 + .../test/parallel/test-http-client-get-url.js | 53 + .../parallel/test-http-client-read-in-error.js | 48 + .../test/parallel/test-http-localaddress.js | 64 + ...st-http-outgoing-internal-headernames-getter.js | 30 + ...st-http-outgoing-internal-headernames-setter.js | 22 + .../test-http-outgoing-internal-headers.js | 51 + .../parallel/test-http-outgoing-renderHeaders.js | 57 + .../test/parallel/test-http-outgoing-settimeout.js | 37 + ...t-http-url.parse-auth-with-header-in-request.js | 59 + .../test/parallel/test-http-url.parse-auth.js | 55 + .../test/parallel/test-http-url.parse-basic.js | 65 + .../parallel/test-http-url.parse-https.request.js | 69 + ...p-url.parse-only-support-http-https-protocol.js | 52 + .../test/parallel/test-http-url.parse-path.js | 53 + .../test/parallel/test-http-url.parse-post.js | 61 + .../test/parallel/test-http-url.parse-search.js | 54 + .../test/parallel/test-net-access-byteswritten.js | 28 + .../test-net-better-error-messages-listen-path.js | 17 + .../test-net-better-error-messages-path.js | 29 + ...test-net-better-error-messages-port-hostname.js | 44 + .../parallel/test-net-connect-after-destroy.js | 16 + .../test/parallel/test-net-connect-buffer.js | 86 + .../test/parallel/test-net-connect-buffer2.js | 63 + .../test/parallel/test-net-connect-destroy.js | 14 + .../parallel/test-net-connect-immediate-destroy.js | 18 + .../parallel/test-net-connect-immediate-finish.js | 66 + .../test/parallel/test-net-connect-no-arg.js | 42 + .../test/parallel/test-net-dns-error.js | 48 + .../test/parallel/test-net-during-close.js | 49 + .../test/parallel/test-net-end-close.js | 44 + .../test/parallel/test-net-end-without-connect.js | 34 + tests/node_compat/test/parallel/test-net-isip.js | 103 + tests/node_compat/test/parallel/test-net-isipv4.js | 53 + tests/node_compat/test/parallel/test-net-isipv6.js | 251 + ...listen-close-server-callback-is-not-function.js | 18 + .../test/parallel/test-net-listen-close-server.js | 37 + .../test/parallel/test-net-listen-invalid-port.js | 52 + .../test/parallel/test-net-listening.js | 23 + .../test/parallel/test-net-localerror.js | 51 + .../test/parallel/test-net-options-lookup.js | 59 + .../test/parallel/test-net-pipe-connect-errors.js | 104 + .../test-net-server-call-listen-multiple-times.js | 56 + .../test-net-server-listen-options-signal.js | 39 + .../parallel/test-net-server-listen-options.js | 101 + .../test/parallel/test-net-server-listen-path.js | 100 + .../test-net-server-listen-remove-callback.js | 51 + .../test/parallel/test-net-server-options.js | 23 + .../test/parallel/test-net-server-try-ports.js | 54 + .../parallel/test-net-server-unref-persistent.js | 19 + .../test/parallel/test-net-server-unref.js | 37 + .../test/parallel/test-net-socket-destroy-twice.js | 43 + .../test-net-socket-no-halfopen-enforcer.js | 18 + .../test/parallel/test-net-socket-timeout.js | 88 + .../test/parallel/test-net-timeout-no-handle.js | 24 + .../test/parallel/test-net-write-arguments.js | 46 + .../test/parallel/test-next-tick-doesnt-hang.js | 37 + .../test-next-tick-fixed-queue-regression.js | 25 + .../test-next-tick-intentional-starvation.js | 68 + .../test/parallel/test-next-tick-ordering.js | 62 + .../test/parallel/test-next-tick-ordering2.js | 46 + .../test/parallel/test-next-tick-when-exiting.js | 21 + tests/node_compat/test/parallel/test-next-tick.js | 70 + .../test/parallel/test-nodeeventtarget.js | 190 + tests/node_compat/test/parallel/test-os.js | 280 + .../test/parallel/test-outgoing-message-destroy.js | 20 + .../test/parallel/test-outgoing-message-pipe.js | 22 + .../node_compat/test/parallel/test-parse-args.mjs | 1001 + .../test/parallel/test-path-basename.js | 83 + .../node_compat/test/parallel/test-path-dirname.js | 66 + .../node_compat/test/parallel/test-path-extname.js | 106 + .../test/parallel/test-path-isabsolute.js | 35 + tests/node_compat/test/parallel/test-path-join.js | 150 + .../test/parallel/test-path-makelong.js | 94 + .../test/parallel/test-path-normalize.js | 79 + .../test/parallel/test-path-parse-format.js | 233 + .../test/parallel/test-path-posix-exists.js | 13 + .../test/parallel/test-path-relative.js | 76 + .../node_compat/test/parallel/test-path-resolve.js | 96 + .../test/parallel/test-path-win32-exists.js | 13 + .../test/parallel/test-path-zero-length-strings.js | 46 + tests/node_compat/test/parallel/test-path.js | 80 + .../test/parallel/test-process-beforeexit.js | 88 + ...st-process-binding-internalbinding-allowlist.js | 48 + .../parallel/test-process-env-allowed-flags.js | 109 + .../parallel/test-process-exit-from-before-exit.js | 37 + .../test/parallel/test-process-exit-handler.js | 21 + .../test/parallel/test-process-exit-recursive.js | 44 + .../node_compat/test/parallel/test-process-exit.js | 42 + .../test/parallel/test-process-kill-pid.js | 116 + .../test/parallel/test-process-uptime.js | 44 + .../test/parallel/test-promise-unhandled-silent.js | 28 + .../test-promise-unhandled-throw-handler.js | 43 + .../test/parallel/test-querystring-escape.js | 48 + .../test-querystring-maxKeys-non-finite.js | 65 + .../test-querystring-multichar-separator.js | 32 + .../node_compat/test/parallel/test-querystring.js | 489 + .../parallel/test-readline-emit-keypress-events.js | 79 + .../test-readline-interface-escapecodetimeout.js | 53 + .../test/parallel/test-readline-interface.js | 1217 + .../test/parallel/test-readline-keys.js | 351 + .../test/parallel/test-readline-position.js | 43 + .../test/parallel/test-readline-reopen.js | 51 + .../test/parallel/test-readline-set-raw-mode.js | 97 + .../parallel/test-readline-undefined-columns.js | 53 + tests/node_compat/test/parallel/test-readline.js | 158 + .../test/parallel/test-stdin-from-file-spawn.js | 52 + .../test/parallel/test-stream-add-abort-signal.js | 34 + .../test/parallel/test-stream-aliases-legacy.js | 21 + .../test/parallel/test-stream-auto-destroy.js | 119 + ...ain-writers-in-synchronously-recursion-write.js | 35 + .../test/parallel/test-stream-backpressure.js | 46 + .../test/parallel/test-stream-big-packet.js | 72 + .../test/parallel/test-stream-big-push.js | 81 + .../test/parallel/test-stream-buffer-list.js | 91 + .../test/parallel/test-stream-construct.js | 287 + .../parallel/test-stream-destroy-event-order.js | 31 + .../test/parallel/test-stream-duplex-destroy.js | 264 + .../test/parallel/test-stream-duplex-end.js | 48 + .../test/parallel/test-stream-duplex-from.js | 413 + .../test/parallel/test-stream-duplex-props.js | 38 + .../parallel/test-stream-duplex-readable-end.js | 36 + .../test-stream-duplex-writable-finished.js | 37 + .../test/parallel/test-stream-duplex.js | 140 + .../test/parallel/test-stream-end-paused.js | 57 + .../test/parallel/test-stream-error-once.js | 26 + .../test/parallel/test-stream-events-prepend.js | 33 + .../test/parallel/test-stream-inheritance.js | 70 + .../test/parallel/test-stream-ispaused.js | 51 + .../parallel/test-stream-objectmode-undefined.js | 51 + .../parallel/test-stream-once-readable-pipe.js | 68 + .../test/parallel/test-stream-pipe-after-end.js | 76 + .../test-stream-pipe-await-drain-manual-resume.js | 82 + ...est-stream-pipe-await-drain-push-while-write.js | 43 + .../test/parallel/test-stream-pipe-await-drain.js | 74 + .../parallel/test-stream-pipe-cleanup-pause.js | 44 + .../test/parallel/test-stream-pipe-cleanup.js | 132 + .../parallel/test-stream-pipe-error-handling.js | 131 + .../test/parallel/test-stream-pipe-event.js | 58 + .../parallel/test-stream-pipe-flow-after-unpipe.js | 36 + .../test/parallel/test-stream-pipe-flow.js | 97 + .../parallel/test-stream-pipe-manual-resume.js | 42 + .../parallel/test-stream-pipe-multiple-pipes.js | 58 + .../test/parallel/test-stream-pipe-needDrain.js | 38 + .../test-stream-pipe-same-destination-twice.js | 85 + .../parallel/test-stream-pipe-unpipe-streams.js | 103 + .../test-stream-pipe-without-listenerCount.js | 24 + .../test-stream-pipeline-async-iterator.js | 38 + .../test-stream-pipeline-queued-end-in-destroy.js | 46 + .../test-stream-pipeline-with-empty-string.js | 25 + .../test/parallel/test-stream-push-strings.js | 74 + .../test/parallel/test-stream-readable-aborted.js | 73 + .../test-stream-readable-add-chunk-during-data.js | 28 + ...test-stream-readable-constructor-set-methods.js | 18 + .../test/parallel/test-stream-readable-data.js | 26 + .../test/parallel/test-stream-readable-destroy.js | 412 + .../test/parallel/test-stream-readable-didRead.js | 118 + ...t-stream-readable-emit-readable-short-stream.js | 153 + .../test-stream-readable-emittedReadable.js | 80 + .../parallel/test-stream-readable-end-destroyed.js | 24 + .../test/parallel/test-stream-readable-ended.js | 53 + .../parallel/test-stream-readable-error-end.js | 22 + .../test/parallel/test-stream-readable-event.js | 135 + .../test-stream-readable-flow-recursion.js | 84 + .../parallel/test-stream-readable-hwm-0-async.js | 34 + .../test-stream-readable-hwm-0-no-flow-data.js | 111 + .../test/parallel/test-stream-readable-hwm-0.js | 37 + .../parallel/test-stream-readable-infinite-read.js | 39 + .../parallel/test-stream-readable-invalid-chunk.js | 41 + .../parallel/test-stream-readable-needReadable.js | 106 + .../parallel/test-stream-readable-next-no-null.js | 26 + .../test-stream-readable-no-unneeded-readable.js | 69 + ...test-stream-readable-object-multi-push-async.js | 190 + .../test-stream-readable-pause-and-resume.js | 81 + .../test-stream-readable-readable-then-resume.js | 38 + .../test/parallel/test-stream-readable-readable.js | 52 + .../test-stream-readable-reading-readingMore.js | 178 + .../parallel/test-stream-readable-resume-hwm.js | 28 + .../test-stream-readable-resumeScheduled.js | 72 + ...stream-readable-setEncoding-existing-buffers.js | 67 + .../test-stream-readable-setEncoding-null.js | 22 + .../test/parallel/test-stream-readable-unshift.js | 177 + ...est-stream-readable-with-unimplemented-_read.js | 20 + .../test-stream-readableListening-state.js | 41 + .../test-stream-transform-callback-twice.js | 21 + ...est-stream-transform-constructor-set-methods.js | 50 + .../test/parallel/test-stream-transform-destroy.js | 150 + .../parallel/test-stream-transform-final-sync.js | 117 + .../test/parallel/test-stream-transform-final.js | 119 + .../parallel/test-stream-transform-flush-data.js | 35 + ...est-stream-transform-objectmode-falsey-value.js | 58 + .../test-stream-transform-split-highwatermark.js | 80 + .../test-stream-transform-split-objectmode.js | 88 + .../test/parallel/test-stream-uint8array.js | 108 + .../test/parallel/test-stream-unpipe-event.js | 92 + .../parallel/test-stream-unshift-empty-chunk.js | 87 + .../test/parallel/test-stream-unshift-read-race.js | 135 + ...test-stream-writable-change-default-encoding.js | 85 + .../parallel/test-stream-writable-clear-buffer.js | 42 + ...test-stream-writable-constructor-set-methods.js | 48 + .../test-stream-writable-decoded-encoding.js | 65 + .../test/parallel/test-stream-writable-destroy.js | 496 + .../parallel/test-stream-writable-end-cb-error.js | 85 + .../parallel/test-stream-writable-end-multiple.js | 29 + .../parallel/test-stream-writable-ended-state.js | 39 + .../test-stream-writable-finish-destroyed.js | 50 + .../test-stream-writable-finished-state.js | 29 + .../test/parallel/test-stream-writable-finished.js | 106 + .../parallel/test-stream-writable-invalid-chunk.js | 43 + .../test-stream-writable-needdrain-state.js | 32 + .../test/parallel/test-stream-writable-null.js | 54 + .../parallel/test-stream-writable-properties.js | 29 + .../test/parallel/test-stream-writable-writable.js | 55 + .../test-stream-writable-write-cb-error.js | 65 + .../test-stream-writable-write-cb-twice.js | 59 + .../parallel/test-stream-writable-write-error.js | 82 + .../test-stream-writable-write-writev-finish.js | 159 + .../parallel/test-stream-writableState-ending.js | 44 + ...-writableState-uncorked-bufferedRequestCount.js | 64 + .../test/parallel/test-stream-write-destroy.js | 69 + .../test/parallel/test-stream-write-drain.js | 23 + .../test/parallel/test-stream-write-final.js | 31 + .../test/parallel/test-stream-writev.js | 137 + .../test-stream2-base64-single-char-read-end.js | 63 + .../test/parallel/test-stream2-basic.js | 452 + .../test/parallel/test-stream2-compatibility.js | 77 + .../test/parallel/test-stream2-decode-partial.js | 30 + .../test/parallel/test-stream2-finish-pipe.js | 51 + .../test/parallel/test-stream2-large-read-stall.js | 81 + .../test/parallel/test-stream2-objects.js | 304 + .../parallel/test-stream2-pipe-error-handling.js | 113 + .../test-stream2-pipe-error-once-listener.js | 60 + .../node_compat/test/parallel/test-stream2-push.js | 143 + .../test/parallel/test-stream2-read-sync-stack.js | 53 + .../test-stream2-readable-empty-buffer-no-eof.js | 124 + .../parallel/test-stream2-readable-from-list.js | 108 + .../parallel/test-stream2-readable-legacy-drain.js | 62 + .../test-stream2-readable-non-empty-end.js | 79 + .../parallel/test-stream2-readable-wrap-destroy.js | 34 + .../parallel/test-stream2-readable-wrap-empty.js | 45 + .../parallel/test-stream2-readable-wrap-error.js | 44 + .../test/parallel/test-stream2-readable-wrap.js | 107 + .../test/parallel/test-stream2-set-encoding.js | 330 + .../test/parallel/test-stream2-transform.js | 501 + .../test/parallel/test-stream2-unpipe-drain.js | 79 + .../test/parallel/test-stream2-unpipe-leak.js | 80 + .../test/parallel/test-stream2-writable.js | 466 + .../test/parallel/test-stream3-cork-end.js | 98 + .../test/parallel/test-stream3-cork-uncork.js | 93 + .../test/parallel/test-stream3-pause-then-read.js | 177 + .../test/parallel/test-streams-highwatermark.js | 94 + .../test/parallel/test-timers-api-refs.js | 28 + .../node_compat/test/parallel/test-timers-args.js | 38 + .../test-timers-clear-null-does-not-throw-error.js | 18 + ...est-timers-clear-object-does-not-throw-error.js | 15 + ...est-timers-clear-timeout-interval-equivalent.js | 25 + .../test/parallel/test-timers-clearImmediate.js | 20 + .../test/parallel/test-timers-interval-throw.js | 24 + .../test/parallel/test-timers-non-integer-delay.js | 88 + .../test/parallel/test-timers-refresh.js | 109 + .../test-timers-same-timeout-wrong-list-deleted.js | 41 + .../test-timers-timeout-with-non-integer.js | 22 + .../parallel/test-timers-uncaught-exception.js | 46 + .../parallel/test-timers-unref-throw-then-ref.js | 26 + .../test/parallel/test-timers-user-call.js | 47 + .../test/parallel/test-timers-zero-timeout.js | 56 + .../test/parallel/test-tty-stdin-end.js | 14 + .../test/parallel/test-ttywrap-invalid-fd.js | 74 + .../test/parallel/test-url-domain-ascii-unicode.js | 38 + .../test/parallel/test-url-fileurltopath.js | 161 + .../test/parallel/test-url-format-invalid-input.js | 34 + .../test/parallel/test-url-format-whatwg.js | 149 + tests/node_compat/test/parallel/test-url-format.js | 284 + .../test/parallel/test-url-parse-invalid-input.js | 83 + .../test/parallel/test-url-parse-query.js | 97 + .../test/parallel/test-url-pathtofileurl.js | 153 + .../node_compat/test/parallel/test-url-relative.js | 441 + .../test/parallel/test-url-urltooptions.js | 45 + .../parallel/test-util-deprecate-invalid-code.js | 21 + .../test/parallel/test-util-deprecate.js | 64 + .../node_compat/test/parallel/test-util-format.js | 504 + .../test/parallel/test-util-inherits.js | 117 + .../parallel/test-util-inspect-long-running.js | 27 + .../test/parallel/test-util-inspect-namespace.js | 28 + .../test/parallel/test-util-inspect-proxy.js | 172 + .../node_compat/test/parallel/test-util-inspect.js | 3201 ++ .../test/parallel/test-util-isDeepStrictEqual.js | 608 + .../test/parallel/test-util-promisify.js | 218 + .../test/parallel/test-util-types-exists.js | 13 + tests/node_compat/test/parallel/test-util-types.js | 304 + tests/node_compat/test/parallel/test-util.js | 202 + .../parallel/test-vm-new-script-this-context.js | 75 + .../test/parallel/test-vm-static-this.js | 72 + .../test/parallel/test-webcrypto-sign-verify.js | 154 + .../test-whatwg-encoding-custom-api-basics.js | 68 + ...whatwg-encoding-custom-textdecoder-ignorebom.js | 37 + ...whatwg-encoding-custom-textdecoder-streaming.js | 45 + ...wg-events-add-event-listener-options-passive.js | 72 + ...twg-events-add-event-listener-options-signal.js | 166 + .../parallel/test-whatwg-events-customevent.js | 40 + .../parallel/test-whatwg-url-custom-deepequal.js | 25 + .../test/parallel/test-whatwg-url-custom-global.js | 33 + .../test-whatwg-url-custom-href-side-effect.js | 22 + .../parallel/test-whatwg-url-custom-tostringtag.js | 39 + .../parallel/test-whatwg-url-override-hostname.js | 27 + .../test/parallel/test-whatwg-url-properties.js | 111 + .../test/parallel/test-zlib-close-after-error.js | 23 + .../test/parallel/test-zlib-close-after-write.js | 37 + .../test/parallel/test-zlib-convenience-methods.js | 144 + .../parallel/test-zlib-deflate-raw-inherits.js | 34 + .../test/parallel/test-zlib-destroy-pipe.js | 28 + .../test/parallel/test-zlib-empty-buffer.js | 35 + .../test/parallel/test-zlib-from-string.js | 90 + .../test/parallel/test-zlib-invalid-input.js | 68 + .../test/parallel/test-zlib-no-stream.js | 21 + .../test/parallel/test-zlib-random-byte-pipes.js | 166 + .../test/parallel/test-zlib-sync-no-event.js | 26 + .../test/parallel/test-zlib-truncated.js | 71 + .../parallel/test-zlib-unzip-one-byte-chunks.js | 37 + .../test/parallel/test-zlib-write-after-end.js | 23 + .../test/parallel/test-zlib-write-after-flush.js | 57 + .../test/parallel/test-zlib-zero-byte.js | 53 + .../test/parallel/test-zlib-zero-windowBits.js | 41 + .../test/pseudo-tty/console-dumb-tty.js | 16 + .../node_compat/test/pseudo-tty/console_colors.js | 29 + .../test/pseudo-tty/no_dropped_stdio.js | 26 + .../test/pseudo-tty/no_interleaved_stdio.js | 28 + tests/node_compat/test/pseudo-tty/package.json | 1 + .../pseudo-tty/test-tty-color-support-warning-2.js | 15 + .../pseudo-tty/test-tty-color-support-warning.js | 16 + .../test/pseudo-tty/test-tty-stdin-end.js | 14 + .../test/pseudo-tty/test-tty-stdout-end.js | 11 + tests/node_compat/test/pummel/package.json | 1 + tests/node_compat/test/sequential/package.json | 1 + .../test/sequential/test-child-process-exit.js | 69 + tests/testdata/allow_run_allowlist_resolution.ts | 66 + .../testdata/allow_run_allowlist_resolution.ts.out | 15 + tests/testdata/assets/DenoWinRunner.cs | 127 + tests/testdata/assets/DenoWinRunner.ps1 | 10 + tests/testdata/assets/deno_dom_0.1.3-alpha2.wasm | Bin 0 -> 616631 bytes tests/testdata/assets/fixture.json | 14 + tests/testdata/assets/hello.txt | 1 + tests/testdata/assets/lock_target.txt | 1 + tests/testdata/assets/unreachable.wasm | Bin 0 -> 42 bytes tests/testdata/bench/allow_all.out | 21 + tests/testdata/bench/allow_all.ts | 43 + tests/testdata/bench/allow_none.out | 22 + tests/testdata/bench/allow_none.ts | 23 + .../bench/before_unload_prevent_default.out | 7 + .../bench/before_unload_prevent_default.ts | 6 + tests/testdata/bench/bench_formatting.out | 8 + tests/testdata/bench/bench_formatting.ts | 3 + tests/testdata/bench/check_local_by_default.out | 6 + tests/testdata/bench/check_local_by_default.ts | 3 + tests/testdata/bench/check_local_by_default2.out | 4 + tests/testdata/bench/check_local_by_default2.ts | 6 + tests/testdata/bench/clear_timeout.out | 10 + tests/testdata/bench/clear_timeout.ts | 5 + tests/testdata/bench/collect.out | 18 + tests/testdata/bench/collect/bench.ts | 0 tests/testdata/bench/collect/deno.jsonc | 5 + tests/testdata/bench/collect/deno.malformed.jsonc | 5 + tests/testdata/bench/collect/deno2.jsonc | 6 + tests/testdata/bench/collect/ignore/bench.ts | 1 + tests/testdata/bench/collect/include/2_bench.ts | 0 tests/testdata/bench/collect/include/bench.ts | 0 tests/testdata/bench/collect2.out | 13 + .../bench/collect_with_malformed_config.out | 4 + tests/testdata/bench/exit_sanitizer.out | 14 + tests/testdata/bench/exit_sanitizer.ts | 11 + tests/testdata/bench/explicit_start_and_end.out | 25 + tests/testdata/bench/explicit_start_and_end.ts | 50 + .../bench/explicit_start_and_end_low_precision.out | 10 + .../bench/explicit_start_and_end_low_precision.ts | 4 + tests/testdata/bench/fail.out | 28 + tests/testdata/bench/fail.ts | 30 + tests/testdata/bench/file_protocol.out | 8 + tests/testdata/bench/file_protocol.ts | 1 + tests/testdata/bench/filter.out | 20 + tests/testdata/bench/filter/a_bench.ts | 3 + tests/testdata/bench/filter/b_bench.ts | 3 + tests/testdata/bench/filter/c_bench.ts | 3 + tests/testdata/bench/finally_timeout.out | 11 + tests/testdata/bench/finally_timeout.ts | 11 + tests/testdata/bench/group_baseline.out | 20 + tests/testdata/bench/group_baseline.ts | 15 + tests/testdata/bench/ignore.out | 8 + tests/testdata/bench/ignore.ts | 9 + tests/testdata/bench/ignore_permissions.out | 8 + tests/testdata/bench/ignore_permissions.ts | 16 + tests/testdata/bench/interval.out | 8 + tests/testdata/bench/interval.ts | 1 + tests/testdata/bench/load_unload.out | 8 + tests/testdata/bench/load_unload.ts | 22 + tests/testdata/bench/meta.out | 10 + tests/testdata/bench/meta.ts | 2 + tests/testdata/bench/multifile_summary.out | 64 + tests/testdata/bench/multiple_group.ts | 15 + tests/testdata/bench/no_check.out | 9 + tests/testdata/bench/no_check.ts | 1 + tests/testdata/bench/no_color.ts | 17 + tests/testdata/bench/no_prompt_by_default.out | 9 + tests/testdata/bench/no_prompt_by_default.ts | 3 + .../testdata/bench/no_prompt_with_denied_perms.out | 9 + .../testdata/bench/no_prompt_with_denied_perms.ts | 3 + tests/testdata/bench/no_run.out | 5 + tests/testdata/bench/no_run.ts | 2 + tests/testdata/bench/only.out | 9 + tests/testdata/bench/only.ts | 15 + tests/testdata/bench/overloads.out | 12 + tests/testdata/bench/overloads.ts | 6 + tests/testdata/bench/pass.json.out | 28 + tests/testdata/bench/pass.out | 17 + tests/testdata/bench/pass.ts | 10 + tests/testdata/bench/quiet.out | 10 + tests/testdata/bench/quiet.ts | 15 + .../testdata/bench/recursive_permissions_pledge.js | 6 + tests/testdata/bench/unhandled_rejection.out | 11 + tests/testdata/bench/unhandled_rejection.ts | 3 + tests/testdata/bench/unresolved_promise.out | 9 + tests/testdata/bench/unresolved_promise.ts | 1 + tests/testdata/benches/response_string_perf.js | 34 + tests/testdata/benches/text_decoder_perf.js | 38 + tests/testdata/benches/text_encoder_into_perf.js | 34 + tests/testdata/benches/text_encoder_perf.js | 33 + .../bundle/bare_imports/error_with_bare_import.ts | 1 + .../bare_imports/error_with_bare_import.ts.out | 2 + tests/testdata/bundle/bundle.test.out | 27 + .../bundle/check_local_by_default/no_errors.out | 6 + .../bundle/check_local_by_default/no_errors.ts | 3 + .../bundle/check_local_by_default/type_error.out | 4 + .../bundle/check_local_by_default/type_error.ts | 6 + tests/testdata/bundle/decorators/ts_decorators.out | 49 + tests/testdata/bundle/decorators/ts_decorators.ts | 25 + tests/testdata/bundle/dynamic_import.ts | 3 + .../file_extensions/js_without_extension.out | 8 + .../file_extensions/ts_without_extension.out | 7 + tests/testdata/bundle/file_tests-fixture01.ts | 3 + tests/testdata/bundle/file_tests-fixture02.ts | 4 + tests/testdata/bundle/file_tests-fixture03.ts | 3 + tests/testdata/bundle/file_tests-fixture04.ts | 3 + tests/testdata/bundle/file_tests-fixture05.ts | 3 + tests/testdata/bundle/file_tests-fixture06.ts | 4 + tests/testdata/bundle/file_tests-fixture07.ts | 4 + tests/testdata/bundle/file_tests-fixture08.ts | 1 + tests/testdata/bundle/file_tests-fixture09.ts | 1 + tests/testdata/bundle/file_tests-fixture10.ts | 7 + tests/testdata/bundle/file_tests-fixture11.ts | 32 + tests/testdata/bundle/file_tests-fixture12.ts | 7 + tests/testdata/bundle/file_tests-fixture13.ts | 11 + tests/testdata/bundle/file_tests-fixture14.ts | 4 + tests/testdata/bundle/file_tests-fixture15.ts | 3 + tests/testdata/bundle/file_tests-fixture16.ts | 6 + tests/testdata/bundle/file_tests-fixture16_2.ts | 2 + tests/testdata/bundle/file_tests-subdir-a.ts | 1 + tests/testdata/bundle/file_tests-subdir-b.ts | 3 + tests/testdata/bundle/file_tests-subdir-c.ts | 2 + tests/testdata/bundle/file_tests-subdir-d.ts | 3 + tests/testdata/bundle/file_tests-subdir-e.ts | 1 + tests/testdata/bundle/file_tests-subdir-f.ts | 2 + tests/testdata/bundle/file_tests-subdir-g.ts | 12 + tests/testdata/bundle/file_tests-subdir-h.ts | 12 + tests/testdata/bundle/file_tests-subdir-i.ts | 3 + tests/testdata/bundle/file_tests-subdir-j.ts | 3 + tests/testdata/bundle/file_tests-subdir-k.ts | 11 + tests/testdata/bundle/file_tests-subdir-l.ts | 1 + tests/testdata/bundle/file_tests-subdir-m.ts | 2 + tests/testdata/bundle/file_tests-subdir-n.ts | 3 + tests/testdata/bundle/file_tests-subdir-o.ts | 5 + tests/testdata/bundle/file_tests-subdir-p.ts | 1 + tests/testdata/bundle/file_tests-subdir-q.ts | 13 + tests/testdata/bundle/fixture01.out | 7 + tests/testdata/bundle/fixture02.out | 12 + tests/testdata/bundle/fixture03.out | 5 + tests/testdata/bundle/fixture04.out | 2 + tests/testdata/bundle/fixture05.out | 2 + tests/testdata/bundle/fixture06.out | 12 + tests/testdata/bundle/fixture07.out | 23 + tests/testdata/bundle/fixture08.out | 7 + tests/testdata/bundle/fixture09.out | 19 + tests/testdata/bundle/fixture10.out | 5 + tests/testdata/bundle/fixture11.out | 30 + tests/testdata/bundle/fixture12.out | 7 + tests/testdata/bundle/fixture13.out | 17 + tests/testdata/bundle/fixture14.out | 2 + tests/testdata/bundle/fixture15.out | 4 + tests/testdata/bundle/fixture16.out | 6 + tests/testdata/bundle/https_deno.land-x-lib-a.ts | 1 + tests/testdata/bundle/https_deno.land-x-lib-b.js | 1 + tests/testdata/bundle/https_deno.land-x-lib-c.d.ts | 1 + tests/testdata/bundle/https_deno.land-x-lib-c.js | 3 + .../testdata/bundle/https_deno.land-x-lib-mod.d.ts | 9 + tests/testdata/bundle/https_deno.land-x-lib-mod.js | 5 + tests/testdata/bundle/ignore_directives.test.out | 6 + tests/testdata/bundle/import_map/import_map.json | 5 + tests/testdata/bundle/import_map/main.ts | 17 + tests/testdata/bundle/jsx.out | 9 + tests/testdata/bundle/lockfile/check_error.json | 5 + tests/testdata/bundle/lockfile/check_error.out | 4 + tests/testdata/bundle/shebang_file.bundle.out | 12 + tests/testdata/cache/036_import_map_fetch.out | 0 tests/testdata/cache/037_fetch_multiple.out | 5 + tests/testdata/cache/095_cache_with_bare_import.ts | 1 + .../cache/095_cache_with_bare_import.ts.out | 2 + tests/testdata/cache/cache_extensionless.out | 2 + tests/testdata/cache/cache_random_extension.out | 2 + tests/testdata/cache/check_local_by_default.out | 0 tests/testdata/cache/check_local_by_default.ts | 3 + tests/testdata/cache/check_local_by_default2.out | 0 tests/testdata/cache/check_local_by_default2.ts | 6 + tests/testdata/cache/ignore_require.js | 2 + tests/testdata/cache/json_import/main.ts | 2 + tests/testdata/cache/json_import/test.json | 5 + tests/testdata/cache/performance_stats.out | 16 + tests/testdata/cache/redirect_cache.out | 5 + tests/testdata/cat.ts | 10 + tests/testdata/cert/cafile_info.ts | 24 + tests/testdata/cert/cafile_info.ts.out | 14 + tests/testdata/cert/cafile_ts_fetch.ts | 3 + tests/testdata/cert/cafile_ts_fetch.ts.out | 2 + .../cert/cafile_ts_fetch_unsafe_ssl.ts.out | 3 + tests/testdata/cert/cafile_url_imports.ts | 3 + tests/testdata/cert/cafile_url_imports.ts.out | 2 + .../cert/cafile_url_imports_unsafe_ssl.ts.out | 3 + tests/testdata/cert/deno_land_unsafe_ssl.ts | 2 + tests/testdata/cert/deno_land_unsafe_ssl.ts.out | 2 + tests/testdata/cert/ip_address_unsafe_ssl.ts | 2 + tests/testdata/cert/ip_address_unsafe_ssl.ts.out | 2 + tests/testdata/cert/listen_tls_alpn.ts | 14 + tests/testdata/cert/listen_tls_alpn_fail.ts | 20 + tests/testdata/cert/localhost_unsafe_ssl.ts.out | 3 + tests/testdata/check/all/check_all.out | 4 + tests/testdata/check/all/check_all.ts | 3 + tests/testdata/check/broadcast_channel.ts | 1 + tests/testdata/check/cache_config_on_off/deno.json | 5 + tests/testdata/check/cache_config_on_off/main.ts | 1 + .../declaration_header_file_with_no_exports.ts | 2 + ...declaration_header_file_with_no_exports_js.d.ts | 0 .../declaration_header_file_with_no_exports_js.js | 1 + tests/testdata/check/deno_not_found/main.out | 4 + tests/testdata/check/deno_not_found/main.ts | 4 + tests/testdata/check/dts/check_dts.d.ts | 2 + tests/testdata/check/dts/check_dts.out | 4 + .../check/exclude_option/deno.exclude_dir.json | 5 + .../check/exclude_option/deno.exclude_glob.json | 5 + tests/testdata/check/exclude_option/deno.json | 3 + .../exclude_option/exclude_option.ts.error.out | 4 + .../testdata/check/exclude_option/ignored/index.ts | 1 + tests/testdata/check/exclude_option/index.ts | 5 + .../check/excluded_file_specified/check.out | 1 + .../check/excluded_file_specified/deno.json | 6 + .../check/excluded_file_specified/lib/types.d.ts | 2 + .../check/export_equals_declaration_file/main.ts | 6 + .../export_equals_declaration_file/other.d.ts | 9 + .../check/export_equals_declaration_file/other.js | 3 + tests/testdata/check/jsx_not_checked/main.jsx | 21 + tests/testdata/check/jsx_not_checked/main.out | 13 + tests/testdata/check/jsx_not_checked/other.ts | 5 + .../jsximportsource_importmap_config/deno.json | 7 + .../import_map.json | 5 + .../jsx_runtime.ts | 4 + .../main.bundle.js | 9 + .../jsximportsource_importmap_config/main.tsx | 1 + tests/testdata/check/module_detection_force.ts | 3 + .../check/module_detection_force/import.ts | 2 + .../testdata/check/module_detection_force/main.ts | 3 + tests/testdata/check/no_error_truncation/deno.json | 5 + tests/testdata/check/no_error_truncation/main.out | 11 + tests/testdata/check/no_error_truncation/main.ts | 12 + tests/testdata/check/node_builtin_modules/mod.js | 3 + .../testdata/check/node_builtin_modules/mod.js.out | 5 + tests/testdata/check/node_builtin_modules/mod.ts | 9 + .../testdata/check/node_builtin_modules/mod.ts.out | 13 + .../check/npm_install_diagnostics/main.out | 11 + .../testdata/check/npm_install_diagnostics/main.ts | 2 + tests/testdata/check/response_json.ts | 5 + tests/testdata/check/types_dts/deno.json | 7 + tests/testdata/check/types_dts/main.out | 1 + tests/testdata/check/types_dts/main.ts | 3 + tests/testdata/check/types_dts/types.d.ts | 3 + tests/testdata/commonjs/data.json | 3 + tests/testdata/commonjs/example.js | 11 + .../commonjs/node_modules/colorette/index.cjs | 74 + .../commonjs/node_modules/colorette/index.js | 75 + .../commonjs/node_modules/colorette/package.json | 23 + .../node_modules/imports_exports/import_export.js | 6 + .../imports_exports/import_polyfill.js | 3 + .../node_modules/imports_exports/package.json | 17 + .../imports_exports/require_export.cjs | 6 + .../imports_exports/require_polyfill.js | 3 + .../commonjs/node_modules/left-pad/README.md | 41 + .../commonjs/node_modules/left-pad/index.js | 54 + .../commonjs/node_modules/left-pad/package.json | 68 + tests/testdata/commonjs/package.json | 17 + tests/testdata/compile/args.ts | 3 + tests/testdata/compile/check_local_by_default.ts | 3 + tests/testdata/compile/check_local_by_default2.ts | 6 + tests/testdata/compile/dynamic_imports/import1.ts | 3 + tests/testdata/compile/dynamic_imports/import2.ts | 1 + tests/testdata/compile/dynamic_imports/import_path | 1 + tests/testdata/compile/dynamic_imports/main.out | 5 + tests/testdata/compile/dynamic_imports/main.ts | 6 + .../compile/dynamic_imports/main_unanalyzable.ts | 18 + .../compile/dynamic_imports_tmp_lit/main.info.out | 10 + .../compile/dynamic_imports_tmp_lit/main.js | 14 + .../dynamic_imports_tmp_lit/other/data.json | 3 + .../dynamic_imports_tmp_lit/other/sub/data2.json | 3 + .../compile/dynamic_imports_tmp_lit/sub/a.js | 1 + .../compile/dynamic_imports_tmp_lit/sub/b.ts | 1 + .../compile/node_modules_symlink_outside/main.out | 2 + .../compile/node_modules_symlink_outside/main.ts | 6 + .../main_compile_file.out | 2 + .../main_compile_folder.out | 6 + tests/testdata/compile/npm_fs/main.out | 1 + tests/testdata/compile/npm_fs/main.ts | 259 + tests/testdata/compile/standalone_error.ts | 9 + .../standalone_error_module_with_imports_1.ts | 1 + .../standalone_error_module_with_imports_2.ts | 2 + .../compile/standalone_follow_redirects.ts | 2 + .../compile/standalone_follow_redirects_2.js | 5 + .../testdata/compile/standalone_import_datauri.ts | 4 + tests/testdata/compile/standalone_import_map.json | 5 + tests/testdata/compile/standalone_import_map.ts | 1 + .../compile/standalone_import_map_config.json | 3 + tests/testdata/compile/standalone_runtime_flags.ts | 3 + tests/testdata/compile/unstable_features.ts | 2 + .../compile/vfs_implicit_read_permission/main.out | 8 + .../compile/vfs_implicit_read_permission/main.ts | 3 + tests/testdata/compile/workers/basic.out | 5 + tests/testdata/compile/workers/basic.ts | 11 + .../testdata/compile/workers/not_in_module_map.ts | 11 + tests/testdata/compile/workers/worker.ts | 14 + tests/testdata/coverage/branch.ts | 15 + tests/testdata/coverage/branch_expected.lcov | 27 + tests/testdata/coverage/branch_expected.out | 12 + tests/testdata/coverage/branch_test.ts | 5 + tests/testdata/coverage/complex.ts | 74 + tests/testdata/coverage/complex_expected.lcov | 67 + tests/testdata/coverage/complex_expected.out | 20 + tests/testdata/coverage/complex_test.ts | 39 + tests/testdata/coverage/doesnt_exist.out | 1 + tests/testdata/coverage/final_blankline.js | 5 + .../coverage/final_blankline_expected.lcov | 16 + .../testdata/coverage/final_blankline_expected.out | 1 + tests/testdata/coverage/final_blankline_test.js | 5 + tests/testdata/coverage/invalid_cache/mod.test.ts | 2 + tests/testdata/coverage/invalid_cache/mod_after.ts | 6 + .../testdata/coverage/invalid_cache/mod_before.ts | 15 + tests/testdata/coverage/multifile/a_test.js | 8 + tests/testdata/coverage/multifile/b_test.js | 8 + tests/testdata/coverage/multifile/expected.lcov | 18 + tests/testdata/coverage/multifile/expected.out | 1 + tests/testdata/coverage/multifile/mod.js | 6 + tests/testdata/coverage/multisource/bar.ts | 7 + tests/testdata/coverage/multisource/baz/quux.ts | 14 + tests/testdata/coverage/multisource/baz/qux.ts | 7 + tests/testdata/coverage/multisource/foo.ts | 14 + tests/testdata/coverage/multisource/test.ts | 22 + tests/testdata/coverage/no_internal_code_test.ts | 7 + .../coverage/no_internal_node_code_test.ts | 8 + .../testdata/coverage/no_npm_coverage/expected.out | 1 + .../coverage/no_npm_coverage/no_npm_coverage.ts | 4 + .../no_npm_coverage/no_npm_coverage_test.ts | 4 + .../__snapshots__/no_snaps_included_test.ts.snap | 3 + .../coverage/no_snaps_included/expected.out | 1 + .../no_snaps_included/no_snaps_included.ts | 3 + .../no_snaps_included/no_snaps_included_test.ts | 11 + .../coverage/no_tests_included/expected.out | 1 + .../coverage/no_tests_included/foo.test.js | 6 + .../coverage/no_tests_included/foo.test.mts | 6 + .../coverage/no_tests_included/foo.test.ts | 6 + tests/testdata/coverage/no_tests_included/foo.ts | 3 + .../coverage/no_transpiled_lines/expected.lcov | 10 + .../coverage/no_transpiled_lines/expected.out | 1 + .../testdata/coverage/no_transpiled_lines/index.ts | 3 + .../coverage/no_transpiled_lines/interface.ts | 3 + .../coverage/no_transpiled_lines/repro_test.ts | 7 + ...o_doc_displays_all_overloads_in_details_view.ts | 6 + ...c_displays_all_overloads_in_details_view.ts.out | 9 + tests/testdata/doc/deno_doc.ts | 3 + tests/testdata/doc/deno_doc2.ts | 3 + tests/testdata/doc/deno_doc_builtin.out | 3 + tests/testdata/doc/import_map.json | 5 + tests/testdata/doc/invalid_url.out | 4 + tests/testdata/doc/lint_success.out | 1 + tests/testdata/doc/lint_success.ts | 5 + tests/testdata/doc/lint_success_html.out | 1 + tests/testdata/doc/lint_success_json.out | 50 + tests/testdata/doc/module/fun.js | 2 + tests/testdata/doc/referenced_private_types.out | 12 + tests/testdata/doc/referenced_private_types.ts | 7 + .../doc/referenced_private_types_fixed.out | 1 + .../testdata/doc/referenced_private_types_fixed.ts | 11 + .../testdata/doc/referenced_private_types_lint.out | 28 + tests/testdata/doc/types_header.out | 6 + tests/testdata/doc/types_header.ts | 1 + tests/testdata/doc/types_hint.out | 5 + tests/testdata/doc/types_hint.ts | 2 + tests/testdata/doc/types_ref.js | 2 + tests/testdata/doc/types_ref.out | 5 + tests/testdata/doc/use_import_map.js | 1 + tests/testdata/doc/use_import_map.out | 5 + tests/testdata/dynamic_import/b.js | 2 + tests/testdata/dynamic_import/c.js | 2 + tests/testdata/dynamic_import/empty_1.ts | 0 tests/testdata/dynamic_import/empty_2.ts | 0 .../dynamic_import/permissions_blob_local.ts | 6 + .../dynamic_import/permissions_blob_local.ts.out | 5 + .../dynamic_import/permissions_blob_remote.ts | 4 + .../dynamic_import/permissions_blob_remote.ts.out | 5 + .../dynamic_import/permissions_data_local.ts | 5 + .../dynamic_import/permissions_data_local.ts.out | 5 + .../dynamic_import/permissions_data_remote.ts | 3 + .../dynamic_import/permissions_data_remote.ts.out | 5 + .../dynamic_import/permissions_remote_remote.ts | 3 + .../permissions_remote_remote.ts.out | 5 + .../static_analysis_no_permissions.ts | 13 + .../static_analysis_no_permissions.ts.out | 2 + tests/testdata/dynamic_import/static_remote.ts | 2 + tests/testdata/echo.ts | 6 + tests/testdata/echo_server.ts | 12 + tests/testdata/encoding/utf-16be.ts | Bin 0 -> 58 bytes tests/testdata/encoding/utf-16le.ts | Bin 0 -> 58 bytes tests/testdata/encoding/utf-8.ts | 1 + tests/testdata/encoding/windows-1255 | 1 + tests/testdata/env | 4 + tests/testdata/error_cause_recursive_aggregate.ts | 9 + .../error_cause_recursive_aggregate.ts.out | 14 + tests/testdata/error_cause_recursive_tail.ts | 5 + tests/testdata/error_cause_recursive_tail.ts.out | 9 + tests/testdata/eval/check_local_by_default.out | 1 + tests/testdata/eval/check_local_by_default2.out | 3 + tests/testdata/eval/check_local_by_default2.ts | 6 + tests/testdata/eval/dyn_import_eval.out | 1 + tests/testdata/eval/env_file_missing.out | 2 + .../testdata/file_extensions/js_without_extension | 3 + .../file_extensions/js_without_extension.out | 1 + .../testdata/file_extensions/ts_with_extension.out | 1 + .../testdata/file_extensions/ts_with_extension.ts | 5 + .../file_extensions/ts_with_js_extension.js | 5 + .../file_extensions/ts_with_js_extension.out | 2 + .../testdata/file_extensions/ts_without_extension | 3 + .../file_extensions/ts_without_extension.out | 2 + tests/testdata/fmt/badly_formatted.ipynb | 105 + tests/testdata/fmt/badly_formatted.json | 12 + tests/testdata/fmt/badly_formatted.md | 46 + tests/testdata/fmt/badly_formatted.mjs | 4 + tests/testdata/fmt/badly_formatted_fixed.ipynb | 106 + tests/testdata/fmt/badly_formatted_fixed.js | 2 + tests/testdata/fmt/badly_formatted_fixed.json | 8 + tests/testdata/fmt/badly_formatted_fixed.md | 37 + tests/testdata/fmt/deno.glob.json | 11 + tests/testdata/fmt/deno.malformed.jsonc | 10 + tests/testdata/fmt/deno.malformed2.jsonc | 10 + .../fmt/expected_fmt_check_formatted_files.out | 1 + tests/testdata/fmt/expected_fmt_check_ignore.out | 1 + .../expected_fmt_check_verbose_formatted_files.out | 1 + tests/testdata/fmt/fmt_check_parse_error.out | 6 + tests/testdata/fmt/fmt_with_config.out | 1 + tests/testdata/fmt/fmt_with_config_and_flags.out | 1 + tests/testdata/fmt/fmt_with_config_default.out | 2 + tests/testdata/fmt/fmt_with_deprecated_config.out | 3 + tests/testdata/fmt/fmt_with_malformed_config.out | 4 + tests/testdata/fmt/fmt_with_malformed_config2.out | 4 + tests/testdata/fmt/glob/data/tes.ts | 3 + tests/testdata/fmt/glob/data/test1.js | 2 + tests/testdata/fmt/glob/data/test1.ts | 2 + tests/testdata/fmt/glob/data/test12.ts | 3 + tests/testdata/fmt/glob/nested/fizz/bar.ts | 2 + tests/testdata/fmt/glob/nested/fizz/bazz.ts | 3 + tests/testdata/fmt/glob/nested/fizz/fizz.ts | 2 + tests/testdata/fmt/glob/nested/fizz/foo.ts | 2 + tests/testdata/fmt/glob/nested/foo/bar.ts | 2 + tests/testdata/fmt/glob/nested/foo/bazz.ts | 3 + tests/testdata/fmt/glob/nested/foo/fizz.ts | 2 + tests/testdata/fmt/glob/nested/foo/foo.ts | 2 + tests/testdata/fmt/glob/pages/[id].ts | 2 + tests/testdata/fmt/invalid_data.json | Bin 0 -> 51200 bytes tests/testdata/fmt/invalid_data.out | 4 + tests/testdata/fmt/parse_error/parse_error.ts | 2 + tests/testdata/fmt/regular/formatted1.js | 5 + tests/testdata/fmt/regular/formatted2.ts | 5 + tests/testdata/fmt/regular/formatted3.markdown | 17 + tests/testdata/fmt/regular/formatted4.jsonc | 4 + .../testdata/fmt/with_config/deno.deprecated.jsonc | 20 + tests/testdata/fmt/with_config/deno.jsonc | 16 + tests/testdata/fmt/with_config/subdir/a.ts | 46 + tests/testdata/fmt/with_config/subdir/b.ts | 15 + tests/testdata/fmt/with_config/subdir/c.md | 17 + tests/testdata/import_attributes/data.json | 6 + tests/testdata/import_attributes/dynamic_error.out | 4 + tests/testdata/import_attributes/dynamic_error.ts | 3 + .../testdata/import_attributes/dynamic_import.out | 3 + tests/testdata/import_attributes/dynamic_import.ts | 5 + .../import_attributes/json_with_shebang.json | 4 + .../import_attributes/json_with_shebang.ts | 3 + .../import_attributes/json_with_shebang.ts.out | 1 + tests/testdata/import_attributes/static_error.out | 3 + tests/testdata/import_attributes/static_error.ts | 3 + tests/testdata/import_attributes/static_export.out | 1 + tests/testdata/import_attributes/static_export.ts | 3 + tests/testdata/import_attributes/static_import.out | 2 + tests/testdata/import_attributes/static_import.ts | 5 + .../testdata/import_attributes/static_reexport.ts | 1 + tests/testdata/import_attributes/type_check.out | 12 + tests/testdata/import_attributes/type_check.ts | 5 + tests/testdata/import_maps/config.json | 15 + tests/testdata/import_maps/import_map.json | 15 + tests/testdata/import_maps/import_map_invalid.json | 7 + tests/testdata/import_maps/import_map_remote.json | 9 + tests/testdata/import_maps/lodash/lodash.ts | 1 + tests/testdata/import_maps/lodash/other_file.ts | 1 + tests/testdata/import_maps/moment/moment.ts | 1 + tests/testdata/import_maps/moment/other_file.ts | 1 + tests/testdata/import_maps/print_hello.ts | 3 + tests/testdata/import_maps/scope/scoped.ts | 2 + tests/testdata/import_maps/scoped_moment.ts | 1 + tests/testdata/import_maps/test.ts | 6 + tests/testdata/import_maps/test_remote.ts | 5 + tests/testdata/import_maps/vue.ts | 1 + tests/testdata/info/031_info_ts_error.out | 6 + tests/testdata/info/031_info_ts_error.ts | 1 + tests/testdata/info/041_info_flag.out | 6 + tests/testdata/info/041_info_flag_location.out | 7 + tests/testdata/info/049_info_flag_script_jsx.out | 15 + tests/testdata/info/054_info_local_imports.out | 9 + tests/testdata/info/065_import_map_info.out | 6 + tests/testdata/info/076_info_json_deps_order.out | 164 + tests/testdata/info/076_info_json_deps_order.ts | 2 + .../info/data_null_error/data_null_error.out | 7 + tests/testdata/info/data_null_error/mod.ts | 1 + tests/testdata/info/data_null_error/types.d.ts | 1 + tests/testdata/info/error_009_missing_js_module.js | 1 + .../info/error_009_missing_js_module.js.out | 1 + tests/testdata/info/info_json.out | 8 + tests/testdata/info/info_json_location.out | 9 + tests/testdata/info/info_missing_module.out | 7 + .../testdata/info/info_recursive_imports_test.out | 13 + tests/testdata/info/info_recursive_imports_test.ts | 5 + tests/testdata/info/info_type_import.out | 7 + tests/testdata/info/info_type_import.ts | 3 + tests/testdata/info/json_output/main.out | 91 + tests/testdata/info/json_output/main.ts | 11 + tests/testdata/info/multiple_imports.out | 15 + tests/testdata/info/recursive_imports/A.ts | 7 + tests/testdata/info/recursive_imports/B.ts | 7 + tests/testdata/info/recursive_imports/C.ts | 8 + tests/testdata/info/recursive_imports/common.ts | 2 + tests/testdata/info/types_header.out | 9 + tests/testdata/info/with_config/deno-override.json | 3 + tests/testdata/info/with_config/deno.json | 1 + tests/testdata/info/with_config/import_map.json | 1 + tests/testdata/info/with_config/test.ts | 1 + tests/testdata/info/with_config/with_config.out | 7 + tests/testdata/info/with_import_map/deno.json | 6 + tests/testdata/info/with_import_map/deno.lock | 7 + tests/testdata/info/with_import_map/main.tsx | 2 + .../info/with_import_map/with_import_map.out | 16 + tests/testdata/inspector/bar.js | 3 + tests/testdata/inspector/error_with_npm_import.js | 7 + tests/testdata/inspector/foo.ts | 10 + tests/testdata/inspector/inspect_wait.js | 2 + tests/testdata/inspector/inspector1.js | 3 + tests/testdata/inspector/inspector2.js | 4 + tests/testdata/inspector/inspector3.js | 13 + tests/testdata/inspector/inspector4.js | 5 + tests/testdata/inspector/inspector_test.js | 3 + tests/testdata/inspector/memory.js | 13 + tests/testdata/inspector/test.ts | 5 + tests/testdata/install/check_local_by_default.ts | 3 + tests/testdata/install/check_local_by_default2.ts | 6 + tests/testdata/jsr/deps/main.out | 13 + tests/testdata/jsr/deps/main.ts | 3 + tests/testdata/jsr/deps/main_info.out | 22 + tests/testdata/jsr/module_graph/main.out | 7 + tests/testdata/jsr/module_graph/main.ts | 3 + tests/testdata/jsr/module_graph/main_info.out | 14 + tests/testdata/jsr/no_module_graph/main.out | 6 + tests/testdata/jsr/no_module_graph/main.ts | 4 + tests/testdata/jsr/no_module_graph/main_info.out | 12 + tests/testdata/jsr/no_module_graph/multiple.out | 2 + tests/testdata/jsr/no_module_graph/multiple.ts | 5 + .../jsr/registry/@denotest/add/1.0.0/mod.ts | 3 + .../jsr/registry/@denotest/add/1.0.0_meta.json | 8 + .../testdata/jsr/registry/@denotest/add/meta.json | 5 + .../jsr/registry/@denotest/deps/1.0.0/mod.ts | 7 + .../jsr/registry/@denotest/deps/1.0.0_meta.json | 22 + .../testdata/jsr/registry/@denotest/deps/meta.json | 5 + .../registry/@denotest/module_graph/1.4.0/mod.ts | 5 + .../registry/@denotest/module_graph/1.4.0/other.ts | 2 + .../@denotest/module_graph/1.4.0_meta.json | 18 + .../jsr/registry/@denotest/module_graph/meta.json | 6 + .../@denotest/no_module_graph/0.1.0/TestClass.ts | 1 + .../@denotest/no_module_graph/0.1.0/mod.ts | 3 + .../@denotest/no_module_graph/0.1.0_meta.json | 5 + .../@denotest/no_module_graph/0.1.1/TestClass.ts | 1 + .../@denotest/no_module_graph/0.1.1/mod.ts | 3 + .../@denotest/no_module_graph/0.1.1_meta.json | 5 + .../@denotest/no_module_graph/0.2.0/TestClass.ts | 1 + .../@denotest/no_module_graph/0.2.0/mod.ts | 3 + .../@denotest/no_module_graph/0.2.0_meta.json | 5 + .../registry/@denotest/no_module_graph/meta.json | 7 + .../@denotest/subset_type_graph/0.1.0/mod.ts | 17 + .../@denotest/subset_type_graph/0.1.0_meta.json | 5 + .../registry/@denotest/subset_type_graph/meta.json | 5 + .../subset_type_graph_invalid/0.1.0/mod.ts | 12 + .../subset_type_graph_invalid/0.1.0_meta.json | 5 + .../@denotest/subset_type_graph_invalid/meta.json | 5 + .../testdata/jsr/subset_type_graph/main.check.out | 45 + tests/testdata/jsr/subset_type_graph/main.ts | 13 + tests/testdata/jsr/version_not_found/main.out | 5 + tests/testdata/jsr/version_not_found/main.ts | 2 + tests/testdata/jsx/deno-jsx-error.jsonc | 6 + tests/testdata/jsx/deno-jsx-import-map.jsonc | 6 + tests/testdata/jsx/deno-jsx-precompile.jsonc | 6 + tests/testdata/jsx/deno-jsx.json | 6 + tests/testdata/jsx/deno-jsx.jsonc | 6 + tests/testdata/jsx/deno-jsxdev-import-map.jsonc | 6 + tests/testdata/jsx/deno-jsxdev.jsonc | 6 + tests/testdata/jsx/deno.lock | 6 + tests/testdata/jsx/import-map-scoped.json | 8 + tests/testdata/jsx/import-map.json | 7 + tests/testdata/jsx/jsx-dev-runtime/index.ts | 12 + tests/testdata/jsx/jsx-precompile/index.ts | 23 + tests/testdata/jsx/jsx-runtime/index.ts | 12 + .../jupyter/install_command_not_exists.out | 5 + tests/testdata/jupyter/integration_test.ipynb | 4440 ++ tests/testdata/lint/Deno.compact.format.jsonc | 11 + tests/testdata/lint/Deno.jsonc | 10 + tests/testdata/lint/Deno.malformed.jsonc | 11 + tests/testdata/lint/Deno.malformed2.jsonc | 11 + tests/testdata/lint/Deno.no_tags.jsonc | 15 + tests/testdata/lint/deno.glob.json | 11 + tests/testdata/lint/expected.out | 3 + tests/testdata/lint/expected_compact.out | 4 + tests/testdata/lint/expected_from_stdin.out | 12 + tests/testdata/lint/expected_from_stdin_json.out | 23 + tests/testdata/lint/expected_glob.out | 3 + tests/testdata/lint/expected_ignore.out | 3 + tests/testdata/lint/expected_json.out | 64 + tests/testdata/lint/expected_quiet.out | 20 + tests/testdata/lint/expected_rules.out | 2 + tests/testdata/lint/expected_verbose.out | 3 + tests/testdata/lint/glob/data/tes.ts | 3 + tests/testdata/lint/glob/data/test1.js | 3 + tests/testdata/lint/glob/data/test1.ts | 3 + tests/testdata/lint/glob/data/test12.ts | 3 + tests/testdata/lint/glob/nested/fizz/bar.ts | 3 + tests/testdata/lint/glob/nested/fizz/bazz.ts | 3 + tests/testdata/lint/glob/nested/fizz/fizz.ts | 2 + tests/testdata/lint/glob/nested/fizz/foo.ts | 3 + tests/testdata/lint/glob/nested/foo/bar.ts | 3 + tests/testdata/lint/glob/nested/foo/bazz.ts | 3 + tests/testdata/lint/glob/nested/foo/fizz.ts | 3 + tests/testdata/lint/glob/nested/foo/foo.ts | 3 + tests/testdata/lint/glob/pages/[id].ts | 3 + tests/testdata/lint/watch/badly_linted.js | 1 + tests/testdata/lint/watch/badly_linted.js.out | 2 + tests/testdata/lint/watch/badly_linted_fixed1.js | 1 + .../testdata/lint/watch/badly_linted_fixed1.js.out | 1 + tests/testdata/lint/watch/badly_linted_fixed2.js | 1 + .../testdata/lint/watch/badly_linted_fixed2.js.out | 0 tests/testdata/lint/with_config.out | 22 + tests/testdata/lint/with_config/a.ts | 4 + tests/testdata/lint/with_config/b.ts | 4 + tests/testdata/lint/with_config_and_flags.out | 22 + tests/testdata/lint/with_config_without_tags.out | 22 + tests/testdata/lint/with_malformed_config.out | 4 + tests/testdata/lint/with_malformed_config2.out | 4 + tests/testdata/lint/with_report_config_compact.out | 4 + .../testdata/lint/with_report_config_override.out | 41 + tests/testdata/lint/without_config/file1.js | 2 + tests/testdata/lint/without_config/file2.ts | 6 + tests/testdata/lint/without_config/ignored_file.ts | 3 + tests/testdata/lint/without_config/malformed.js | 4 + tests/testdata/lockfile/basic/bench.nolock.out | 6 + tests/testdata/lockfile/basic/deno.json | 5 + tests/testdata/lockfile/basic/deno.lock | 6 + tests/testdata/lockfile/basic/doc.nolock.out | 1 + tests/testdata/lockfile/basic/fail.out | 4 + tests/testdata/lockfile/basic/info.nolock.out | 8 + tests/testdata/lockfile/basic/main.bench.ts | 8 + tests/testdata/lockfile/basic/main.test.ts | 8 + tests/testdata/lockfile/basic/main.ts | 3 + tests/testdata/lockfile/basic/mod.ts | 3 + tests/testdata/lockfile/basic/test.nolock.out | 4 + tests/testdata/lockfile/no_dts/deno.lock.out | 6 + tests/testdata/lockfile/no_dts/main.cache.out | 2 + tests/testdata/lockfile/no_dts/main.ts | 3 + tests/testdata/lockfile/no_dts/mod.d.ts | 1 + tests/testdata/lockfile/no_dts/mod.js | 4 + tests/testdata/lsp/deno.import_map.jsonc | 3 + tests/testdata/lsp/deno.lint.exclude.jsonc | 16 + tests/testdata/lsp/diagnostics_deno_types.json | 101 + tests/testdata/lsp/import-map.json | 5 + tests/testdata/lsp/large_file.txt | 676 + tests/testdata/lsp/registries/a_latest_.json | 4 + tests/testdata/lsp/registries/a_v1.0.0_.json | 4 + tests/testdata/lsp/registries/a_v1.0.0_b.json | 3 + tests/testdata/lsp/registries/a_v1.0.1_.json | 4 + tests/testdata/lsp/registries/a_v2.0.0_.json | 4 + tests/testdata/lsp/registries/a_versions_.json | 5 + tests/testdata/lsp/registries/a_versions_v1..json | 4 + tests/testdata/lsp/registries/b_latest_.json | 4 + tests/testdata/lsp/registries/b_v0.0.1_.json | 4 + tests/testdata/lsp/registries/b_v0.0.2_.json | 4 + tests/testdata/lsp/registries/b_v0.0.3_.json | 4 + tests/testdata/lsp/registries/b_versions_.json | 5 + tests/testdata/lsp/registries/cde_tags.json | 4 + tests/testdata/lsp/registries/cdef_tags.json | 4 + tests/testdata/lsp/registries/complex.json | 5 + tests/testdata/lsp/registries/complex_efg.json | 6 + .../testdata/lsp/registries/complex_efg_0.2.0.json | 6 + tests/testdata/lsp/registries/def_tags.json | 3 + .../deno-import-intellisense-complex.json | 22 + .../deno-import-intellisense-key-first.json | 18 + .../lsp/registries/deno-import-intellisense.json | 62 + tests/testdata/lsp/registries/doc_a.json | 4 + .../lsp/registries/doc_a_latest_mod.ts.json | 4 + tests/testdata/lsp/registries/key_first.json | 5 + tests/testdata/lsp/registries/modules_.json | 8 + tests/testdata/lsp/registries/modules_a.json | 10 + tests/testdata/lsp/types.tsconfig.json | 12 + tests/testdata/lsp/x_deno_warning_redirect.js | 1 + tests/testdata/malformed_config/deno.json | 1 + tests/testdata/module_graph/file_tests-a.mjs | 3 + tests/testdata/module_graph/file_tests-b-mod.js | 1 + tests/testdata/module_graph/file_tests-b.ts | 1 + tests/testdata/module_graph/file_tests-c-mod.ts | 1 + .../module_graph/file_tests-checkwithconfig.ts | 5 + tests/testdata/module_graph/file_tests-diag.ts | 4 + .../module_graph/file_tests-dynamicimport.ts | 5 + .../testdata/module_graph/file_tests-importjson.ts | 3 + .../module_graph/file_tests-importremap.ts | 3 + tests/testdata/module_graph/file_tests-main.ts | 4 + tests/testdata/module_graph/file_tests-some.json | 5 + tests/testdata/module_graph/file_typesref.d.ts | 1 + tests/testdata/module_graph/file_typesref.js | 3 + .../https_deno.land-std-http-server.ts | 5 + .../module_graph/https_deno.land-x-a-mod.ts | 1 + tests/testdata/module_graph/https_deno.land-x-a.ts | 1 + .../module_graph/https_deno.land-x-import_map.ts | 4 + .../module_graph/https_deno.land-x-jquery.js | 3 + .../module_graph/https_deno.land-x-lib-a.ts | 1 + .../module_graph/https_deno.land-x-lib-b.js | 1 + .../module_graph/https_deno.land-x-lib-c.d.ts | 1 + .../module_graph/https_deno.land-x-lib-c.js | 3 + .../module_graph/https_deno.land-x-lib-mod.d.ts | 9 + .../module_graph/https_deno.land-x-lib-mod.js | 5 + .../testdata/module_graph/https_deno.land-x-mod.ts | 3 + .../module_graph/https_deno.land-x-transpile.tsx | 5 + .../module_graph/https_unpkg.com-lodash-index.js | 3 + tests/testdata/module_graph/lockfile.json | 8 + tests/testdata/module_graph/lockfile_fail.json | 8 + tests/testdata/module_graph/tsconfig.json | 6 + tests/testdata/module_graph/tsconfig_01.json | 13 + tests/testdata/navigator_language.ts | 1 + tests/testdata/navigator_languages.ts | 1 + .../testdata/node/rejection_handled_web_process.ts | 26 + .../node/rejection_handled_web_process.ts.out | 6 + tests/testdata/node/require_esm_error/esm.js | 1 + tests/testdata/node/require_esm_error/main.out | 3 + tests/testdata/node/require_esm_error/main.ts | 5 + tests/testdata/node/test.js | 390 + tests/testdata/node/test.out | 175 + tests/testdata/node/unhandled_rejection_web.ts | 17 + tests/testdata/node/unhandled_rejection_web.ts.out | 4 + .../node/unhandled_rejection_web_process.ts | 21 + .../node/unhandled_rejection_web_process.ts.out | 5 + tests/testdata/npm/README.md | 18 + tests/testdata/npm/binary_package/main.js | 1 + tests/testdata/npm/builtin_module_module/main.js | 1 + tests/testdata/npm/builtin_module_module/main.out | 4 + tests/testdata/npm/cached_only/main.out | 2 + tests/testdata/npm/cached_only/main.ts | 3 + .../npm/cached_only_after_first_run/main1.ts | 3 + .../npm/cached_only_after_first_run/main2.ts | 3 + tests/testdata/npm/check_errors/main.ts | 3 + tests/testdata/npm/check_errors/main_all.out | 19 + tests/testdata/npm/check_errors/main_local.out | 7 + .../testdata/npm/child_process_fork_test/main.out | 2 + tests/testdata/npm/child_process_fork_test/main.ts | 4 + .../testdata/npm/cjs-invalid-name-exports/main.out | 13 + .../testdata/npm/cjs-invalid-name-exports/main.ts | 3 + tests/testdata/npm/cjs_local_global_decls/main.out | 3 + tests/testdata/npm/cjs_local_global_decls/main.ts | 1 + .../npm/cjs_module_export_assignment/main.out | 6 + .../npm/cjs_module_export_assignment/main.ts | 6 + .../cjs_module_export_assignment_number/main.out | 3 + .../cjs_module_export_assignment_number/main.ts | 7 + tests/testdata/npm/cjs_reexport_collision/main.out | 1 + tests/testdata/npm/cjs_reexport_collision/main.ts | 2 + tests/testdata/npm/cjs_require_esm_error/main.out | 2 + tests/testdata/npm/cjs_require_esm_error/main.ts | 1 + .../npm/cjs_require_esm_mjs_error/main.out | 2 + .../testdata/npm/cjs_require_esm_mjs_error/main.ts | 1 + tests/testdata/npm/cjs_sub_path/main.js | 21 + tests/testdata/npm/cjs_sub_path/main.out | 35 + tests/testdata/npm/cjs_this_in_exports/main.js | 11 + tests/testdata/npm/cjs_this_in_exports/main.out | 5 + tests/testdata/npm/cjs_with_deps/main.js | 12 + tests/testdata/npm/cjs_with_deps/main.out | 33 + tests/testdata/npm/cjs_with_deps/main_info.out | 22 + .../testdata/npm/cjs_with_deps/main_info_json.out | 149 + .../npm/cjs_with_deps/main_node_modules.out | 47 + tests/testdata/npm/cjs_yargs/main.js | 20 + tests/testdata/npm/cjs_yargs/main.out | 84 + tests/testdata/npm/compare_globals/main.out | 28 + tests/testdata/npm/compare_globals/main.ts | 52 + tests/testdata/npm/conditional_exports/main.js | 15 + tests/testdata/npm/conditional_exports/main.out | 19 + .../npm/conditional_exports/main_node_modules.out | 23 + tests/testdata/npm/create_require/main.out | 12 + tests/testdata/npm/create_require/main.ts | 1 + tests/testdata/npm/d_ext/main.out | 3 + tests/testdata/npm/d_ext/main.ts | 3 + tests/testdata/npm/deno_cache.out | 8 + tests/testdata/npm/deno_run_cjs.out | 4 + tests/testdata/npm/deno_run_cowsay.out | 8 + .../npm/deno_run_cowsay_no_permissions.out | 2 + tests/testdata/npm/deno_run_cowthink.out | 8 + tests/testdata/npm/deno_run_esm.out | 4 + tests/testdata/npm/deno_run_no_bin_entrypoint.out | 1 + ..._run_no_bin_entrypoint_non_existent_subpath.out | 3 + tests/testdata/npm/deno_run_no_ext.out | 4 + tests/testdata/npm/deno_run_non_existent.out | 3 + .../npm/deno_run_special_chars_in_bin_name.out | 4 + tests/testdata/npm/different_nested_dep/main.js | 5 + tests/testdata/npm/different_nested_dep/main.out | 2 + .../testdata/npm/different_nested_dep/package.json | 6 + .../npm/directory_import/folder_index_js.out | 7 + .../npm/directory_import/folder_index_js.ts | 2 + .../npm/directory_import/folder_no_index.out | 6 + .../npm/directory_import/folder_no_index.ts | 2 + tests/testdata/npm/dual_cjs_esm/main.out | 3 + tests/testdata/npm/dual_cjs_esm/main.ts | 6 + tests/testdata/npm/dynamic_import/main.out | 6 + tests/testdata/npm/dynamic_import/main.ts | 3 + tests/testdata/npm/dynamic_import/other.ts | 11 + .../npm/dynamic_import_deno_ts_from_npm/add.ts | 3 + .../npm/dynamic_import_deno_ts_from_npm/main.out | 2 + .../npm/dynamic_import_deno_ts_from_npm/main.ts | 8 + .../dynamic_import_deno_ts_from_npm/subtract.mts | 3 + .../dynamic_import_invalid_package_name/main.out | 6 + .../dynamic_import_invalid_package_name/main.ts | 6 + tests/testdata/npm/dynamic_import_json/main.js | 4 + tests/testdata/npm/dynamic_import_json/main.out | 14 + .../dynamic_import_reload_same_package/main.out | 5 + .../npm/dynamic_import_reload_same_package/main.ts | 7 + .../dynamic_import_reload_same_package/other.ts | 3 + tests/testdata/npm/env_var_re_export/main.js | 3 + .../npm/error_version_after_subpath/main.js | 1 + .../npm/error_version_after_subpath/main.out | 2 + tests/testdata/npm/esm/main.js | 9 + tests/testdata/npm/esm/main.out | 3 + tests/testdata/npm/esm/test.js | 5 + tests/testdata/npm/esm/test.out | 11 + tests/testdata/npm/esm_import_cjs_default/main.out | 51 + tests/testdata/npm/esm_import_cjs_default/main.ts | 23 + tests/testdata/npm/file_dts_dmts_dcts/main.out | 24 + tests/testdata/npm/file_dts_dmts_dcts/main.ts | 9 + tests/testdata/npm/import_json/main.js | 4 + tests/testdata/npm/import_json/main.out | 10 + tests/testdata/npm/import_map/import_map.json | 6 + tests/testdata/npm/import_map/main.js | 10 + tests/testdata/npm/import_map/main.out | 10 + .../npm/imports_package_json/import_not_defined.js | 3 + .../imports_package_json/import_not_defined.out | 6 + tests/testdata/npm/imports_package_json/main.js | 7 + tests/testdata/npm/imports_package_json/main.out | 7 + .../testdata/npm/imports_package_json/package.json | 6 + .../sub_path_import_not_defined.js | 3 + .../sub_path_import_not_defined.out | 6 + tests/testdata/npm/info/chalk.out | 9 + tests/testdata/npm/info/chalk_json.out | 56 + tests/testdata/npm/invalid_package_name/main.js | 1 + tests/testdata/npm/invalid_package_name/main.out | 2 + .../npm/local_dir_resolves_symlinks/index.js | 3 + .../npm/local_dir_resolves_symlinks/index.out | 2 + .../npm/local_dir_resolves_symlinks/package.json | 7 + tests/testdata/npm/lock_file/lock.json | 164 + tests/testdata/npm/lock_file/main.js | 5 + tests/testdata/npm/lock_file/main.out | 12 + .../npm/mixed_case_package_name/global.out | 9 + .../testdata/npm/mixed_case_package_name/global.ts | 2 + .../testdata/npm/mixed_case_package_name/local.out | 13 + .../testdata/npm/mixed_case_package_name/local.ts | 18 + tests/testdata/npm/no_npm_after_first_run/main1.ts | 3 + tests/testdata/npm/no_types_cjs/main.ts | 7 + .../npm/no_types_in_conditional_exports/main.out | 4 + .../npm/no_types_in_conditional_exports/main.ts | 2 + .../npm/node_modules_deno_node_modules/main.out | 2 + .../npm/node_modules_deno_node_modules/main.ts | 7 + tests/testdata/npm/node_modules_import/main.out | 3 + tests/testdata/npm/node_modules_import/main.ts | 16 + .../npm/node_modules_import/main_check.out | 16 + .../testdata/npm/node_modules_import/package.json | 5 + tests/testdata/npm/nonexistent_file/main.js | 2 + tests/testdata/npm/nonexistent_file/main.out | 4 + .../npm/peer_deps_with_copied_folders/main.out | 14 + .../npm/peer_deps_with_copied_folders/main.ts | 5 + .../peer_deps_with_copied_folders/main_info.out | 14 + .../main_info_json.out | 98 + .../main_node_modules.out | 9 + .../main_node_modules_reload.out | 19 + .../npm/permissions_outside_package/foo/config.js | 4 + .../permissions_outside_package/foo/package.json | 4 + .../npm/permissions_outside_package/main.out | 3 + .../npm/permissions_outside_package/main.ts | 5 + .../npm/registry/@babel/parser/parser-7.19.0.tgz | Bin 0 -> 444189 bytes .../npm/registry/@babel/parser/registry.json | 1 + .../npm/registry/@denotest/CAPITALS/1.0.0/index.js | 1 + .../registry/@denotest/CAPITALS/1.0.0/package.json | 4 + .../registry/@denotest/MixedCase/1.0.0/index.js | 2 + .../@denotest/MixedCase/1.0.0/package.json | 7 + .../npm/registry/@denotest/bin/0.5.0/cli.mjs | 5 + .../npm/registry/@denotest/bin/0.5.0/package.json | 5 + .../npm/registry/@denotest/bin/0.6.0/cli-cjs.js | 5 + .../npm/registry/@denotest/bin/0.6.0/cli.mjs | 5 + .../npm/registry/@denotest/bin/0.6.0/package.json | 4 + .../npm/registry/@denotest/bin/1.0.0/cli-cjs.js | 5 + .../npm/registry/@denotest/bin/1.0.0/cli-no-ext | 5 + .../npm/registry/@denotest/bin/1.0.0/cli.mjs | 5 + .../npm/registry/@denotest/bin/1.0.0/package.json | 9 + .../@denotest/binary-package-linux/1.0.0/index.js | 1 + .../binary-package-linux/1.0.0/package.json | 8 + .../@denotest/binary-package-mac/1.0.0/index.js | 1 + .../binary-package-mac/1.0.0/package.json | 8 + .../binary-package-windows/1.0.0/index.js | 1 + .../binary-package-windows/1.0.0/package.json | 8 + .../@denotest/binary-package/1.0.0/index.js | 13 + .../@denotest/binary-package/1.0.0/package.json | 10 + .../1.0.0/index.d.ts | 1 + .../1.0.0/index.js | 3 + .../1.0.0/package.json | 6 + .../2.0.0/index.d.ts | 1 + .../2.0.0/index.js | 3 + .../2.0.0/package.json | 6 + .../@denotest/builtin-module-module/1.0.0/index.js | 7 + .../builtin-module-module/1.0.0/package.json | 5 + .../@denotest/check-error/1.0.0/index.d.ts | 10 + .../registry/@denotest/check-error/1.0.0/index.js | 6 + .../@denotest/check-error/1.0.0/other_dir.d.ts | 1 + .../@denotest/check-error/1.0.0/other_dir/index.js | 1 + .../@denotest/check-error/1.0.0/package.json | 5 + .../@denotest/check-error/1.0.0/sub_dir/index.d.ts | 1 + .../@denotest/check-error/1.0.0/sub_dir/index.js | 1 + .../@denotest/check-error/1.0.0/sub_dir/lib.d.ts | 1 + .../child-process-fork/1.0.0/forked_path.js | 3 + .../@denotest/child-process-fork/1.0.0/index.js | 20 + .../child-process-fork/1.0.0/package.json | 4 + .../@denotest/cjs-default-export/1.0.0/index.d.ts | 6 + .../@denotest/cjs-default-export/1.0.0/index.js | 17 + .../cjs-default-export/1.0.0/package.json | 5 + .../cjs-invalid-name-exports/1.0.0/index.js | 6 + .../cjs-invalid-name-exports/1.0.0/package.json | 4 + .../cjs-local-global-decls/1.0.0/index.js | 3 + .../cjs-local-global-decls/1.0.0/other.js | 2 + .../cjs-local-global-decls/1.0.0/package.json | 4 + .../1.0.0/index.d.ts | 2 + .../1.0.0/index.js | 1 + .../1.0.0/package.json | 5 + .../cjs-module-export-assignment/1.0.0/index.d.ts | 5 + .../cjs-module-export-assignment/1.0.0/index.js | 5 + .../1.0.0/package.json | 5 + .../cjs-reexport-collision/1.0.0/index.js | 19 + .../cjs-reexport-collision/1.0.0/other_file.js | 10 + .../cjs-reexport-collision/1.0.0/package.json | 5 + .../1.0.0/esm/my_es_module.js | 1 + .../cjs-require-esm-error/1.0.0/esm/package.json | 3 + .../cjs-require-esm-error/1.0.0/esm_mjs.mjs | 1 + .../@denotest/cjs-require-esm-error/1.0.0/index.js | 1 + .../cjs-require-esm-error/1.0.0/package.json | 4 + .../cjs-require-esm-error/1.0.0/require_mjs.js | 1 + .../@denotest/cjs-this-in-exports/1.0.0/index.js | 8 + .../cjs-this-in-exports/1.0.0/package.json | 5 + .../@denotest/cjs-with-file-stem/1.0.0/index.js | 5 + .../cjs-with-file-stem/1.0.0/other.service.js | 4 + .../cjs-with-file-stem/1.0.0/package.json | 4 + .../@denotest/cjs-with-file-stem/1.0.0/tslib.js | 3 + .../conditional-exports-strict/1.0.0/cjs/index.cjs | 3 + .../1.0.0/esm/client/bar.js | 3 + .../1.0.0/esm/client/foo.js | 3 + .../1.0.0/esm/client/index.js | 3 + .../1.0.0/esm/client/m.js | 3 + .../conditional-exports-strict/1.0.0/esm/index.js | 3 + .../conditional-exports-strict/1.0.0/foo.js | 3 + .../conditional-exports-strict/1.0.0/package.json | 16 + .../conditional-exports/1.0.0/cjs/index.cjs | 3 + .../conditional-exports/1.0.0/esm/client/bar.js | 3 + .../conditional-exports/1.0.0/esm/client/foo.js | 3 + .../conditional-exports/1.0.0/esm/client/index.js | 3 + .../conditional-exports/1.0.0/esm/client/m.js | 3 + .../conditional-exports/1.0.0/esm/index.js | 3 + .../@denotest/conditional-exports/1.0.0/foo.js | 3 + .../conditional-exports/1.0.0/package.json | 21 + .../@denotest/create-require/1.0.0/index.js | 33 + .../@denotest/create-require/1.0.0/package.json | 6 + .../npm/registry/@denotest/d-ext/1.0.0/index.d.ts | 1 + .../npm/registry/@denotest/d-ext/1.0.0/index.js | 1 + .../registry/@denotest/d-ext/1.0.0/package.json | 5 + .../npm/registry/@denotest/d-ext/1.0.0/types.d.ts | 1 + .../different-nested-dep-child/1.0.0/index.js | 1 + .../different-nested-dep-child/1.0.0/package.json | 5 + .../different-nested-dep-child/2.0.0/index.js | 1 + .../different-nested-dep-child/2.0.0/package.json | 5 + .../@denotest/different-nested-dep/1.0.0/index.js | 2 + .../different-nested-dep/1.0.0/package.json | 8 + .../dual-cjs-esm-dep-missing/1.0.0/index.cjs | 3 + .../dual-cjs-esm-dep-missing/1.0.0/index.d.ts | 1 + .../dual-cjs-esm-dep-missing/1.0.0/index.mjs | 3 + .../dual-cjs-esm-dep-missing/1.0.0/package.json | 7 + .../@denotest/dual-cjs-esm-dep/1.0.0/index.cjs | 3 + .../@denotest/dual-cjs-esm-dep/1.0.0/index.d.ts | 1 + .../@denotest/dual-cjs-esm-dep/1.0.0/index.mjs | 3 + .../@denotest/dual-cjs-esm-dep/1.0.0/package.json | 10 + .../@denotest/dual-cjs-esm/1.0.0/cjs/main.cjs | 10 + .../@denotest/dual-cjs-esm/1.0.0/cjs/package.json | 3 + .../registry/@denotest/dual-cjs-esm/1.0.0/main.cjs | 3 + .../@denotest/dual-cjs-esm/1.0.0/main.d.cts | 1 + .../@denotest/dual-cjs-esm/1.0.0/main.d.mts | 1 + .../registry/@denotest/dual-cjs-esm/1.0.0/main.mjs | 3 + .../@denotest/dual-cjs-esm/1.0.0/package.json | 7 + .../@denotest/dual-cjs-esm/1.0.0/subpath/main.cjs | 3 + .../@denotest/dual-cjs-esm/1.0.0/subpath/main.mjs | 3 + .../dual-cjs-esm/1.0.0/subpath/package.json | 5 + .../@denotest/dynamic-import/1.0.0/index.js | 3 + .../@denotest/dynamic-import/1.0.0/package.json | 5 + .../@denotest/env-var-re-export/1.0.0/dev.cjs | 5 + .../@denotest/env-var-re-export/1.0.0/index.cjs | 5 + .../@denotest/env-var-re-export/1.0.0/package.json | 5 + .../@denotest/env-var-re-export/1.0.0/prod.cjs | 5 + .../registry/@denotest/esm-basic/1.0.0/main.d.mts | 3 + .../registry/@denotest/esm-basic/1.0.0/main.mjs | 11 + .../registry/@denotest/esm-basic/1.0.0/other.mjs | 3 + .../@denotest/esm-basic/1.0.0/package.json | 7 + .../esm-import-cjs-default/1.0.0/index.mjs | 17 + .../esm-import-cjs-default/1.0.0/local.cjs | 9 + .../esm-import-cjs-default/1.0.0/package.json | 8 + .../@denotest/file-dts-dmts-dcts/1.0.0/main.cjs | 0 .../@denotest/file-dts-dmts-dcts/1.0.0/main.d.cts | 1 + .../@denotest/file-dts-dmts-dcts/1.0.0/main.d.mts | 1 + .../@denotest/file-dts-dmts-dcts/1.0.0/main.d.ts | 1 + .../@denotest/file-dts-dmts-dcts/1.0.0/main.js | 0 .../@denotest/file-dts-dmts-dcts/1.0.0/main.mjs | 0 .../file-dts-dmts-dcts/1.0.0/package.json | 13 + .../registry/@denotest/globals/1.0.0/index.d.ts | 21 + .../npm/registry/@denotest/globals/1.0.0/index.js | 25 + .../registry/@denotest/globals/1.0.0/package.json | 5 + .../@denotest/imports-package-json/1.0.0/hi.js | 1 + .../1.0.0/import_not_defined.js | 3 + .../@denotest/imports-package-json/1.0.0/main.js | 13 + .../imports-package-json/1.0.0/package.json | 21 + .../imports-package-json/1.0.0/sub_path/bye.js | 1 + .../1.0.0/sub_path/import_not_defined.js | 4 + .../imports-package-json/1.0.0/sub_path/main.js | 3 + .../1.0.0/sub_path/package.json | 6 + .../registry/@denotest/no-types-cjs/1.0.0/main.js | 6 + .../@denotest/no-types-cjs/1.0.0/package.json | 5 + .../1.0.0/lib/foo-esm.js | 3 + .../1.0.0/lib/foo.js | 3 + .../1.0.0/package.json | 14 + .../non-existent-dep-version/1.0.0/index.js | 1 + .../non-existent-dep-version/1.0.0/package.json | 7 + .../@denotest/non-existent-dep/1.0.0/index.js | 1 + .../@denotest/non-existent-dep/1.0.0/package.json | 7 + .../@denotest/peer-dep-test-child/1.0.0/index.js | 1 + .../peer-dep-test-child/1.0.0/package.json | 8 + .../@denotest/peer-dep-test-child/2.0.0/index.js | 1 + .../peer-dep-test-child/2.0.0/package.json | 8 + .../peer-dep-test-grandchild/1.0.0/dist/index.js | 1 + .../peer-dep-test-grandchild/1.0.0/index.js | 1 + .../peer-dep-test-grandchild/1.0.0/package.json | 7 + .../@denotest/peer-dep-test-peer/1.0.0/index.js | 1 + .../peer-dep-test-peer/1.0.0/package.json | 4 + .../@denotest/peer-dep-test-peer/2.0.0/index.js | 1 + .../peer-dep-test-peer/2.0.0/package.json | 4 + .../permissions-outside-package/1.0.0/index.js | 5 + .../permissions-outside-package/1.0.0/package.json | 5 + .../require-added-nm-folder/1.0.0/index.js | 3 + .../require-added-nm-folder/1.0.0/package.json | 4 + .../reserved-word-exports/1.0.0/index.cjs | 68 + .../reserved-word-exports/1.0.0/package.json | 5 + .../special-chars-in-bin-name/1.0.0/main.mjs | 5 + .../special-chars-in-bin-name/1.0.0/package.json | 10 + .../sub-folders/1.0.0/folder_index_js/index.d.ts | 1 + .../sub-folders/1.0.0/folder_index_js/index.js | 3 + .../1.0.0/folder_no_index/random_name.js | 1 + .../registry/@denotest/sub-folders/1.0.0/main.mjs | 3 + .../@denotest/sub-folders/1.0.0/package.json | 6 + .../@denotest/types-ambient/1.0.0/index.d.ts | 10 + .../@denotest/types-ambient/1.0.0/index.js | 3 + .../@denotest/types-ambient/1.0.0/package.json | 5 + .../1.0.0/dist/main.d.ts | 1 + .../1.0.0/dist/main.js | 1 + .../1.0.0/package.json | 13 + .../1.0.0/dist/main.d.ts | 1 + .../types-exports-import-types/1.0.0/dist/main.mjs | 3 + .../types-exports-import-types/1.0.0/package.json | 10 + .../types-exports-subpaths/1.0.0/client.d.ts | 1 + .../types-exports-subpaths/1.0.0/dist/client.mjs | 3 + .../types-exports-subpaths/1.0.0/dist/entry-a.d.ts | 1 + .../types-exports-subpaths/1.0.0/dist/entry-a.js | 3 + .../types-exports-subpaths/1.0.0/dist/entry-b.d.ts | 1 + .../types-exports-subpaths/1.0.0/dist/entry-b.js | 3 + .../types-exports-subpaths/1.0.0/entry-import.d.ts | 1 + .../types-exports-subpaths/1.0.0/entry-import.js | 0 .../types-exports-subpaths/1.0.0/entry-js-only.js | 0 .../types-exports-subpaths/1.0.0/entry-types.d.ts | 1 + .../types-exports-subpaths/1.0.0/package.json | 26 + .../types-no-types-entry/1.0.0/dist/main.d.ts | 1 + .../types-no-types-entry/1.0.0/dist/main.js | 1 + .../types-no-types-entry/1.0.0/package.json | 8 + .../npm/registry/@denotest/types/1.0.0/index.d.ts | 4 + .../registry/@denotest/types/1.0.0/package.json | 5 + .../@denotest/types_imported/1.0.0/index.d.ts | 4 + .../@denotest/types_imported/1.0.0/package.json | 5 + .../@denotest/types_imported/1.0.0/subpath.d.ts | 4 + .../@denotest/typescript-file/1.0.0/index.ts | 4 + .../@denotest/typescript-file/1.0.0/package.json | 5 + .../has-package-exports-patterns-0.0.2.tgz | Bin 0 -> 483 bytes .../has-package-exports-patterns/registry.json | 1 + .../npm/registry/@types/node/node-18.8.2.tgz | Bin 0 -> 649087 bytes .../npm/registry/@types/node/registry.json | 73 + .../@vue/compiler-core/compiler-core-3.2.38.tgz | Bin 0 -> 158201 bytes .../npm/registry/@vue/compiler-core/registry.json | 1 + .../@vue/compiler-dom/compiler-dom-3.2.38.tgz | Bin 0 -> 197010 bytes .../npm/registry/@vue/compiler-dom/registry.json | 1 + .../@vue/compiler-sfc/compiler-sfc-3.2.38.tgz | Bin 0 -> 469167 bytes .../npm/registry/@vue/compiler-sfc/registry.json | 1 + .../@vue/compiler-ssr/compiler-ssr-3.2.38.tgz | Bin 0 -> 13870 bytes .../npm/registry/@vue/compiler-ssr/registry.json | 1 + .../reactivity-transform-3.2.38.tgz | Bin 0 -> 7582 bytes .../@vue/reactivity-transform/registry.json | 1 + .../registry/@vue/reactivity/reactivity-3.2.38.tgz | Bin 0 -> 57456 bytes .../npm/registry/@vue/reactivity/registry.json | 1 + .../npm/registry/@vue/runtime-core/registry.json | 1 + .../@vue/runtime-core/runtime-core-3.2.38.tgz | Bin 0 -> 217627 bytes .../npm/registry/@vue/runtime-dom/registry.json | 1 + .../@vue/runtime-dom/runtime-dom-3.2.38.tgz | Bin 0 -> 315216 bytes .../registry/@vue/server-renderer/registry.json | 1 + .../server-renderer/server-renderer-3.2.38.tgz | Bin 0 -> 120768 bytes .../npm/registry/@vue/shared/registry.json | 1 + .../npm/registry/@vue/shared/shared-3.2.38.tgz | Bin 0 -> 20773 bytes .../npm/registry/ajv-formats/ajv-formats-2.1.1.tgz | Bin 0 -> 14851 bytes .../npm/registry/ajv-formats/registry.json | 1 + tests/testdata/npm/registry/ajv/ajv-8.11.0.tgz | Bin 0 -> 219252 bytes tests/testdata/npm/registry/ajv/registry.json | 1 + .../npm/registry/ansi-regex/ansi-regex-3.0.1.tgz | Bin 0 -> 2246 bytes .../npm/registry/ansi-regex/ansi-regex-5.0.1.tgz | Bin 0 -> 2768 bytes .../testdata/npm/registry/ansi-regex/registry.json | 1 + .../npm/registry/ansi-styles/ansi-styles-4.3.0.tgz | Bin 0 -> 5849 bytes .../npm/registry/ansi-styles/registry.json | 1 + tests/testdata/npm/registry/asn1/asn1-0.2.6.tgz | Bin 0 -> 5977 bytes tests/testdata/npm/registry/asn1/registry.json | 1 + .../assertion-error/assertion-error-1.1.0.tgz | Bin 0 -> 2668 bytes .../npm/registry/assertion-error/registry.json | 1 + .../registry/autoprefixer/autoprefixer-10.4.14.tgz | Bin 0 -> 46185 bytes .../npm/registry/autoprefixer/registry.json | 1 + .../registry/bcrypt-pbkdf/bcrypt-pbkdf-1.0.2.tgz | Bin 0 -> 11109 bytes .../npm/registry/bcrypt-pbkdf/registry.json | 1 + .../registry/browserslist/browserslist-4.21.5.tgz | Bin 0 -> 15212 bytes .../npm/registry/browserslist/registry.json | 1 + .../npm/registry/buildcheck/buildcheck-0.0.3.tgz | Bin 0 -> 12331 bytes .../testdata/npm/registry/buildcheck/registry.json | 1 + .../npm/registry/camelcase/camelcase-5.3.1.tgz | Bin 0 -> 3028 bytes .../testdata/npm/registry/camelcase/registry.json | 1 + .../caniuse-lite/caniuse-lite-1.0.30001473.tgz | Bin 0 -> 275752 bytes .../npm/registry/caniuse-lite/registry.json | 1 + tests/testdata/npm/registry/chai/chai-4.3.6.tgz | Bin 0 -> 140277 bytes tests/testdata/npm/registry/chai/registry.json | 1 + tests/testdata/npm/registry/chalk/chalk-4.1.2.tgz | Bin 0 -> 11577 bytes tests/testdata/npm/registry/chalk/chalk-5.0.1.tgz | Bin 0 -> 13294 bytes tests/testdata/npm/registry/chalk/registry.json | 1 + .../npm/registry/check-error/check-error-1.0.2.tgz | Bin 0 -> 4986 bytes .../npm/registry/check-error/registry.json | 1 + tests/testdata/npm/registry/cliui/cliui-6.0.0.tgz | Bin 0 -> 5566 bytes tests/testdata/npm/registry/cliui/registry.json | 1 + .../registry/color-convert/color-convert-2.0.1.tgz | Bin 0 -> 8996 bytes .../npm/registry/color-convert/registry.json | 1 + .../npm/registry/color-name/color-name-1.1.4.tgz | Bin 0 -> 2868 bytes .../testdata/npm/registry/color-name/registry.json | 1 + .../testdata/npm/registry/cowsay/cowsay-1.5.0.tgz | Bin 0 -> 80330 bytes tests/testdata/npm/registry/cowsay/registry.json | 1 + .../registry/cpu-features/cpu-features-0.0.4.tgz | Bin 0 -> 90867 bytes .../npm/registry/cpu-features/registry.json | 1 + .../npm/registry/crypto-js/crypto-js-4.1.1.tgz | Bin 0 -> 71882 bytes .../testdata/npm/registry/crypto-js/registry.json | 1 + .../npm/registry/csstype/csstype-2.6.20.tgz | Bin 0 -> 289961 bytes tests/testdata/npm/registry/csstype/registry.json | 1 + .../npm/registry/decamelize/decamelize-1.2.0.tgz | Bin 0 -> 1691 bytes .../testdata/npm/registry/decamelize/registry.json | 1 + .../npm/registry/deep-eql/deep-eql-3.0.1.tgz | Bin 0 -> 10566 bytes tests/testdata/npm/registry/deep-eql/registry.json | 1 + .../define-properties/define-properties-1.2.0.tgz | Bin 0 -> 5093 bytes .../npm/registry/define-properties/registry.json | 1 + .../electron-to-chromium-1.4.348.tgz | Bin 0 -> 32855 bytes .../registry/electron-to-chromium/registry.json | 1 + .../npm/registry/emoji-regex/emoji-regex-8.0.0.tgz | Bin 0 -> 6664 bytes .../npm/registry/emoji-regex/registry.json | 1 + .../npm/registry/escalade/escalade-3.1.1.tgz | Bin 0 -> 4312 bytes tests/testdata/npm/registry/escalade/registry.json | 1 + .../registry/estree-walker/estree-walker-2.0.2.tgz | Bin 0 -> 8353 bytes .../npm/registry/estree-walker/registry.json | 1 + .../fast-deep-equal/fast-deep-equal-3.1.3.tgz | Bin 0 -> 3656 bytes .../npm/registry/fast-deep-equal/registry.json | 1 + .../npm/registry/find-up/find-up-4.1.0.tgz | Bin 0 -> 3745 bytes tests/testdata/npm/registry/find-up/registry.json | 1 + .../npm/registry/fraction.js/fraction.js-4.2.0.tgz | Bin 0 -> 16713 bytes .../npm/registry/fraction.js/registry.json | 1 + .../npm/registry/fs-extra/fs-extra-10.1.0.tgz | Bin 0 -> 16920 bytes tests/testdata/npm/registry/fs-extra/registry.json | 1 + .../registry/function-bind/function-bind-1.1.1.tgz | Bin 0 -> 6301 bytes .../npm/registry/function-bind/registry.json | 1 + .../get-caller-file/get-caller-file-2.0.5.tgz | Bin 0 -> 2383 bytes .../npm/registry/get-caller-file/registry.json | 1 + .../registry/get-func-name/get-func-name-2.0.0.tgz | Bin 0 -> 3581 bytes .../npm/registry/get-func-name/registry.json | 1 + .../registry/get-intrinsic/get-intrinsic-1.2.0.tgz | Bin 0 -> 11608 bytes .../npm/registry/get-intrinsic/registry.json | 1 + .../npm/registry/get-stdin/get-stdin-8.0.0.tgz | Bin 0 -> 2235 bytes .../testdata/npm/registry/get-stdin/registry.json | 1 + .../npm/registry/globals/globals-13.17.0.tgz | Bin 0 -> 9431 bytes tests/testdata/npm/registry/globals/registry.json | 1 + .../registry/graceful-fs/graceful-fs-4.2.10.tgz | Bin 0 -> 9770 bytes .../npm/registry/graceful-fs/registry.json | 1 + .../npm/registry/has-flag/has-flag-4.0.0.tgz | Bin 0 -> 2206 bytes tests/testdata/npm/registry/has-flag/registry.json | 1 + .../has-package-exports-1.3.0.tgz | Bin 0 -> 6761 bytes .../npm/registry/has-package-exports/registry.json | 1 + .../has-property-descriptors-1.0.0.tgz | Bin 0 -> 3854 bytes .../has-property-descriptors/registry.json | 1 + .../npm/registry/has-symbols/has-symbols-1.0.3.tgz | Bin 0 -> 7067 bytes .../npm/registry/has-symbols/registry.json | 1 + tests/testdata/npm/registry/has/has-1.0.3.tgz | Bin 0 -> 1553 bytes tests/testdata/npm/registry/has/registry.json | 1 + .../is-fullwidth-code-point-2.0.0.tgz | Bin 0 -> 2063 bytes .../is-fullwidth-code-point-3.0.0.tgz | Bin 0 -> 2169 bytes .../registry/is-fullwidth-code-point/registry.json | 1 + .../npm/registry/js-tokens/js-tokens-4.0.0.tgz | Bin 0 -> 6542 bytes .../testdata/npm/registry/js-tokens/registry.json | 1 + .../json-schema-traverse-1.0.0.tgz | Bin 0 -> 6074 bytes .../registry/json-schema-traverse/registry.json | 1 + .../npm/registry/jsonfile/jsonfile-6.1.0.tgz | Bin 0 -> 5816 bytes tests/testdata/npm/registry/jsonfile/registry.json | 1 + .../npm/registry/locate-path/locate-path-5.0.0.tgz | Bin 0 -> 2723 bytes .../npm/registry/locate-path/registry.json | 1 + .../registry/loose-envify/loose-envify-1.4.0.tgz | Bin 0 -> 2842 bytes .../npm/registry/loose-envify/registry.json | 1 + tests/testdata/npm/registry/loupe/loupe-2.3.4.tgz | Bin 0 -> 14566 bytes tests/testdata/npm/registry/loupe/registry.json | 1 + .../registry/magic-string/magic-string-0.25.9.tgz | Bin 0 -> 71318 bytes .../npm/registry/magic-string/registry.json | 1 + .../testdata/npm/registry/mkdirp/mkdirp-1.0.4.tgz | Bin 0 -> 6665 bytes tests/testdata/npm/registry/mkdirp/registry.json | 1 + tests/testdata/npm/registry/nan/nan-2.16.0.tgz | Bin 0 -> 75350 bytes tests/testdata/npm/registry/nan/registry.json | 1 + .../testdata/npm/registry/nanoid/nanoid-3.3.4.tgz | Bin 0 -> 5417 bytes tests/testdata/npm/registry/nanoid/registry.json | 1 + .../node-releases/node-releases-2.0.10.tgz | Bin 0 -> 3742 bytes .../npm/registry/node-releases/registry.json | 1 + .../normalize-range/normalize-range-0.1.2.tgz | Bin 0 -> 3234 bytes .../npm/registry/normalize-range/registry.json | 1 + .../npm/registry/object-keys/object-keys-1.1.1.tgz | Bin 0 -> 7677 bytes .../npm/registry/object-keys/registry.json | 1 + .../npm/registry/p-limit/p-limit-2.3.0.tgz | Bin 0 -> 3140 bytes tests/testdata/npm/registry/p-limit/registry.json | 1 + .../npm/registry/p-locate/p-locate-4.1.0.tgz | Bin 0 -> 3060 bytes tests/testdata/npm/registry/p-locate/registry.json | 1 + tests/testdata/npm/registry/p-try/p-try-2.2.0.tgz | Bin 0 -> 2194 bytes tests/testdata/npm/registry/p-try/registry.json | 1 + .../npm/registry/path-exists/path-exists-4.0.0.tgz | Bin 0 -> 2073 bytes .../npm/registry/path-exists/registry.json | 1 + .../npm/registry/pathval/pathval-1.1.1.tgz | Bin 0 -> 5554 bytes tests/testdata/npm/registry/pathval/registry.json | 1 + .../npm/registry/picocolors/picocolors-1.0.0.tgz | Bin 0 -> 2411 bytes .../testdata/npm/registry/picocolors/registry.json | 1 + .../postcss-value-parser-4.2.0.tgz | Bin 0 -> 7997 bytes .../registry/postcss-value-parser/registry.json | 1 + .../npm/registry/postcss/postcss-8.4.16.tgz | Bin 0 -> 44045 bytes tests/testdata/npm/registry/postcss/registry.json | 1 + .../npm/registry/punycode/punycode-2.1.1.tgz | Bin 0 -> 7270 bytes tests/testdata/npm/registry/punycode/registry.json | 1 + .../npm/registry/react-dom/react-dom-18.2.0.tgz | Bin 0 -> 1087708 bytes .../testdata/npm/registry/react-dom/registry.json | 1 + tests/testdata/npm/registry/react/react-18.2.0.tgz | Bin 0 -> 81152 bytes tests/testdata/npm/registry/react/registry.json | 1 + .../npm/registry/require-directory/registry.json | 1 + .../require-directory/require-directory-2.1.1.tgz | Bin 0 -> 4372 bytes .../npm/registry/require-from-string/registry.json | 1 + .../require-from-string-2.0.2.tgz | Bin 0 -> 1816 bytes .../registry/require-main-filename/registry.json | 1 + .../require-main-filename-2.0.0.tgz | Bin 0 -> 1965 bytes .../npm/registry/safer-buffer/registry.json | 1 + .../registry/safer-buffer/safer-buffer-2.1.2.tgz | Bin 0 -> 12035 bytes .../testdata/npm/registry/scheduler/registry.json | 1 + .../npm/registry/scheduler/scheduler-0.23.0.tgz | Bin 0 -> 17697 bytes .../npm/registry/set-blocking/registry.json | 1 + .../registry/set-blocking/set-blocking-2.0.0.tgz | Bin 0 -> 2212 bytes .../npm/registry/source-map-js/registry.json | 1 + .../registry/source-map-js/source-map-js-1.0.2.tgz | Bin 0 -> 38056 bytes .../testdata/npm/registry/source-map/registry.json | 1 + .../npm/registry/source-map/source-map-0.6.1.tgz | Bin 0 -> 199644 bytes .../npm/registry/sourcemap-codec/registry.json | 1 + .../sourcemap-codec/sourcemap-codec-1.4.8.tgz | Bin 0 -> 7135 bytes tests/testdata/npm/registry/ssh2/registry.json | 1 + tests/testdata/npm/registry/ssh2/ssh2-1.11.0.tgz | Bin 0 -> 247466 bytes .../npm/registry/string-width/registry.json | 1 + .../registry/string-width/string-width-2.1.1.tgz | Bin 0 -> 1972 bytes .../registry/string-width/string-width-4.2.3.tgz | Bin 0 -> 2383 bytes .../testdata/npm/registry/strip-ansi/registry.json | 1 + .../npm/registry/strip-ansi/strip-ansi-4.0.0.tgz | Bin 0 -> 1644 bytes .../npm/registry/strip-ansi/strip-ansi-6.0.1.tgz | Bin 0 -> 2041 bytes .../npm/registry/strip-final-newline/registry.json | 1 + .../strip-final-newline-2.0.0.tgz | Bin 0 -> 1704 bytes .../npm/registry/supports-color/registry.json | 1 + .../supports-color/supports-color-7.2.0.tgz | Bin 0 -> 3210 bytes .../npm/registry/supports-esm/registry.json | 1 + .../registry/supports-esm/supports-esm-1.0.0.tgz | Bin 0 -> 1879 bytes .../testdata/npm/registry/tweetnacl/registry.json | 1 + .../npm/registry/tweetnacl/tweetnacl-0.14.5.tgz | Bin 0 -> 49663 bytes .../npm/registry/type-detect/registry.json | 1 + .../npm/registry/type-detect/type-detect-4.0.8.tgz | Bin 0 -> 8070 bytes .../testdata/npm/registry/type-fest/registry.json | 1 + .../npm/registry/type-fest/type-fest-0.20.2.tgz | Bin 0 -> 37225 bytes .../npm/registry/universalify/registry.json | 1 + .../registry/universalify/universalify-2.0.0.tgz | Bin 0 -> 2067 bytes .../registry/update-browserslist-db/registry.json | 1 + .../update-browserslist-db-1.0.10.tgz | Bin 0 -> 4797 bytes tests/testdata/npm/registry/uri-js/registry.json | 1 + .../testdata/npm/registry/uri-js/uri-js-4.4.1.tgz | Bin 0 -> 132003 bytes tests/testdata/npm/registry/vue/registry.json | 1 + tests/testdata/npm/registry/vue/vue-3.2.38.tgz | Bin 0 -> 651102 bytes .../npm/registry/which-module/registry.json | 1 + .../registry/which-module/which-module-2.0.0.tgz | Bin 0 -> 2232 bytes .../testdata/npm/registry/wrap-ansi/registry.json | 1 + .../npm/registry/wrap-ansi/wrap-ansi-6.2.0.tgz | Bin 0 -> 4004 bytes tests/testdata/npm/registry/y18n/registry.json | 1 + tests/testdata/npm/registry/y18n/y18n-4.0.3.tgz | Bin 0 -> 4296 bytes .../npm/registry/yargs-parser/registry.json | 1 + .../registry/yargs-parser/yargs-parser-18.1.3.tgz | Bin 0 -> 19027 bytes tests/testdata/npm/registry/yargs/registry.json | 1 + tests/testdata/npm/registry/yargs/yargs-15.4.1.tgz | Bin 0 -> 56286 bytes tests/testdata/npm/reload/main.ts | 3 + tests/testdata/npm/remote_npm_specifier/main.out | 1 + tests/testdata/npm/remote_npm_specifier/main.ts | 1 + tests/testdata/npm/remote_npm_specifier/remote.ts | 3 + tests/testdata/npm/require_added_nm_folder/main.js | 10 + .../testdata/npm/require_added_nm_folder/main.out | 1 + tests/testdata/npm/require_json/main.js | 2 + tests/testdata/npm/require_json/main.out | 3 + tests/testdata/npm/require_main/main.js | 2 + tests/testdata/npm/require_main/main.out | 1 + .../testdata/npm/require_resolve_url/package.json | 7 + .../testdata/npm/require_resolve_url/url_paths.out | 2 + .../testdata/npm/require_resolve_url/url_paths.ts | 12 + tests/testdata/npm/reserved_word_exports/main.out | 141 + tests/testdata/npm/reserved_word_exports/main.ts | 3 + .../testdata/npm/run_existing_npm_package/main.out | 3 + .../npm/run_existing_npm_package/package.json | 6 + .../run_existing_npm_package_with_subpath/main.out | 5 + .../package.json | 6 + tests/testdata/npm/sub_paths/main.jsx | 8 + tests/testdata/npm/sub_paths/main.out | 1 + .../npm/tarball_with_global_header/main.js | 3 + .../npm/tarball_with_global_header/main.out | 1 + tests/testdata/npm/translate_cjs_to_esm/main.js | 6 + tests/testdata/npm/translate_cjs_to_esm/main.out | 4 + tests/testdata/npm/types/main.out | 71 + tests/testdata/npm/types/main.ts | 27 + .../npm/types_ambient_module/import_map.json | 5 + tests/testdata/npm/types_ambient_module/main.out | 21 + tests/testdata/npm/types_ambient_module/main.ts | 7 + .../npm/types_ambient_module/main_import_map.out | 9 + .../npm/types_ambient_module/main_import_map.ts | 4 + .../npm/types_entry_value_not_exists/main.out | 7 + .../npm/types_entry_value_not_exists/main.ts | 5 + .../npm/types_exports_import_types/main.out | 7 + .../npm/types_exports_import_types/main.ts | 5 + tests/testdata/npm/types_no_types_entry/main.out | 13 + tests/testdata/npm/types_no_types_entry/main.ts | 5 + .../npm/typescript_file_in_package/main.out | 6 + .../npm/typescript_file_in_package/main.ts | 5 + .../package_json/basic/fail_check.check.out | 4 + tests/testdata/package_json/basic/fail_check.ts | 3 + tests/testdata/package_json/basic/lib.bench.out | 11 + tests/testdata/package_json/basic/lib.bench.ts | 7 + tests/testdata/package_json/basic/lib.test.out | 9 + tests/testdata/package_json/basic/lib.test.ts | 7 + tests/testdata/package_json/basic/lib.ts | 9 + tests/testdata/package_json/basic/main.cache.out | 3 + tests/testdata/package_json/basic/main.check.out | 4 + tests/testdata/package_json/basic/main.info.out | 8 + tests/testdata/package_json/basic/main.ts | 3 + tests/testdata/package_json/basic/package.json | 5 + tests/testdata/package_json/deno_json/deno.json | 5 + .../testdata/package_json/deno_json/main.check.out | 11 + tests/testdata/package_json/deno_json/main.out | 2 + tests/testdata/package_json/deno_json/main.ts | 9 + tests/testdata/package_json/deno_json/other.ts | 3 + tests/testdata/package_json/deno_json/package.json | 5 + tests/testdata/package_json/invalid_value/error.ts | 4 + .../package_json/invalid_value/error.ts.out | 6 + tests/testdata/package_json/invalid_value/ok.ts | 4 + .../testdata/package_json/invalid_value/ok.ts.out | 4 + .../package_json/invalid_value/package.json | 9 + tests/testdata/package_json/invalid_value/task.out | 5 + tests/testdata/publish/deno_jsonc.out | 6 + tests/testdata/publish/deno_jsonc/deno.jsonc | 11 + tests/testdata/publish/deno_jsonc/mod.ts | 5 + tests/testdata/publish/deno_jsonc/std_http.ts | 6 + tests/testdata/publish/dry_run.out | 4 + tests/testdata/publish/invalid_fast_check.out | 16 + .../testdata/publish/invalid_fast_check/deno.json | 7 + tests/testdata/publish/invalid_fast_check/mod.ts | 4 + tests/testdata/publish/invalid_import.out | 32 + tests/testdata/publish/invalid_import/deno.json | 10 + tests/testdata/publish/invalid_import/mod.ts | 9 + tests/testdata/publish/invalid_path.out | 11 + tests/testdata/publish/invalid_path/deno.json | 7 + tests/testdata/publish/invalid_path/mod.ts | 3 + .../publish/invalid_path/path with spaces.txt | 0 tests/testdata/publish/javascript_decl_file.out | 6 + .../publish/javascript_decl_file/deno.json | 7 + .../testdata/publish/javascript_decl_file/mod.d.ts | 1 + tests/testdata/publish/javascript_decl_file/mod.js | 5 + .../publish/javascript_missing_decl_file.out | 12 + .../publish/javascript_missing_decl_file/deno.json | 8 + .../publish/javascript_missing_decl_file/mod.js | 3 + .../publish/javascript_missing_decl_file/other.js | 3 + tests/testdata/publish/missing_deno_json.out | 1 + tests/testdata/publish/missing_deno_json/main.ts | 3 + tests/testdata/publish/no_token.out | 1 + tests/testdata/publish/no_zap.out | 5 + tests/testdata/publish/node_specifier.out | 8 + tests/testdata/publish/node_specifier/deno.json | 7 + tests/testdata/publish/node_specifier/mod.ts | 5 + tests/testdata/publish/successful.out | 6 + tests/testdata/publish/successful/deno.json | 10 + tests/testdata/publish/successful/mod.ts | 5 + tests/testdata/publish/successful/std_http.ts | 6 + tests/testdata/publish/symlink.out | 12 + tests/testdata/publish/symlink/deno.json | 7 + tests/testdata/publish/symlink/mod.ts | 3 + tests/testdata/publish/symlink/symlink | 1 + .../publish/unanalyzable_dynamic_import.out | 16 + .../publish/unanalyzable_dynamic_import/deno.json | 7 + .../publish/unanalyzable_dynamic_import/mod.ts | 1 + tests/testdata/publish/workspace.out | 11 + tests/testdata/publish/workspace/bar/deno.json | 7 + tests/testdata/publish/workspace/bar/mod.ts | 3 + tests/testdata/publish/workspace/deno.json | 6 + tests/testdata/publish/workspace/foo/deno.json | 10 + tests/testdata/publish/workspace/foo/mod.ts | 5 + tests/testdata/publish/workspace_individual.out | 6 + tests/testdata/repl/import_type.ts | 5 + tests/testdata/run/001_hello.js | 1 + tests/testdata/run/001_hello.js.out | 1 + tests/testdata/run/002_hello.ts | 1 + tests/testdata/run/002_hello.ts.out | 1 + tests/testdata/run/003_relative_import.ts | 3 + tests/testdata/run/003_relative_import.ts.out | 1 + tests/testdata/run/004_set_timeout.ts | 11 + tests/testdata/run/004_set_timeout.ts.out | 2 + tests/testdata/run/005_more_imports.ts | 11 + tests/testdata/run/005_more_imports.ts.out | 1 + tests/testdata/run/006_url_imports.ts | 3 + tests/testdata/run/006_url_imports.ts.out | 2 + tests/testdata/run/012_async.ts | 11 + tests/testdata/run/012_async.ts.out | 3 + tests/testdata/run/013_dynamic_import.ts | 15 + tests/testdata/run/013_dynamic_import.ts.out | 1 + tests/testdata/run/014_duplicate_import.ts | 9 + tests/testdata/run/014_duplicate_import.ts.out | 1 + .../testdata/run/015_duplicate_parallel_import.js | 20 + .../run/015_duplicate_parallel_import.js.out | 1 + tests/testdata/run/016_double_await.ts | 8 + tests/testdata/run/016_double_await.ts.out | 2 + tests/testdata/run/017_import_redirect.ts | 4 + tests/testdata/run/017_import_redirect.ts.out | 1 + tests/testdata/run/017_import_redirect_info.out | 7 + tests/testdata/run/018_async_catch.ts | 14 + tests/testdata/run/018_async_catch.ts.out | 3 + tests/testdata/run/019_media_types.ts | 24 + tests/testdata/run/019_media_types.ts.out | 1 + tests/testdata/run/020_json_modules.ts | 2 + tests/testdata/run/020_json_modules.ts.out | 3 + tests/testdata/run/021_mjs_modules.ts | 2 + tests/testdata/run/021_mjs_modules.ts.out | 1 + tests/testdata/run/023_no_ext | 2 + tests/testdata/run/023_no_ext.out | 1 + tests/testdata/run/025_hrtime.ts | 5 + tests/testdata/run/025_hrtime.ts.out | 2 + tests/testdata/run/025_reload_js_type_error.js | 6 + tests/testdata/run/025_reload_js_type_error.js.out | 1 + tests/testdata/run/026_redirect_javascript.js | 2 + tests/testdata/run/026_redirect_javascript.js.out | 1 + tests/testdata/run/027_redirect_typescript.ts | 2 + tests/testdata/run/027_redirect_typescript.ts.out | 1 + tests/testdata/run/028_args.ts | 3 + tests/testdata/run/028_args.ts.out | 6 + tests/testdata/run/033_import_map.out | 7 + .../testdata/run/033_import_map_in_config_file.out | 8 + .../run/033_import_map_in_flag_has_precedence.out | 1 + tests/testdata/run/033_import_map_remote.out | 5 + tests/testdata/run/035_cached_only_flag.out | 1 + tests/testdata/run/038_checkjs.js | 5 + tests/testdata/run/038_checkjs.js.out | 22 + tests/testdata/run/042_dyn_import_evalcontext.ts | 5 + .../testdata/run/042_dyn_import_evalcontext.ts.out | 1 + tests/testdata/run/044_bad_resource.ts | 3 + tests/testdata/run/044_bad_resource.ts.out | 2 + tests/testdata/run/045_mod.ts | 5 + tests/testdata/run/045_output.ts | 3 + .../testdata/run/045_programmatic_proxy_client.ts | 16 + tests/testdata/run/045_proxy_client.ts | 5 + tests/testdata/run/045_proxy_test.ts | 121 + tests/testdata/run/045_proxy_test.ts.out | 6 + tests/testdata/run/046_jsx_test.tsx | 14 + tests/testdata/run/046_jsx_test.tsx.out | 1 + tests/testdata/run/047_jsx_test.jsx | 7 + tests/testdata/run/047_jsx_test.jsx.out | 1 + tests/testdata/run/048_media_types_jsx.ts | 32 + tests/testdata/run/048_media_types_jsx.ts.out | 2 + tests/testdata/run/052_no_remote_flag.out | 1 + .../testdata/run/056_make_temp_file_write_perm.out | 1 + .../testdata/run/056_make_temp_file_write_perm.ts | 9 + tests/testdata/run/058_tasks_microtasks_close.ts | 19 + .../testdata/run/058_tasks_microtasks_close.ts.out | 6 + tests/testdata/run/059_fs_relative_path_perm.ts | 2 + .../testdata/run/059_fs_relative_path_perm.ts.out | 4 + tests/testdata/run/061_permissions_request.ts | 9 + tests/testdata/run/061_permissions_request_sync.ts | 8 + .../testdata/run/062_permissions_request_global.ts | 6 + .../run/062_permissions_request_global_sync.ts | 6 + tests/testdata/run/063_permissions_revoke.ts | 6 + tests/testdata/run/063_permissions_revoke.ts.out | 3 + tests/testdata/run/063_permissions_revoke_sync.ts | 6 + .../testdata/run/064_permissions_revoke_global.ts | 6 + .../run/064_permissions_revoke_global.ts.out | 3 + .../run/064_permissions_revoke_global_sync.ts | 6 + tests/testdata/run/065_permissions_revoke_net.ts | 6 + .../testdata/run/065_permissions_revoke_net.ts.out | 3 + tests/testdata/run/066_prompt.ts | 17 + tests/testdata/run/070_location.ts | 18 + tests/testdata/run/070_location.ts.out | 15 + tests/testdata/run/071_location_unset.ts | 16 + tests/testdata/run/071_location_unset.ts.out | 4 + tests/testdata/run/072_location_relative_fetch.ts | 2 + .../run/072_location_relative_fetch.ts.out | 2 + tests/testdata/run/075_import_local_query_hash.ts | 2 + .../run/075_import_local_query_hash.ts.out | 2 + tests/testdata/run/077_fetch_empty.ts | 1 + tests/testdata/run/077_fetch_empty.ts.out | 2 + tests/testdata/run/078_unload_on_exit.ts | 9 + tests/testdata/run/078_unload_on_exit.ts.out | 1 + tests/testdata/run/079_location_authentication.ts | 1 + .../run/079_location_authentication.ts.out | 1 + .../run/081_location_relative_fetch_redirect.ts | 2 + .../081_location_relative_fetch_redirect.ts.out | 1 + .../testdata/run/082_prepare_stack_trace_throw.js | 6 + .../run/082_prepare_stack_trace_throw.js.out | 2 + .../testdata/run/083_legacy_external_source_map.ts | 2 + .../run/088_dynamic_import_already_evaluating.ts | 2 + .../088_dynamic_import_already_evaluating.ts.out | 4 + tests/testdata/run/088_dynamic_import_target.ts | 3 + tests/testdata/run/089_run_allow_list.ts | 12 + tests/testdata/run/089_run_allow_list.ts.out | 3 + tests/testdata/run/090_run_permissions_request.ts | 18 + .../run/090_run_permissions_request_sync.ts | 18 + .../run/091_use_define_for_class_fields.ts | 4 + .../run/091_use_define_for_class_fields.ts.out | 4 + .../run/092_import_map_unmapped_bare_specifier.ts | 1 + .../092_import_map_unmapped_bare_specifier.ts.out | 6 + tests/testdata/run/aggregate_error.out | 18 + tests/testdata/run/aggregate_error.ts | 9 + tests/testdata/run/async_error.ts | 9 + tests/testdata/run/async_error.ts.out | 8 + .../testdata/run/auto_discover_lockfile/deno.json | 3 + .../testdata/run/auto_discover_lockfile/deno.lock | 7 + tests/testdata/run/auto_discover_lockfile/main.out | 5 + tests/testdata/run/auto_discover_lockfile/main.ts | 1 + tests/testdata/run/before_unload.js | 21 + tests/testdata/run/before_unload.js.out | 8 + tests/testdata/run/blob_gc_finalization.js | 11 + tests/testdata/run/blob_gc_finalization.js.out | 1 + tests/testdata/run/byte_order_mark.out | 1 + tests/testdata/run/byte_order_mark.ts | 4 + tests/testdata/run/check_js_points_to_ts/bar.ts | 3 + tests/testdata/run/check_js_points_to_ts/foo.d.ts | 0 tests/testdata/run/check_js_points_to_ts/foo.js | 4 + tests/testdata/run/check_js_points_to_ts/test.js | 3 + .../testdata/run/check_js_points_to_ts/test.js.out | 4 + tests/testdata/run/checkjs.tsconfig.json | 6 + tests/testdata/run/cjs_imports/commonjs.cjs | 1 + tests/testdata/run/cjs_imports/main.out | 1 + tests/testdata/run/cjs_imports/main.ts | 1 + tests/testdata/run/classic_workers_event_loop.js | 4 + .../testdata/run/classic_workers_event_loop.js.out | 1 + tests/testdata/run/colors_without_globalThis.js | 1 + tests/testdata/run/complex_error.ts | 18 + tests/testdata/run/complex_error.ts.out | 44 + tests/testdata/run/complex_permissions_test.ts | 53 + tests/testdata/run/config/main.out | 4 + tests/testdata/run/config/main.ts | 5 + tests/testdata/run/config/tsconfig.json | 7 + .../run/config_file_lock_boolean/deno.lock | 7 + .../run/config_file_lock_boolean/false.json | 3 + .../run/config_file_lock_boolean/false.main.out | 2 + .../testdata/run/config_file_lock_boolean/main.ts | 1 + .../run/config_file_lock_boolean/true.json | 3 + .../run/config_file_lock_boolean/true.main.out | 3 + tests/testdata/run/config_file_lock_path.json | 3 + tests/testdata/run/config_file_lock_path.out | 3 + tests/testdata/run/config_json_import.ts | 2 + tests/testdata/run/config_json_import.ts.out | 3 + tests/testdata/run/config_types/deno.lock | 6 + tests/testdata/run/config_types/main.out | 1 + tests/testdata/run/config_types/main.ts | 1 + .../testdata/run/config_types/remote.tsconfig.json | 7 + tests/testdata/run/config_types/tsconfig.json | 7 + tests/testdata/run/config_types/types.d.ts | 2 + tests/testdata/run/custom_inspect_url.js | 3 + tests/testdata/run/custom_inspect_url.js.out | 47 + .../testdata/run/decorators/experimental/deno.json | 5 + .../run/decorators/experimental/no_check/main.out | 3 + .../run/decorators/experimental/no_check/main.ts | 21 + .../run/decorators/experimental/runtime/main.out | 7 + .../run/decorators/experimental/runtime/main.ts | 42 + .../run/decorators/experimental/ts/main.out | 2 + .../run/decorators/experimental/ts/main.ts | 14 + .../testdata/run/decorators/tc39_proposal/main.out | 3 + .../testdata/run/decorators/tc39_proposal/main.ts | 21 + tests/testdata/run/delete_window.js | 1 + tests/testdata/run/deno_exit_tampering.ts | 3 + tests/testdata/run/deny_all_permission_args.js | 8 + tests/testdata/run/deny_all_permission_args.out | 8 + tests/testdata/run/deny_some_permission_args.js | 22 + tests/testdata/run/deny_some_permission_args.out | 22 + tests/testdata/run/disallow_http_from_https.js | 2 + tests/testdata/run/disallow_http_from_https.ts | 2 + tests/testdata/run/disallow_http_from_https_js.out | 3 + tests/testdata/run/disallow_http_from_https_ts.out | 3 + tests/testdata/run/dom_exception_formatting.ts | 1 + tests/testdata/run/dom_exception_formatting.ts.out | 3 + .../dynamic_import_already_rejected/error_001.ts | 9 + .../run/dynamic_import_already_rejected/main.out | 4 + .../run/dynamic_import_already_rejected/main.ts | 15 + .../dynamic_import_async_error/delayed_error.ts | 2 + .../run/dynamic_import_async_error/main.out | 2 + .../run/dynamic_import_async_error/main.ts | 7 + .../main.out | 100 + .../main.ts | 16 + .../mod.ts | 7 + tests/testdata/run/dynamic_import_conditional.js | 3 + .../testdata/run/dynamic_import_conditional.js.out | 1 + tests/testdata/run/dynamic_import_syntax_error.js | 1 + .../run/dynamic_import_syntax_error.js.out | 4 + .../run/dynamic_import_syntax_error_import.js | 5 + tests/testdata/run/empty.ts | 0 tests/testdata/run/env_file.out | 4 + tests/testdata/run/env_file.ts | 3 + tests/testdata/run/env_file_missing.out | 4 + tests/testdata/run/error_001.ts | 9 + tests/testdata/run/error_001.ts.out | 6 + tests/testdata/run/error_002.ts | 7 + tests/testdata/run/error_002.ts.out | 6 + tests/testdata/run/error_003_typescript.ts | 20 + tests/testdata/run/error_003_typescript.ts.out | 7 + tests/testdata/run/error_004_missing_module.ts | 3 + tests/testdata/run/error_004_missing_module.ts.out | 2 + .../run/error_005_missing_dynamic_import.ts | 3 + .../run/error_005_missing_dynamic_import.ts.out | 4 + tests/testdata/run/error_006_import_ext_failure.ts | 1 + .../run/error_006_import_ext_failure.ts.out | 2 + tests/testdata/run/error_007_any.ts | 1 + tests/testdata/run/error_007_any.ts.out | 1 + tests/testdata/run/error_008_checkjs.js | 5 + tests/testdata/run/error_008_checkjs.js.out | 4 + tests/testdata/run/error_009_extensions_error.js | 2 + .../testdata/run/error_009_extensions_error.js.out | 6 + .../run/error_009_missing_js_module.disabled | 4 + .../testdata/run/error_011_bad_module_specifier.ts | 3 + .../run/error_011_bad_module_specifier.ts.out | 2 + .../run/error_012_bad_dynamic_import_specifier.ts | 3 + .../error_012_bad_dynamic_import_specifier.ts.out | 7 + tests/testdata/run/error_013_missing_script.out | 1 + .../run/error_014_catch_dynamic_import_error.js | 31 + .../error_014_catch_dynamic_import_error.js.out | 19 + .../run/error_015_dynamic_import_permissions.js | 3 + .../run/error_015_dynamic_import_permissions.out | 4 + .../run/error_016_dynamic_import_permissions2.js | 5 + .../run/error_016_dynamic_import_permissions2.out | 7 + .../testdata/run/error_017_hide_long_source_ts.ts | 3 + .../run/error_017_hide_long_source_ts.ts.out | 3 + .../testdata/run/error_018_hide_long_source_js.js | 3 + .../run/error_018_hide_long_source_js.js.out | 2 + tests/testdata/run/error_019_stack_function.ts | 12 + tests/testdata/run/error_019_stack_function.ts.out | 8 + tests/testdata/run/error_020_stack_constructor.ts | 14 + .../run/error_020_stack_constructor.ts.out | 8 + tests/testdata/run/error_021_stack_method.ts | 14 + tests/testdata/run/error_021_stack_method.ts.out | 8 + tests/testdata/run/error_022_stack_custom_error.ts | 14 + .../run/error_022_stack_custom_error.ts.out | 6 + tests/testdata/run/error_023_stack_async.ts | 14 + tests/testdata/run/error_023_stack_async.ts.out | 10 + tests/testdata/run/error_024_stack_promise_all.ts | 16 + .../run/error_024_stack_promise_all.ts.out | 10 + tests/testdata/run/error_025_tab_indent | 9 + tests/testdata/run/error_025_tab_indent.out | 6 + .../testdata/run/error_026_remote_import_error.ts | 1 + .../run/error_026_remote_import_error.ts.out | 7 + tests/testdata/run/error_cause.ts | 14 + tests/testdata/run/error_cause.ts.out | 13 + tests/testdata/run/error_cause_recursive.ts | 4 + tests/testdata/run/error_cause_recursive.ts.out | 7 + tests/testdata/run/error_for_await.ts | 12 + tests/testdata/run/error_for_await.ts.out | 10 + .../run/error_import_map_unable_to_load.out | 4 + .../run/error_local_static_import_from_remote.js | 1 + .../error_local_static_import_from_remote.js.out | 4 + .../run/error_local_static_import_from_remote.ts | 1 + .../error_local_static_import_from_remote.ts.out | 4 + .../run/error_missing_module_named_import.ts | 3 + .../run/error_missing_module_named_import.ts.out | 2 + tests/testdata/run/error_name_non_string.js | 8 + tests/testdata/run/error_name_non_string.js.out | 4 + tests/testdata/run/error_no_check.ts | 1 + tests/testdata/run/error_no_check.ts.out | 2 + tests/testdata/run/error_syntax.js | 3 + tests/testdata/run/error_syntax.js.out | 4 + .../run/error_syntax_empty_trailing_line.mjs | 2 + .../run/error_syntax_empty_trailing_line.mjs.out | 4 + tests/testdata/run/error_type_definitions.ts | 5 + tests/testdata/run/error_type_definitions.ts.out | 2 + tests/testdata/run/error_with_errors_prop.js | 10 + tests/testdata/run/error_with_errors_prop.js.out | 17 + tests/testdata/run/es_private_fields.js | 15 + tests/testdata/run/es_private_fields.js.out | 1 + .../run/eval_context_throw_dom_exception.js | 5 + .../run/eval_context_throw_dom_exception.js.out | 9 + tests/testdata/run/event_listener_error.ts | 6 + tests/testdata/run/event_listener_error.ts.out | 7 + tests/testdata/run/event_listener_error_handled.ts | 23 + .../run/event_listener_error_handled.ts.out | 17 + .../run/event_listener_error_immediate_exit.ts | 12 + .../run/event_listener_error_immediate_exit.ts.out | 6 + .../event_listener_error_immediate_exit_worker.ts | 4 + ...ent_listener_error_immediate_exit_worker.ts.out | 8 + tests/testdata/run/exec_path.ts | 1 + tests/testdata/run/exit_error42.ts | 3 + tests/testdata/run/exit_error42.ts.out | 1 + .../run/explicit_resource_management/main.out | 5 + .../run/explicit_resource_management/main.ts | 21 + tests/testdata/run/export_type_def.ts | 2 + tests/testdata/run/extension_dynamic_import.ts | 1 + tests/testdata/run/extension_dynamic_import.ts.out | 4 + tests/testdata/run/extension_import.ts | 1 + tests/testdata/run/extension_import.ts.out | 8 + tests/testdata/run/fetch/hello.txt | 1 + tests/testdata/run/fetch/other.ts | 1 + tests/testdata/run/fetch/test.ts | 1 + tests/testdata/run/fetch_async_error_stack.ts | 1 + tests/testdata/run/fetch_async_error_stack.ts.out | 5 + tests/testdata/run/fetch_response_finalization.js | 16 + .../run/fetch_response_finalization.js.out | 2 + tests/testdata/run/finalization_registry.js | 20 + tests/testdata/run/finalization_registry.js.out | 1 + tests/testdata/run/fix_dynamic_import_errors.js | 7 + .../testdata/run/fix_dynamic_import_errors.js.out | 2 + tests/testdata/run/fix_emittable_skipped.js | 7 + tests/testdata/run/fix_emittable_skipped.ts.out | 1 + tests/testdata/run/fix_js_import_js.ts | 3 + tests/testdata/run/fix_js_import_js.ts.out | 1 + tests/testdata/run/fix_js_imports.ts | 3 + tests/testdata/run/fix_js_imports.ts.out | 1 + tests/testdata/run/fix_tsc_file_exists.out | 1 + tests/testdata/run/fix_worker_dispatchevent.ts | 43 + tests/testdata/run/fix_worker_dispatchevent.ts.out | 1 + .../run/followup_dyn_import_resolves/main.ts | 14 + .../run/followup_dyn_import_resolves/main.ts.out | 3 + .../run/followup_dyn_import_resolves/sub1.ts | 2 + .../run/followup_dyn_import_resolves/sub2.ts | 1 + tests/testdata/run/heapstats.js | 37 + tests/testdata/run/heapstats.js.out | 2 + tests/testdata/run/http2_request_url.ts | 12 + tests/testdata/run/https_import.ts | 3 + tests/testdata/run/https_import.ts.out | 1 + tests/testdata/run/if_main.ts | 6 + tests/testdata/run/if_main.ts.out | 1 + tests/testdata/run/import_blob_url.ts | 13 + tests/testdata/run/import_blob_url.ts.out | 3 + tests/testdata/run/import_blob_url_error_stack.ts | 13 + .../run/import_blob_url_error_stack.ts.out | 5 + .../run/import_blob_url_import_relative.ts | 8 + .../run/import_blob_url_import_relative.ts.out | 5 + tests/testdata/run/import_blob_url_imports.ts | 11 + tests/testdata/run/import_blob_url_imports.ts.out | 1 + tests/testdata/run/import_blob_url_jsx.ts | 16 + tests/testdata/run/import_blob_url_jsx.ts.out | 1 + tests/testdata/run/import_compression/brotli | 2 + tests/testdata/run/import_compression/gziped | Bin 0 -> 39 bytes tests/testdata/run/import_compression/main.out | 4 + tests/testdata/run/import_compression/main.ts | 13 + tests/testdata/run/import_data_url.ts | 12 + tests/testdata/run/import_data_url.ts.out | 3 + tests/testdata/run/import_data_url_error_stack.ts | 3 + .../run/import_data_url_error_stack.ts.out | 5 + .../run/import_data_url_import_relative.ts | 4 + .../run/import_data_url_import_relative.ts.out | 2 + tests/testdata/run/import_data_url_imports.ts | 4 + tests/testdata/run/import_data_url_imports.ts.out | 1 + tests/testdata/run/import_data_url_jsx.ts | 10 + tests/testdata/run/import_data_url_jsx.ts.out | 1 + tests/testdata/run/import_dynamic_data_url.ts | 14 + tests/testdata/run/import_dynamic_data_url.ts.out | 3 + tests/testdata/run/import_extensionless.ts | 3 + tests/testdata/run/import_extensionless.ts.out | 1 + tests/testdata/run/import_file_with_colon.ts | 1 + tests/testdata/run/import_file_with_colon.ts.out | 1 + tests/testdata/run/import_maps/test_data.ts | 1 + tests/testdata/run/import_maps/test_data.ts.out | 1 + tests/testdata/run/import_meta/importmap.json | 12 + tests/testdata/run/import_meta/main.out | 13 + tests/testdata/run/import_meta/main.ts | 52 + tests/testdata/run/import_meta/other.ts | 7 + tests/testdata/run/import_type.ts | 5 + tests/testdata/run/import_type.ts.out | 1 + tests/testdata/run/inline_js_source_map.ts | 6 + tests/testdata/run/inline_js_source_map_2.js | 4 + tests/testdata/run/inline_js_source_map_2.js.out | 2 + tests/testdata/run/inline_js_source_map_2.ts | 6 + .../inline_js_source_map_2_with_inline_contents.js | 4 + ...ine_js_source_map_2_with_inline_contents.js.out | 2 + ...nline_js_source_map_with_contents_from_graph.js | 4 + ...e_js_source_map_with_contents_from_graph.js.out | 4 + tests/testdata/run/issue13562.ts | 3 + tests/testdata/run/issue13562.ts.out | 1 + tests/testdata/run/issue9750.js | 6 + tests/testdata/run/js_import_detect.ts | 3 + tests/testdata/run/js_import_detect.ts.out | 1 + tests/testdata/run/js_root_with_ts_check.js | 5 + tests/testdata/run/js_root_with_ts_check.js.out | 4 + tests/testdata/run/jsx_import_from_ts.App.jsx | 11 + tests/testdata/run/jsx_import_from_ts.ts | 3 + tests/testdata/run/jsx_import_from_ts.ts.out | 1 + tests/testdata/run/jsx_import_source.out | 2 + tests/testdata/run/jsx_import_source_dev.out | 2 + tests/testdata/run/jsx_import_source_error.out | 2 + .../testdata/run/jsx_import_source_import_map.out | 2 + .../run/jsx_import_source_import_map_dev.out | 2 + tests/testdata/run/jsx_import_source_no_pragma.tsx | 7 + tests/testdata/run/jsx_import_source_pragma.tsx | 9 + .../run/jsx_import_source_pragma_import_map.tsx | 9 + tests/testdata/run/jsx_precompile/no_pragma.out | 3 + tests/testdata/run/jsx_precompile/no_pragma.tsx | 3 + tests/testdata/run/lock_check_err.json | 4 + tests/testdata/run/lock_check_err.out | 3 + tests/testdata/run/lock_check_err2.json | 10 + tests/testdata/run/lock_check_err2.out | 3 + tests/testdata/run/lock_check_ok.json | 4 + tests/testdata/run/lock_check_ok2.json | 13 + tests/testdata/run/lock_dynamic_imports.json | 6 + tests/testdata/run/lock_dynamic_imports.out | 4 + tests/testdata/run/lock_only_http_and_https/b.ts | 3 + .../run/lock_only_http_and_https/deno.lock | 7 + .../testdata/run/lock_only_http_and_https/main.out | 5 + .../testdata/run/lock_only_http_and_https/main.ts | 6 + tests/testdata/run/lock_v2_check_err.json | 7 + tests/testdata/run/lock_v2_check_err.out | 3 + tests/testdata/run/lock_v2_check_err2.json | 13 + tests/testdata/run/lock_v2_check_err2.out | 3 + tests/testdata/run/lock_v2_check_ok.json | 7 + tests/testdata/run/lock_v2_check_ok2.json | 13 + tests/testdata/run/lock_v2_dynamic_imports.json | 9 + tests/testdata/run/lock_v2_dynamic_imports.out | 4 + tests/testdata/run/lock_write_fetch/file_exists.ts | 6 + tests/testdata/run/lock_write_fetch/main.out | 3 + tests/testdata/run/lock_write_fetch/main.ts | 52 + tests/testdata/run/long_data_url_formatting.ts | 3 + tests/testdata/run/long_data_url_formatting.ts.out | 8 + tests/testdata/run/main_module/main.out | 2 + tests/testdata/run/main_module/main.ts | 3 + tests/testdata/run/main_module/other.ts | 1 + tests/testdata/run/mts_dmts_mjs.out | 1 + tests/testdata/run/nested_error/main.ts | 3 + tests/testdata/run/nested_error/main.ts.out | 4 + .../no_check_imports_not_used_as_values/hello.ts | 2 + .../no_check_imports_not_used_as_values/main.out | 2 + .../no_check_imports_not_used_as_values/main.ts | 4 + .../preserve_imports.tsconfig.json | 5 + tests/testdata/run/no_check_remote.ts | 3 + tests/testdata/run/no_check_remote.ts.disabled.out | 4 + tests/testdata/run/no_check_remote.ts.enabled.out | 1 + tests/testdata/run/no_lock_flag/deno.json | 3 + tests/testdata/run/no_lock_flag/deno.lock | 7 + tests/testdata/run/no_lock_flag/main.out | 2 + tests/testdata/run/no_lock_flag/main.ts | 1 + tests/testdata/run/no_mem_cache.js | 33 + tests/testdata/run/no_mem_cache.js.out | 2 + tests/testdata/run/no_prompt.ts | 10 + tests/testdata/run/no_validate_asm.js | 20 + tests/testdata/run/node_builtin_modules/mod.js | 5 + tests/testdata/run/node_builtin_modules/mod.js.out | 3 + tests/testdata/run/node_builtin_modules/mod.ts | 5 + tests/testdata/run/node_builtin_modules/mod.ts.out | 3 + tests/testdata/run/node_env_var_allowlist.ts | 2 + tests/testdata/run/node_env_var_allowlist.ts.out | 5 + tests/testdata/run/node_prefix_missing/config.json | 1 + .../run/node_prefix_missing/import_map.json | 1 + tests/testdata/run/node_prefix_missing/main.ts | 3 + tests/testdata/run/node_prefix_missing/main.ts.out | 3 + .../main.ts.out_feature_enabled | 2 + tests/testdata/run/onload/imported.ts | 13 + tests/testdata/run/onload/main.out | 15 + tests/testdata/run/onload/main.ts | 34 + tests/testdata/run/onload/nest_imported.ts | 12 + .../run/op_exit_op_set_exit_code_in_worker.ts | 13 + .../run/op_exit_op_set_exit_code_worker.js | 4 + tests/testdata/run/permission_args.out | 4 + tests/testdata/run/permission_request_long.ts | 1 + tests/testdata/run/permission_test.ts | 30 + tests/testdata/run/permissions_cache.ts | 5 + tests/testdata/run/permissions_prompt_allow_all.ts | 20 + .../testdata/run/permissions_prompt_allow_all_2.ts | 8 + tests/testdata/run/private_field_presence.ts | 20 + tests/testdata/run/private_field_presence.ts.out | 2 + tests/testdata/run/proto_exploit.js | 5 + tests/testdata/run/proto_exploit.js.out | 2 + tests/testdata/run/queue_microtask_error.ts | 5 + tests/testdata/run/queue_microtask_error.ts.out | 6 + .../testdata/run/queue_microtask_error_handled.ts | 21 + .../run/queue_microtask_error_handled.ts.out | 15 + tests/testdata/run/reference_types.ts | 3 + tests/testdata/run/reference_types.ts.out | 1 + tests/testdata/run/reference_types_error.js | 2 + tests/testdata/run/reference_types_error.js.out | 2 + tests/testdata/run/reference_types_remote.ts | 3 + tests/testdata/run/reference_types_remote.ts.out | 1 + tests/testdata/run/rejection_handled.out | 5 + tests/testdata/run/rejection_handled.ts | 17 + tests/testdata/run/remote_type_error/main.ts | 3 + tests/testdata/run/remote_type_error/remote.ts | 5 + tests/testdata/run/replace_self.js | 21 + tests/testdata/run/replace_self.js.out | 4 + tests/testdata/run/report_error.ts | 3 + tests/testdata/run/report_error.ts.out | 5 + tests/testdata/run/report_error_end_of_program.ts | 1 + .../run/report_error_end_of_program.ts.out | 4 + tests/testdata/run/report_error_handled.ts | 19 + tests/testdata/run/report_error_handled.ts.out | 13 + tests/testdata/run/resolve_dns.ts | 93 + tests/testdata/run/resolve_dns.ts.out | 28 + tests/testdata/run/resolve_dns.zone.in | 32 + tests/testdata/run/runtime_decorators.ts | 42 + tests/testdata/run/runtime_decorators.ts.out | 7 + tests/testdata/run/seed_random.js | 11 + tests/testdata/run/seed_random.js.out | 22 + tests/testdata/run/set_exit_code_0.ts | 2 + tests/testdata/run/set_exit_code_1.ts | 2 + tests/testdata/run/set_exit_code_2.ts | 2 + tests/testdata/run/set_timeout_error.ts | 3 + tests/testdata/run/set_timeout_error.ts.out | 5 + tests/testdata/run/set_timeout_error_handled.ts | 19 + .../testdata/run/set_timeout_error_handled.ts.out | 13 + tests/testdata/run/shebang.ts | 5 + tests/testdata/run/shebang.ts.out | 1 + tests/testdata/run/shebang2.ts | 3 + tests/testdata/run/single_compile_with_reload.ts | 18 + .../testdata/run/single_compile_with_reload.ts.out | 7 + .../testdata/run/single_compile_with_reload_dyn.ts | 11 + .../run/single_compile_with_reload_worker.ts | 3 + tests/testdata/run/spawn_stdout_inherit.ts | 8 + tests/testdata/run/spawn_stdout_inherit.ts.out | 2 + tests/testdata/run/stdin_read_all.out | 1 + tests/testdata/run/stdin_read_all.ts | 17 + .../worker.js | 3 + tests/testdata/run/stdout_write_all.out | 100 + tests/testdata/run/stdout_write_all.ts | 13 + tests/testdata/run/stdout_write_sync_async.out | 200 + tests/testdata/run/stdout_write_sync_async.ts | 14 + tests/testdata/run/swc_syntax_error.ts | 4 + tests/testdata/run/swc_syntax_error.ts.out | 4 + tests/testdata/run/test_and_bench_in_run.js | 5 + tests/testdata/run/textproto.ts | 173 + tests/testdata/run/tls.out | 1 + tests/testdata/run/tls_connecttls.js | 66 + tests/testdata/run/tls_starttls.js | 65 + tests/testdata/run/top_level_await/circular.js | 8 + tests/testdata/run/top_level_await/circular.out | 10 + tests/testdata/run/top_level_await/loop.js | 20 + tests/testdata/run/top_level_await/loop.out | 5 + tests/testdata/run/top_level_await/nested.out | 5 + tests/testdata/run/top_level_await/nested/a.js | 3 + tests/testdata/run/top_level_await/nested/b.js | 1 + tests/testdata/run/top_level_await/nested/main.js | 3 + tests/testdata/run/top_level_await/order.js | 21 + tests/testdata/run/top_level_await/order.out | 2 + tests/testdata/run/top_level_await/tla/a.js | 3 + tests/testdata/run/top_level_await/tla/b.js | 7 + tests/testdata/run/top_level_await/tla/c.js | 3 + tests/testdata/run/top_level_await/tla/d.js | 8 + tests/testdata/run/top_level_await/tla/order.js | 1 + tests/testdata/run/top_level_await/tla/parent.js | 9 + tests/testdata/run/top_level_await/tla2/a.js | 5 + tests/testdata/run/top_level_await/tla2/b.js | 5 + tests/testdata/run/top_level_await/tla3/b.js | 7 + .../run/top_level_await/tla3/timeout_loop.js | 23 + .../run/top_level_await/top_level_await.js | 3 + .../run/top_level_await/top_level_await.out | 3 + .../run/top_level_await/top_level_await.ts | 3 + .../run/top_level_await/top_level_for_await.js | 10 + .../run/top_level_await/top_level_for_await.out | 3 + .../run/top_level_await/top_level_for_await.ts | 10 + tests/testdata/run/top_level_await/unresolved.js | 1 + tests/testdata/run/top_level_await/unresolved.out | 4 + tests/testdata/run/ts_import_from_js/deps.js | 2 + tests/testdata/run/ts_import_from_js/main.js | 3 + tests/testdata/run/ts_import_from_js/main.out | 3 + tests/testdata/run/ts_type_imports.ts | 5 + tests/testdata/run/ts_type_imports.ts.out | 6 + tests/testdata/run/ts_type_imports_foo.ts | 1 + tests/testdata/run/ts_type_only_import.d.ts | 3 + tests/testdata/run/ts_type_only_import.ts | 1 + tests/testdata/run/ts_type_only_import.ts.out | 1 + tests/testdata/run/tsx_imports/Component.tsx | 1 + tests/testdata/run/tsx_imports/tsx_imports.ts | 1 + tests/testdata/run/tsx_imports/tsx_imports.ts.out | 2 + tests/testdata/run/type_definitions.ts | 12 + tests/testdata/run/type_definitions.ts.out | 3 + tests/testdata/run/type_definitions_for_export.ts | 7 + .../run/type_definitions_for_export.ts.out | 5 + tests/testdata/run/type_directives_01.ts | 3 + tests/testdata/run/type_directives_01.ts.out | 3 + tests/testdata/run/type_directives_02.ts | 3 + tests/testdata/run/type_directives_02.ts.out | 3 + tests/testdata/run/type_directives_js_main.js | 3 + tests/testdata/run/type_directives_redirect.ts | 1 + tests/testdata/run/type_directives_redirect.ts.out | 5 + tests/testdata/run/type_headers_deno_types.ts | 18 + tests/testdata/run/type_headers_deno_types.ts.out | 5 + tests/testdata/run/unbuffered_stderr.ts | 1 + tests/testdata/run/unbuffered_stderr.ts.out | 1 + tests/testdata/run/unbuffered_stdout.ts | 1 + tests/testdata/run/unbuffered_stdout.ts.out | 1 + tests/testdata/run/unhandled_rejection.ts | 13 + tests/testdata/run/unhandled_rejection.ts.out | 9 + .../unhandled_rejection_dynamic_import/import.ts | 5 + .../run/unhandled_rejection_dynamic_import/main.ts | 1 + .../unhandled_rejection_dynamic_import/main.ts.out | 3 + .../unhandled_rejection_dynamic_import2/import.ts | 3 + .../unhandled_rejection_dynamic_import2/main.ts | 21 + .../main.ts.out | 5 + .../testdata/run/unhandled_rejection_sync_error.ts | 6 + .../run/unhandled_rejection_sync_error.ts.out | 6 + tests/testdata/run/unsafe_proto/main.js | 5 + tests/testdata/run/unsafe_proto/main.out | 2 + .../unsafe_proto/main_with_unsafe_proto_flag.out | 2 + tests/testdata/run/unsafe_proto/worker.js | 2 + tests/testdata/run/unstable.js | 1 + tests/testdata/run/unstable.ts | 1 + .../run/unstable_broadcast_channel.disabled.out | 2 + .../run/unstable_broadcast_channel.enabled.out | 2 + tests/testdata/run/unstable_broadcast_channel.js | 10 + tests/testdata/run/unstable_cron.disabled.out | 2 + tests/testdata/run/unstable_cron.enabled.out | 2 + tests/testdata/run/unstable_cron.js | 10 + tests/testdata/run/unstable_disabled_js.out | 1 + tests/testdata/run/unstable_enabled.out | 1 + tests/testdata/run/unstable_enabled_js.out | 1 + tests/testdata/run/unstable_ffi.disabled.out | 10 + tests/testdata/run/unstable_ffi.enabled.out | 10 + tests/testdata/run/unstable_ffi.js | 14 + tests/testdata/run/unstable_fs.disabled.out | 10 + tests/testdata/run/unstable_fs.enabled.out | 10 + tests/testdata/run/unstable_fs.js | 14 + tests/testdata/run/unstable_http.disabled.out | 12 + tests/testdata/run/unstable_http.enabled.out | 12 + tests/testdata/run/unstable_http.js | 15 + tests/testdata/run/unstable_kv.disabled.out | 10 + tests/testdata/run/unstable_kv.enabled.out | 10 + tests/testdata/run/unstable_kv.js | 14 + tests/testdata/run/unstable_net.disabled.out | 4 + tests/testdata/run/unstable_net.enabled.out | 4 + tests/testdata/run/unstable_net.js | 11 + tests/testdata/run/unstable_temporal_api/main.out | 12 + tests/testdata/run/unstable_temporal_api/main.ts | 71 + .../run/unstable_temporal_api/missing_flag.js | 1 + .../run/unstable_temporal_api/missing_flag.out | 4 + tests/testdata/run/unstable_webgpu.disabled.out | 2 + tests/testdata/run/unstable_webgpu.enabled.out | 2 + tests/testdata/run/unstable_webgpu.js | 10 + tests/testdata/run/unstable_worker.ts | 6 + tests/testdata/run/unstable_worker.ts.out | 2 + .../run/unstable_worker_options.disabled.out | 1 + .../run/unstable_worker_options.enabled.out | 2 + tests/testdata/run/unstable_worker_options.js | 19 + .../run/unsupported_dynamic_import_scheme.out | 7 + tests/testdata/run/v8_flags.js | 1 + tests/testdata/run/v8_flags.js.out | 1 + tests/testdata/run/v8_flags_unrecognized.out | 5 + tests/testdata/run/v8_help.out | 4 + tests/testdata/run/warn_on_deprecated_api/main.js | 32 + tests/testdata/run/warn_on_deprecated_api/main.out | 16 + .../run/warn_on_deprecated_api/main.verbose.out | 65 + .../warn_on_deprecated_api/main_disabled_env.out | 15 + .../warn_on_deprecated_api/main_disabled_flag.out | 14 + tests/testdata/run/warn_on_deprecated_api/mod.ts | 11 + tests/testdata/run/wasm.ts | 16 + tests/testdata/run/wasm.ts.out | 1 + tests/testdata/run/wasm_async.js | 27 + tests/testdata/run/wasm_async.out | 1 + tests/testdata/run/wasm_shared.out | 0 tests/testdata/run/wasm_shared.ts | 6 + tests/testdata/run/wasm_streaming_panic_test.js | 3 + .../testdata/run/wasm_streaming_panic_test.js.out | 2 + tests/testdata/run/wasm_unreachable.js | 9 + tests/testdata/run/wasm_unreachable.out | 3 + tests/testdata/run/wasm_url.js | 8 + tests/testdata/run/wasm_url.out | 3 + tests/testdata/run/weakref.ts | 1 + tests/testdata/run/weakref.ts.out | 1 + tests/testdata/run/websocket_server_idletimeout.ts | 25 + ...et_server_multi_field_connection_header_test.ts | 15 + tests/testdata/run/websocketstream_ping_test.ts | 5 + tests/testdata/run/webstorage/config_a.jsonc | 3 + tests/testdata/run/webstorage/config_b.jsonc | 3 + tests/testdata/run/webstorage/fixture.ts | 2 + tests/testdata/run/webstorage/logger.ts | 1 + tests/testdata/run/webstorage/serialization.ts | 4 + tests/testdata/run/webstorage/serialization.ts.out | 2 + tests/testdata/run/webstorage/setter.ts | 1 + .../run/with_config/auto_discovery_log.out | 4 + tests/testdata/run/with_config/deno.jsonc | 6 + tests/testdata/run/with_config/frontend_work.ts | 4 + .../testdata/run/with_config/no_auto_discovery.out | 4 + tests/testdata/run/with_config/server_side_work.ts | 2 + .../run/with_package_json/no_deno_json/main.out | 4 + .../run/with_package_json/no_deno_json/main.ts | 4 + .../no_deno_json/no_package_json_imports.out | 1 + .../no_deno_json/no_package_json_imports.ts | 1 + .../with_package_json/no_deno_json/noconfig.out | 4 + .../run/with_package_json/no_deno_json/noconfig.ts | 8 + .../with_package_json/no_deno_json/package.json | 9 + .../with_package_json/no_deno_json/sub_dir/main.js | 3 + .../no_deno_json/sub_dir/main.out | 7 + .../run/with_package_json/npm_binary/main.out | 7 + .../run/with_package_json/npm_binary/package.json | 8 + .../run/with_package_json/with_stop/main.out | 5 + .../run/with_package_json/with_stop/package.json | 8 + .../with_stop/some/nested/deno.json | 5 + .../with_stop/some/nested/dir/main.ts | 6 + .../testdata/run/worker_close_in_wasm_reactions.js | 10 + .../run/worker_close_in_wasm_reactions.js.out | 2 + tests/testdata/run/worker_close_nested.js | 20 + tests/testdata/run/worker_close_nested.js.out | 5 + tests/testdata/run/worker_close_race.js | 14 + tests/testdata/run/worker_close_race.js.out | 0 tests/testdata/run/worker_drop_handle_race.js | 12 + tests/testdata/run/worker_drop_handle_race.js.out | 8 + .../run/worker_drop_handle_race_terminate.js | 37 + .../run/worker_drop_handle_race_terminate.js.out | 4 + tests/testdata/run/worker_event_handler_test.js | 5 + .../testdata/run/worker_event_handler_test.js.out | 11 + tests/testdata/run/worker_message_before_close.js | 26 + .../run/worker_message_before_close.js.out | 1 + tests/testdata/run/workspaces/basic/bar/deno.json | 8 + .../testdata/run/workspaces/basic/bar/fizz/buzz.ts | 1 + tests/testdata/run/workspaces/basic/bar/mod.ts | 5 + .../run/workspaces/basic/bar/some_mod/hello.ts | 1 + tests/testdata/run/workspaces/basic/deno.json | 9 + .../testdata/run/workspaces/basic/foo/bar/hello.ts | 1 + tests/testdata/run/workspaces/basic/foo/deno.json | 8 + .../testdata/run/workspaces/basic/foo/fizz/buzz.ts | 1 + tests/testdata/run/workspaces/basic/foo/mod.ts | 5 + tests/testdata/run/workspaces/basic/main.out | 21 + tests/testdata/run/workspaces/basic/main.ts | 5 + .../workspaces/member_outside_root_dir/deno.json | 9 + .../member_outside_root_dir/foo/bar/hello.ts | 1 + .../member_outside_root_dir/foo/deno.json | 8 + .../member_outside_root_dir/foo/fizz/buzz.ts | 1 + .../workspaces/member_outside_root_dir/foo/mod.ts | 5 + .../workspaces/member_outside_root_dir/main.out | 1 + .../run/workspaces/member_outside_root_dir/main.ts | 4 + .../run/workspaces/nested_member/bar/deno.json | 8 + .../run/workspaces/nested_member/bar/fizz/buzz.ts | 1 + .../run/workspaces/nested_member/bar/mod.ts | 5 + .../workspaces/nested_member/bar/some_mod/hello.ts | 1 + .../run/workspaces/nested_member/deno.json | 6 + .../run/workspaces/nested_member/foo/bar/deno.json | 7 + .../run/workspaces/nested_member/foo/bar/hello.ts | 3 + .../run/workspaces/nested_member/foo/deno.json | 7 + .../run/workspaces/nested_member/foo/fizz/buzz.ts | 1 + .../run/workspaces/nested_member/foo/mod.ts | 3 + .../testdata/run/workspaces/nested_member/main.out | 1 + .../testdata/run/workspaces/nested_member/main.ts | 4 + tests/testdata/runtime/esm_imports_a.js | 3 + tests/testdata/runtime/esm_imports_b.js | 4 + tests/testdata/spawn_kill_permissions.ts | 6 + tests/testdata/subdir/CAPITALS/main.js | 3 + tests/testdata/subdir/amd_like.js | 3 + tests/testdata/subdir/auto_print_hello.ts | 2 + tests/testdata/subdir/circular1.ts | 7 + tests/testdata/subdir/circular2.ts | 7 + tests/testdata/subdir/comment.ts | 4 + tests/testdata/subdir/config.json | 6 + tests/testdata/subdir/emittable.d.ts | 1 + tests/testdata/subdir/evil_remote_import.js | 4 + tests/testdata/subdir/export_types.ts | 11 + tests/testdata/subdir/foo_types.d.ts | 3 + tests/testdata/subdir/form_urlencoded.txt | 1 + tests/testdata/subdir/import.mts | 4 + tests/testdata/subdir/indirect_import_error.js | 1 + tests/testdata/subdir/indirect_throws.js | 1 + tests/testdata/subdir/json_1.json | 5 + tests/testdata/subdir/json_2.json | 1 + tests/testdata/subdir/json_3.json | 1 + .../subdir/jsx_import_source_no_pragma.tsx | 7 + tests/testdata/subdir/main.ts | 3 + tests/testdata/subdir/mismatch_ext.ts | 1 + tests/testdata/subdir/mod.mjs | 1 + tests/testdata/subdir/mod1.ts | 17 + tests/testdata/subdir/mod2.ts | 1 + tests/testdata/subdir/mod3.js | 1 + tests/testdata/subdir/mod4.js | 1 + tests/testdata/subdir/mod5.mjs | 1 + tests/testdata/subdir/mod6.js | 1 + tests/testdata/subdir/mod7.js | 3 + tests/testdata/subdir/mod8.js | 3 + tests/testdata/subdir/more_decorators.ts | 18 + .../subdir/mt_application_ecmascript.j2.js | 1 + .../subdir/mt_application_ecmascript_jsx.j2.jsx | 5 + .../subdir/mt_application_x_javascript.j4.js | 1 + .../subdir/mt_application_x_javascript_jsx.j4.jsx | 5 + .../subdir/mt_application_x_typescript.t4.ts | 1 + .../subdir/mt_application_x_typescript_tsx.t4.tsx | 5 + tests/testdata/subdir/mt_javascript.js | 1 + tests/testdata/subdir/mt_javascript_jsx.jsx | 5 + tests/testdata/subdir/mt_text_ecmascript.j3.js | 1 + .../testdata/subdir/mt_text_ecmascript_jsx.j3.jsx | 5 + tests/testdata/subdir/mt_text_javascript.j1.js | 1 + .../testdata/subdir/mt_text_javascript_jsx.j1.jsx | 5 + tests/testdata/subdir/mt_text_typescript.t1.ts | 1 + .../testdata/subdir/mt_text_typescript_tsx.t1.tsx | 5 + tests/testdata/subdir/mt_video_mp2t.t3.ts | 1 + tests/testdata/subdir/mt_video_mp2t_tsx.t3.tsx | 5 + tests/testdata/subdir/mt_video_vdn.t2.ts | 1 + tests/testdata/subdir/mt_video_vdn_tsx.t2.tsx | 5 + tests/testdata/subdir/no_ext | 1 + tests/testdata/subdir/no_js_ext | 3 + tests/testdata/subdir/polyfill.ts | 8 + tests/testdata/subdir/print_hello.ts | 3 + tests/testdata/subdir/redirects/a.ts | 9 + tests/testdata/subdir/redirects/b.ts | 5 + tests/testdata/subdir/redirects/redirect1.js | 1 + tests/testdata/subdir/redirects/redirect1.ts | 1 + tests/testdata/subdir/redirects/redirect2.js | 1 + tests/testdata/subdir/redirects/redirect3.js | 2 + tests/testdata/subdir/redirects/redirect4.ts | 2 + tests/testdata/subdir/shebang_file.js | 5 + tests/testdata/subdir/single_module.ts | 1 + tests/testdata/subdir/subdir2/dynamic_import.ts | 4 + tests/testdata/subdir/subdir2/mod2.ts | 9 + tests/testdata/subdir/test_worker_basic.js | 14 + tests/testdata/subdir/throws.js | 6 + tests/testdata/subdir/tla.ts | 1 + tests/testdata/subdir/type_and_code.ts | 7 + tests/testdata/subdir/type_error.ts | 1 + tests/testdata/subdir/type_reference.d.ts | 1 + tests/testdata/subdir/type_reference.js | 3 + tests/testdata/subdir/types.d.mts | 1 + tests/testdata/subdir/unknown_ext.deno | 1 + tests/testdata/symlink_to_subdir | 1 + tests/testdata/task/both/deno.json | 6 + tests/testdata/task/both/deno_selected.out | 2 + tests/testdata/task/both/echo.out | 0 tests/testdata/task/both/no_args.out | 7 + tests/testdata/task/both/package.json | 9 + tests/testdata/task/both/package_json_selected.out | 8 + tests/testdata/task/both/prefers_deno.out | 2 + tests/testdata/task/deno_json/deno.json | 13 + .../task/deno_json/task_additional_args.out | 1 + .../task_additional_args_nested_strings.out | 1 + .../deno_json/task_additional_args_no_logic.out | 1 + .../task_additional_args_no_shell_expansion.out | 1 + .../testdata/task/deno_json/task_boolean_logic.out | 4 + tests/testdata/task/deno_json/task_cwd.out | 1 + .../task/deno_json/task_deno_exe_no_env.out | 1 + tests/testdata/task/deno_json/task_exit_code_5.out | 2 + tests/testdata/task/deno_json/task_init_cwd.out | 1 + .../task/deno_json/task_init_cwd_already_set.out | 1 + tests/testdata/task/deno_json/task_no_args.out | 19 + .../testdata/task/deno_json/task_non_existent.out | 20 + tests/testdata/task/deno_json/task_piped_stdin.out | 2 + tests/testdata/task/deno_json_pre_post/bin.out | 2 + tests/testdata/task/deno_json_pre_post/deno.json | 7 + tests/testdata/task/deno_json_pre_post/echo.out | 1 + tests/testdata/task/npx/non_existent.out | 2 + tests/testdata/task/npx/on_own.out | 2 + tests/testdata/task/npx/package.json | 6 + tests/testdata/task/package_json/bin.out | 14 + tests/testdata/task/package_json/echo.out | 1 + tests/testdata/task/package_json/no_args.out | 5 + tests/testdata/task/package_json/package.json | 10 + .../package_json_node_modules_dir_false/bin.out | 2 + .../package_json_node_modules_dir_false/deno.json | 3 + .../package.json | 9 + tests/testdata/task/package_json_post/bin.out | 4 + tests/testdata/task/package_json_post/echo.out | 1 + tests/testdata/task/package_json_post/package.json | 6 + tests/testdata/task/package_json_post_only/bin.out | 4 + .../testdata/task/package_json_post_only/echo.out | 1 + .../task/package_json_post_only/package.json | 5 + tests/testdata/task/package_json_pre/bin.out | 4 + tests/testdata/task/package_json_pre/echo.out | 1 + tests/testdata/task/package_json_pre/package.json | 6 + tests/testdata/task/package_json_pre_only/bin.out | 4 + tests/testdata/task/package_json_pre_only/echo.out | 1 + .../task/package_json_pre_only/package.json | 5 + tests/testdata/task/package_json_pre_post/bin.out | 6 + tests/testdata/task/package_json_pre_post/echo.out | 1 + .../task/package_json_pre_post/package.json | 7 + tests/testdata/test/aggregate_error.out | 22 + tests/testdata/test/aggregate_error.ts | 6 + tests/testdata/test/allow_all.out | 18 + tests/testdata/test/allow_all.ts | 43 + tests/testdata/test/allow_none.out | 51 + tests/testdata/test/allow_none.ts | 23 + .../test/before_unload_prevent_default.out | 5 + .../testdata/test/before_unload_prevent_default.ts | 6 + tests/testdata/test/captured_output.ts | 33 + tests/testdata/test/captured_output.worker.js | 6 + tests/testdata/test/check_local_by_default.out | 4 + tests/testdata/test/check_local_by_default.ts | 3 + tests/testdata/test/check_local_by_default2.out | 4 + tests/testdata/test/check_local_by_default2.ts | 6 + tests/testdata/test/clear_timeout.out | 8 + tests/testdata/test/clear_timeout.ts | 5 + tests/testdata/test/collect.deprecated.out | 10 + tests/testdata/test/collect.out | 9 + tests/testdata/test/collect/deno.deprecated.jsonc | 7 + tests/testdata/test/collect/deno.jsonc | 5 + tests/testdata/test/collect/deno.malformed.jsonc | 5 + tests/testdata/test/collect/deno2.jsonc | 6 + tests/testdata/test/collect/ignore/test.ts | 1 + tests/testdata/test/collect/include.ts | 0 tests/testdata/test/collect/include/2_test.ts | 0 tests/testdata/test/collect/include/test.ts | 0 tests/testdata/test/collect/test.ts | 0 tests/testdata/test/collect2.out | 7 + .../test/collect_with_malformed_config.out | 4 + tests/testdata/test/deno.glob.json | 11 + tests/testdata/test/deno_custom_jsx.json | 6 + tests/testdata/test/doc.out | 9 + tests/testdata/test/doc.ts | 38 + tests/testdata/test/doc_only.out | 4 + tests/testdata/test/doc_only/mod.ts | 10 + tests/testdata/test/exit_sanitizer.out | 38 + tests/testdata/test/exit_sanitizer.ts | 11 + tests/testdata/test/fail.out | 91 + tests/testdata/test/fail.ts | 30 + tests/testdata/test/fail_fast.out | 20 + tests/testdata/test/fail_fast.ts | 30 + tests/testdata/test/fail_fast_other.ts | 3 + tests/testdata/test/fail_fast_with_val.out | 23 + tests/testdata/test/fail_fast_with_val.ts | 30 + tests/testdata/test/file_protocol.out | 6 + tests/testdata/test/file_protocol.ts | 1 + tests/testdata/test/filter.out | 12 + tests/testdata/test/filter/a_test.ts | 3 + tests/testdata/test/filter/b_test.ts | 3 + tests/testdata/test/filter/c_test.ts | 3 + tests/testdata/test/filtered_out_only.out | 5 + tests/testdata/test/filtered_out_only.ts | 2 + tests/testdata/test/finally_timeout.out | 20 + tests/testdata/test/finally_timeout.ts | 11 + tests/testdata/test/glob/data/tes.ts | 3 + tests/testdata/test/glob/data/test1.js | 3 + tests/testdata/test/glob/data/test1.ts | 3 + tests/testdata/test/glob/data/test12.ts | 3 + tests/testdata/test/glob/nested/fizz/bar.ts | 3 + tests/testdata/test/glob/nested/fizz/bazz.ts | 3 + tests/testdata/test/glob/nested/fizz/fizz.ts | 2 + tests/testdata/test/glob/nested/fizz/foo.ts | 3 + tests/testdata/test/glob/nested/foo/bar.ts | 3 + tests/testdata/test/glob/nested/foo/bazz.ts | 3 + tests/testdata/test/glob/nested/foo/fizz.ts | 3 + tests/testdata/test/glob/nested/foo/foo.ts | 3 + tests/testdata/test/glob/pages/[id].ts | 3 + tests/testdata/test/hello_world.out | 5 + tests/testdata/test/hello_world.ts | 9 + tests/testdata/test/hide_empty_suites.out | 4 + tests/testdata/test/ignore.out | 15 + tests/testdata/test/ignore.ts | 17 + tests/testdata/test/ignore_permissions.out | 6 + tests/testdata/test/ignore_permissions.ts | 16 + tests/testdata/test/interval.out | 5 + tests/testdata/test/interval.ts | 1 + tests/testdata/test/load_unload.out | 6 + tests/testdata/test/load_unload.ts | 22 + tests/testdata/test/markdown.md | 31 + tests/testdata/test/markdown.out | 7 + tests/testdata/test/markdown_full_block_names.md | 19 + tests/testdata/test/markdown_full_block_names.out | 6 + tests/testdata/test/markdown_windows.md | 31 + tests/testdata/test/markdown_windows.out | 7 + tests/testdata/test/markdown_with_comment.md | 36 + tests/testdata/test/markdown_with_comment.out | 5 + tests/testdata/test/meta.out | 11 + tests/testdata/test/meta.ts | 7 + tests/testdata/test/no_check.out | 19 + tests/testdata/test/no_check.ts | 1 + tests/testdata/test/no_color.ts | 17 + tests/testdata/test/no_prompt_by_default.out | 16 + tests/testdata/test/no_prompt_by_default.ts | 3 + .../testdata/test/no_prompt_with_denied_perms.out | 16 + tests/testdata/test/no_prompt_with_denied_perms.ts | 3 + tests/testdata/test/no_run.out | 5 + tests/testdata/test/no_run.ts | 1 + tests/testdata/test/non_error_thrown.out | 40 + tests/testdata/test/non_error_thrown.ts | 23 + tests/testdata/test/only.out | 8 + tests/testdata/test/only.ts | 20 + .../ops_sanitizer_closed_inside_started_before.out | 19 + .../ops_sanitizer_closed_inside_started_before.ts | 5 + .../test/ops_sanitizer_missing_details.out | 18 + .../testdata/test/ops_sanitizer_missing_details.ts | 10 + .../test/ops_sanitizer_multiple_timeout_tests.out | 45 + .../test/ops_sanitizer_multiple_timeout_tests.ts | 10 + ...s_sanitizer_multiple_timeout_tests_no_trace.out | 25 + tests/testdata/test/ops_sanitizer_nexttick.out | 6 + tests/testdata/test/ops_sanitizer_nexttick.ts | 11 + tests/testdata/test/ops_sanitizer_step_leak.out | 10 + tests/testdata/test/ops_sanitizer_step_leak.ts | 10 + .../test/ops_sanitizer_timeout_failure.out | 6 + .../testdata/test/ops_sanitizer_timeout_failure.ts | 22 + tests/testdata/test/ops_sanitizer_unstable.out | 22 + tests/testdata/test/ops_sanitizer_unstable.ts | 9 + tests/testdata/test/overloads.out | 11 + tests/testdata/test/overloads.ts | 6 + tests/testdata/test/parallel_output.out | 56 + tests/testdata/test/parallel_output.ts | 27 + tests/testdata/test/pass.junit.out | 38 + tests/testdata/test/pass.out | 53 + tests/testdata/test/pass.ts | 37 + tests/testdata/test/quiet.out | 8 + tests/testdata/test/quiet.ts | 15 + .../testdata/test/recursive_permissions_pledge.js | 6 + .../test/relative_pattern_dot_slash/deno.json | 7 + .../test/relative_pattern_dot_slash/output.out | 5 + .../test/relative_pattern_dot_slash/test/add.mjs | 3 + .../relative_pattern_dot_slash/test/add.test.mjs | 7 + tests/testdata/test/replace_timers.js | 7 + tests/testdata/test/replace_timers.js.out | 7 + tests/testdata/test/report_error.out | 23 + tests/testdata/test/report_error.ts | 6 + tests/testdata/test/resource_sanitizer.out | 20 + tests/testdata/test/resource_sanitizer.ts | 4 + .../testdata/test/short-pass-jobs-flag-warning.out | 8 + tests/testdata/test/short-pass.out | 5 + tests/testdata/test/short-pass.ts | 1 + tests/testdata/test/shuffle.out | 39 + tests/testdata/test/shuffle/bar_test.ts | 3 + tests/testdata/test/shuffle/baz_test.ts | 3 + tests/testdata/test/shuffle/foo_test.ts | 3 + tests/testdata/test/sigint_with_hanging_test.out | 10 + tests/testdata/test/sigint_with_hanging_test.ts | 15 + tests/testdata/test/steps/failing_steps.dot.out | 53 + tests/testdata/test/steps/failing_steps.out | 59 + tests/testdata/test/steps/failing_steps.tap.out | 43 + tests/testdata/test/steps/failing_steps.ts | 27 + tests/testdata/test/steps/ignored_steps.dot.out | 5 + tests/testdata/test/steps/ignored_steps.out | 8 + tests/testdata/test/steps/ignored_steps.tap.out | 8 + tests/testdata/test/steps/ignored_steps.ts | 16 + tests/testdata/test/steps/invalid_usage.out | 82 + tests/testdata/test/steps/invalid_usage.ts | 118 + tests/testdata/test/steps/output_within.out | 29 + tests/testdata/test/steps/output_within.ts | 15 + tests/testdata/test/steps/passing_steps.dot.out | 17 + tests/testdata/test/steps/passing_steps.out | 44 + tests/testdata/test/steps/passing_steps.tap.out | 42 + tests/testdata/test/steps/passing_steps.ts | 127 + tests/testdata/test/text.md | 1 + tests/testdata/test/text.out | 3 + .../testdata/test/trace_ops_caught_error/main.out | 6 + tests/testdata/test/trace_ops_caught_error/main.ts | 12 + tests/testdata/test/uncaught_errors.out | 59 + tests/testdata/test/uncaught_errors_1.ts | 9 + tests/testdata/test/uncaught_errors_2.ts | 8 + tests/testdata/test/uncaught_errors_3.ts | 1 + tests/testdata/test/unhandled_rejection.out | 22 + tests/testdata/test/unhandled_rejection.ts | 3 + tests/testdata/test/unresolved_promise.out | 10 + tests/testdata/test/unresolved_promise.ts | 1 + tests/testdata/tls/README.md | 47 + tests/testdata/tls/RootCA.crt | 19 + tests/testdata/tls/RootCA.key | 28 + tests/testdata/tls/RootCA.pem | 19 + tests/testdata/tls/domains.txt | 6 + tests/testdata/tls/invalid.crt | 3 + tests/testdata/tls/invalid.key | 3 + tests/testdata/tls/localhost.crt | 21 + tests/testdata/tls/localhost.key | 28 + tests/testdata/tsc/a.js | 2 + tests/testdata/tsc/d.ts | 3 + tests/testdata/tsc/node_modules/b.js | 2 + tests/testdata/tsc/node_modules/c.js | 1 + tests/testdata/tsc/test.js | 4 + tests/testdata/tsc2/file_exportc.ts | 1 + tests/testdata/tsc2/file_libref.ts | 8 + tests/testdata/tsc2/file_main.ts | 1 + tests/testdata/tsc2/file_reexports.ts | 3 + tests/testdata/tsc2/https_deno.land-x-a.ts | 3 + tests/testdata/tsc2/https_deno.land-x-b.ts | 1 + tests/testdata/tsc2/https_deno.land-x-c.d.ts | 1 + tests/testdata/tsc2/https_deno.land-x-c.js | 1 + tests/testdata/tsc2/https_deno.land-x-mod.ts | 1 + tests/testdata/type_definitions/bar.d.ts | 7 + tests/testdata/type_definitions/bar.js | 5 + tests/testdata/type_definitions/fizz.d.ts | 2 + tests/testdata/type_definitions/fizz.js | 1 + tests/testdata/type_definitions/foo.d.ts | 2 + tests/testdata/type_definitions/foo.js | 1 + tests/testdata/type_definitions/qat.ts | 1 + tests/testdata/types/types.out | 3 + tests/testdata/vendor/dynamic.ts | 3 + tests/testdata/vendor/dynamic_non_analyzable.ts | 4 + tests/testdata/vendor/dynamic_non_existent.ts | 11 + tests/testdata/vendor/dynamic_non_existent.ts.out | 7 + tests/testdata/vendor/logger.ts | 5 + tests/testdata/vendor/mod.ts | 1 + tests/testdata/vendor/npm_and_node_specifier.ts | 2 + tests/testdata/vendor/query_reexport.ts | 1 + tests/testdata/webcrypto/id_rsaEncryption.pem | 28 + tests/testdata/webcrypto/id_rsassaPss.pem | 29 + tests/testdata/webcrypto/id_rsassaPss_default.pem | 28 + .../testdata/webcrypto/id_rsassaPss_saltLen_30.pem | 28 + tests/testdata/webgpu/computepass_shader.wgsl | 38 + tests/testdata/webgpu/hellotriangle.out | Bin 0 -> 204800 bytes tests/testdata/webgpu/hellotriangle_shader.wgsl | 11 + tests/testdata/welcome.ts | 1 + tests/testdata/workers/async_error.ts | 4 + tests/testdata/workers/bench_large_message.ts | 31 + tests/testdata/workers/bench_round_robin.ts | 65 + tests/testdata/workers/bench_startup.ts | 33 + tests/testdata/workers/bench_worker.ts | 21 + tests/testdata/workers/broadcast_channel.ts | 5 + tests/testdata/workers/busy_worker.js | 8 + tests/testdata/workers/close_in_wasm_reactions.js | 21 + tests/testdata/workers/close_nested_child.js | 8 + tests/testdata/workers/close_nested_parent.js | 13 + tests/testdata/workers/close_race_worker.js | 6 + tests/testdata/workers/custom_inspect/main.out | 1 + tests/testdata/workers/custom_inspect/main.ts | 4 + tests/testdata/workers/custom_inspect/worker.ts | 2 + tests/testdata/workers/deno_worker.ts | 16 + tests/testdata/workers/drop_handle_race.js | 3 + tests/testdata/workers/dynamic_remote.ts | 2 + tests/testdata/workers/env_read_check_worker.js | 14 + tests/testdata/workers/error.ts | 5 + tests/testdata/workers/error_event.ts | 11 + tests/testdata/workers/error_event.ts.out | 13 + .../workers/error_worker_permissions_local.ts | 4 + .../workers/error_worker_permissions_local.ts.out | 2 + .../workers/error_worker_permissions_remote.ts | 4 + .../workers/error_worker_permissions_remote.ts.out | 2 + tests/testdata/workers/event_worker.js | 7 + tests/testdata/workers/event_worker_scope.js | 43 + tests/testdata/workers/fetching_worker.js | 6 + tests/testdata/workers/http_worker.js | 11 + tests/testdata/workers/image_data_worker.ts | 2 + tests/testdata/workers/immediately_close_worker.js | 1 + tests/testdata/workers/message_before_close.js | 4 + tests/testdata/workers/message_handler_error.ts | 4 + tests/testdata/workers/message_port.ts | 14 + tests/testdata/workers/nested_worker.js | 18 + tests/testdata/workers/no_permissions_worker.js | 17 + tests/testdata/workers/non_deno_worker.js | 7 + tests/testdata/workers/nonexistent_worker.out | 3 + tests/testdata/workers/nonexistent_worker.ts | 5 + tests/testdata/workers/parent_read_check_worker.js | 12 + tests/testdata/workers/permission_echo.js | 19 + tests/testdata/workers/permissions_blob_local.ts | 6 + .../testdata/workers/permissions_blob_local.ts.out | 4 + tests/testdata/workers/permissions_blob_remote.ts | 4 + .../workers/permissions_blob_remote.ts.out | 4 + tests/testdata/workers/permissions_data_local.ts | 7 + .../testdata/workers/permissions_data_local.ts.out | 4 + tests/testdata/workers/permissions_data_remote.ts | 5 + .../workers/permissions_data_remote.ts.out | 4 + .../testdata/workers/permissions_dynamic_remote.ts | 11 + .../workers/permissions_dynamic_remote.ts.out | 6 + .../testdata/workers/permissions_remote_remote.ts | 3 + .../workers/permissions_remote_remote.ts.out | 4 + tests/testdata/workers/post_undefined.ts | 5 + tests/testdata/workers/racy_worker.js | 25 + .../testdata/workers/read_check_granular_worker.js | 29 + tests/testdata/workers/read_check_worker.js | 7 + tests/testdata/workers/shared_array_buffer.ts | 9 + tests/testdata/workers/sibling_worker.js | 4 + tests/testdata/workers/static_remote.ts | 2 + tests/testdata/workers/terminate_tla_crash.js | 21 + tests/testdata/workers/terminate_tla_crash.js.out | 0 tests/testdata/workers/test_worker.js | 8 + tests/testdata/workers/test_worker.ts | 8 + tests/testdata/workers/throwing_worker.js | 2 + tests/testdata/workers/worker_async_error.ts | 5 + tests/testdata/workers/worker_async_error.ts.out | 7 + tests/testdata/workers/worker_crypto.js | 5 + .../workers/worker_doest_stall_event_loop.ts | 29 + .../workers/worker_doest_stall_event_loop.ts.out | 6 + tests/testdata/workers/worker_error.ts | 5 + tests/testdata/workers/worker_error.ts.out | 5 + tests/testdata/workers/worker_event_handlers.js | 26 + tests/testdata/workers/worker_globals.ts | 13 + tests/testdata/workers/worker_large_message.js | 14 + tests/testdata/workers/worker_location.ts | 6 + .../workers/worker_message_handler_error.ts | 8 + .../workers/worker_message_handler_error.ts.out | 7 + tests/testdata/workers/worker_navigator.ts | 11 + tests/testdata/workers/worker_nested_error.ts | 5 + tests/testdata/workers/worker_nested_error.ts.out | 9 + .../testdata/workers/worker_structured_cloning.ts | 15 + tests/testdata/workers/worker_types.ts | 4 + tests/testdata/workers/worker_unstable.ts | 5 + .../workers/worker_with_top_level_await.ts | 15 + tests/unit/README.md | 43 + tests/unit/abort_controller_test.ts | 64 + tests/unit/blob_test.ts | 115 + tests/unit/body_test.ts | 189 + tests/unit/broadcast_channel_test.ts | 34 + tests/unit/buffer_test.ts | 461 + tests/unit/build_test.ts | 10 + tests/unit/cache_api_test.ts | 207 + tests/unit/chmod_test.ts | 190 + tests/unit/chown_test.ts | 190 + tests/unit/command_test.ts | 967 + tests/unit/console_test.ts | 2411 + tests/unit/copy_file_test.ts | 249 + tests/unit/cron_test.ts | 460 + tests/unit/custom_event_test.ts | 27 + tests/unit/dir_test.ts | 63 + tests/unit/dom_exception_test.ts | 23 + tests/unit/error_stack_test.ts | 54 + tests/unit/error_test.ts | 33 + tests/unit/esnext_test.ts | 43 + tests/unit/event_target_test.ts | 295 + tests/unit/event_test.ts | 143 + tests/unit/fetch_test.ts | 2071 + tests/unit/ffi_test.ts | 137 + tests/unit/file_test.ts | 112 + tests/unit/filereader_test.ts | 242 + tests/unit/files_test.ts | 1095 + tests/unit/flock_test.ts | 197 + tests/unit/fs_events_test.ts | 139 + tests/unit/get_random_values_test.ts | 63 + tests/unit/globals_test.ts | 225 + tests/unit/headers_test.ts | 416 + tests/unit/http_test.ts | 2801 + tests/unit/image_bitmap_test.ts | 92 + tests/unit/image_data_test.ts | 53 + tests/unit/internals_test.ts | 10 + tests/unit/intl_test.ts | 7 + tests/unit/io_test.ts | 77 + tests/unit/jupyter_test.ts | 79 + tests/unit/kv_queue_test.ts | 13 + tests/unit/kv_queue_test_no_db_close.ts | 20 + tests/unit/kv_queue_undelivered_test.ts | 59 + tests/unit/kv_test.ts | 2321 + tests/unit/link_test.ts | 195 + tests/unit/make_temp_test.ts | 157 + tests/unit/message_channel_test.ts | 55 + tests/unit/mkdir_test.ts | 235 + tests/unit/navigator_test.ts | 11 + tests/unit/net_test.ts | 1274 + tests/unit/network_interfaces_test.ts | 30 + tests/unit/ops_test.ts | 17 + tests/unit/os_test.ts | 304 + tests/unit/path_from_url_test.ts | 41 + tests/unit/performance_test.ts | 185 + tests/unit/permissions_test.ts | 202 + tests/unit/process_test.ts | 689 + tests/unit/progressevent_test.ts | 18 + tests/unit/promise_hooks_test.ts | 109 + tests/unit/read_dir_test.ts | 113 + tests/unit/read_file_test.ts | 182 + tests/unit/read_link_test.ts | 99 + tests/unit/read_text_file_test.ts | 208 + tests/unit/real_path_test.ts | 114 + tests/unit/ref_unref_test.ts | 12 + tests/unit/remove_test.ts | 291 + tests/unit/rename_test.ts | 274 + tests/unit/request_test.ts | 77 + tests/unit/resources_test.ts | 55 + tests/unit/response_test.ts | 102 + tests/unit/serve_test.ts | 3932 ++ tests/unit/signal_test.ts | 296 + tests/unit/stat_test.ts | 342 + tests/unit/stdio_test.ts | 32 + tests/unit/streams_test.ts | 478 + tests/unit/structured_clone_test.ts | 55 + tests/unit/symbol_test.ts | 11 + tests/unit/symlink_test.ts | 140 + tests/unit/sync_test.ts | 69 + tests/unit/test_util.ts | 87 + tests/unit/testing_test.ts | 154 + tests/unit/text_encoding_test.ts | 326 + tests/unit/timers_test.ts | 763 + tests/unit/tls_test.ts | 1546 + tests/unit/truncate_test.ts | 114 + tests/unit/tty_color_test.ts | 55 + tests/unit/tty_test.ts | 32 + tests/unit/umask_test.ts | 15 + tests/unit/url_search_params_test.ts | 356 + tests/unit/url_test.ts | 529 + tests/unit/urlpattern_test.ts | 65 + tests/unit/utime_test.ts | 337 + tests/unit/version_test.ts | 10 + tests/unit/wasm_test.ts | 104 + tests/unit/webcrypto_test.ts | 2047 + tests/unit/webgpu_test.ts | 267 + tests/unit/websocket_test.ts | 738 + tests/unit/websocketstream_test.ts.disabled | 359 + tests/unit/webstorage_test.ts | 52 + tests/unit/worker_permissions_test.ts | 34 + tests/unit/worker_test.ts | 843 + tests/unit/write_file_test.ts | 427 + tests/unit/write_text_file_test.ts | 218 + tests/unit_node/_fs/_fs_access_test.ts | 67 + tests/unit_node/_fs/_fs_appendFile_test.ts | 237 + tests/unit_node/_fs/_fs_chmod_test.ts | 121 + tests/unit_node/_fs/_fs_chown_test.ts | 69 + tests/unit_node/_fs/_fs_close_test.ts | 86 + tests/unit_node/_fs/_fs_copy_test.ts | 52 + tests/unit_node/_fs/_fs_dir_test.ts | 205 + tests/unit_node/_fs/_fs_dirent_test.ts | 86 + tests/unit_node/_fs/_fs_exists_test.ts | 65 + tests/unit_node/_fs/_fs_fdatasync_test.ts | 58 + tests/unit_node/_fs/_fs_fstat_test.ts | 90 + tests/unit_node/_fs/_fs_fsync_test.ts | 56 + tests/unit_node/_fs/_fs_ftruncate_test.ts | 123 + tests/unit_node/_fs/_fs_futimes_test.ts | 106 + tests/unit_node/_fs/_fs_handle_test.ts | 88 + tests/unit_node/_fs/_fs_link_test.ts | 77 + tests/unit_node/_fs/_fs_lstat_test.ts | 71 + tests/unit_node/_fs/_fs_mkdir_test.ts | 43 + tests/unit_node/_fs/_fs_mkdtemp_test.ts | 86 + tests/unit_node/_fs/_fs_open_test.ts | 400 + tests/unit_node/_fs/_fs_opendir_test.ts | 146 + tests/unit_node/_fs/_fs_readFile_test.ts | 123 + tests/unit_node/_fs/_fs_read_test.ts | 322 + tests/unit_node/_fs/_fs_readdir_test.ts | 96 + tests/unit_node/_fs/_fs_readlink_test.ts | 75 + tests/unit_node/_fs/_fs_realpath_test.ts | 55 + tests/unit_node/_fs/_fs_rename_test.ts | 52 + tests/unit_node/_fs/_fs_rm_test.ts | 139 + tests/unit_node/_fs/_fs_rmdir_test.ts | 81 + tests/unit_node/_fs/_fs_stat_test.ts | 131 + tests/unit_node/_fs/_fs_symlink_test.ts | 107 + tests/unit_node/_fs/_fs_truncate_test.ts | 95 + tests/unit_node/_fs/_fs_unlink_test.ts | 40 + tests/unit_node/_fs/_fs_utimes_test.ts | 100 + tests/unit_node/_fs/_fs_watch_test.ts | 27 + tests/unit_node/_fs/_fs_writeFile_test.ts | 345 + tests/unit_node/_fs/_fs_write_test.ts | 51 + tests/unit_node/_fs/testdata/hello.txt | 1 + tests/unit_node/_test_utils.ts | 40 + tests/unit_node/assertion_error_test.ts | 66 + tests/unit_node/async_hooks_test.ts | 79 + tests/unit_node/buffer_test.ts | 650 + tests/unit_node/child_process_test.ts | 773 + tests/unit_node/console_test.ts | 28 + tests/unit_node/crypto/crypto_cipher_gcm_test.ts | 103 + tests/unit_node/crypto/crypto_cipher_test.ts | 258 + tests/unit_node/crypto/crypto_hash_test.ts | 139 + tests/unit_node/crypto/crypto_key_test.ts | 233 + tests/unit_node/crypto/crypto_sign_test.ts | 129 + tests/unit_node/crypto/ec_private_secp256r1.pem | 5 + tests/unit_node/crypto/gcmEncryptExtIV128.json | 51377 +++++++++++++++++ tests/unit_node/crypto/gcmEncryptExtIV256.json | 57377 +++++++++++++++++++ tests/unit_node/dgram_test.ts | 59 + tests/unit_node/events_test.ts | 27 + tests/unit_node/fs_test.ts | 116 + tests/unit_node/http2_test.ts | 138 + tests/unit_node/http_test.ts | 940 + tests/unit_node/internal/_randomBytes_test.ts | 112 + tests/unit_node/internal/_randomFill_test.ts | 65 + tests/unit_node/internal/_randomInt_test.ts | 32 + tests/unit_node/internal/pbkdf2_test.ts | 387 + tests/unit_node/internal/scrypt_test.ts | 190 + tests/unit_node/module_test.ts | 72 + tests/unit_node/net_test.ts | 201 + tests/unit_node/os_test.ts | 325 + tests/unit_node/path_test.ts | 16 + tests/unit_node/perf_hooks_test.ts | 62 + tests/unit_node/process_test.ts | 986 + tests/unit_node/querystring_test.ts | 51 + tests/unit_node/readline_test.ts | 27 + tests/unit_node/repl_test.ts | 17 + tests/unit_node/stream_test.ts | 25 + tests/unit_node/string_decoder_test.ts | 167 + tests/unit_node/testdata/add_global_property.js | 1 + .../testdata/add_global_property_run_main.js | 1 + tests/unit_node/testdata/binary_stdio.js | 11 + tests/unit_node/testdata/child_process_stdio.js | 16 + .../unit_node/testdata/child_process_stdio_012.js | 16 + tests/unit_node/testdata/child_process_unref.js | 10 + tests/unit_node/testdata/exec_file_text_error.js | 2 + tests/unit_node/testdata/exec_file_text_output.js | 1 + tests/unit_node/testdata/infinite_loop.js | 3 + tests/unit_node/testdata/lorem_ipsum.txt | 1 + tests/unit_node/testdata/node_modules/foo/index.js | 4 + .../testdata/node_modules/foo/package.json | 3 + tests/unit_node/testdata/process_exit.ts | 19 + tests/unit_node/testdata/process_exit2.ts | 4 + tests/unit_node/testdata/process_really_exit.ts | 10 + tests/unit_node/testdata/process_stdin.ts | 11 + tests/unit_node/testdata/process_stdin_dummy.txt | 2 + tests/unit_node/testdata/rsa_private.pem | 28 + tests/unit_node/testdata/rsa_private_pkcs1.pem | 27 + tests/unit_node/testdata/rsa_public.pem | 9 + tests/unit_node/testdata/worker_module/index.js | 3 + .../unit_node/testdata/worker_module/other_file.js | 3 + .../unit_node/testdata/worker_module/package.json | 4 + tests/unit_node/testdata/worker_threads.mjs | 34 + tests/unit_node/timers_test.ts | 62 + tests/unit_node/tls_test.ts | 150 + tests/unit_node/tty_test.ts | 36 + tests/unit_node/util_test.ts | 317 + tests/unit_node/v8_test.ts | 55 + tests/unit_node/vm_test.ts | 66 + tests/unit_node/worker_threads_test.ts | 204 + tests/unit_node/zlib_test.ts | 172 + 3434 files changed, 274902 insertions(+) create mode 100644 tests/Cargo.toml create mode 100644 tests/config/deno.json create mode 100644 tests/integration/bench_tests.rs create mode 100644 tests/integration/bundle_tests.rs create mode 100644 tests/integration/cache_tests.rs create mode 100644 tests/integration/cert_tests.rs create mode 100644 tests/integration/check_tests.rs create mode 100644 tests/integration/compile_tests.rs create mode 100644 tests/integration/coverage_tests.rs create mode 100644 tests/integration/doc_tests.rs create mode 100644 tests/integration/eval_tests.rs create mode 100644 tests/integration/flags_tests.rs create mode 100644 tests/integration/fmt_tests.rs create mode 100644 tests/integration/info_tests.rs create mode 100644 tests/integration/init_tests.rs create mode 100644 tests/integration/inspector_tests.rs create mode 100644 tests/integration/install_tests.rs create mode 100644 tests/integration/js_unit_tests.rs create mode 100644 tests/integration/jsr_tests.rs create mode 100644 tests/integration/jupyter_tests.rs create mode 100644 tests/integration/lint_tests.rs create mode 100644 tests/integration/lsp_tests.rs create mode 100644 tests/integration/mod.rs create mode 100644 tests/integration/node_compat_tests.rs create mode 100644 tests/integration/node_unit_tests.rs create mode 100644 tests/integration/npm_tests.rs create mode 100644 tests/integration/publish_tests.rs create mode 100644 tests/integration/repl_tests.rs create mode 100644 tests/integration/run_tests.rs create mode 100644 tests/integration/shared_library_tests.rs create mode 100644 tests/integration/task_tests.rs create mode 100644 tests/integration/test_tests.rs create mode 100644 tests/integration/upgrade_tests.rs create mode 100644 tests/integration/vendor_tests.rs create mode 100644 tests/integration/watcher_tests.rs create mode 100644 tests/integration/worker_tests.rs create mode 100644 tests/integration_tests.rs create mode 100644 tests/integration_tests_runner.rs create mode 100644 tests/lib.rs create mode 100644 tests/node_compat/common.ts create mode 100644 tests/node_compat/config.jsonc create mode 100644 tests/node_compat/deno.json create mode 100644 tests/node_compat/polyfill_globals.js create mode 100644 tests/node_compat/runner.ts create mode 100644 tests/node_compat/test.ts create mode 100644 tests/node_compat/test/common/child_process.js create mode 100644 tests/node_compat/test/common/countdown.js create mode 100644 tests/node_compat/test/common/dns.js create mode 100644 tests/node_compat/test/common/duplexpair.js create mode 100644 tests/node_compat/test/common/fixtures.js create mode 100644 tests/node_compat/test/common/hijackstdio.js create mode 100644 tests/node_compat/test/common/index.js create mode 100644 tests/node_compat/test/common/index.mjs create mode 100644 tests/node_compat/test/common/internet.js create mode 100644 tests/node_compat/test/common/package.json create mode 100644 tests/node_compat/test/common/tmpdir.js create mode 100644 tests/node_compat/test/fixtures/GH-1899-output.js create mode 100644 tests/node_compat/test/fixtures/a.js create mode 100644 tests/node_compat/test/fixtures/child-process-spawn-node.js create mode 100644 tests/node_compat/test/fixtures/child_process_should_emit_error.js create mode 100644 tests/node_compat/test/fixtures/echo.js create mode 100644 tests/node_compat/test/fixtures/elipses.txt create mode 100644 tests/node_compat/test/fixtures/empty.txt create mode 100644 tests/node_compat/test/fixtures/exit.js create mode 100644 tests/node_compat/test/fixtures/keys/agent1-cert.pem create mode 100644 tests/node_compat/test/fixtures/keys/agent1-key.pem create mode 100644 tests/node_compat/test/fixtures/keys/ca1-cert.pem create mode 100644 tests/node_compat/test/fixtures/loop.js create mode 100644 tests/node_compat/test/fixtures/package.json create mode 100644 tests/node_compat/test/fixtures/print-chars.js create mode 100644 tests/node_compat/test/fixtures/x.txt create mode 100644 tests/node_compat/test/internet/package.json create mode 100644 tests/node_compat/test/internet/test-dns-any.js create mode 100644 tests/node_compat/test/internet/test-dns-idna2008.js create mode 100644 tests/node_compat/test/internet/test-dns-ipv4.js create mode 100644 tests/node_compat/test/internet/test-dns-ipv6.js create mode 100644 tests/node_compat/test/internet/test-dns-lookup.js create mode 100644 tests/node_compat/test/internet/test-dns-promises-resolve.js create mode 100644 tests/node_compat/test/internet/test-dns-regress-6244.js create mode 100644 tests/node_compat/test/internet/test-dns-setserver-in-callback-of-resolve4.js create mode 100644 tests/node_compat/test/internet/test-dns.js create mode 100644 tests/node_compat/test/internet/test-http-https-default-ports.js create mode 100644 tests/node_compat/test/parallel/package.json create mode 100644 tests/node_compat/test/parallel/test-assert-async.js create mode 100644 tests/node_compat/test/parallel/test-assert-fail.js create mode 100644 tests/node_compat/test/parallel/test-assert-strict-exists.js create mode 100644 tests/node_compat/test/parallel/test-assert.js create mode 100644 tests/node_compat/test/parallel/test-bad-unicode.js create mode 100644 tests/node_compat/test/parallel/test-btoa-atob.js create mode 100644 tests/node_compat/test/parallel/test-buffer-alloc.js create mode 100644 tests/node_compat/test/parallel/test-buffer-arraybuffer.js create mode 100644 tests/node_compat/test/parallel/test-buffer-ascii.js create mode 100644 tests/node_compat/test/parallel/test-buffer-badhex.js create mode 100644 tests/node_compat/test/parallel/test-buffer-bigint64.js create mode 100644 tests/node_compat/test/parallel/test-buffer-bytelength.js create mode 100644 tests/node_compat/test/parallel/test-buffer-compare-offset.js create mode 100644 tests/node_compat/test/parallel/test-buffer-concat.js create mode 100644 tests/node_compat/test/parallel/test-buffer-constants.js create mode 100644 tests/node_compat/test/parallel/test-buffer-copy.js create mode 100644 tests/node_compat/test/parallel/test-buffer-equals.js create mode 100644 tests/node_compat/test/parallel/test-buffer-failed-alloc-typed-arrays.js create mode 100644 tests/node_compat/test/parallel/test-buffer-fakes.js create mode 100644 tests/node_compat/test/parallel/test-buffer-from.js create mode 100644 tests/node_compat/test/parallel/test-buffer-includes.js create mode 100644 tests/node_compat/test/parallel/test-buffer-indexof.js create mode 100644 tests/node_compat/test/parallel/test-buffer-inheritance.js create mode 100644 tests/node_compat/test/parallel/test-buffer-isencoding.js create mode 100644 tests/node_compat/test/parallel/test-buffer-iterator.js create mode 100644 tests/node_compat/test/parallel/test-buffer-new.js create mode 100644 tests/node_compat/test/parallel/test-buffer-no-negative-allocation.js create mode 100644 tests/node_compat/test/parallel/test-buffer-nopendingdep-map.js create mode 100644 tests/node_compat/test/parallel/test-buffer-of-no-deprecation.js create mode 100644 tests/node_compat/test/parallel/test-buffer-over-max-length.js create mode 100644 tests/node_compat/test/parallel/test-buffer-parent-property.js create mode 100644 tests/node_compat/test/parallel/test-buffer-read.js create mode 100644 tests/node_compat/test/parallel/test-buffer-readdouble.js create mode 100644 tests/node_compat/test/parallel/test-buffer-readfloat.js create mode 100644 tests/node_compat/test/parallel/test-buffer-readint.js create mode 100644 tests/node_compat/test/parallel/test-buffer-readuint.js create mode 100644 tests/node_compat/test/parallel/test-buffer-safe-unsafe.js create mode 100644 tests/node_compat/test/parallel/test-buffer-slice.js create mode 100644 tests/node_compat/test/parallel/test-buffer-slow.js create mode 100644 tests/node_compat/test/parallel/test-buffer-swap.js create mode 100644 tests/node_compat/test/parallel/test-buffer-tojson.js create mode 100644 tests/node_compat/test/parallel/test-buffer-tostring-range.js create mode 100644 tests/node_compat/test/parallel/test-buffer-tostring-rangeerror.js create mode 100644 tests/node_compat/test/parallel/test-buffer-tostring.js create mode 100644 tests/node_compat/test/parallel/test-buffer-writedouble.js create mode 100644 tests/node_compat/test/parallel/test-buffer-writefloat.js create mode 100644 tests/node_compat/test/parallel/test-buffer-writeint.js create mode 100644 tests/node_compat/test/parallel/test-buffer-writeuint.js create mode 100644 tests/node_compat/test/parallel/test-buffer-zero-fill-cli.js create mode 100644 tests/node_compat/test/parallel/test-buffer-zero-fill-reset.js create mode 100644 tests/node_compat/test/parallel/test-buffer-zero-fill.js create mode 100644 tests/node_compat/test/parallel/test-child-process-default-options.js create mode 100644 tests/node_compat/test/parallel/test-child-process-double-pipe.js create mode 100644 tests/node_compat/test/parallel/test-child-process-exec-abortcontroller-promisified.js create mode 100644 tests/node_compat/test/parallel/test-child-process-exec-cwd.js create mode 100644 tests/node_compat/test/parallel/test-child-process-exec-encoding.js create mode 100644 tests/node_compat/test/parallel/test-child-process-exec-env.js create mode 100644 tests/node_compat/test/parallel/test-child-process-exec-error.js create mode 100644 tests/node_compat/test/parallel/test-child-process-exec-kill-throws.js create mode 100644 tests/node_compat/test/parallel/test-child-process-exec-maxbuf.js create mode 100644 tests/node_compat/test/parallel/test-child-process-exec-std-encoding.js create mode 100644 tests/node_compat/test/parallel/test-child-process-exec-stdout-stderr-data-string.js create mode 100644 tests/node_compat/test/parallel/test-child-process-exec-timeout-not-expired.js create mode 100644 tests/node_compat/test/parallel/test-child-process-execfile-maxbuf.js create mode 100644 tests/node_compat/test/parallel/test-child-process-execfile.js create mode 100644 tests/node_compat/test/parallel/test-child-process-execfilesync-maxbuf.js create mode 100644 tests/node_compat/test/parallel/test-child-process-execsync-maxbuf.js create mode 100644 tests/node_compat/test/parallel/test-child-process-exit-code.js create mode 100644 tests/node_compat/test/parallel/test-child-process-flush-stdio.js create mode 100644 tests/node_compat/test/parallel/test-child-process-fork-ref.js create mode 100644 tests/node_compat/test/parallel/test-child-process-fork-ref2.js create mode 100644 tests/node_compat/test/parallel/test-child-process-ipc-next-tick.js create mode 100644 tests/node_compat/test/parallel/test-child-process-ipc.js create mode 100644 tests/node_compat/test/parallel/test-child-process-kill.js create mode 100644 tests/node_compat/test/parallel/test-child-process-set-blocking.js create mode 100644 tests/node_compat/test/parallel/test-child-process-spawn-args.js create mode 100644 tests/node_compat/test/parallel/test-child-process-spawn-event.js create mode 100644 tests/node_compat/test/parallel/test-child-process-spawnsync-args.js create mode 100644 tests/node_compat/test/parallel/test-child-process-spawnsync-env.js create mode 100644 tests/node_compat/test/parallel/test-child-process-spawnsync-maxbuf.js create mode 100644 tests/node_compat/test/parallel/test-child-process-spawnsync-validation-errors.js create mode 100644 tests/node_compat/test/parallel/test-child-process-spawnsync.js create mode 100644 tests/node_compat/test/parallel/test-child-process-stdio-inherit.js create mode 100644 tests/node_compat/test/parallel/test-child-process-stdout-flush-exit.js create mode 100644 tests/node_compat/test/parallel/test-child-process-stdout-flush.js create mode 100644 tests/node_compat/test/parallel/test-console-async-write-error.js create mode 100644 tests/node_compat/test/parallel/test-console-group.js create mode 100644 tests/node_compat/test/parallel/test-console-instance.js create mode 100644 tests/node_compat/test/parallel/test-console-log-stdio-broken-dest.js create mode 100644 tests/node_compat/test/parallel/test-console-log-throw-primitive.js create mode 100644 tests/node_compat/test/parallel/test-console-no-swallow-stack-overflow.js create mode 100644 tests/node_compat/test/parallel/test-console-sync-write-error.js create mode 100644 tests/node_compat/test/parallel/test-console-table.js create mode 100644 tests/node_compat/test/parallel/test-console-tty-colors.js create mode 100644 tests/node_compat/test/parallel/test-crypto-dh-shared.js create mode 100644 tests/node_compat/test/parallel/test-crypto-dh.js create mode 100644 tests/node_compat/test/parallel/test-crypto-hkdf.js create mode 100644 tests/node_compat/test/parallel/test-crypto-hmac.js create mode 100644 tests/node_compat/test/parallel/test-crypto-prime.js create mode 100644 tests/node_compat/test/parallel/test-crypto-secret-keygen.js create mode 100644 tests/node_compat/test/parallel/test-crypto-stream.js create mode 100644 tests/node_compat/test/parallel/test-crypto-update-encoding.js create mode 100644 tests/node_compat/test/parallel/test-crypto-x509.js create mode 100644 tests/node_compat/test/parallel/test-dgram-close-during-bind.js create mode 100644 tests/node_compat/test/parallel/test-dgram-close-signal.js create mode 100644 tests/node_compat/test/parallel/test-dgram-custom-lookup.js create mode 100644 tests/node_compat/test/parallel/test-dgram-ipv6only.js create mode 100644 tests/node_compat/test/parallel/test-dgram-send-cb-quelches-error.js create mode 100644 tests/node_compat/test/parallel/test-dgram-socket-buffer-size.js create mode 100644 tests/node_compat/test/parallel/test-dgram-udp6-link-local-address.js create mode 100644 tests/node_compat/test/parallel/test-diagnostics-channel-has-subscribers.js create mode 100644 tests/node_compat/test/parallel/test-diagnostics-channel-object-channel-pub-sub.js create mode 100644 tests/node_compat/test/parallel/test-diagnostics-channel-pub-sub.js create mode 100644 tests/node_compat/test/parallel/test-diagnostics-channel-symbol-named.js create mode 100644 tests/node_compat/test/parallel/test-diagnostics-channel-udp.js create mode 100644 tests/node_compat/test/parallel/test-dns-lookup.js create mode 100644 tests/node_compat/test/parallel/test-dns-memory-error.js create mode 100644 tests/node_compat/test/parallel/test-dns-promises-exists.js create mode 100644 tests/node_compat/test/parallel/test-dns-resolveany.js create mode 100644 tests/node_compat/test/parallel/test-dns-resolvens-typeerror.js create mode 100644 tests/node_compat/test/parallel/test-dns-setservers-type-check.js create mode 100644 tests/node_compat/test/parallel/test-dns.js create mode 100644 tests/node_compat/test/parallel/test-eval-strict-referenceerror.js create mode 100644 tests/node_compat/test/parallel/test-eval.js create mode 100644 tests/node_compat/test/parallel/test-event-emitter-add-listeners.js create mode 100644 tests/node_compat/test/parallel/test-event-emitter-emit-context.js create mode 100644 tests/node_compat/test/parallel/test-event-emitter-error-monitor.js create mode 100644 tests/node_compat/test/parallel/test-event-emitter-errors.js create mode 100644 tests/node_compat/test/parallel/test-event-emitter-get-max-listeners.js create mode 100644 tests/node_compat/test/parallel/test-event-emitter-invalid-listener.js create mode 100644 tests/node_compat/test/parallel/test-event-emitter-listener-count.js create mode 100644 tests/node_compat/test/parallel/test-event-emitter-listeners-side-effects.js create mode 100644 tests/node_compat/test/parallel/test-event-emitter-listeners.js create mode 100644 tests/node_compat/test/parallel/test-event-emitter-max-listeners.js create mode 100644 tests/node_compat/test/parallel/test-event-emitter-method-names.js create mode 100644 tests/node_compat/test/parallel/test-event-emitter-modify-in-emit.js create mode 100644 tests/node_compat/test/parallel/test-event-emitter-no-error-provided-to-error-event.js create mode 100644 tests/node_compat/test/parallel/test-event-emitter-num-args.js create mode 100644 tests/node_compat/test/parallel/test-event-emitter-once.js create mode 100644 tests/node_compat/test/parallel/test-event-emitter-prepend.js create mode 100644 tests/node_compat/test/parallel/test-event-emitter-remove-all-listeners.js create mode 100644 tests/node_compat/test/parallel/test-event-emitter-remove-listeners.js create mode 100644 tests/node_compat/test/parallel/test-event-emitter-set-max-listeners-side-effects.js create mode 100644 tests/node_compat/test/parallel/test-event-emitter-special-event-names.js create mode 100644 tests/node_compat/test/parallel/test-event-emitter-subclass.js create mode 100644 tests/node_compat/test/parallel/test-event-emitter-symbols.js create mode 100644 tests/node_compat/test/parallel/test-events-list.js create mode 100644 tests/node_compat/test/parallel/test-events-on-async-iterator.js create mode 100644 tests/node_compat/test/parallel/test-events-once.js create mode 100644 tests/node_compat/test/parallel/test-events-uncaught-exception-stack.js create mode 100644 tests/node_compat/test/parallel/test-eventtarget-brandcheck.js create mode 100644 tests/node_compat/test/parallel/test-exception-handler.js create mode 100644 tests/node_compat/test/parallel/test-exception-handler2.js create mode 100644 tests/node_compat/test/parallel/test-file-read-noexist.js create mode 100644 tests/node_compat/test/parallel/test-file-write-stream.js create mode 100644 tests/node_compat/test/parallel/test-file-write-stream2.js create mode 100644 tests/node_compat/test/parallel/test-file-write-stream3.js create mode 100644 tests/node_compat/test/parallel/test-file-write-stream4.js create mode 100644 tests/node_compat/test/parallel/test-fs-access.js create mode 100644 tests/node_compat/test/parallel/test-fs-append-file-sync.js create mode 100644 tests/node_compat/test/parallel/test-fs-append-file.js create mode 100644 tests/node_compat/test/parallel/test-fs-chmod-mask.js create mode 100644 tests/node_compat/test/parallel/test-fs-chmod.js create mode 100644 tests/node_compat/test/parallel/test-fs-chown-type-check.js create mode 100644 tests/node_compat/test/parallel/test-fs-copyfile.js create mode 100644 tests/node_compat/test/parallel/test-fs-empty-readStream.js create mode 100644 tests/node_compat/test/parallel/test-fs-mkdir.js create mode 100644 tests/node_compat/test/parallel/test-fs-open-flags.js create mode 100644 tests/node_compat/test/parallel/test-fs-open-mode-mask.js create mode 100644 tests/node_compat/test/parallel/test-fs-open-no-close.js create mode 100644 tests/node_compat/test/parallel/test-fs-open-numeric-flags.js create mode 100644 tests/node_compat/test/parallel/test-fs-open.js create mode 100644 tests/node_compat/test/parallel/test-fs-opendir.js create mode 100644 tests/node_compat/test/parallel/test-fs-read-stream-autoClose.js create mode 100644 tests/node_compat/test/parallel/test-fs-read-stream-concurrent-reads.js create mode 100644 tests/node_compat/test/parallel/test-fs-read-stream-double-close.js create mode 100644 tests/node_compat/test/parallel/test-fs-read-stream-encoding.js create mode 100644 tests/node_compat/test/parallel/test-fs-read-stream-fd.js create mode 100644 tests/node_compat/test/parallel/test-fs-read-stream-inherit.js create mode 100644 tests/node_compat/test/parallel/test-fs-read-stream-patch-open.js create mode 100644 tests/node_compat/test/parallel/test-fs-read-stream-resume.js create mode 100644 tests/node_compat/test/parallel/test-fs-read-stream-throw-type-error.js create mode 100644 tests/node_compat/test/parallel/test-fs-read-stream.js create mode 100644 tests/node_compat/test/parallel/test-fs-read-type.js create mode 100644 tests/node_compat/test/parallel/test-fs-read-zero-length.js create mode 100644 tests/node_compat/test/parallel/test-fs-read.js create mode 100644 tests/node_compat/test/parallel/test-fs-readdir-stack-overflow.js create mode 100644 tests/node_compat/test/parallel/test-fs-readdir.js create mode 100644 tests/node_compat/test/parallel/test-fs-readfile-empty.js create mode 100644 tests/node_compat/test/parallel/test-fs-realpath-native.js create mode 100644 tests/node_compat/test/parallel/test-fs-rmdir-recursive-sync-warns-not-found.js create mode 100644 tests/node_compat/test/parallel/test-fs-rmdir-recursive-sync-warns-on-file.js create mode 100644 tests/node_compat/test/parallel/test-fs-rmdir-recursive-throws-not-found.js create mode 100644 tests/node_compat/test/parallel/test-fs-rmdir-recursive-throws-on-file.js create mode 100644 tests/node_compat/test/parallel/test-fs-rmdir-recursive-warns-not-found.js create mode 100644 tests/node_compat/test/parallel/test-fs-rmdir-recursive-warns-on-file.js create mode 100644 tests/node_compat/test/parallel/test-fs-rmdir-recursive.js create mode 100644 tests/node_compat/test/parallel/test-fs-rmdir-type-check.js create mode 100644 tests/node_compat/test/parallel/test-fs-watchfile.js create mode 100644 tests/node_compat/test/parallel/test-fs-write-buffer.js create mode 100644 tests/node_compat/test/parallel/test-fs-write-file-buffer.js create mode 100644 tests/node_compat/test/parallel/test-fs-write-file-invalid-path.js create mode 100644 tests/node_compat/test/parallel/test-fs-write-file-sync.js create mode 100644 tests/node_compat/test/parallel/test-fs-write-file.js create mode 100644 tests/node_compat/test/parallel/test-fs-write-no-fd.js create mode 100644 tests/node_compat/test/parallel/test-fs-write-stream-autoclose-option.js create mode 100644 tests/node_compat/test/parallel/test-fs-write-stream-close-without-callback.js create mode 100644 tests/node_compat/test/parallel/test-fs-write-stream-double-close.js create mode 100644 tests/node_compat/test/parallel/test-fs-write-stream-end.js create mode 100644 tests/node_compat/test/parallel/test-fs-write-stream-fs.js create mode 100644 tests/node_compat/test/parallel/test-fs-write-stream-throw-type-error.js create mode 100644 tests/node_compat/test/parallel/test-fs-write-stream.js create mode 100644 tests/node_compat/test/parallel/test-fs-write-sync.js create mode 100644 tests/node_compat/test/parallel/test-fs-write.js create mode 100644 tests/node_compat/test/parallel/test-fs-writev-sync.js create mode 100644 tests/node_compat/test/parallel/test-handle-wrap-close-abort.js create mode 100644 tests/node_compat/test/parallel/test-http-agent-getname.js create mode 100644 tests/node_compat/test/parallel/test-http-client-get-url.js create mode 100644 tests/node_compat/test/parallel/test-http-client-read-in-error.js create mode 100644 tests/node_compat/test/parallel/test-http-localaddress.js create mode 100644 tests/node_compat/test/parallel/test-http-outgoing-internal-headernames-getter.js create mode 100644 tests/node_compat/test/parallel/test-http-outgoing-internal-headernames-setter.js create mode 100644 tests/node_compat/test/parallel/test-http-outgoing-internal-headers.js create mode 100644 tests/node_compat/test/parallel/test-http-outgoing-renderHeaders.js create mode 100644 tests/node_compat/test/parallel/test-http-outgoing-settimeout.js create mode 100644 tests/node_compat/test/parallel/test-http-url.parse-auth-with-header-in-request.js create mode 100644 tests/node_compat/test/parallel/test-http-url.parse-auth.js create mode 100644 tests/node_compat/test/parallel/test-http-url.parse-basic.js create mode 100644 tests/node_compat/test/parallel/test-http-url.parse-https.request.js create mode 100644 tests/node_compat/test/parallel/test-http-url.parse-only-support-http-https-protocol.js create mode 100644 tests/node_compat/test/parallel/test-http-url.parse-path.js create mode 100644 tests/node_compat/test/parallel/test-http-url.parse-post.js create mode 100644 tests/node_compat/test/parallel/test-http-url.parse-search.js create mode 100644 tests/node_compat/test/parallel/test-net-access-byteswritten.js create mode 100644 tests/node_compat/test/parallel/test-net-better-error-messages-listen-path.js create mode 100644 tests/node_compat/test/parallel/test-net-better-error-messages-path.js create mode 100644 tests/node_compat/test/parallel/test-net-better-error-messages-port-hostname.js create mode 100644 tests/node_compat/test/parallel/test-net-connect-after-destroy.js create mode 100644 tests/node_compat/test/parallel/test-net-connect-buffer.js create mode 100644 tests/node_compat/test/parallel/test-net-connect-buffer2.js create mode 100644 tests/node_compat/test/parallel/test-net-connect-destroy.js create mode 100644 tests/node_compat/test/parallel/test-net-connect-immediate-destroy.js create mode 100644 tests/node_compat/test/parallel/test-net-connect-immediate-finish.js create mode 100644 tests/node_compat/test/parallel/test-net-connect-no-arg.js create mode 100644 tests/node_compat/test/parallel/test-net-dns-error.js create mode 100644 tests/node_compat/test/parallel/test-net-during-close.js create mode 100644 tests/node_compat/test/parallel/test-net-end-close.js create mode 100644 tests/node_compat/test/parallel/test-net-end-without-connect.js create mode 100644 tests/node_compat/test/parallel/test-net-isip.js create mode 100644 tests/node_compat/test/parallel/test-net-isipv4.js create mode 100644 tests/node_compat/test/parallel/test-net-isipv6.js create mode 100644 tests/node_compat/test/parallel/test-net-listen-close-server-callback-is-not-function.js create mode 100644 tests/node_compat/test/parallel/test-net-listen-close-server.js create mode 100644 tests/node_compat/test/parallel/test-net-listen-invalid-port.js create mode 100644 tests/node_compat/test/parallel/test-net-listening.js create mode 100644 tests/node_compat/test/parallel/test-net-localerror.js create mode 100644 tests/node_compat/test/parallel/test-net-options-lookup.js create mode 100644 tests/node_compat/test/parallel/test-net-pipe-connect-errors.js create mode 100644 tests/node_compat/test/parallel/test-net-server-call-listen-multiple-times.js create mode 100644 tests/node_compat/test/parallel/test-net-server-listen-options-signal.js create mode 100644 tests/node_compat/test/parallel/test-net-server-listen-options.js create mode 100644 tests/node_compat/test/parallel/test-net-server-listen-path.js create mode 100644 tests/node_compat/test/parallel/test-net-server-listen-remove-callback.js create mode 100644 tests/node_compat/test/parallel/test-net-server-options.js create mode 100644 tests/node_compat/test/parallel/test-net-server-try-ports.js create mode 100644 tests/node_compat/test/parallel/test-net-server-unref-persistent.js create mode 100644 tests/node_compat/test/parallel/test-net-server-unref.js create mode 100644 tests/node_compat/test/parallel/test-net-socket-destroy-twice.js create mode 100644 tests/node_compat/test/parallel/test-net-socket-no-halfopen-enforcer.js create mode 100644 tests/node_compat/test/parallel/test-net-socket-timeout.js create mode 100644 tests/node_compat/test/parallel/test-net-timeout-no-handle.js create mode 100644 tests/node_compat/test/parallel/test-net-write-arguments.js create mode 100644 tests/node_compat/test/parallel/test-next-tick-doesnt-hang.js create mode 100644 tests/node_compat/test/parallel/test-next-tick-fixed-queue-regression.js create mode 100644 tests/node_compat/test/parallel/test-next-tick-intentional-starvation.js create mode 100644 tests/node_compat/test/parallel/test-next-tick-ordering.js create mode 100644 tests/node_compat/test/parallel/test-next-tick-ordering2.js create mode 100644 tests/node_compat/test/parallel/test-next-tick-when-exiting.js create mode 100644 tests/node_compat/test/parallel/test-next-tick.js create mode 100644 tests/node_compat/test/parallel/test-nodeeventtarget.js create mode 100644 tests/node_compat/test/parallel/test-os.js create mode 100644 tests/node_compat/test/parallel/test-outgoing-message-destroy.js create mode 100644 tests/node_compat/test/parallel/test-outgoing-message-pipe.js create mode 100644 tests/node_compat/test/parallel/test-parse-args.mjs create mode 100644 tests/node_compat/test/parallel/test-path-basename.js create mode 100644 tests/node_compat/test/parallel/test-path-dirname.js create mode 100644 tests/node_compat/test/parallel/test-path-extname.js create mode 100644 tests/node_compat/test/parallel/test-path-isabsolute.js create mode 100644 tests/node_compat/test/parallel/test-path-join.js create mode 100644 tests/node_compat/test/parallel/test-path-makelong.js create mode 100644 tests/node_compat/test/parallel/test-path-normalize.js create mode 100644 tests/node_compat/test/parallel/test-path-parse-format.js create mode 100644 tests/node_compat/test/parallel/test-path-posix-exists.js create mode 100644 tests/node_compat/test/parallel/test-path-relative.js create mode 100644 tests/node_compat/test/parallel/test-path-resolve.js create mode 100644 tests/node_compat/test/parallel/test-path-win32-exists.js create mode 100644 tests/node_compat/test/parallel/test-path-zero-length-strings.js create mode 100644 tests/node_compat/test/parallel/test-path.js create mode 100644 tests/node_compat/test/parallel/test-process-beforeexit.js create mode 100644 tests/node_compat/test/parallel/test-process-binding-internalbinding-allowlist.js create mode 100644 tests/node_compat/test/parallel/test-process-env-allowed-flags.js create mode 100644 tests/node_compat/test/parallel/test-process-exit-from-before-exit.js create mode 100644 tests/node_compat/test/parallel/test-process-exit-handler.js create mode 100644 tests/node_compat/test/parallel/test-process-exit-recursive.js create mode 100644 tests/node_compat/test/parallel/test-process-exit.js create mode 100644 tests/node_compat/test/parallel/test-process-kill-pid.js create mode 100644 tests/node_compat/test/parallel/test-process-uptime.js create mode 100644 tests/node_compat/test/parallel/test-promise-unhandled-silent.js create mode 100644 tests/node_compat/test/parallel/test-promise-unhandled-throw-handler.js create mode 100644 tests/node_compat/test/parallel/test-querystring-escape.js create mode 100644 tests/node_compat/test/parallel/test-querystring-maxKeys-non-finite.js create mode 100644 tests/node_compat/test/parallel/test-querystring-multichar-separator.js create mode 100644 tests/node_compat/test/parallel/test-querystring.js create mode 100644 tests/node_compat/test/parallel/test-readline-emit-keypress-events.js create mode 100644 tests/node_compat/test/parallel/test-readline-interface-escapecodetimeout.js create mode 100644 tests/node_compat/test/parallel/test-readline-interface.js create mode 100644 tests/node_compat/test/parallel/test-readline-keys.js create mode 100644 tests/node_compat/test/parallel/test-readline-position.js create mode 100644 tests/node_compat/test/parallel/test-readline-reopen.js create mode 100644 tests/node_compat/test/parallel/test-readline-set-raw-mode.js create mode 100644 tests/node_compat/test/parallel/test-readline-undefined-columns.js create mode 100644 tests/node_compat/test/parallel/test-readline.js create mode 100644 tests/node_compat/test/parallel/test-stdin-from-file-spawn.js create mode 100644 tests/node_compat/test/parallel/test-stream-add-abort-signal.js create mode 100644 tests/node_compat/test/parallel/test-stream-aliases-legacy.js create mode 100644 tests/node_compat/test/parallel/test-stream-auto-destroy.js create mode 100644 tests/node_compat/test/parallel/test-stream-await-drain-writers-in-synchronously-recursion-write.js create mode 100644 tests/node_compat/test/parallel/test-stream-backpressure.js create mode 100644 tests/node_compat/test/parallel/test-stream-big-packet.js create mode 100644 tests/node_compat/test/parallel/test-stream-big-push.js create mode 100644 tests/node_compat/test/parallel/test-stream-buffer-list.js create mode 100644 tests/node_compat/test/parallel/test-stream-construct.js create mode 100644 tests/node_compat/test/parallel/test-stream-destroy-event-order.js create mode 100644 tests/node_compat/test/parallel/test-stream-duplex-destroy.js create mode 100644 tests/node_compat/test/parallel/test-stream-duplex-end.js create mode 100644 tests/node_compat/test/parallel/test-stream-duplex-from.js create mode 100644 tests/node_compat/test/parallel/test-stream-duplex-props.js create mode 100644 tests/node_compat/test/parallel/test-stream-duplex-readable-end.js create mode 100644 tests/node_compat/test/parallel/test-stream-duplex-writable-finished.js create mode 100644 tests/node_compat/test/parallel/test-stream-duplex.js create mode 100644 tests/node_compat/test/parallel/test-stream-end-paused.js create mode 100644 tests/node_compat/test/parallel/test-stream-error-once.js create mode 100644 tests/node_compat/test/parallel/test-stream-events-prepend.js create mode 100644 tests/node_compat/test/parallel/test-stream-inheritance.js create mode 100644 tests/node_compat/test/parallel/test-stream-ispaused.js create mode 100644 tests/node_compat/test/parallel/test-stream-objectmode-undefined.js create mode 100644 tests/node_compat/test/parallel/test-stream-once-readable-pipe.js create mode 100644 tests/node_compat/test/parallel/test-stream-pipe-after-end.js create mode 100644 tests/node_compat/test/parallel/test-stream-pipe-await-drain-manual-resume.js create mode 100644 tests/node_compat/test/parallel/test-stream-pipe-await-drain-push-while-write.js create mode 100644 tests/node_compat/test/parallel/test-stream-pipe-await-drain.js create mode 100644 tests/node_compat/test/parallel/test-stream-pipe-cleanup-pause.js create mode 100644 tests/node_compat/test/parallel/test-stream-pipe-cleanup.js create mode 100644 tests/node_compat/test/parallel/test-stream-pipe-error-handling.js create mode 100644 tests/node_compat/test/parallel/test-stream-pipe-event.js create mode 100644 tests/node_compat/test/parallel/test-stream-pipe-flow-after-unpipe.js create mode 100644 tests/node_compat/test/parallel/test-stream-pipe-flow.js create mode 100644 tests/node_compat/test/parallel/test-stream-pipe-manual-resume.js create mode 100644 tests/node_compat/test/parallel/test-stream-pipe-multiple-pipes.js create mode 100644 tests/node_compat/test/parallel/test-stream-pipe-needDrain.js create mode 100644 tests/node_compat/test/parallel/test-stream-pipe-same-destination-twice.js create mode 100644 tests/node_compat/test/parallel/test-stream-pipe-unpipe-streams.js create mode 100644 tests/node_compat/test/parallel/test-stream-pipe-without-listenerCount.js create mode 100644 tests/node_compat/test/parallel/test-stream-pipeline-async-iterator.js create mode 100644 tests/node_compat/test/parallel/test-stream-pipeline-queued-end-in-destroy.js create mode 100644 tests/node_compat/test/parallel/test-stream-pipeline-with-empty-string.js create mode 100644 tests/node_compat/test/parallel/test-stream-push-strings.js create mode 100644 tests/node_compat/test/parallel/test-stream-readable-aborted.js create mode 100644 tests/node_compat/test/parallel/test-stream-readable-add-chunk-during-data.js create mode 100644 tests/node_compat/test/parallel/test-stream-readable-constructor-set-methods.js create mode 100644 tests/node_compat/test/parallel/test-stream-readable-data.js create mode 100644 tests/node_compat/test/parallel/test-stream-readable-destroy.js create mode 100644 tests/node_compat/test/parallel/test-stream-readable-didRead.js create mode 100644 tests/node_compat/test/parallel/test-stream-readable-emit-readable-short-stream.js create mode 100644 tests/node_compat/test/parallel/test-stream-readable-emittedReadable.js create mode 100644 tests/node_compat/test/parallel/test-stream-readable-end-destroyed.js create mode 100644 tests/node_compat/test/parallel/test-stream-readable-ended.js create mode 100644 tests/node_compat/test/parallel/test-stream-readable-error-end.js create mode 100644 tests/node_compat/test/parallel/test-stream-readable-event.js create mode 100644 tests/node_compat/test/parallel/test-stream-readable-flow-recursion.js create mode 100644 tests/node_compat/test/parallel/test-stream-readable-hwm-0-async.js create mode 100644 tests/node_compat/test/parallel/test-stream-readable-hwm-0-no-flow-data.js create mode 100644 tests/node_compat/test/parallel/test-stream-readable-hwm-0.js create mode 100644 tests/node_compat/test/parallel/test-stream-readable-infinite-read.js create mode 100644 tests/node_compat/test/parallel/test-stream-readable-invalid-chunk.js create mode 100644 tests/node_compat/test/parallel/test-stream-readable-needReadable.js create mode 100644 tests/node_compat/test/parallel/test-stream-readable-next-no-null.js create mode 100644 tests/node_compat/test/parallel/test-stream-readable-no-unneeded-readable.js create mode 100644 tests/node_compat/test/parallel/test-stream-readable-object-multi-push-async.js create mode 100644 tests/node_compat/test/parallel/test-stream-readable-pause-and-resume.js create mode 100644 tests/node_compat/test/parallel/test-stream-readable-readable-then-resume.js create mode 100644 tests/node_compat/test/parallel/test-stream-readable-readable.js create mode 100644 tests/node_compat/test/parallel/test-stream-readable-reading-readingMore.js create mode 100644 tests/node_compat/test/parallel/test-stream-readable-resume-hwm.js create mode 100644 tests/node_compat/test/parallel/test-stream-readable-resumeScheduled.js create mode 100644 tests/node_compat/test/parallel/test-stream-readable-setEncoding-existing-buffers.js create mode 100644 tests/node_compat/test/parallel/test-stream-readable-setEncoding-null.js create mode 100644 tests/node_compat/test/parallel/test-stream-readable-unshift.js create mode 100644 tests/node_compat/test/parallel/test-stream-readable-with-unimplemented-_read.js create mode 100644 tests/node_compat/test/parallel/test-stream-readableListening-state.js create mode 100644 tests/node_compat/test/parallel/test-stream-transform-callback-twice.js create mode 100644 tests/node_compat/test/parallel/test-stream-transform-constructor-set-methods.js create mode 100644 tests/node_compat/test/parallel/test-stream-transform-destroy.js create mode 100644 tests/node_compat/test/parallel/test-stream-transform-final-sync.js create mode 100644 tests/node_compat/test/parallel/test-stream-transform-final.js create mode 100644 tests/node_compat/test/parallel/test-stream-transform-flush-data.js create mode 100644 tests/node_compat/test/parallel/test-stream-transform-objectmode-falsey-value.js create mode 100644 tests/node_compat/test/parallel/test-stream-transform-split-highwatermark.js create mode 100644 tests/node_compat/test/parallel/test-stream-transform-split-objectmode.js create mode 100644 tests/node_compat/test/parallel/test-stream-uint8array.js create mode 100644 tests/node_compat/test/parallel/test-stream-unpipe-event.js create mode 100644 tests/node_compat/test/parallel/test-stream-unshift-empty-chunk.js create mode 100644 tests/node_compat/test/parallel/test-stream-unshift-read-race.js create mode 100644 tests/node_compat/test/parallel/test-stream-writable-change-default-encoding.js create mode 100644 tests/node_compat/test/parallel/test-stream-writable-clear-buffer.js create mode 100644 tests/node_compat/test/parallel/test-stream-writable-constructor-set-methods.js create mode 100644 tests/node_compat/test/parallel/test-stream-writable-decoded-encoding.js create mode 100644 tests/node_compat/test/parallel/test-stream-writable-destroy.js create mode 100644 tests/node_compat/test/parallel/test-stream-writable-end-cb-error.js create mode 100644 tests/node_compat/test/parallel/test-stream-writable-end-multiple.js create mode 100644 tests/node_compat/test/parallel/test-stream-writable-ended-state.js create mode 100644 tests/node_compat/test/parallel/test-stream-writable-finish-destroyed.js create mode 100644 tests/node_compat/test/parallel/test-stream-writable-finished-state.js create mode 100644 tests/node_compat/test/parallel/test-stream-writable-finished.js create mode 100644 tests/node_compat/test/parallel/test-stream-writable-invalid-chunk.js create mode 100644 tests/node_compat/test/parallel/test-stream-writable-needdrain-state.js create mode 100644 tests/node_compat/test/parallel/test-stream-writable-null.js create mode 100644 tests/node_compat/test/parallel/test-stream-writable-properties.js create mode 100644 tests/node_compat/test/parallel/test-stream-writable-writable.js create mode 100644 tests/node_compat/test/parallel/test-stream-writable-write-cb-error.js create mode 100644 tests/node_compat/test/parallel/test-stream-writable-write-cb-twice.js create mode 100644 tests/node_compat/test/parallel/test-stream-writable-write-error.js create mode 100644 tests/node_compat/test/parallel/test-stream-writable-write-writev-finish.js create mode 100644 tests/node_compat/test/parallel/test-stream-writableState-ending.js create mode 100644 tests/node_compat/test/parallel/test-stream-writableState-uncorked-bufferedRequestCount.js create mode 100644 tests/node_compat/test/parallel/test-stream-write-destroy.js create mode 100644 tests/node_compat/test/parallel/test-stream-write-drain.js create mode 100644 tests/node_compat/test/parallel/test-stream-write-final.js create mode 100644 tests/node_compat/test/parallel/test-stream-writev.js create mode 100644 tests/node_compat/test/parallel/test-stream2-base64-single-char-read-end.js create mode 100644 tests/node_compat/test/parallel/test-stream2-basic.js create mode 100644 tests/node_compat/test/parallel/test-stream2-compatibility.js create mode 100644 tests/node_compat/test/parallel/test-stream2-decode-partial.js create mode 100644 tests/node_compat/test/parallel/test-stream2-finish-pipe.js create mode 100644 tests/node_compat/test/parallel/test-stream2-large-read-stall.js create mode 100644 tests/node_compat/test/parallel/test-stream2-objects.js create mode 100644 tests/node_compat/test/parallel/test-stream2-pipe-error-handling.js create mode 100644 tests/node_compat/test/parallel/test-stream2-pipe-error-once-listener.js create mode 100644 tests/node_compat/test/parallel/test-stream2-push.js create mode 100644 tests/node_compat/test/parallel/test-stream2-read-sync-stack.js create mode 100644 tests/node_compat/test/parallel/test-stream2-readable-empty-buffer-no-eof.js create mode 100644 tests/node_compat/test/parallel/test-stream2-readable-from-list.js create mode 100644 tests/node_compat/test/parallel/test-stream2-readable-legacy-drain.js create mode 100644 tests/node_compat/test/parallel/test-stream2-readable-non-empty-end.js create mode 100644 tests/node_compat/test/parallel/test-stream2-readable-wrap-destroy.js create mode 100644 tests/node_compat/test/parallel/test-stream2-readable-wrap-empty.js create mode 100644 tests/node_compat/test/parallel/test-stream2-readable-wrap-error.js create mode 100644 tests/node_compat/test/parallel/test-stream2-readable-wrap.js create mode 100644 tests/node_compat/test/parallel/test-stream2-set-encoding.js create mode 100644 tests/node_compat/test/parallel/test-stream2-transform.js create mode 100644 tests/node_compat/test/parallel/test-stream2-unpipe-drain.js create mode 100644 tests/node_compat/test/parallel/test-stream2-unpipe-leak.js create mode 100644 tests/node_compat/test/parallel/test-stream2-writable.js create mode 100644 tests/node_compat/test/parallel/test-stream3-cork-end.js create mode 100644 tests/node_compat/test/parallel/test-stream3-cork-uncork.js create mode 100644 tests/node_compat/test/parallel/test-stream3-pause-then-read.js create mode 100644 tests/node_compat/test/parallel/test-streams-highwatermark.js create mode 100644 tests/node_compat/test/parallel/test-timers-api-refs.js create mode 100644 tests/node_compat/test/parallel/test-timers-args.js create mode 100644 tests/node_compat/test/parallel/test-timers-clear-null-does-not-throw-error.js create mode 100644 tests/node_compat/test/parallel/test-timers-clear-object-does-not-throw-error.js create mode 100644 tests/node_compat/test/parallel/test-timers-clear-timeout-interval-equivalent.js create mode 100644 tests/node_compat/test/parallel/test-timers-clearImmediate.js create mode 100644 tests/node_compat/test/parallel/test-timers-interval-throw.js create mode 100644 tests/node_compat/test/parallel/test-timers-non-integer-delay.js create mode 100644 tests/node_compat/test/parallel/test-timers-refresh.js create mode 100644 tests/node_compat/test/parallel/test-timers-same-timeout-wrong-list-deleted.js create mode 100644 tests/node_compat/test/parallel/test-timers-timeout-with-non-integer.js create mode 100644 tests/node_compat/test/parallel/test-timers-uncaught-exception.js create mode 100644 tests/node_compat/test/parallel/test-timers-unref-throw-then-ref.js create mode 100644 tests/node_compat/test/parallel/test-timers-user-call.js create mode 100644 tests/node_compat/test/parallel/test-timers-zero-timeout.js create mode 100644 tests/node_compat/test/parallel/test-tty-stdin-end.js create mode 100644 tests/node_compat/test/parallel/test-ttywrap-invalid-fd.js create mode 100644 tests/node_compat/test/parallel/test-url-domain-ascii-unicode.js create mode 100644 tests/node_compat/test/parallel/test-url-fileurltopath.js create mode 100644 tests/node_compat/test/parallel/test-url-format-invalid-input.js create mode 100644 tests/node_compat/test/parallel/test-url-format-whatwg.js create mode 100644 tests/node_compat/test/parallel/test-url-format.js create mode 100644 tests/node_compat/test/parallel/test-url-parse-invalid-input.js create mode 100644 tests/node_compat/test/parallel/test-url-parse-query.js create mode 100644 tests/node_compat/test/parallel/test-url-pathtofileurl.js create mode 100644 tests/node_compat/test/parallel/test-url-relative.js create mode 100644 tests/node_compat/test/parallel/test-url-urltooptions.js create mode 100644 tests/node_compat/test/parallel/test-util-deprecate-invalid-code.js create mode 100644 tests/node_compat/test/parallel/test-util-deprecate.js create mode 100644 tests/node_compat/test/parallel/test-util-format.js create mode 100644 tests/node_compat/test/parallel/test-util-inherits.js create mode 100644 tests/node_compat/test/parallel/test-util-inspect-long-running.js create mode 100644 tests/node_compat/test/parallel/test-util-inspect-namespace.js create mode 100644 tests/node_compat/test/parallel/test-util-inspect-proxy.js create mode 100644 tests/node_compat/test/parallel/test-util-inspect.js create mode 100644 tests/node_compat/test/parallel/test-util-isDeepStrictEqual.js create mode 100644 tests/node_compat/test/parallel/test-util-promisify.js create mode 100644 tests/node_compat/test/parallel/test-util-types-exists.js create mode 100644 tests/node_compat/test/parallel/test-util-types.js create mode 100644 tests/node_compat/test/parallel/test-util.js create mode 100644 tests/node_compat/test/parallel/test-vm-new-script-this-context.js create mode 100644 tests/node_compat/test/parallel/test-vm-static-this.js create mode 100644 tests/node_compat/test/parallel/test-webcrypto-sign-verify.js create mode 100644 tests/node_compat/test/parallel/test-whatwg-encoding-custom-api-basics.js create mode 100644 tests/node_compat/test/parallel/test-whatwg-encoding-custom-textdecoder-ignorebom.js create mode 100644 tests/node_compat/test/parallel/test-whatwg-encoding-custom-textdecoder-streaming.js create mode 100644 tests/node_compat/test/parallel/test-whatwg-events-add-event-listener-options-passive.js create mode 100644 tests/node_compat/test/parallel/test-whatwg-events-add-event-listener-options-signal.js create mode 100644 tests/node_compat/test/parallel/test-whatwg-events-customevent.js create mode 100644 tests/node_compat/test/parallel/test-whatwg-url-custom-deepequal.js create mode 100644 tests/node_compat/test/parallel/test-whatwg-url-custom-global.js create mode 100644 tests/node_compat/test/parallel/test-whatwg-url-custom-href-side-effect.js create mode 100644 tests/node_compat/test/parallel/test-whatwg-url-custom-tostringtag.js create mode 100644 tests/node_compat/test/parallel/test-whatwg-url-override-hostname.js create mode 100644 tests/node_compat/test/parallel/test-whatwg-url-properties.js create mode 100644 tests/node_compat/test/parallel/test-zlib-close-after-error.js create mode 100644 tests/node_compat/test/parallel/test-zlib-close-after-write.js create mode 100644 tests/node_compat/test/parallel/test-zlib-convenience-methods.js create mode 100644 tests/node_compat/test/parallel/test-zlib-deflate-raw-inherits.js create mode 100644 tests/node_compat/test/parallel/test-zlib-destroy-pipe.js create mode 100644 tests/node_compat/test/parallel/test-zlib-empty-buffer.js create mode 100644 tests/node_compat/test/parallel/test-zlib-from-string.js create mode 100644 tests/node_compat/test/parallel/test-zlib-invalid-input.js create mode 100644 tests/node_compat/test/parallel/test-zlib-no-stream.js create mode 100644 tests/node_compat/test/parallel/test-zlib-random-byte-pipes.js create mode 100644 tests/node_compat/test/parallel/test-zlib-sync-no-event.js create mode 100644 tests/node_compat/test/parallel/test-zlib-truncated.js create mode 100644 tests/node_compat/test/parallel/test-zlib-unzip-one-byte-chunks.js create mode 100644 tests/node_compat/test/parallel/test-zlib-write-after-end.js create mode 100644 tests/node_compat/test/parallel/test-zlib-write-after-flush.js create mode 100644 tests/node_compat/test/parallel/test-zlib-zero-byte.js create mode 100644 tests/node_compat/test/parallel/test-zlib-zero-windowBits.js create mode 100644 tests/node_compat/test/pseudo-tty/console-dumb-tty.js create mode 100644 tests/node_compat/test/pseudo-tty/console_colors.js create mode 100644 tests/node_compat/test/pseudo-tty/no_dropped_stdio.js create mode 100644 tests/node_compat/test/pseudo-tty/no_interleaved_stdio.js create mode 100644 tests/node_compat/test/pseudo-tty/package.json create mode 100644 tests/node_compat/test/pseudo-tty/test-tty-color-support-warning-2.js create mode 100644 tests/node_compat/test/pseudo-tty/test-tty-color-support-warning.js create mode 100644 tests/node_compat/test/pseudo-tty/test-tty-stdin-end.js create mode 100644 tests/node_compat/test/pseudo-tty/test-tty-stdout-end.js create mode 100644 tests/node_compat/test/pummel/package.json create mode 100644 tests/node_compat/test/sequential/package.json create mode 100644 tests/node_compat/test/sequential/test-child-process-exit.js create mode 100644 tests/testdata/allow_run_allowlist_resolution.ts create mode 100644 tests/testdata/allow_run_allowlist_resolution.ts.out create mode 100644 tests/testdata/assets/DenoWinRunner.cs create mode 100644 tests/testdata/assets/DenoWinRunner.ps1 create mode 100644 tests/testdata/assets/deno_dom_0.1.3-alpha2.wasm create mode 100644 tests/testdata/assets/fixture.json create mode 100644 tests/testdata/assets/hello.txt create mode 100644 tests/testdata/assets/lock_target.txt create mode 100644 tests/testdata/assets/unreachable.wasm create mode 100644 tests/testdata/bench/allow_all.out create mode 100644 tests/testdata/bench/allow_all.ts create mode 100644 tests/testdata/bench/allow_none.out create mode 100644 tests/testdata/bench/allow_none.ts create mode 100644 tests/testdata/bench/before_unload_prevent_default.out create mode 100644 tests/testdata/bench/before_unload_prevent_default.ts create mode 100644 tests/testdata/bench/bench_formatting.out create mode 100644 tests/testdata/bench/bench_formatting.ts create mode 100644 tests/testdata/bench/check_local_by_default.out create mode 100644 tests/testdata/bench/check_local_by_default.ts create mode 100644 tests/testdata/bench/check_local_by_default2.out create mode 100644 tests/testdata/bench/check_local_by_default2.ts create mode 100644 tests/testdata/bench/clear_timeout.out create mode 100644 tests/testdata/bench/clear_timeout.ts create mode 100644 tests/testdata/bench/collect.out create mode 100644 tests/testdata/bench/collect/bench.ts create mode 100644 tests/testdata/bench/collect/deno.jsonc create mode 100644 tests/testdata/bench/collect/deno.malformed.jsonc create mode 100644 tests/testdata/bench/collect/deno2.jsonc create mode 100644 tests/testdata/bench/collect/ignore/bench.ts create mode 100644 tests/testdata/bench/collect/include/2_bench.ts create mode 100644 tests/testdata/bench/collect/include/bench.ts create mode 100644 tests/testdata/bench/collect2.out create mode 100644 tests/testdata/bench/collect_with_malformed_config.out create mode 100644 tests/testdata/bench/exit_sanitizer.out create mode 100644 tests/testdata/bench/exit_sanitizer.ts create mode 100644 tests/testdata/bench/explicit_start_and_end.out create mode 100644 tests/testdata/bench/explicit_start_and_end.ts create mode 100644 tests/testdata/bench/explicit_start_and_end_low_precision.out create mode 100644 tests/testdata/bench/explicit_start_and_end_low_precision.ts create mode 100644 tests/testdata/bench/fail.out create mode 100644 tests/testdata/bench/fail.ts create mode 100644 tests/testdata/bench/file_protocol.out create mode 100644 tests/testdata/bench/file_protocol.ts create mode 100644 tests/testdata/bench/filter.out create mode 100644 tests/testdata/bench/filter/a_bench.ts create mode 100644 tests/testdata/bench/filter/b_bench.ts create mode 100644 tests/testdata/bench/filter/c_bench.ts create mode 100644 tests/testdata/bench/finally_timeout.out create mode 100644 tests/testdata/bench/finally_timeout.ts create mode 100644 tests/testdata/bench/group_baseline.out create mode 100644 tests/testdata/bench/group_baseline.ts create mode 100644 tests/testdata/bench/ignore.out create mode 100644 tests/testdata/bench/ignore.ts create mode 100644 tests/testdata/bench/ignore_permissions.out create mode 100644 tests/testdata/bench/ignore_permissions.ts create mode 100644 tests/testdata/bench/interval.out create mode 100644 tests/testdata/bench/interval.ts create mode 100644 tests/testdata/bench/load_unload.out create mode 100644 tests/testdata/bench/load_unload.ts create mode 100644 tests/testdata/bench/meta.out create mode 100644 tests/testdata/bench/meta.ts create mode 100644 tests/testdata/bench/multifile_summary.out create mode 100644 tests/testdata/bench/multiple_group.ts create mode 100644 tests/testdata/bench/no_check.out create mode 100644 tests/testdata/bench/no_check.ts create mode 100644 tests/testdata/bench/no_color.ts create mode 100644 tests/testdata/bench/no_prompt_by_default.out create mode 100644 tests/testdata/bench/no_prompt_by_default.ts create mode 100644 tests/testdata/bench/no_prompt_with_denied_perms.out create mode 100644 tests/testdata/bench/no_prompt_with_denied_perms.ts create mode 100644 tests/testdata/bench/no_run.out create mode 100644 tests/testdata/bench/no_run.ts create mode 100644 tests/testdata/bench/only.out create mode 100644 tests/testdata/bench/only.ts create mode 100644 tests/testdata/bench/overloads.out create mode 100644 tests/testdata/bench/overloads.ts create mode 100644 tests/testdata/bench/pass.json.out create mode 100644 tests/testdata/bench/pass.out create mode 100644 tests/testdata/bench/pass.ts create mode 100644 tests/testdata/bench/quiet.out create mode 100644 tests/testdata/bench/quiet.ts create mode 100644 tests/testdata/bench/recursive_permissions_pledge.js create mode 100644 tests/testdata/bench/unhandled_rejection.out create mode 100644 tests/testdata/bench/unhandled_rejection.ts create mode 100644 tests/testdata/bench/unresolved_promise.out create mode 100644 tests/testdata/bench/unresolved_promise.ts create mode 100644 tests/testdata/benches/response_string_perf.js create mode 100644 tests/testdata/benches/text_decoder_perf.js create mode 100644 tests/testdata/benches/text_encoder_into_perf.js create mode 100644 tests/testdata/benches/text_encoder_perf.js create mode 100644 tests/testdata/bundle/bare_imports/error_with_bare_import.ts create mode 100644 tests/testdata/bundle/bare_imports/error_with_bare_import.ts.out create mode 100644 tests/testdata/bundle/bundle.test.out create mode 100644 tests/testdata/bundle/check_local_by_default/no_errors.out create mode 100644 tests/testdata/bundle/check_local_by_default/no_errors.ts create mode 100644 tests/testdata/bundle/check_local_by_default/type_error.out create mode 100644 tests/testdata/bundle/check_local_by_default/type_error.ts create mode 100644 tests/testdata/bundle/decorators/ts_decorators.out create mode 100644 tests/testdata/bundle/decorators/ts_decorators.ts create mode 100644 tests/testdata/bundle/dynamic_import.ts create mode 100644 tests/testdata/bundle/file_extensions/js_without_extension.out create mode 100644 tests/testdata/bundle/file_extensions/ts_without_extension.out create mode 100644 tests/testdata/bundle/file_tests-fixture01.ts create mode 100644 tests/testdata/bundle/file_tests-fixture02.ts create mode 100644 tests/testdata/bundle/file_tests-fixture03.ts create mode 100644 tests/testdata/bundle/file_tests-fixture04.ts create mode 100644 tests/testdata/bundle/file_tests-fixture05.ts create mode 100644 tests/testdata/bundle/file_tests-fixture06.ts create mode 100644 tests/testdata/bundle/file_tests-fixture07.ts create mode 100644 tests/testdata/bundle/file_tests-fixture08.ts create mode 100644 tests/testdata/bundle/file_tests-fixture09.ts create mode 100644 tests/testdata/bundle/file_tests-fixture10.ts create mode 100644 tests/testdata/bundle/file_tests-fixture11.ts create mode 100644 tests/testdata/bundle/file_tests-fixture12.ts create mode 100644 tests/testdata/bundle/file_tests-fixture13.ts create mode 100644 tests/testdata/bundle/file_tests-fixture14.ts create mode 100644 tests/testdata/bundle/file_tests-fixture15.ts create mode 100644 tests/testdata/bundle/file_tests-fixture16.ts create mode 100644 tests/testdata/bundle/file_tests-fixture16_2.ts create mode 100644 tests/testdata/bundle/file_tests-subdir-a.ts create mode 100644 tests/testdata/bundle/file_tests-subdir-b.ts create mode 100644 tests/testdata/bundle/file_tests-subdir-c.ts create mode 100644 tests/testdata/bundle/file_tests-subdir-d.ts create mode 100644 tests/testdata/bundle/file_tests-subdir-e.ts create mode 100644 tests/testdata/bundle/file_tests-subdir-f.ts create mode 100644 tests/testdata/bundle/file_tests-subdir-g.ts create mode 100644 tests/testdata/bundle/file_tests-subdir-h.ts create mode 100644 tests/testdata/bundle/file_tests-subdir-i.ts create mode 100644 tests/testdata/bundle/file_tests-subdir-j.ts create mode 100644 tests/testdata/bundle/file_tests-subdir-k.ts create mode 100644 tests/testdata/bundle/file_tests-subdir-l.ts create mode 100644 tests/testdata/bundle/file_tests-subdir-m.ts create mode 100644 tests/testdata/bundle/file_tests-subdir-n.ts create mode 100644 tests/testdata/bundle/file_tests-subdir-o.ts create mode 100644 tests/testdata/bundle/file_tests-subdir-p.ts create mode 100644 tests/testdata/bundle/file_tests-subdir-q.ts create mode 100644 tests/testdata/bundle/fixture01.out create mode 100644 tests/testdata/bundle/fixture02.out create mode 100644 tests/testdata/bundle/fixture03.out create mode 100644 tests/testdata/bundle/fixture04.out create mode 100644 tests/testdata/bundle/fixture05.out create mode 100644 tests/testdata/bundle/fixture06.out create mode 100644 tests/testdata/bundle/fixture07.out create mode 100644 tests/testdata/bundle/fixture08.out create mode 100644 tests/testdata/bundle/fixture09.out create mode 100644 tests/testdata/bundle/fixture10.out create mode 100644 tests/testdata/bundle/fixture11.out create mode 100644 tests/testdata/bundle/fixture12.out create mode 100644 tests/testdata/bundle/fixture13.out create mode 100644 tests/testdata/bundle/fixture14.out create mode 100644 tests/testdata/bundle/fixture15.out create mode 100644 tests/testdata/bundle/fixture16.out create mode 100644 tests/testdata/bundle/https_deno.land-x-lib-a.ts create mode 100644 tests/testdata/bundle/https_deno.land-x-lib-b.js create mode 100644 tests/testdata/bundle/https_deno.land-x-lib-c.d.ts create mode 100644 tests/testdata/bundle/https_deno.land-x-lib-c.js create mode 100644 tests/testdata/bundle/https_deno.land-x-lib-mod.d.ts create mode 100644 tests/testdata/bundle/https_deno.land-x-lib-mod.js create mode 100644 tests/testdata/bundle/ignore_directives.test.out create mode 100644 tests/testdata/bundle/import_map/import_map.json create mode 100644 tests/testdata/bundle/import_map/main.ts create mode 100644 tests/testdata/bundle/jsx.out create mode 100644 tests/testdata/bundle/lockfile/check_error.json create mode 100644 tests/testdata/bundle/lockfile/check_error.out create mode 100644 tests/testdata/bundle/shebang_file.bundle.out create mode 100644 tests/testdata/cache/036_import_map_fetch.out create mode 100644 tests/testdata/cache/037_fetch_multiple.out create mode 100644 tests/testdata/cache/095_cache_with_bare_import.ts create mode 100644 tests/testdata/cache/095_cache_with_bare_import.ts.out create mode 100644 tests/testdata/cache/cache_extensionless.out create mode 100644 tests/testdata/cache/cache_random_extension.out create mode 100644 tests/testdata/cache/check_local_by_default.out create mode 100644 tests/testdata/cache/check_local_by_default.ts create mode 100644 tests/testdata/cache/check_local_by_default2.out create mode 100644 tests/testdata/cache/check_local_by_default2.ts create mode 100644 tests/testdata/cache/ignore_require.js create mode 100644 tests/testdata/cache/json_import/main.ts create mode 100644 tests/testdata/cache/json_import/test.json create mode 100644 tests/testdata/cache/performance_stats.out create mode 100644 tests/testdata/cache/redirect_cache.out create mode 100644 tests/testdata/cat.ts create mode 100644 tests/testdata/cert/cafile_info.ts create mode 100644 tests/testdata/cert/cafile_info.ts.out create mode 100644 tests/testdata/cert/cafile_ts_fetch.ts create mode 100644 tests/testdata/cert/cafile_ts_fetch.ts.out create mode 100644 tests/testdata/cert/cafile_ts_fetch_unsafe_ssl.ts.out create mode 100644 tests/testdata/cert/cafile_url_imports.ts create mode 100644 tests/testdata/cert/cafile_url_imports.ts.out create mode 100644 tests/testdata/cert/cafile_url_imports_unsafe_ssl.ts.out create mode 100644 tests/testdata/cert/deno_land_unsafe_ssl.ts create mode 100644 tests/testdata/cert/deno_land_unsafe_ssl.ts.out create mode 100644 tests/testdata/cert/ip_address_unsafe_ssl.ts create mode 100644 tests/testdata/cert/ip_address_unsafe_ssl.ts.out create mode 100644 tests/testdata/cert/listen_tls_alpn.ts create mode 100644 tests/testdata/cert/listen_tls_alpn_fail.ts create mode 100644 tests/testdata/cert/localhost_unsafe_ssl.ts.out create mode 100644 tests/testdata/check/all/check_all.out create mode 100644 tests/testdata/check/all/check_all.ts create mode 100644 tests/testdata/check/broadcast_channel.ts create mode 100644 tests/testdata/check/cache_config_on_off/deno.json create mode 100644 tests/testdata/check/cache_config_on_off/main.ts create mode 100644 tests/testdata/check/declaration_header_file_with_no_exports.ts create mode 100644 tests/testdata/check/declaration_header_file_with_no_exports_js.d.ts create mode 100644 tests/testdata/check/declaration_header_file_with_no_exports_js.js create mode 100644 tests/testdata/check/deno_not_found/main.out create mode 100644 tests/testdata/check/deno_not_found/main.ts create mode 100644 tests/testdata/check/dts/check_dts.d.ts create mode 100644 tests/testdata/check/dts/check_dts.out create mode 100644 tests/testdata/check/exclude_option/deno.exclude_dir.json create mode 100644 tests/testdata/check/exclude_option/deno.exclude_glob.json create mode 100644 tests/testdata/check/exclude_option/deno.json create mode 100644 tests/testdata/check/exclude_option/exclude_option.ts.error.out create mode 100644 tests/testdata/check/exclude_option/ignored/index.ts create mode 100644 tests/testdata/check/exclude_option/index.ts create mode 100644 tests/testdata/check/excluded_file_specified/check.out create mode 100644 tests/testdata/check/excluded_file_specified/deno.json create mode 100644 tests/testdata/check/excluded_file_specified/lib/types.d.ts create mode 100644 tests/testdata/check/export_equals_declaration_file/main.ts create mode 100644 tests/testdata/check/export_equals_declaration_file/other.d.ts create mode 100644 tests/testdata/check/export_equals_declaration_file/other.js create mode 100644 tests/testdata/check/jsx_not_checked/main.jsx create mode 100644 tests/testdata/check/jsx_not_checked/main.out create mode 100644 tests/testdata/check/jsx_not_checked/other.ts create mode 100644 tests/testdata/check/jsximportsource_importmap_config/deno.json create mode 100644 tests/testdata/check/jsximportsource_importmap_config/import_map.json create mode 100644 tests/testdata/check/jsximportsource_importmap_config/jsx_runtime.ts create mode 100644 tests/testdata/check/jsximportsource_importmap_config/main.bundle.js create mode 100644 tests/testdata/check/jsximportsource_importmap_config/main.tsx create mode 100644 tests/testdata/check/module_detection_force.ts create mode 100644 tests/testdata/check/module_detection_force/import.ts create mode 100644 tests/testdata/check/module_detection_force/main.ts create mode 100644 tests/testdata/check/no_error_truncation/deno.json create mode 100644 tests/testdata/check/no_error_truncation/main.out create mode 100644 tests/testdata/check/no_error_truncation/main.ts create mode 100644 tests/testdata/check/node_builtin_modules/mod.js create mode 100644 tests/testdata/check/node_builtin_modules/mod.js.out create mode 100644 tests/testdata/check/node_builtin_modules/mod.ts create mode 100644 tests/testdata/check/node_builtin_modules/mod.ts.out create mode 100644 tests/testdata/check/npm_install_diagnostics/main.out create mode 100644 tests/testdata/check/npm_install_diagnostics/main.ts create mode 100644 tests/testdata/check/response_json.ts create mode 100644 tests/testdata/check/types_dts/deno.json create mode 100644 tests/testdata/check/types_dts/main.out create mode 100644 tests/testdata/check/types_dts/main.ts create mode 100644 tests/testdata/check/types_dts/types.d.ts create mode 100644 tests/testdata/commonjs/data.json create mode 100644 tests/testdata/commonjs/example.js create mode 100644 tests/testdata/commonjs/node_modules/colorette/index.cjs create mode 100644 tests/testdata/commonjs/node_modules/colorette/index.js create mode 100644 tests/testdata/commonjs/node_modules/colorette/package.json create mode 100644 tests/testdata/commonjs/node_modules/imports_exports/import_export.js create mode 100644 tests/testdata/commonjs/node_modules/imports_exports/import_polyfill.js create mode 100644 tests/testdata/commonjs/node_modules/imports_exports/package.json create mode 100644 tests/testdata/commonjs/node_modules/imports_exports/require_export.cjs create mode 100644 tests/testdata/commonjs/node_modules/imports_exports/require_polyfill.js create mode 100644 tests/testdata/commonjs/node_modules/left-pad/README.md create mode 100644 tests/testdata/commonjs/node_modules/left-pad/index.js create mode 100644 tests/testdata/commonjs/node_modules/left-pad/package.json create mode 100644 tests/testdata/commonjs/package.json create mode 100644 tests/testdata/compile/args.ts create mode 100644 tests/testdata/compile/check_local_by_default.ts create mode 100644 tests/testdata/compile/check_local_by_default2.ts create mode 100644 tests/testdata/compile/dynamic_imports/import1.ts create mode 100644 tests/testdata/compile/dynamic_imports/import2.ts create mode 100644 tests/testdata/compile/dynamic_imports/import_path create mode 100644 tests/testdata/compile/dynamic_imports/main.out create mode 100644 tests/testdata/compile/dynamic_imports/main.ts create mode 100644 tests/testdata/compile/dynamic_imports/main_unanalyzable.ts create mode 100644 tests/testdata/compile/dynamic_imports_tmp_lit/main.info.out create mode 100644 tests/testdata/compile/dynamic_imports_tmp_lit/main.js create mode 100644 tests/testdata/compile/dynamic_imports_tmp_lit/other/data.json create mode 100644 tests/testdata/compile/dynamic_imports_tmp_lit/other/sub/data2.json create mode 100644 tests/testdata/compile/dynamic_imports_tmp_lit/sub/a.js create mode 100644 tests/testdata/compile/dynamic_imports_tmp_lit/sub/b.ts create mode 100644 tests/testdata/compile/node_modules_symlink_outside/main.out create mode 100644 tests/testdata/compile/node_modules_symlink_outside/main.ts create mode 100644 tests/testdata/compile/node_modules_symlink_outside/main_compile_file.out create mode 100644 tests/testdata/compile/node_modules_symlink_outside/main_compile_folder.out create mode 100644 tests/testdata/compile/npm_fs/main.out create mode 100644 tests/testdata/compile/npm_fs/main.ts create mode 100644 tests/testdata/compile/standalone_error.ts create mode 100644 tests/testdata/compile/standalone_error_module_with_imports_1.ts create mode 100644 tests/testdata/compile/standalone_error_module_with_imports_2.ts create mode 100644 tests/testdata/compile/standalone_follow_redirects.ts create mode 100644 tests/testdata/compile/standalone_follow_redirects_2.js create mode 100644 tests/testdata/compile/standalone_import_datauri.ts create mode 100644 tests/testdata/compile/standalone_import_map.json create mode 100644 tests/testdata/compile/standalone_import_map.ts create mode 100644 tests/testdata/compile/standalone_import_map_config.json create mode 100644 tests/testdata/compile/standalone_runtime_flags.ts create mode 100644 tests/testdata/compile/unstable_features.ts create mode 100644 tests/testdata/compile/vfs_implicit_read_permission/main.out create mode 100644 tests/testdata/compile/vfs_implicit_read_permission/main.ts create mode 100644 tests/testdata/compile/workers/basic.out create mode 100644 tests/testdata/compile/workers/basic.ts create mode 100644 tests/testdata/compile/workers/not_in_module_map.ts create mode 100644 tests/testdata/compile/workers/worker.ts create mode 100644 tests/testdata/coverage/branch.ts create mode 100644 tests/testdata/coverage/branch_expected.lcov create mode 100644 tests/testdata/coverage/branch_expected.out create mode 100644 tests/testdata/coverage/branch_test.ts create mode 100644 tests/testdata/coverage/complex.ts create mode 100644 tests/testdata/coverage/complex_expected.lcov create mode 100644 tests/testdata/coverage/complex_expected.out create mode 100644 tests/testdata/coverage/complex_test.ts create mode 100644 tests/testdata/coverage/doesnt_exist.out create mode 100644 tests/testdata/coverage/final_blankline.js create mode 100644 tests/testdata/coverage/final_blankline_expected.lcov create mode 100644 tests/testdata/coverage/final_blankline_expected.out create mode 100644 tests/testdata/coverage/final_blankline_test.js create mode 100644 tests/testdata/coverage/invalid_cache/mod.test.ts create mode 100644 tests/testdata/coverage/invalid_cache/mod_after.ts create mode 100644 tests/testdata/coverage/invalid_cache/mod_before.ts create mode 100644 tests/testdata/coverage/multifile/a_test.js create mode 100644 tests/testdata/coverage/multifile/b_test.js create mode 100644 tests/testdata/coverage/multifile/expected.lcov create mode 100644 tests/testdata/coverage/multifile/expected.out create mode 100644 tests/testdata/coverage/multifile/mod.js create mode 100644 tests/testdata/coverage/multisource/bar.ts create mode 100644 tests/testdata/coverage/multisource/baz/quux.ts create mode 100644 tests/testdata/coverage/multisource/baz/qux.ts create mode 100644 tests/testdata/coverage/multisource/foo.ts create mode 100644 tests/testdata/coverage/multisource/test.ts create mode 100644 tests/testdata/coverage/no_internal_code_test.ts create mode 100644 tests/testdata/coverage/no_internal_node_code_test.ts create mode 100644 tests/testdata/coverage/no_npm_coverage/expected.out create mode 100644 tests/testdata/coverage/no_npm_coverage/no_npm_coverage.ts create mode 100644 tests/testdata/coverage/no_npm_coverage/no_npm_coverage_test.ts create mode 100644 tests/testdata/coverage/no_snaps_included/__snapshots__/no_snaps_included_test.ts.snap create mode 100644 tests/testdata/coverage/no_snaps_included/expected.out create mode 100644 tests/testdata/coverage/no_snaps_included/no_snaps_included.ts create mode 100644 tests/testdata/coverage/no_snaps_included/no_snaps_included_test.ts create mode 100644 tests/testdata/coverage/no_tests_included/expected.out create mode 100644 tests/testdata/coverage/no_tests_included/foo.test.js create mode 100644 tests/testdata/coverage/no_tests_included/foo.test.mts create mode 100644 tests/testdata/coverage/no_tests_included/foo.test.ts create mode 100644 tests/testdata/coverage/no_tests_included/foo.ts create mode 100644 tests/testdata/coverage/no_transpiled_lines/expected.lcov create mode 100644 tests/testdata/coverage/no_transpiled_lines/expected.out create mode 100644 tests/testdata/coverage/no_transpiled_lines/index.ts create mode 100644 tests/testdata/coverage/no_transpiled_lines/interface.ts create mode 100644 tests/testdata/coverage/no_transpiled_lines/repro_test.ts create mode 100644 tests/testdata/doc/060_deno_doc_displays_all_overloads_in_details_view.ts create mode 100644 tests/testdata/doc/060_deno_doc_displays_all_overloads_in_details_view.ts.out create mode 100644 tests/testdata/doc/deno_doc.ts create mode 100644 tests/testdata/doc/deno_doc2.ts create mode 100644 tests/testdata/doc/deno_doc_builtin.out create mode 100644 tests/testdata/doc/import_map.json create mode 100644 tests/testdata/doc/invalid_url.out create mode 100644 tests/testdata/doc/lint_success.out create mode 100644 tests/testdata/doc/lint_success.ts create mode 100644 tests/testdata/doc/lint_success_html.out create mode 100644 tests/testdata/doc/lint_success_json.out create mode 100644 tests/testdata/doc/module/fun.js create mode 100644 tests/testdata/doc/referenced_private_types.out create mode 100644 tests/testdata/doc/referenced_private_types.ts create mode 100644 tests/testdata/doc/referenced_private_types_fixed.out create mode 100644 tests/testdata/doc/referenced_private_types_fixed.ts create mode 100644 tests/testdata/doc/referenced_private_types_lint.out create mode 100644 tests/testdata/doc/types_header.out create mode 100644 tests/testdata/doc/types_header.ts create mode 100644 tests/testdata/doc/types_hint.out create mode 100644 tests/testdata/doc/types_hint.ts create mode 100644 tests/testdata/doc/types_ref.js create mode 100644 tests/testdata/doc/types_ref.out create mode 100644 tests/testdata/doc/use_import_map.js create mode 100644 tests/testdata/doc/use_import_map.out create mode 100644 tests/testdata/dynamic_import/b.js create mode 100644 tests/testdata/dynamic_import/c.js create mode 100644 tests/testdata/dynamic_import/empty_1.ts create mode 100644 tests/testdata/dynamic_import/empty_2.ts create mode 100644 tests/testdata/dynamic_import/permissions_blob_local.ts create mode 100644 tests/testdata/dynamic_import/permissions_blob_local.ts.out create mode 100644 tests/testdata/dynamic_import/permissions_blob_remote.ts create mode 100644 tests/testdata/dynamic_import/permissions_blob_remote.ts.out create mode 100644 tests/testdata/dynamic_import/permissions_data_local.ts create mode 100644 tests/testdata/dynamic_import/permissions_data_local.ts.out create mode 100644 tests/testdata/dynamic_import/permissions_data_remote.ts create mode 100644 tests/testdata/dynamic_import/permissions_data_remote.ts.out create mode 100644 tests/testdata/dynamic_import/permissions_remote_remote.ts create mode 100644 tests/testdata/dynamic_import/permissions_remote_remote.ts.out create mode 100644 tests/testdata/dynamic_import/static_analysis_no_permissions.ts create mode 100644 tests/testdata/dynamic_import/static_analysis_no_permissions.ts.out create mode 100644 tests/testdata/dynamic_import/static_remote.ts create mode 100644 tests/testdata/echo.ts create mode 100644 tests/testdata/echo_server.ts create mode 100644 tests/testdata/encoding/utf-16be.ts create mode 100644 tests/testdata/encoding/utf-16le.ts create mode 100644 tests/testdata/encoding/utf-8.ts create mode 100644 tests/testdata/encoding/windows-1255 create mode 100644 tests/testdata/env create mode 100644 tests/testdata/error_cause_recursive_aggregate.ts create mode 100644 tests/testdata/error_cause_recursive_aggregate.ts.out create mode 100644 tests/testdata/error_cause_recursive_tail.ts create mode 100644 tests/testdata/error_cause_recursive_tail.ts.out create mode 100644 tests/testdata/eval/check_local_by_default.out create mode 100644 tests/testdata/eval/check_local_by_default2.out create mode 100644 tests/testdata/eval/check_local_by_default2.ts create mode 100644 tests/testdata/eval/dyn_import_eval.out create mode 100644 tests/testdata/eval/env_file_missing.out create mode 100644 tests/testdata/file_extensions/js_without_extension create mode 100644 tests/testdata/file_extensions/js_without_extension.out create mode 100644 tests/testdata/file_extensions/ts_with_extension.out create mode 100644 tests/testdata/file_extensions/ts_with_extension.ts create mode 100644 tests/testdata/file_extensions/ts_with_js_extension.js create mode 100644 tests/testdata/file_extensions/ts_with_js_extension.out create mode 100644 tests/testdata/file_extensions/ts_without_extension create mode 100644 tests/testdata/file_extensions/ts_without_extension.out create mode 100644 tests/testdata/fmt/badly_formatted.ipynb create mode 100644 tests/testdata/fmt/badly_formatted.json create mode 100644 tests/testdata/fmt/badly_formatted.md create mode 100644 tests/testdata/fmt/badly_formatted.mjs create mode 100644 tests/testdata/fmt/badly_formatted_fixed.ipynb create mode 100644 tests/testdata/fmt/badly_formatted_fixed.js create mode 100644 tests/testdata/fmt/badly_formatted_fixed.json create mode 100644 tests/testdata/fmt/badly_formatted_fixed.md create mode 100644 tests/testdata/fmt/deno.glob.json create mode 100644 tests/testdata/fmt/deno.malformed.jsonc create mode 100644 tests/testdata/fmt/deno.malformed2.jsonc create mode 100644 tests/testdata/fmt/expected_fmt_check_formatted_files.out create mode 100644 tests/testdata/fmt/expected_fmt_check_ignore.out create mode 100644 tests/testdata/fmt/expected_fmt_check_verbose_formatted_files.out create mode 100644 tests/testdata/fmt/fmt_check_parse_error.out create mode 100644 tests/testdata/fmt/fmt_with_config.out create mode 100644 tests/testdata/fmt/fmt_with_config_and_flags.out create mode 100644 tests/testdata/fmt/fmt_with_config_default.out create mode 100644 tests/testdata/fmt/fmt_with_deprecated_config.out create mode 100644 tests/testdata/fmt/fmt_with_malformed_config.out create mode 100644 tests/testdata/fmt/fmt_with_malformed_config2.out create mode 100644 tests/testdata/fmt/glob/data/tes.ts create mode 100644 tests/testdata/fmt/glob/data/test1.js create mode 100644 tests/testdata/fmt/glob/data/test1.ts create mode 100644 tests/testdata/fmt/glob/data/test12.ts create mode 100644 tests/testdata/fmt/glob/nested/fizz/bar.ts create mode 100644 tests/testdata/fmt/glob/nested/fizz/bazz.ts create mode 100644 tests/testdata/fmt/glob/nested/fizz/fizz.ts create mode 100644 tests/testdata/fmt/glob/nested/fizz/foo.ts create mode 100644 tests/testdata/fmt/glob/nested/foo/bar.ts create mode 100644 tests/testdata/fmt/glob/nested/foo/bazz.ts create mode 100644 tests/testdata/fmt/glob/nested/foo/fizz.ts create mode 100644 tests/testdata/fmt/glob/nested/foo/foo.ts create mode 100644 tests/testdata/fmt/glob/pages/[id].ts create mode 100644 tests/testdata/fmt/invalid_data.json create mode 100644 tests/testdata/fmt/invalid_data.out create mode 100644 tests/testdata/fmt/parse_error/parse_error.ts create mode 100644 tests/testdata/fmt/regular/formatted1.js create mode 100644 tests/testdata/fmt/regular/formatted2.ts create mode 100644 tests/testdata/fmt/regular/formatted3.markdown create mode 100644 tests/testdata/fmt/regular/formatted4.jsonc create mode 100644 tests/testdata/fmt/with_config/deno.deprecated.jsonc create mode 100644 tests/testdata/fmt/with_config/deno.jsonc create mode 100644 tests/testdata/fmt/with_config/subdir/a.ts create mode 100644 tests/testdata/fmt/with_config/subdir/b.ts create mode 100644 tests/testdata/fmt/with_config/subdir/c.md create mode 100644 tests/testdata/import_attributes/data.json create mode 100644 tests/testdata/import_attributes/dynamic_error.out create mode 100644 tests/testdata/import_attributes/dynamic_error.ts create mode 100644 tests/testdata/import_attributes/dynamic_import.out create mode 100644 tests/testdata/import_attributes/dynamic_import.ts create mode 100644 tests/testdata/import_attributes/json_with_shebang.json create mode 100644 tests/testdata/import_attributes/json_with_shebang.ts create mode 100644 tests/testdata/import_attributes/json_with_shebang.ts.out create mode 100644 tests/testdata/import_attributes/static_error.out create mode 100644 tests/testdata/import_attributes/static_error.ts create mode 100644 tests/testdata/import_attributes/static_export.out create mode 100644 tests/testdata/import_attributes/static_export.ts create mode 100644 tests/testdata/import_attributes/static_import.out create mode 100644 tests/testdata/import_attributes/static_import.ts create mode 100644 tests/testdata/import_attributes/static_reexport.ts create mode 100644 tests/testdata/import_attributes/type_check.out create mode 100644 tests/testdata/import_attributes/type_check.ts create mode 100644 tests/testdata/import_maps/config.json create mode 100644 tests/testdata/import_maps/import_map.json create mode 100644 tests/testdata/import_maps/import_map_invalid.json create mode 100644 tests/testdata/import_maps/import_map_remote.json create mode 100644 tests/testdata/import_maps/lodash/lodash.ts create mode 100644 tests/testdata/import_maps/lodash/other_file.ts create mode 100644 tests/testdata/import_maps/moment/moment.ts create mode 100644 tests/testdata/import_maps/moment/other_file.ts create mode 100644 tests/testdata/import_maps/print_hello.ts create mode 100644 tests/testdata/import_maps/scope/scoped.ts create mode 100644 tests/testdata/import_maps/scoped_moment.ts create mode 100644 tests/testdata/import_maps/test.ts create mode 100644 tests/testdata/import_maps/test_remote.ts create mode 100644 tests/testdata/import_maps/vue.ts create mode 100644 tests/testdata/info/031_info_ts_error.out create mode 100644 tests/testdata/info/031_info_ts_error.ts create mode 100644 tests/testdata/info/041_info_flag.out create mode 100644 tests/testdata/info/041_info_flag_location.out create mode 100644 tests/testdata/info/049_info_flag_script_jsx.out create mode 100644 tests/testdata/info/054_info_local_imports.out create mode 100644 tests/testdata/info/065_import_map_info.out create mode 100644 tests/testdata/info/076_info_json_deps_order.out create mode 100644 tests/testdata/info/076_info_json_deps_order.ts create mode 100644 tests/testdata/info/data_null_error/data_null_error.out create mode 100644 tests/testdata/info/data_null_error/mod.ts create mode 100644 tests/testdata/info/data_null_error/types.d.ts create mode 100644 tests/testdata/info/error_009_missing_js_module.js create mode 100644 tests/testdata/info/error_009_missing_js_module.js.out create mode 100644 tests/testdata/info/info_json.out create mode 100644 tests/testdata/info/info_json_location.out create mode 100644 tests/testdata/info/info_missing_module.out create mode 100644 tests/testdata/info/info_recursive_imports_test.out create mode 100644 tests/testdata/info/info_recursive_imports_test.ts create mode 100644 tests/testdata/info/info_type_import.out create mode 100644 tests/testdata/info/info_type_import.ts create mode 100644 tests/testdata/info/json_output/main.out create mode 100644 tests/testdata/info/json_output/main.ts create mode 100644 tests/testdata/info/multiple_imports.out create mode 100644 tests/testdata/info/recursive_imports/A.ts create mode 100644 tests/testdata/info/recursive_imports/B.ts create mode 100644 tests/testdata/info/recursive_imports/C.ts create mode 100644 tests/testdata/info/recursive_imports/common.ts create mode 100644 tests/testdata/info/types_header.out create mode 100644 tests/testdata/info/with_config/deno-override.json create mode 100644 tests/testdata/info/with_config/deno.json create mode 100644 tests/testdata/info/with_config/import_map.json create mode 100644 tests/testdata/info/with_config/test.ts create mode 100644 tests/testdata/info/with_config/with_config.out create mode 100644 tests/testdata/info/with_import_map/deno.json create mode 100644 tests/testdata/info/with_import_map/deno.lock create mode 100644 tests/testdata/info/with_import_map/main.tsx create mode 100644 tests/testdata/info/with_import_map/with_import_map.out create mode 100644 tests/testdata/inspector/bar.js create mode 100644 tests/testdata/inspector/error_with_npm_import.js create mode 100644 tests/testdata/inspector/foo.ts create mode 100644 tests/testdata/inspector/inspect_wait.js create mode 100644 tests/testdata/inspector/inspector1.js create mode 100644 tests/testdata/inspector/inspector2.js create mode 100644 tests/testdata/inspector/inspector3.js create mode 100644 tests/testdata/inspector/inspector4.js create mode 100644 tests/testdata/inspector/inspector_test.js create mode 100644 tests/testdata/inspector/memory.js create mode 100644 tests/testdata/inspector/test.ts create mode 100644 tests/testdata/install/check_local_by_default.ts create mode 100644 tests/testdata/install/check_local_by_default2.ts create mode 100644 tests/testdata/jsr/deps/main.out create mode 100644 tests/testdata/jsr/deps/main.ts create mode 100644 tests/testdata/jsr/deps/main_info.out create mode 100644 tests/testdata/jsr/module_graph/main.out create mode 100644 tests/testdata/jsr/module_graph/main.ts create mode 100644 tests/testdata/jsr/module_graph/main_info.out create mode 100644 tests/testdata/jsr/no_module_graph/main.out create mode 100644 tests/testdata/jsr/no_module_graph/main.ts create mode 100644 tests/testdata/jsr/no_module_graph/main_info.out create mode 100644 tests/testdata/jsr/no_module_graph/multiple.out create mode 100644 tests/testdata/jsr/no_module_graph/multiple.ts create mode 100644 tests/testdata/jsr/registry/@denotest/add/1.0.0/mod.ts create mode 100644 tests/testdata/jsr/registry/@denotest/add/1.0.0_meta.json create mode 100644 tests/testdata/jsr/registry/@denotest/add/meta.json create mode 100644 tests/testdata/jsr/registry/@denotest/deps/1.0.0/mod.ts create mode 100644 tests/testdata/jsr/registry/@denotest/deps/1.0.0_meta.json create mode 100644 tests/testdata/jsr/registry/@denotest/deps/meta.json create mode 100644 tests/testdata/jsr/registry/@denotest/module_graph/1.4.0/mod.ts create mode 100644 tests/testdata/jsr/registry/@denotest/module_graph/1.4.0/other.ts create mode 100644 tests/testdata/jsr/registry/@denotest/module_graph/1.4.0_meta.json create mode 100644 tests/testdata/jsr/registry/@denotest/module_graph/meta.json create mode 100644 tests/testdata/jsr/registry/@denotest/no_module_graph/0.1.0/TestClass.ts create mode 100644 tests/testdata/jsr/registry/@denotest/no_module_graph/0.1.0/mod.ts create mode 100644 tests/testdata/jsr/registry/@denotest/no_module_graph/0.1.0_meta.json create mode 100644 tests/testdata/jsr/registry/@denotest/no_module_graph/0.1.1/TestClass.ts create mode 100644 tests/testdata/jsr/registry/@denotest/no_module_graph/0.1.1/mod.ts create mode 100644 tests/testdata/jsr/registry/@denotest/no_module_graph/0.1.1_meta.json create mode 100644 tests/testdata/jsr/registry/@denotest/no_module_graph/0.2.0/TestClass.ts create mode 100644 tests/testdata/jsr/registry/@denotest/no_module_graph/0.2.0/mod.ts create mode 100644 tests/testdata/jsr/registry/@denotest/no_module_graph/0.2.0_meta.json create mode 100644 tests/testdata/jsr/registry/@denotest/no_module_graph/meta.json create mode 100644 tests/testdata/jsr/registry/@denotest/subset_type_graph/0.1.0/mod.ts create mode 100644 tests/testdata/jsr/registry/@denotest/subset_type_graph/0.1.0_meta.json create mode 100644 tests/testdata/jsr/registry/@denotest/subset_type_graph/meta.json create mode 100644 tests/testdata/jsr/registry/@denotest/subset_type_graph_invalid/0.1.0/mod.ts create mode 100644 tests/testdata/jsr/registry/@denotest/subset_type_graph_invalid/0.1.0_meta.json create mode 100644 tests/testdata/jsr/registry/@denotest/subset_type_graph_invalid/meta.json create mode 100644 tests/testdata/jsr/subset_type_graph/main.check.out create mode 100644 tests/testdata/jsr/subset_type_graph/main.ts create mode 100644 tests/testdata/jsr/version_not_found/main.out create mode 100644 tests/testdata/jsr/version_not_found/main.ts create mode 100644 tests/testdata/jsx/deno-jsx-error.jsonc create mode 100644 tests/testdata/jsx/deno-jsx-import-map.jsonc create mode 100644 tests/testdata/jsx/deno-jsx-precompile.jsonc create mode 100644 tests/testdata/jsx/deno-jsx.json create mode 100644 tests/testdata/jsx/deno-jsx.jsonc create mode 100644 tests/testdata/jsx/deno-jsxdev-import-map.jsonc create mode 100644 tests/testdata/jsx/deno-jsxdev.jsonc create mode 100644 tests/testdata/jsx/deno.lock create mode 100644 tests/testdata/jsx/import-map-scoped.json create mode 100644 tests/testdata/jsx/import-map.json create mode 100644 tests/testdata/jsx/jsx-dev-runtime/index.ts create mode 100644 tests/testdata/jsx/jsx-precompile/index.ts create mode 100644 tests/testdata/jsx/jsx-runtime/index.ts create mode 100644 tests/testdata/jupyter/install_command_not_exists.out create mode 100644 tests/testdata/jupyter/integration_test.ipynb create mode 100644 tests/testdata/lint/Deno.compact.format.jsonc create mode 100644 tests/testdata/lint/Deno.jsonc create mode 100644 tests/testdata/lint/Deno.malformed.jsonc create mode 100644 tests/testdata/lint/Deno.malformed2.jsonc create mode 100644 tests/testdata/lint/Deno.no_tags.jsonc create mode 100644 tests/testdata/lint/deno.glob.json create mode 100644 tests/testdata/lint/expected.out create mode 100644 tests/testdata/lint/expected_compact.out create mode 100644 tests/testdata/lint/expected_from_stdin.out create mode 100644 tests/testdata/lint/expected_from_stdin_json.out create mode 100644 tests/testdata/lint/expected_glob.out create mode 100644 tests/testdata/lint/expected_ignore.out create mode 100644 tests/testdata/lint/expected_json.out create mode 100644 tests/testdata/lint/expected_quiet.out create mode 100644 tests/testdata/lint/expected_rules.out create mode 100644 tests/testdata/lint/expected_verbose.out create mode 100644 tests/testdata/lint/glob/data/tes.ts create mode 100644 tests/testdata/lint/glob/data/test1.js create mode 100644 tests/testdata/lint/glob/data/test1.ts create mode 100644 tests/testdata/lint/glob/data/test12.ts create mode 100644 tests/testdata/lint/glob/nested/fizz/bar.ts create mode 100644 tests/testdata/lint/glob/nested/fizz/bazz.ts create mode 100644 tests/testdata/lint/glob/nested/fizz/fizz.ts create mode 100644 tests/testdata/lint/glob/nested/fizz/foo.ts create mode 100644 tests/testdata/lint/glob/nested/foo/bar.ts create mode 100644 tests/testdata/lint/glob/nested/foo/bazz.ts create mode 100644 tests/testdata/lint/glob/nested/foo/fizz.ts create mode 100644 tests/testdata/lint/glob/nested/foo/foo.ts create mode 100644 tests/testdata/lint/glob/pages/[id].ts create mode 100644 tests/testdata/lint/watch/badly_linted.js create mode 100644 tests/testdata/lint/watch/badly_linted.js.out create mode 100644 tests/testdata/lint/watch/badly_linted_fixed1.js create mode 100644 tests/testdata/lint/watch/badly_linted_fixed1.js.out create mode 100644 tests/testdata/lint/watch/badly_linted_fixed2.js create mode 100644 tests/testdata/lint/watch/badly_linted_fixed2.js.out create mode 100644 tests/testdata/lint/with_config.out create mode 100644 tests/testdata/lint/with_config/a.ts create mode 100644 tests/testdata/lint/with_config/b.ts create mode 100644 tests/testdata/lint/with_config_and_flags.out create mode 100644 tests/testdata/lint/with_config_without_tags.out create mode 100644 tests/testdata/lint/with_malformed_config.out create mode 100644 tests/testdata/lint/with_malformed_config2.out create mode 100644 tests/testdata/lint/with_report_config_compact.out create mode 100644 tests/testdata/lint/with_report_config_override.out create mode 100644 tests/testdata/lint/without_config/file1.js create mode 100644 tests/testdata/lint/without_config/file2.ts create mode 100644 tests/testdata/lint/without_config/ignored_file.ts create mode 100644 tests/testdata/lint/without_config/malformed.js create mode 100644 tests/testdata/lockfile/basic/bench.nolock.out create mode 100644 tests/testdata/lockfile/basic/deno.json create mode 100644 tests/testdata/lockfile/basic/deno.lock create mode 100644 tests/testdata/lockfile/basic/doc.nolock.out create mode 100644 tests/testdata/lockfile/basic/fail.out create mode 100644 tests/testdata/lockfile/basic/info.nolock.out create mode 100644 tests/testdata/lockfile/basic/main.bench.ts create mode 100644 tests/testdata/lockfile/basic/main.test.ts create mode 100644 tests/testdata/lockfile/basic/main.ts create mode 100644 tests/testdata/lockfile/basic/mod.ts create mode 100644 tests/testdata/lockfile/basic/test.nolock.out create mode 100644 tests/testdata/lockfile/no_dts/deno.lock.out create mode 100644 tests/testdata/lockfile/no_dts/main.cache.out create mode 100644 tests/testdata/lockfile/no_dts/main.ts create mode 100644 tests/testdata/lockfile/no_dts/mod.d.ts create mode 100644 tests/testdata/lockfile/no_dts/mod.js create mode 100644 tests/testdata/lsp/deno.import_map.jsonc create mode 100644 tests/testdata/lsp/deno.lint.exclude.jsonc create mode 100644 tests/testdata/lsp/diagnostics_deno_types.json create mode 100644 tests/testdata/lsp/import-map.json create mode 100644 tests/testdata/lsp/large_file.txt create mode 100644 tests/testdata/lsp/registries/a_latest_.json create mode 100644 tests/testdata/lsp/registries/a_v1.0.0_.json create mode 100644 tests/testdata/lsp/registries/a_v1.0.0_b.json create mode 100644 tests/testdata/lsp/registries/a_v1.0.1_.json create mode 100644 tests/testdata/lsp/registries/a_v2.0.0_.json create mode 100644 tests/testdata/lsp/registries/a_versions_.json create mode 100644 tests/testdata/lsp/registries/a_versions_v1..json create mode 100644 tests/testdata/lsp/registries/b_latest_.json create mode 100644 tests/testdata/lsp/registries/b_v0.0.1_.json create mode 100644 tests/testdata/lsp/registries/b_v0.0.2_.json create mode 100644 tests/testdata/lsp/registries/b_v0.0.3_.json create mode 100644 tests/testdata/lsp/registries/b_versions_.json create mode 100644 tests/testdata/lsp/registries/cde_tags.json create mode 100644 tests/testdata/lsp/registries/cdef_tags.json create mode 100644 tests/testdata/lsp/registries/complex.json create mode 100644 tests/testdata/lsp/registries/complex_efg.json create mode 100644 tests/testdata/lsp/registries/complex_efg_0.2.0.json create mode 100644 tests/testdata/lsp/registries/def_tags.json create mode 100644 tests/testdata/lsp/registries/deno-import-intellisense-complex.json create mode 100644 tests/testdata/lsp/registries/deno-import-intellisense-key-first.json create mode 100644 tests/testdata/lsp/registries/deno-import-intellisense.json create mode 100644 tests/testdata/lsp/registries/doc_a.json create mode 100644 tests/testdata/lsp/registries/doc_a_latest_mod.ts.json create mode 100644 tests/testdata/lsp/registries/key_first.json create mode 100644 tests/testdata/lsp/registries/modules_.json create mode 100644 tests/testdata/lsp/registries/modules_a.json create mode 100644 tests/testdata/lsp/types.tsconfig.json create mode 100644 tests/testdata/lsp/x_deno_warning_redirect.js create mode 100644 tests/testdata/malformed_config/deno.json create mode 100644 tests/testdata/module_graph/file_tests-a.mjs create mode 100644 tests/testdata/module_graph/file_tests-b-mod.js create mode 100644 tests/testdata/module_graph/file_tests-b.ts create mode 100644 tests/testdata/module_graph/file_tests-c-mod.ts create mode 100644 tests/testdata/module_graph/file_tests-checkwithconfig.ts create mode 100644 tests/testdata/module_graph/file_tests-diag.ts create mode 100644 tests/testdata/module_graph/file_tests-dynamicimport.ts create mode 100644 tests/testdata/module_graph/file_tests-importjson.ts create mode 100644 tests/testdata/module_graph/file_tests-importremap.ts create mode 100644 tests/testdata/module_graph/file_tests-main.ts create mode 100644 tests/testdata/module_graph/file_tests-some.json create mode 100644 tests/testdata/module_graph/file_typesref.d.ts create mode 100644 tests/testdata/module_graph/file_typesref.js create mode 100644 tests/testdata/module_graph/https_deno.land-std-http-server.ts create mode 100644 tests/testdata/module_graph/https_deno.land-x-a-mod.ts create mode 100644 tests/testdata/module_graph/https_deno.land-x-a.ts create mode 100644 tests/testdata/module_graph/https_deno.land-x-import_map.ts create mode 100644 tests/testdata/module_graph/https_deno.land-x-jquery.js create mode 100644 tests/testdata/module_graph/https_deno.land-x-lib-a.ts create mode 100644 tests/testdata/module_graph/https_deno.land-x-lib-b.js create mode 100644 tests/testdata/module_graph/https_deno.land-x-lib-c.d.ts create mode 100644 tests/testdata/module_graph/https_deno.land-x-lib-c.js create mode 100644 tests/testdata/module_graph/https_deno.land-x-lib-mod.d.ts create mode 100644 tests/testdata/module_graph/https_deno.land-x-lib-mod.js create mode 100644 tests/testdata/module_graph/https_deno.land-x-mod.ts create mode 100644 tests/testdata/module_graph/https_deno.land-x-transpile.tsx create mode 100644 tests/testdata/module_graph/https_unpkg.com-lodash-index.js create mode 100644 tests/testdata/module_graph/lockfile.json create mode 100644 tests/testdata/module_graph/lockfile_fail.json create mode 100644 tests/testdata/module_graph/tsconfig.json create mode 100644 tests/testdata/module_graph/tsconfig_01.json create mode 100644 tests/testdata/navigator_language.ts create mode 100644 tests/testdata/navigator_languages.ts create mode 100644 tests/testdata/node/rejection_handled_web_process.ts create mode 100644 tests/testdata/node/rejection_handled_web_process.ts.out create mode 100644 tests/testdata/node/require_esm_error/esm.js create mode 100644 tests/testdata/node/require_esm_error/main.out create mode 100644 tests/testdata/node/require_esm_error/main.ts create mode 100644 tests/testdata/node/test.js create mode 100644 tests/testdata/node/test.out create mode 100644 tests/testdata/node/unhandled_rejection_web.ts create mode 100644 tests/testdata/node/unhandled_rejection_web.ts.out create mode 100644 tests/testdata/node/unhandled_rejection_web_process.ts create mode 100644 tests/testdata/node/unhandled_rejection_web_process.ts.out create mode 100644 tests/testdata/npm/README.md create mode 100644 tests/testdata/npm/binary_package/main.js create mode 100644 tests/testdata/npm/builtin_module_module/main.js create mode 100644 tests/testdata/npm/builtin_module_module/main.out create mode 100644 tests/testdata/npm/cached_only/main.out create mode 100644 tests/testdata/npm/cached_only/main.ts create mode 100644 tests/testdata/npm/cached_only_after_first_run/main1.ts create mode 100644 tests/testdata/npm/cached_only_after_first_run/main2.ts create mode 100644 tests/testdata/npm/check_errors/main.ts create mode 100644 tests/testdata/npm/check_errors/main_all.out create mode 100644 tests/testdata/npm/check_errors/main_local.out create mode 100644 tests/testdata/npm/child_process_fork_test/main.out create mode 100644 tests/testdata/npm/child_process_fork_test/main.ts create mode 100644 tests/testdata/npm/cjs-invalid-name-exports/main.out create mode 100644 tests/testdata/npm/cjs-invalid-name-exports/main.ts create mode 100644 tests/testdata/npm/cjs_local_global_decls/main.out create mode 100644 tests/testdata/npm/cjs_local_global_decls/main.ts create mode 100644 tests/testdata/npm/cjs_module_export_assignment/main.out create mode 100644 tests/testdata/npm/cjs_module_export_assignment/main.ts create mode 100644 tests/testdata/npm/cjs_module_export_assignment_number/main.out create mode 100644 tests/testdata/npm/cjs_module_export_assignment_number/main.ts create mode 100644 tests/testdata/npm/cjs_reexport_collision/main.out create mode 100644 tests/testdata/npm/cjs_reexport_collision/main.ts create mode 100644 tests/testdata/npm/cjs_require_esm_error/main.out create mode 100644 tests/testdata/npm/cjs_require_esm_error/main.ts create mode 100644 tests/testdata/npm/cjs_require_esm_mjs_error/main.out create mode 100644 tests/testdata/npm/cjs_require_esm_mjs_error/main.ts create mode 100644 tests/testdata/npm/cjs_sub_path/main.js create mode 100644 tests/testdata/npm/cjs_sub_path/main.out create mode 100644 tests/testdata/npm/cjs_this_in_exports/main.js create mode 100644 tests/testdata/npm/cjs_this_in_exports/main.out create mode 100644 tests/testdata/npm/cjs_with_deps/main.js create mode 100644 tests/testdata/npm/cjs_with_deps/main.out create mode 100644 tests/testdata/npm/cjs_with_deps/main_info.out create mode 100644 tests/testdata/npm/cjs_with_deps/main_info_json.out create mode 100644 tests/testdata/npm/cjs_with_deps/main_node_modules.out create mode 100644 tests/testdata/npm/cjs_yargs/main.js create mode 100644 tests/testdata/npm/cjs_yargs/main.out create mode 100644 tests/testdata/npm/compare_globals/main.out create mode 100644 tests/testdata/npm/compare_globals/main.ts create mode 100644 tests/testdata/npm/conditional_exports/main.js create mode 100644 tests/testdata/npm/conditional_exports/main.out create mode 100644 tests/testdata/npm/conditional_exports/main_node_modules.out create mode 100644 tests/testdata/npm/create_require/main.out create mode 100644 tests/testdata/npm/create_require/main.ts create mode 100644 tests/testdata/npm/d_ext/main.out create mode 100644 tests/testdata/npm/d_ext/main.ts create mode 100644 tests/testdata/npm/deno_cache.out create mode 100644 tests/testdata/npm/deno_run_cjs.out create mode 100644 tests/testdata/npm/deno_run_cowsay.out create mode 100644 tests/testdata/npm/deno_run_cowsay_no_permissions.out create mode 100644 tests/testdata/npm/deno_run_cowthink.out create mode 100644 tests/testdata/npm/deno_run_esm.out create mode 100644 tests/testdata/npm/deno_run_no_bin_entrypoint.out create mode 100644 tests/testdata/npm/deno_run_no_bin_entrypoint_non_existent_subpath.out create mode 100644 tests/testdata/npm/deno_run_no_ext.out create mode 100644 tests/testdata/npm/deno_run_non_existent.out create mode 100644 tests/testdata/npm/deno_run_special_chars_in_bin_name.out create mode 100644 tests/testdata/npm/different_nested_dep/main.js create mode 100644 tests/testdata/npm/different_nested_dep/main.out create mode 100644 tests/testdata/npm/different_nested_dep/package.json create mode 100644 tests/testdata/npm/directory_import/folder_index_js.out create mode 100644 tests/testdata/npm/directory_import/folder_index_js.ts create mode 100644 tests/testdata/npm/directory_import/folder_no_index.out create mode 100644 tests/testdata/npm/directory_import/folder_no_index.ts create mode 100644 tests/testdata/npm/dual_cjs_esm/main.out create mode 100644 tests/testdata/npm/dual_cjs_esm/main.ts create mode 100644 tests/testdata/npm/dynamic_import/main.out create mode 100644 tests/testdata/npm/dynamic_import/main.ts create mode 100644 tests/testdata/npm/dynamic_import/other.ts create mode 100644 tests/testdata/npm/dynamic_import_deno_ts_from_npm/add.ts create mode 100644 tests/testdata/npm/dynamic_import_deno_ts_from_npm/main.out create mode 100644 tests/testdata/npm/dynamic_import_deno_ts_from_npm/main.ts create mode 100644 tests/testdata/npm/dynamic_import_deno_ts_from_npm/subtract.mts create mode 100644 tests/testdata/npm/dynamic_import_invalid_package_name/main.out create mode 100644 tests/testdata/npm/dynamic_import_invalid_package_name/main.ts create mode 100644 tests/testdata/npm/dynamic_import_json/main.js create mode 100644 tests/testdata/npm/dynamic_import_json/main.out create mode 100644 tests/testdata/npm/dynamic_import_reload_same_package/main.out create mode 100644 tests/testdata/npm/dynamic_import_reload_same_package/main.ts create mode 100644 tests/testdata/npm/dynamic_import_reload_same_package/other.ts create mode 100644 tests/testdata/npm/env_var_re_export/main.js create mode 100644 tests/testdata/npm/error_version_after_subpath/main.js create mode 100644 tests/testdata/npm/error_version_after_subpath/main.out create mode 100644 tests/testdata/npm/esm/main.js create mode 100644 tests/testdata/npm/esm/main.out create mode 100644 tests/testdata/npm/esm/test.js create mode 100644 tests/testdata/npm/esm/test.out create mode 100644 tests/testdata/npm/esm_import_cjs_default/main.out create mode 100644 tests/testdata/npm/esm_import_cjs_default/main.ts create mode 100644 tests/testdata/npm/file_dts_dmts_dcts/main.out create mode 100644 tests/testdata/npm/file_dts_dmts_dcts/main.ts create mode 100644 tests/testdata/npm/import_json/main.js create mode 100644 tests/testdata/npm/import_json/main.out create mode 100644 tests/testdata/npm/import_map/import_map.json create mode 100644 tests/testdata/npm/import_map/main.js create mode 100644 tests/testdata/npm/import_map/main.out create mode 100644 tests/testdata/npm/imports_package_json/import_not_defined.js create mode 100644 tests/testdata/npm/imports_package_json/import_not_defined.out create mode 100644 tests/testdata/npm/imports_package_json/main.js create mode 100644 tests/testdata/npm/imports_package_json/main.out create mode 100644 tests/testdata/npm/imports_package_json/package.json create mode 100644 tests/testdata/npm/imports_package_json/sub_path_import_not_defined.js create mode 100644 tests/testdata/npm/imports_package_json/sub_path_import_not_defined.out create mode 100644 tests/testdata/npm/info/chalk.out create mode 100644 tests/testdata/npm/info/chalk_json.out create mode 100644 tests/testdata/npm/invalid_package_name/main.js create mode 100644 tests/testdata/npm/invalid_package_name/main.out create mode 100644 tests/testdata/npm/local_dir_resolves_symlinks/index.js create mode 100644 tests/testdata/npm/local_dir_resolves_symlinks/index.out create mode 100644 tests/testdata/npm/local_dir_resolves_symlinks/package.json create mode 100644 tests/testdata/npm/lock_file/lock.json create mode 100644 tests/testdata/npm/lock_file/main.js create mode 100644 tests/testdata/npm/lock_file/main.out create mode 100644 tests/testdata/npm/mixed_case_package_name/global.out create mode 100644 tests/testdata/npm/mixed_case_package_name/global.ts create mode 100644 tests/testdata/npm/mixed_case_package_name/local.out create mode 100644 tests/testdata/npm/mixed_case_package_name/local.ts create mode 100644 tests/testdata/npm/no_npm_after_first_run/main1.ts create mode 100644 tests/testdata/npm/no_types_cjs/main.ts create mode 100644 tests/testdata/npm/no_types_in_conditional_exports/main.out create mode 100644 tests/testdata/npm/no_types_in_conditional_exports/main.ts create mode 100644 tests/testdata/npm/node_modules_deno_node_modules/main.out create mode 100644 tests/testdata/npm/node_modules_deno_node_modules/main.ts create mode 100644 tests/testdata/npm/node_modules_import/main.out create mode 100644 tests/testdata/npm/node_modules_import/main.ts create mode 100644 tests/testdata/npm/node_modules_import/main_check.out create mode 100644 tests/testdata/npm/node_modules_import/package.json create mode 100644 tests/testdata/npm/nonexistent_file/main.js create mode 100644 tests/testdata/npm/nonexistent_file/main.out create mode 100644 tests/testdata/npm/peer_deps_with_copied_folders/main.out create mode 100644 tests/testdata/npm/peer_deps_with_copied_folders/main.ts create mode 100644 tests/testdata/npm/peer_deps_with_copied_folders/main_info.out create mode 100644 tests/testdata/npm/peer_deps_with_copied_folders/main_info_json.out create mode 100644 tests/testdata/npm/peer_deps_with_copied_folders/main_node_modules.out create mode 100644 tests/testdata/npm/peer_deps_with_copied_folders/main_node_modules_reload.out create mode 100644 tests/testdata/npm/permissions_outside_package/foo/config.js create mode 100644 tests/testdata/npm/permissions_outside_package/foo/package.json create mode 100644 tests/testdata/npm/permissions_outside_package/main.out create mode 100644 tests/testdata/npm/permissions_outside_package/main.ts create mode 100644 tests/testdata/npm/registry/@babel/parser/parser-7.19.0.tgz create mode 100644 tests/testdata/npm/registry/@babel/parser/registry.json create mode 100644 tests/testdata/npm/registry/@denotest/CAPITALS/1.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/CAPITALS/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/MixedCase/1.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/MixedCase/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/bin/0.5.0/cli.mjs create mode 100644 tests/testdata/npm/registry/@denotest/bin/0.5.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/bin/0.6.0/cli-cjs.js create mode 100644 tests/testdata/npm/registry/@denotest/bin/0.6.0/cli.mjs create mode 100644 tests/testdata/npm/registry/@denotest/bin/0.6.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/bin/1.0.0/cli-cjs.js create mode 100644 tests/testdata/npm/registry/@denotest/bin/1.0.0/cli-no-ext create mode 100644 tests/testdata/npm/registry/@denotest/bin/1.0.0/cli.mjs create mode 100644 tests/testdata/npm/registry/@denotest/bin/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/binary-package-linux/1.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/binary-package-linux/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/binary-package-mac/1.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/binary-package-mac/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/binary-package-windows/1.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/binary-package-windows/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/binary-package/1.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/binary-package/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/breaking-change-between-versions/1.0.0/index.d.ts create mode 100644 tests/testdata/npm/registry/@denotest/breaking-change-between-versions/1.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/breaking-change-between-versions/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/breaking-change-between-versions/2.0.0/index.d.ts create mode 100644 tests/testdata/npm/registry/@denotest/breaking-change-between-versions/2.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/breaking-change-between-versions/2.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/builtin-module-module/1.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/builtin-module-module/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/check-error/1.0.0/index.d.ts create mode 100644 tests/testdata/npm/registry/@denotest/check-error/1.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/check-error/1.0.0/other_dir.d.ts create mode 100644 tests/testdata/npm/registry/@denotest/check-error/1.0.0/other_dir/index.js create mode 100644 tests/testdata/npm/registry/@denotest/check-error/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/check-error/1.0.0/sub_dir/index.d.ts create mode 100644 tests/testdata/npm/registry/@denotest/check-error/1.0.0/sub_dir/index.js create mode 100644 tests/testdata/npm/registry/@denotest/check-error/1.0.0/sub_dir/lib.d.ts create mode 100644 tests/testdata/npm/registry/@denotest/child-process-fork/1.0.0/forked_path.js create mode 100644 tests/testdata/npm/registry/@denotest/child-process-fork/1.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/child-process-fork/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/cjs-default-export/1.0.0/index.d.ts create mode 100644 tests/testdata/npm/registry/@denotest/cjs-default-export/1.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/cjs-default-export/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/cjs-invalid-name-exports/1.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/cjs-invalid-name-exports/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/cjs-local-global-decls/1.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/cjs-local-global-decls/1.0.0/other.js create mode 100644 tests/testdata/npm/registry/@denotest/cjs-local-global-decls/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/cjs-module-export-assignment-number/1.0.0/index.d.ts create mode 100644 tests/testdata/npm/registry/@denotest/cjs-module-export-assignment-number/1.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/cjs-module-export-assignment-number/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/cjs-module-export-assignment/1.0.0/index.d.ts create mode 100644 tests/testdata/npm/registry/@denotest/cjs-module-export-assignment/1.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/cjs-module-export-assignment/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/cjs-reexport-collision/1.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/cjs-reexport-collision/1.0.0/other_file.js create mode 100644 tests/testdata/npm/registry/@denotest/cjs-reexport-collision/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/cjs-require-esm-error/1.0.0/esm/my_es_module.js create mode 100644 tests/testdata/npm/registry/@denotest/cjs-require-esm-error/1.0.0/esm/package.json create mode 100644 tests/testdata/npm/registry/@denotest/cjs-require-esm-error/1.0.0/esm_mjs.mjs create mode 100644 tests/testdata/npm/registry/@denotest/cjs-require-esm-error/1.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/cjs-require-esm-error/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/cjs-require-esm-error/1.0.0/require_mjs.js create mode 100644 tests/testdata/npm/registry/@denotest/cjs-this-in-exports/1.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/cjs-this-in-exports/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/cjs-with-file-stem/1.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/cjs-with-file-stem/1.0.0/other.service.js create mode 100644 tests/testdata/npm/registry/@denotest/cjs-with-file-stem/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/cjs-with-file-stem/1.0.0/tslib.js create mode 100644 tests/testdata/npm/registry/@denotest/conditional-exports-strict/1.0.0/cjs/index.cjs create mode 100644 tests/testdata/npm/registry/@denotest/conditional-exports-strict/1.0.0/esm/client/bar.js create mode 100644 tests/testdata/npm/registry/@denotest/conditional-exports-strict/1.0.0/esm/client/foo.js create mode 100644 tests/testdata/npm/registry/@denotest/conditional-exports-strict/1.0.0/esm/client/index.js create mode 100644 tests/testdata/npm/registry/@denotest/conditional-exports-strict/1.0.0/esm/client/m.js create mode 100644 tests/testdata/npm/registry/@denotest/conditional-exports-strict/1.0.0/esm/index.js create mode 100644 tests/testdata/npm/registry/@denotest/conditional-exports-strict/1.0.0/foo.js create mode 100644 tests/testdata/npm/registry/@denotest/conditional-exports-strict/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/conditional-exports/1.0.0/cjs/index.cjs create mode 100644 tests/testdata/npm/registry/@denotest/conditional-exports/1.0.0/esm/client/bar.js create mode 100644 tests/testdata/npm/registry/@denotest/conditional-exports/1.0.0/esm/client/foo.js create mode 100644 tests/testdata/npm/registry/@denotest/conditional-exports/1.0.0/esm/client/index.js create mode 100644 tests/testdata/npm/registry/@denotest/conditional-exports/1.0.0/esm/client/m.js create mode 100644 tests/testdata/npm/registry/@denotest/conditional-exports/1.0.0/esm/index.js create mode 100644 tests/testdata/npm/registry/@denotest/conditional-exports/1.0.0/foo.js create mode 100644 tests/testdata/npm/registry/@denotest/conditional-exports/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/create-require/1.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/create-require/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/d-ext/1.0.0/index.d.ts create mode 100644 tests/testdata/npm/registry/@denotest/d-ext/1.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/d-ext/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/d-ext/1.0.0/types.d.ts create mode 100644 tests/testdata/npm/registry/@denotest/different-nested-dep-child/1.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/different-nested-dep-child/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/different-nested-dep-child/2.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/different-nested-dep-child/2.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/different-nested-dep/1.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/different-nested-dep/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/dual-cjs-esm-dep-missing/1.0.0/index.cjs create mode 100644 tests/testdata/npm/registry/@denotest/dual-cjs-esm-dep-missing/1.0.0/index.d.ts create mode 100644 tests/testdata/npm/registry/@denotest/dual-cjs-esm-dep-missing/1.0.0/index.mjs create mode 100644 tests/testdata/npm/registry/@denotest/dual-cjs-esm-dep-missing/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/dual-cjs-esm-dep/1.0.0/index.cjs create mode 100644 tests/testdata/npm/registry/@denotest/dual-cjs-esm-dep/1.0.0/index.d.ts create mode 100644 tests/testdata/npm/registry/@denotest/dual-cjs-esm-dep/1.0.0/index.mjs create mode 100644 tests/testdata/npm/registry/@denotest/dual-cjs-esm-dep/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/cjs/main.cjs create mode 100644 tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/cjs/package.json create mode 100644 tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/main.cjs create mode 100644 tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/main.d.cts create mode 100644 tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/main.d.mts create mode 100644 tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/main.mjs create mode 100644 tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/subpath/main.cjs create mode 100644 tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/subpath/main.mjs create mode 100644 tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/subpath/package.json create mode 100644 tests/testdata/npm/registry/@denotest/dynamic-import/1.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/dynamic-import/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/env-var-re-export/1.0.0/dev.cjs create mode 100644 tests/testdata/npm/registry/@denotest/env-var-re-export/1.0.0/index.cjs create mode 100644 tests/testdata/npm/registry/@denotest/env-var-re-export/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/env-var-re-export/1.0.0/prod.cjs create mode 100644 tests/testdata/npm/registry/@denotest/esm-basic/1.0.0/main.d.mts create mode 100644 tests/testdata/npm/registry/@denotest/esm-basic/1.0.0/main.mjs create mode 100644 tests/testdata/npm/registry/@denotest/esm-basic/1.0.0/other.mjs create mode 100644 tests/testdata/npm/registry/@denotest/esm-basic/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/esm-import-cjs-default/1.0.0/index.mjs create mode 100644 tests/testdata/npm/registry/@denotest/esm-import-cjs-default/1.0.0/local.cjs create mode 100644 tests/testdata/npm/registry/@denotest/esm-import-cjs-default/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.cjs create mode 100644 tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.d.cts create mode 100644 tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.d.mts create mode 100644 tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.d.ts create mode 100644 tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.js create mode 100644 tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.mjs create mode 100644 tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/globals/1.0.0/index.d.ts create mode 100644 tests/testdata/npm/registry/@denotest/globals/1.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/globals/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/imports-package-json/1.0.0/hi.js create mode 100644 tests/testdata/npm/registry/@denotest/imports-package-json/1.0.0/import_not_defined.js create mode 100644 tests/testdata/npm/registry/@denotest/imports-package-json/1.0.0/main.js create mode 100644 tests/testdata/npm/registry/@denotest/imports-package-json/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/imports-package-json/1.0.0/sub_path/bye.js create mode 100644 tests/testdata/npm/registry/@denotest/imports-package-json/1.0.0/sub_path/import_not_defined.js create mode 100644 tests/testdata/npm/registry/@denotest/imports-package-json/1.0.0/sub_path/main.js create mode 100644 tests/testdata/npm/registry/@denotest/imports-package-json/1.0.0/sub_path/package.json create mode 100644 tests/testdata/npm/registry/@denotest/no-types-cjs/1.0.0/main.js create mode 100644 tests/testdata/npm/registry/@denotest/no-types-cjs/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/no-types-in-conditional-exports/1.0.0/lib/foo-esm.js create mode 100644 tests/testdata/npm/registry/@denotest/no-types-in-conditional-exports/1.0.0/lib/foo.js create mode 100644 tests/testdata/npm/registry/@denotest/no-types-in-conditional-exports/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/non-existent-dep-version/1.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/non-existent-dep-version/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/non-existent-dep/1.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/non-existent-dep/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/peer-dep-test-child/1.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/peer-dep-test-child/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/peer-dep-test-child/2.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/peer-dep-test-child/2.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/peer-dep-test-grandchild/1.0.0/dist/index.js create mode 100644 tests/testdata/npm/registry/@denotest/peer-dep-test-grandchild/1.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/peer-dep-test-grandchild/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/peer-dep-test-peer/1.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/peer-dep-test-peer/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/peer-dep-test-peer/2.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/peer-dep-test-peer/2.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/permissions-outside-package/1.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/permissions-outside-package/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/require-added-nm-folder/1.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/require-added-nm-folder/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/reserved-word-exports/1.0.0/index.cjs create mode 100644 tests/testdata/npm/registry/@denotest/reserved-word-exports/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/special-chars-in-bin-name/1.0.0/main.mjs create mode 100644 tests/testdata/npm/registry/@denotest/special-chars-in-bin-name/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/sub-folders/1.0.0/folder_index_js/index.d.ts create mode 100644 tests/testdata/npm/registry/@denotest/sub-folders/1.0.0/folder_index_js/index.js create mode 100644 tests/testdata/npm/registry/@denotest/sub-folders/1.0.0/folder_no_index/random_name.js create mode 100644 tests/testdata/npm/registry/@denotest/sub-folders/1.0.0/main.mjs create mode 100644 tests/testdata/npm/registry/@denotest/sub-folders/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/types-ambient/1.0.0/index.d.ts create mode 100644 tests/testdata/npm/registry/@denotest/types-ambient/1.0.0/index.js create mode 100644 tests/testdata/npm/registry/@denotest/types-ambient/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/types-entry-value-not-exists/1.0.0/dist/main.d.ts create mode 100644 tests/testdata/npm/registry/@denotest/types-entry-value-not-exists/1.0.0/dist/main.js create mode 100644 tests/testdata/npm/registry/@denotest/types-entry-value-not-exists/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/types-exports-import-types/1.0.0/dist/main.d.ts create mode 100644 tests/testdata/npm/registry/@denotest/types-exports-import-types/1.0.0/dist/main.mjs create mode 100644 tests/testdata/npm/registry/@denotest/types-exports-import-types/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/client.d.ts create mode 100644 tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/dist/client.mjs create mode 100644 tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/dist/entry-a.d.ts create mode 100644 tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/dist/entry-a.js create mode 100644 tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/dist/entry-b.d.ts create mode 100644 tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/dist/entry-b.js create mode 100644 tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/entry-import.d.ts create mode 100644 tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/entry-import.js create mode 100644 tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/entry-js-only.js create mode 100644 tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/entry-types.d.ts create mode 100644 tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/types-no-types-entry/1.0.0/dist/main.d.ts create mode 100644 tests/testdata/npm/registry/@denotest/types-no-types-entry/1.0.0/dist/main.js create mode 100644 tests/testdata/npm/registry/@denotest/types-no-types-entry/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/types/1.0.0/index.d.ts create mode 100644 tests/testdata/npm/registry/@denotest/types/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/types_imported/1.0.0/index.d.ts create mode 100644 tests/testdata/npm/registry/@denotest/types_imported/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@denotest/types_imported/1.0.0/subpath.d.ts create mode 100644 tests/testdata/npm/registry/@denotest/typescript-file/1.0.0/index.ts create mode 100644 tests/testdata/npm/registry/@denotest/typescript-file/1.0.0/package.json create mode 100644 tests/testdata/npm/registry/@ljharb/has-package-exports-patterns/has-package-exports-patterns-0.0.2.tgz create mode 100644 tests/testdata/npm/registry/@ljharb/has-package-exports-patterns/registry.json create mode 100644 tests/testdata/npm/registry/@types/node/node-18.8.2.tgz create mode 100644 tests/testdata/npm/registry/@types/node/registry.json create mode 100644 tests/testdata/npm/registry/@vue/compiler-core/compiler-core-3.2.38.tgz create mode 100644 tests/testdata/npm/registry/@vue/compiler-core/registry.json create mode 100644 tests/testdata/npm/registry/@vue/compiler-dom/compiler-dom-3.2.38.tgz create mode 100644 tests/testdata/npm/registry/@vue/compiler-dom/registry.json create mode 100644 tests/testdata/npm/registry/@vue/compiler-sfc/compiler-sfc-3.2.38.tgz create mode 100644 tests/testdata/npm/registry/@vue/compiler-sfc/registry.json create mode 100644 tests/testdata/npm/registry/@vue/compiler-ssr/compiler-ssr-3.2.38.tgz create mode 100644 tests/testdata/npm/registry/@vue/compiler-ssr/registry.json create mode 100644 tests/testdata/npm/registry/@vue/reactivity-transform/reactivity-transform-3.2.38.tgz create mode 100644 tests/testdata/npm/registry/@vue/reactivity-transform/registry.json create mode 100644 tests/testdata/npm/registry/@vue/reactivity/reactivity-3.2.38.tgz create mode 100644 tests/testdata/npm/registry/@vue/reactivity/registry.json create mode 100644 tests/testdata/npm/registry/@vue/runtime-core/registry.json create mode 100644 tests/testdata/npm/registry/@vue/runtime-core/runtime-core-3.2.38.tgz create mode 100644 tests/testdata/npm/registry/@vue/runtime-dom/registry.json create mode 100644 tests/testdata/npm/registry/@vue/runtime-dom/runtime-dom-3.2.38.tgz create mode 100644 tests/testdata/npm/registry/@vue/server-renderer/registry.json create mode 100644 tests/testdata/npm/registry/@vue/server-renderer/server-renderer-3.2.38.tgz create mode 100644 tests/testdata/npm/registry/@vue/shared/registry.json create mode 100644 tests/testdata/npm/registry/@vue/shared/shared-3.2.38.tgz create mode 100644 tests/testdata/npm/registry/ajv-formats/ajv-formats-2.1.1.tgz create mode 100644 tests/testdata/npm/registry/ajv-formats/registry.json create mode 100644 tests/testdata/npm/registry/ajv/ajv-8.11.0.tgz create mode 100644 tests/testdata/npm/registry/ajv/registry.json create mode 100644 tests/testdata/npm/registry/ansi-regex/ansi-regex-3.0.1.tgz create mode 100644 tests/testdata/npm/registry/ansi-regex/ansi-regex-5.0.1.tgz create mode 100644 tests/testdata/npm/registry/ansi-regex/registry.json create mode 100644 tests/testdata/npm/registry/ansi-styles/ansi-styles-4.3.0.tgz create mode 100644 tests/testdata/npm/registry/ansi-styles/registry.json create mode 100644 tests/testdata/npm/registry/asn1/asn1-0.2.6.tgz create mode 100644 tests/testdata/npm/registry/asn1/registry.json create mode 100644 tests/testdata/npm/registry/assertion-error/assertion-error-1.1.0.tgz create mode 100644 tests/testdata/npm/registry/assertion-error/registry.json create mode 100644 tests/testdata/npm/registry/autoprefixer/autoprefixer-10.4.14.tgz create mode 100644 tests/testdata/npm/registry/autoprefixer/registry.json create mode 100644 tests/testdata/npm/registry/bcrypt-pbkdf/bcrypt-pbkdf-1.0.2.tgz create mode 100644 tests/testdata/npm/registry/bcrypt-pbkdf/registry.json create mode 100644 tests/testdata/npm/registry/browserslist/browserslist-4.21.5.tgz create mode 100644 tests/testdata/npm/registry/browserslist/registry.json create mode 100644 tests/testdata/npm/registry/buildcheck/buildcheck-0.0.3.tgz create mode 100644 tests/testdata/npm/registry/buildcheck/registry.json create mode 100644 tests/testdata/npm/registry/camelcase/camelcase-5.3.1.tgz create mode 100644 tests/testdata/npm/registry/camelcase/registry.json create mode 100644 tests/testdata/npm/registry/caniuse-lite/caniuse-lite-1.0.30001473.tgz create mode 100644 tests/testdata/npm/registry/caniuse-lite/registry.json create mode 100644 tests/testdata/npm/registry/chai/chai-4.3.6.tgz create mode 100644 tests/testdata/npm/registry/chai/registry.json create mode 100644 tests/testdata/npm/registry/chalk/chalk-4.1.2.tgz create mode 100644 tests/testdata/npm/registry/chalk/chalk-5.0.1.tgz create mode 100644 tests/testdata/npm/registry/chalk/registry.json create mode 100644 tests/testdata/npm/registry/check-error/check-error-1.0.2.tgz create mode 100644 tests/testdata/npm/registry/check-error/registry.json create mode 100644 tests/testdata/npm/registry/cliui/cliui-6.0.0.tgz create mode 100644 tests/testdata/npm/registry/cliui/registry.json create mode 100644 tests/testdata/npm/registry/color-convert/color-convert-2.0.1.tgz create mode 100644 tests/testdata/npm/registry/color-convert/registry.json create mode 100644 tests/testdata/npm/registry/color-name/color-name-1.1.4.tgz create mode 100644 tests/testdata/npm/registry/color-name/registry.json create mode 100644 tests/testdata/npm/registry/cowsay/cowsay-1.5.0.tgz create mode 100644 tests/testdata/npm/registry/cowsay/registry.json create mode 100644 tests/testdata/npm/registry/cpu-features/cpu-features-0.0.4.tgz create mode 100644 tests/testdata/npm/registry/cpu-features/registry.json create mode 100644 tests/testdata/npm/registry/crypto-js/crypto-js-4.1.1.tgz create mode 100644 tests/testdata/npm/registry/crypto-js/registry.json create mode 100644 tests/testdata/npm/registry/csstype/csstype-2.6.20.tgz create mode 100644 tests/testdata/npm/registry/csstype/registry.json create mode 100644 tests/testdata/npm/registry/decamelize/decamelize-1.2.0.tgz create mode 100644 tests/testdata/npm/registry/decamelize/registry.json create mode 100644 tests/testdata/npm/registry/deep-eql/deep-eql-3.0.1.tgz create mode 100644 tests/testdata/npm/registry/deep-eql/registry.json create mode 100644 tests/testdata/npm/registry/define-properties/define-properties-1.2.0.tgz create mode 100644 tests/testdata/npm/registry/define-properties/registry.json create mode 100644 tests/testdata/npm/registry/electron-to-chromium/electron-to-chromium-1.4.348.tgz create mode 100644 tests/testdata/npm/registry/electron-to-chromium/registry.json create mode 100644 tests/testdata/npm/registry/emoji-regex/emoji-regex-8.0.0.tgz create mode 100644 tests/testdata/npm/registry/emoji-regex/registry.json create mode 100644 tests/testdata/npm/registry/escalade/escalade-3.1.1.tgz create mode 100644 tests/testdata/npm/registry/escalade/registry.json create mode 100644 tests/testdata/npm/registry/estree-walker/estree-walker-2.0.2.tgz create mode 100644 tests/testdata/npm/registry/estree-walker/registry.json create mode 100644 tests/testdata/npm/registry/fast-deep-equal/fast-deep-equal-3.1.3.tgz create mode 100644 tests/testdata/npm/registry/fast-deep-equal/registry.json create mode 100644 tests/testdata/npm/registry/find-up/find-up-4.1.0.tgz create mode 100644 tests/testdata/npm/registry/find-up/registry.json create mode 100644 tests/testdata/npm/registry/fraction.js/fraction.js-4.2.0.tgz create mode 100644 tests/testdata/npm/registry/fraction.js/registry.json create mode 100644 tests/testdata/npm/registry/fs-extra/fs-extra-10.1.0.tgz create mode 100644 tests/testdata/npm/registry/fs-extra/registry.json create mode 100644 tests/testdata/npm/registry/function-bind/function-bind-1.1.1.tgz create mode 100644 tests/testdata/npm/registry/function-bind/registry.json create mode 100644 tests/testdata/npm/registry/get-caller-file/get-caller-file-2.0.5.tgz create mode 100644 tests/testdata/npm/registry/get-caller-file/registry.json create mode 100644 tests/testdata/npm/registry/get-func-name/get-func-name-2.0.0.tgz create mode 100644 tests/testdata/npm/registry/get-func-name/registry.json create mode 100644 tests/testdata/npm/registry/get-intrinsic/get-intrinsic-1.2.0.tgz create mode 100644 tests/testdata/npm/registry/get-intrinsic/registry.json create mode 100644 tests/testdata/npm/registry/get-stdin/get-stdin-8.0.0.tgz create mode 100644 tests/testdata/npm/registry/get-stdin/registry.json create mode 100644 tests/testdata/npm/registry/globals/globals-13.17.0.tgz create mode 100644 tests/testdata/npm/registry/globals/registry.json create mode 100644 tests/testdata/npm/registry/graceful-fs/graceful-fs-4.2.10.tgz create mode 100644 tests/testdata/npm/registry/graceful-fs/registry.json create mode 100644 tests/testdata/npm/registry/has-flag/has-flag-4.0.0.tgz create mode 100644 tests/testdata/npm/registry/has-flag/registry.json create mode 100644 tests/testdata/npm/registry/has-package-exports/has-package-exports-1.3.0.tgz create mode 100644 tests/testdata/npm/registry/has-package-exports/registry.json create mode 100644 tests/testdata/npm/registry/has-property-descriptors/has-property-descriptors-1.0.0.tgz create mode 100644 tests/testdata/npm/registry/has-property-descriptors/registry.json create mode 100644 tests/testdata/npm/registry/has-symbols/has-symbols-1.0.3.tgz create mode 100644 tests/testdata/npm/registry/has-symbols/registry.json create mode 100644 tests/testdata/npm/registry/has/has-1.0.3.tgz create mode 100644 tests/testdata/npm/registry/has/registry.json create mode 100644 tests/testdata/npm/registry/is-fullwidth-code-point/is-fullwidth-code-point-2.0.0.tgz create mode 100644 tests/testdata/npm/registry/is-fullwidth-code-point/is-fullwidth-code-point-3.0.0.tgz create mode 100644 tests/testdata/npm/registry/is-fullwidth-code-point/registry.json create mode 100644 tests/testdata/npm/registry/js-tokens/js-tokens-4.0.0.tgz create mode 100644 tests/testdata/npm/registry/js-tokens/registry.json create mode 100644 tests/testdata/npm/registry/json-schema-traverse/json-schema-traverse-1.0.0.tgz create mode 100644 tests/testdata/npm/registry/json-schema-traverse/registry.json create mode 100644 tests/testdata/npm/registry/jsonfile/jsonfile-6.1.0.tgz create mode 100644 tests/testdata/npm/registry/jsonfile/registry.json create mode 100644 tests/testdata/npm/registry/locate-path/locate-path-5.0.0.tgz create mode 100644 tests/testdata/npm/registry/locate-path/registry.json create mode 100644 tests/testdata/npm/registry/loose-envify/loose-envify-1.4.0.tgz create mode 100644 tests/testdata/npm/registry/loose-envify/registry.json create mode 100644 tests/testdata/npm/registry/loupe/loupe-2.3.4.tgz create mode 100644 tests/testdata/npm/registry/loupe/registry.json create mode 100644 tests/testdata/npm/registry/magic-string/magic-string-0.25.9.tgz create mode 100644 tests/testdata/npm/registry/magic-string/registry.json create mode 100644 tests/testdata/npm/registry/mkdirp/mkdirp-1.0.4.tgz create mode 100644 tests/testdata/npm/registry/mkdirp/registry.json create mode 100644 tests/testdata/npm/registry/nan/nan-2.16.0.tgz create mode 100644 tests/testdata/npm/registry/nan/registry.json create mode 100644 tests/testdata/npm/registry/nanoid/nanoid-3.3.4.tgz create mode 100644 tests/testdata/npm/registry/nanoid/registry.json create mode 100644 tests/testdata/npm/registry/node-releases/node-releases-2.0.10.tgz create mode 100644 tests/testdata/npm/registry/node-releases/registry.json create mode 100644 tests/testdata/npm/registry/normalize-range/normalize-range-0.1.2.tgz create mode 100644 tests/testdata/npm/registry/normalize-range/registry.json create mode 100644 tests/testdata/npm/registry/object-keys/object-keys-1.1.1.tgz create mode 100644 tests/testdata/npm/registry/object-keys/registry.json create mode 100644 tests/testdata/npm/registry/p-limit/p-limit-2.3.0.tgz create mode 100644 tests/testdata/npm/registry/p-limit/registry.json create mode 100644 tests/testdata/npm/registry/p-locate/p-locate-4.1.0.tgz create mode 100644 tests/testdata/npm/registry/p-locate/registry.json create mode 100644 tests/testdata/npm/registry/p-try/p-try-2.2.0.tgz create mode 100644 tests/testdata/npm/registry/p-try/registry.json create mode 100644 tests/testdata/npm/registry/path-exists/path-exists-4.0.0.tgz create mode 100644 tests/testdata/npm/registry/path-exists/registry.json create mode 100644 tests/testdata/npm/registry/pathval/pathval-1.1.1.tgz create mode 100644 tests/testdata/npm/registry/pathval/registry.json create mode 100644 tests/testdata/npm/registry/picocolors/picocolors-1.0.0.tgz create mode 100644 tests/testdata/npm/registry/picocolors/registry.json create mode 100644 tests/testdata/npm/registry/postcss-value-parser/postcss-value-parser-4.2.0.tgz create mode 100644 tests/testdata/npm/registry/postcss-value-parser/registry.json create mode 100644 tests/testdata/npm/registry/postcss/postcss-8.4.16.tgz create mode 100644 tests/testdata/npm/registry/postcss/registry.json create mode 100644 tests/testdata/npm/registry/punycode/punycode-2.1.1.tgz create mode 100644 tests/testdata/npm/registry/punycode/registry.json create mode 100644 tests/testdata/npm/registry/react-dom/react-dom-18.2.0.tgz create mode 100644 tests/testdata/npm/registry/react-dom/registry.json create mode 100644 tests/testdata/npm/registry/react/react-18.2.0.tgz create mode 100644 tests/testdata/npm/registry/react/registry.json create mode 100644 tests/testdata/npm/registry/require-directory/registry.json create mode 100644 tests/testdata/npm/registry/require-directory/require-directory-2.1.1.tgz create mode 100644 tests/testdata/npm/registry/require-from-string/registry.json create mode 100644 tests/testdata/npm/registry/require-from-string/require-from-string-2.0.2.tgz create mode 100644 tests/testdata/npm/registry/require-main-filename/registry.json create mode 100644 tests/testdata/npm/registry/require-main-filename/require-main-filename-2.0.0.tgz create mode 100644 tests/testdata/npm/registry/safer-buffer/registry.json create mode 100644 tests/testdata/npm/registry/safer-buffer/safer-buffer-2.1.2.tgz create mode 100644 tests/testdata/npm/registry/scheduler/registry.json create mode 100644 tests/testdata/npm/registry/scheduler/scheduler-0.23.0.tgz create mode 100644 tests/testdata/npm/registry/set-blocking/registry.json create mode 100644 tests/testdata/npm/registry/set-blocking/set-blocking-2.0.0.tgz create mode 100644 tests/testdata/npm/registry/source-map-js/registry.json create mode 100644 tests/testdata/npm/registry/source-map-js/source-map-js-1.0.2.tgz create mode 100644 tests/testdata/npm/registry/source-map/registry.json create mode 100644 tests/testdata/npm/registry/source-map/source-map-0.6.1.tgz create mode 100644 tests/testdata/npm/registry/sourcemap-codec/registry.json create mode 100644 tests/testdata/npm/registry/sourcemap-codec/sourcemap-codec-1.4.8.tgz create mode 100644 tests/testdata/npm/registry/ssh2/registry.json create mode 100644 tests/testdata/npm/registry/ssh2/ssh2-1.11.0.tgz create mode 100644 tests/testdata/npm/registry/string-width/registry.json create mode 100644 tests/testdata/npm/registry/string-width/string-width-2.1.1.tgz create mode 100644 tests/testdata/npm/registry/string-width/string-width-4.2.3.tgz create mode 100644 tests/testdata/npm/registry/strip-ansi/registry.json create mode 100644 tests/testdata/npm/registry/strip-ansi/strip-ansi-4.0.0.tgz create mode 100644 tests/testdata/npm/registry/strip-ansi/strip-ansi-6.0.1.tgz create mode 100644 tests/testdata/npm/registry/strip-final-newline/registry.json create mode 100644 tests/testdata/npm/registry/strip-final-newline/strip-final-newline-2.0.0.tgz create mode 100644 tests/testdata/npm/registry/supports-color/registry.json create mode 100644 tests/testdata/npm/registry/supports-color/supports-color-7.2.0.tgz create mode 100644 tests/testdata/npm/registry/supports-esm/registry.json create mode 100644 tests/testdata/npm/registry/supports-esm/supports-esm-1.0.0.tgz create mode 100644 tests/testdata/npm/registry/tweetnacl/registry.json create mode 100644 tests/testdata/npm/registry/tweetnacl/tweetnacl-0.14.5.tgz create mode 100644 tests/testdata/npm/registry/type-detect/registry.json create mode 100644 tests/testdata/npm/registry/type-detect/type-detect-4.0.8.tgz create mode 100644 tests/testdata/npm/registry/type-fest/registry.json create mode 100644 tests/testdata/npm/registry/type-fest/type-fest-0.20.2.tgz create mode 100644 tests/testdata/npm/registry/universalify/registry.json create mode 100644 tests/testdata/npm/registry/universalify/universalify-2.0.0.tgz create mode 100644 tests/testdata/npm/registry/update-browserslist-db/registry.json create mode 100644 tests/testdata/npm/registry/update-browserslist-db/update-browserslist-db-1.0.10.tgz create mode 100644 tests/testdata/npm/registry/uri-js/registry.json create mode 100644 tests/testdata/npm/registry/uri-js/uri-js-4.4.1.tgz create mode 100644 tests/testdata/npm/registry/vue/registry.json create mode 100644 tests/testdata/npm/registry/vue/vue-3.2.38.tgz create mode 100644 tests/testdata/npm/registry/which-module/registry.json create mode 100644 tests/testdata/npm/registry/which-module/which-module-2.0.0.tgz create mode 100644 tests/testdata/npm/registry/wrap-ansi/registry.json create mode 100644 tests/testdata/npm/registry/wrap-ansi/wrap-ansi-6.2.0.tgz create mode 100644 tests/testdata/npm/registry/y18n/registry.json create mode 100644 tests/testdata/npm/registry/y18n/y18n-4.0.3.tgz create mode 100644 tests/testdata/npm/registry/yargs-parser/registry.json create mode 100644 tests/testdata/npm/registry/yargs-parser/yargs-parser-18.1.3.tgz create mode 100644 tests/testdata/npm/registry/yargs/registry.json create mode 100644 tests/testdata/npm/registry/yargs/yargs-15.4.1.tgz create mode 100644 tests/testdata/npm/reload/main.ts create mode 100644 tests/testdata/npm/remote_npm_specifier/main.out create mode 100644 tests/testdata/npm/remote_npm_specifier/main.ts create mode 100644 tests/testdata/npm/remote_npm_specifier/remote.ts create mode 100644 tests/testdata/npm/require_added_nm_folder/main.js create mode 100644 tests/testdata/npm/require_added_nm_folder/main.out create mode 100644 tests/testdata/npm/require_json/main.js create mode 100644 tests/testdata/npm/require_json/main.out create mode 100644 tests/testdata/npm/require_main/main.js create mode 100644 tests/testdata/npm/require_main/main.out create mode 100644 tests/testdata/npm/require_resolve_url/package.json create mode 100644 tests/testdata/npm/require_resolve_url/url_paths.out create mode 100644 tests/testdata/npm/require_resolve_url/url_paths.ts create mode 100644 tests/testdata/npm/reserved_word_exports/main.out create mode 100644 tests/testdata/npm/reserved_word_exports/main.ts create mode 100644 tests/testdata/npm/run_existing_npm_package/main.out create mode 100644 tests/testdata/npm/run_existing_npm_package/package.json create mode 100644 tests/testdata/npm/run_existing_npm_package_with_subpath/main.out create mode 100644 tests/testdata/npm/run_existing_npm_package_with_subpath/package.json create mode 100644 tests/testdata/npm/sub_paths/main.jsx create mode 100644 tests/testdata/npm/sub_paths/main.out create mode 100644 tests/testdata/npm/tarball_with_global_header/main.js create mode 100644 tests/testdata/npm/tarball_with_global_header/main.out create mode 100644 tests/testdata/npm/translate_cjs_to_esm/main.js create mode 100644 tests/testdata/npm/translate_cjs_to_esm/main.out create mode 100644 tests/testdata/npm/types/main.out create mode 100644 tests/testdata/npm/types/main.ts create mode 100644 tests/testdata/npm/types_ambient_module/import_map.json create mode 100644 tests/testdata/npm/types_ambient_module/main.out create mode 100644 tests/testdata/npm/types_ambient_module/main.ts create mode 100644 tests/testdata/npm/types_ambient_module/main_import_map.out create mode 100644 tests/testdata/npm/types_ambient_module/main_import_map.ts create mode 100644 tests/testdata/npm/types_entry_value_not_exists/main.out create mode 100644 tests/testdata/npm/types_entry_value_not_exists/main.ts create mode 100644 tests/testdata/npm/types_exports_import_types/main.out create mode 100644 tests/testdata/npm/types_exports_import_types/main.ts create mode 100644 tests/testdata/npm/types_no_types_entry/main.out create mode 100644 tests/testdata/npm/types_no_types_entry/main.ts create mode 100644 tests/testdata/npm/typescript_file_in_package/main.out create mode 100644 tests/testdata/npm/typescript_file_in_package/main.ts create mode 100644 tests/testdata/package_json/basic/fail_check.check.out create mode 100644 tests/testdata/package_json/basic/fail_check.ts create mode 100644 tests/testdata/package_json/basic/lib.bench.out create mode 100644 tests/testdata/package_json/basic/lib.bench.ts create mode 100644 tests/testdata/package_json/basic/lib.test.out create mode 100644 tests/testdata/package_json/basic/lib.test.ts create mode 100644 tests/testdata/package_json/basic/lib.ts create mode 100644 tests/testdata/package_json/basic/main.cache.out create mode 100644 tests/testdata/package_json/basic/main.check.out create mode 100644 tests/testdata/package_json/basic/main.info.out create mode 100644 tests/testdata/package_json/basic/main.ts create mode 100644 tests/testdata/package_json/basic/package.json create mode 100644 tests/testdata/package_json/deno_json/deno.json create mode 100644 tests/testdata/package_json/deno_json/main.check.out create mode 100644 tests/testdata/package_json/deno_json/main.out create mode 100644 tests/testdata/package_json/deno_json/main.ts create mode 100644 tests/testdata/package_json/deno_json/other.ts create mode 100644 tests/testdata/package_json/deno_json/package.json create mode 100644 tests/testdata/package_json/invalid_value/error.ts create mode 100644 tests/testdata/package_json/invalid_value/error.ts.out create mode 100644 tests/testdata/package_json/invalid_value/ok.ts create mode 100644 tests/testdata/package_json/invalid_value/ok.ts.out create mode 100644 tests/testdata/package_json/invalid_value/package.json create mode 100644 tests/testdata/package_json/invalid_value/task.out create mode 100644 tests/testdata/publish/deno_jsonc.out create mode 100644 tests/testdata/publish/deno_jsonc/deno.jsonc create mode 100644 tests/testdata/publish/deno_jsonc/mod.ts create mode 100644 tests/testdata/publish/deno_jsonc/std_http.ts create mode 100644 tests/testdata/publish/dry_run.out create mode 100644 tests/testdata/publish/invalid_fast_check.out create mode 100644 tests/testdata/publish/invalid_fast_check/deno.json create mode 100644 tests/testdata/publish/invalid_fast_check/mod.ts create mode 100644 tests/testdata/publish/invalid_import.out create mode 100644 tests/testdata/publish/invalid_import/deno.json create mode 100644 tests/testdata/publish/invalid_import/mod.ts create mode 100644 tests/testdata/publish/invalid_path.out create mode 100644 tests/testdata/publish/invalid_path/deno.json create mode 100644 tests/testdata/publish/invalid_path/mod.ts create mode 100644 tests/testdata/publish/invalid_path/path with spaces.txt create mode 100644 tests/testdata/publish/javascript_decl_file.out create mode 100644 tests/testdata/publish/javascript_decl_file/deno.json create mode 100644 tests/testdata/publish/javascript_decl_file/mod.d.ts create mode 100644 tests/testdata/publish/javascript_decl_file/mod.js create mode 100644 tests/testdata/publish/javascript_missing_decl_file.out create mode 100644 tests/testdata/publish/javascript_missing_decl_file/deno.json create mode 100644 tests/testdata/publish/javascript_missing_decl_file/mod.js create mode 100644 tests/testdata/publish/javascript_missing_decl_file/other.js create mode 100644 tests/testdata/publish/missing_deno_json.out create mode 100644 tests/testdata/publish/missing_deno_json/main.ts create mode 100644 tests/testdata/publish/no_token.out create mode 100644 tests/testdata/publish/no_zap.out create mode 100644 tests/testdata/publish/node_specifier.out create mode 100644 tests/testdata/publish/node_specifier/deno.json create mode 100644 tests/testdata/publish/node_specifier/mod.ts create mode 100644 tests/testdata/publish/successful.out create mode 100644 tests/testdata/publish/successful/deno.json create mode 100644 tests/testdata/publish/successful/mod.ts create mode 100644 tests/testdata/publish/successful/std_http.ts create mode 100644 tests/testdata/publish/symlink.out create mode 100644 tests/testdata/publish/symlink/deno.json create mode 100644 tests/testdata/publish/symlink/mod.ts create mode 120000 tests/testdata/publish/symlink/symlink create mode 100644 tests/testdata/publish/unanalyzable_dynamic_import.out create mode 100644 tests/testdata/publish/unanalyzable_dynamic_import/deno.json create mode 100644 tests/testdata/publish/unanalyzable_dynamic_import/mod.ts create mode 100644 tests/testdata/publish/workspace.out create mode 100644 tests/testdata/publish/workspace/bar/deno.json create mode 100644 tests/testdata/publish/workspace/bar/mod.ts create mode 100644 tests/testdata/publish/workspace/deno.json create mode 100644 tests/testdata/publish/workspace/foo/deno.json create mode 100644 tests/testdata/publish/workspace/foo/mod.ts create mode 100644 tests/testdata/publish/workspace_individual.out create mode 100644 tests/testdata/repl/import_type.ts create mode 100644 tests/testdata/run/001_hello.js create mode 100644 tests/testdata/run/001_hello.js.out create mode 100644 tests/testdata/run/002_hello.ts create mode 100644 tests/testdata/run/002_hello.ts.out create mode 100644 tests/testdata/run/003_relative_import.ts create mode 100644 tests/testdata/run/003_relative_import.ts.out create mode 100644 tests/testdata/run/004_set_timeout.ts create mode 100644 tests/testdata/run/004_set_timeout.ts.out create mode 100644 tests/testdata/run/005_more_imports.ts create mode 100644 tests/testdata/run/005_more_imports.ts.out create mode 100644 tests/testdata/run/006_url_imports.ts create mode 100644 tests/testdata/run/006_url_imports.ts.out create mode 100644 tests/testdata/run/012_async.ts create mode 100644 tests/testdata/run/012_async.ts.out create mode 100644 tests/testdata/run/013_dynamic_import.ts create mode 100644 tests/testdata/run/013_dynamic_import.ts.out create mode 100644 tests/testdata/run/014_duplicate_import.ts create mode 100644 tests/testdata/run/014_duplicate_import.ts.out create mode 100644 tests/testdata/run/015_duplicate_parallel_import.js create mode 100644 tests/testdata/run/015_duplicate_parallel_import.js.out create mode 100644 tests/testdata/run/016_double_await.ts create mode 100644 tests/testdata/run/016_double_await.ts.out create mode 100644 tests/testdata/run/017_import_redirect.ts create mode 100644 tests/testdata/run/017_import_redirect.ts.out create mode 100644 tests/testdata/run/017_import_redirect_info.out create mode 100644 tests/testdata/run/018_async_catch.ts create mode 100644 tests/testdata/run/018_async_catch.ts.out create mode 100644 tests/testdata/run/019_media_types.ts create mode 100644 tests/testdata/run/019_media_types.ts.out create mode 100644 tests/testdata/run/020_json_modules.ts create mode 100644 tests/testdata/run/020_json_modules.ts.out create mode 100644 tests/testdata/run/021_mjs_modules.ts create mode 100644 tests/testdata/run/021_mjs_modules.ts.out create mode 100644 tests/testdata/run/023_no_ext create mode 100644 tests/testdata/run/023_no_ext.out create mode 100644 tests/testdata/run/025_hrtime.ts create mode 100644 tests/testdata/run/025_hrtime.ts.out create mode 100644 tests/testdata/run/025_reload_js_type_error.js create mode 100644 tests/testdata/run/025_reload_js_type_error.js.out create mode 100644 tests/testdata/run/026_redirect_javascript.js create mode 100644 tests/testdata/run/026_redirect_javascript.js.out create mode 100644 tests/testdata/run/027_redirect_typescript.ts create mode 100644 tests/testdata/run/027_redirect_typescript.ts.out create mode 100644 tests/testdata/run/028_args.ts create mode 100644 tests/testdata/run/028_args.ts.out create mode 100644 tests/testdata/run/033_import_map.out create mode 100644 tests/testdata/run/033_import_map_in_config_file.out create mode 100644 tests/testdata/run/033_import_map_in_flag_has_precedence.out create mode 100644 tests/testdata/run/033_import_map_remote.out create mode 100644 tests/testdata/run/035_cached_only_flag.out create mode 100644 tests/testdata/run/038_checkjs.js create mode 100644 tests/testdata/run/038_checkjs.js.out create mode 100644 tests/testdata/run/042_dyn_import_evalcontext.ts create mode 100644 tests/testdata/run/042_dyn_import_evalcontext.ts.out create mode 100644 tests/testdata/run/044_bad_resource.ts create mode 100644 tests/testdata/run/044_bad_resource.ts.out create mode 100644 tests/testdata/run/045_mod.ts create mode 100644 tests/testdata/run/045_output.ts create mode 100644 tests/testdata/run/045_programmatic_proxy_client.ts create mode 100644 tests/testdata/run/045_proxy_client.ts create mode 100644 tests/testdata/run/045_proxy_test.ts create mode 100644 tests/testdata/run/045_proxy_test.ts.out create mode 100644 tests/testdata/run/046_jsx_test.tsx create mode 100644 tests/testdata/run/046_jsx_test.tsx.out create mode 100644 tests/testdata/run/047_jsx_test.jsx create mode 100644 tests/testdata/run/047_jsx_test.jsx.out create mode 100644 tests/testdata/run/048_media_types_jsx.ts create mode 100644 tests/testdata/run/048_media_types_jsx.ts.out create mode 100644 tests/testdata/run/052_no_remote_flag.out create mode 100644 tests/testdata/run/056_make_temp_file_write_perm.out create mode 100644 tests/testdata/run/056_make_temp_file_write_perm.ts create mode 100644 tests/testdata/run/058_tasks_microtasks_close.ts create mode 100644 tests/testdata/run/058_tasks_microtasks_close.ts.out create mode 100644 tests/testdata/run/059_fs_relative_path_perm.ts create mode 100644 tests/testdata/run/059_fs_relative_path_perm.ts.out create mode 100644 tests/testdata/run/061_permissions_request.ts create mode 100644 tests/testdata/run/061_permissions_request_sync.ts create mode 100644 tests/testdata/run/062_permissions_request_global.ts create mode 100644 tests/testdata/run/062_permissions_request_global_sync.ts create mode 100644 tests/testdata/run/063_permissions_revoke.ts create mode 100644 tests/testdata/run/063_permissions_revoke.ts.out create mode 100644 tests/testdata/run/063_permissions_revoke_sync.ts create mode 100644 tests/testdata/run/064_permissions_revoke_global.ts create mode 100644 tests/testdata/run/064_permissions_revoke_global.ts.out create mode 100644 tests/testdata/run/064_permissions_revoke_global_sync.ts create mode 100644 tests/testdata/run/065_permissions_revoke_net.ts create mode 100644 tests/testdata/run/065_permissions_revoke_net.ts.out create mode 100644 tests/testdata/run/066_prompt.ts create mode 100644 tests/testdata/run/070_location.ts create mode 100644 tests/testdata/run/070_location.ts.out create mode 100644 tests/testdata/run/071_location_unset.ts create mode 100644 tests/testdata/run/071_location_unset.ts.out create mode 100644 tests/testdata/run/072_location_relative_fetch.ts create mode 100644 tests/testdata/run/072_location_relative_fetch.ts.out create mode 100644 tests/testdata/run/075_import_local_query_hash.ts create mode 100644 tests/testdata/run/075_import_local_query_hash.ts.out create mode 100644 tests/testdata/run/077_fetch_empty.ts create mode 100644 tests/testdata/run/077_fetch_empty.ts.out create mode 100644 tests/testdata/run/078_unload_on_exit.ts create mode 100644 tests/testdata/run/078_unload_on_exit.ts.out create mode 100644 tests/testdata/run/079_location_authentication.ts create mode 100644 tests/testdata/run/079_location_authentication.ts.out create mode 100644 tests/testdata/run/081_location_relative_fetch_redirect.ts create mode 100644 tests/testdata/run/081_location_relative_fetch_redirect.ts.out create mode 100644 tests/testdata/run/082_prepare_stack_trace_throw.js create mode 100644 tests/testdata/run/082_prepare_stack_trace_throw.js.out create mode 100644 tests/testdata/run/083_legacy_external_source_map.ts create mode 100644 tests/testdata/run/088_dynamic_import_already_evaluating.ts create mode 100644 tests/testdata/run/088_dynamic_import_already_evaluating.ts.out create mode 100644 tests/testdata/run/088_dynamic_import_target.ts create mode 100644 tests/testdata/run/089_run_allow_list.ts create mode 100644 tests/testdata/run/089_run_allow_list.ts.out create mode 100644 tests/testdata/run/090_run_permissions_request.ts create mode 100644 tests/testdata/run/090_run_permissions_request_sync.ts create mode 100644 tests/testdata/run/091_use_define_for_class_fields.ts create mode 100644 tests/testdata/run/091_use_define_for_class_fields.ts.out create mode 100644 tests/testdata/run/092_import_map_unmapped_bare_specifier.ts create mode 100644 tests/testdata/run/092_import_map_unmapped_bare_specifier.ts.out create mode 100644 tests/testdata/run/aggregate_error.out create mode 100644 tests/testdata/run/aggregate_error.ts create mode 100644 tests/testdata/run/async_error.ts create mode 100644 tests/testdata/run/async_error.ts.out create mode 100644 tests/testdata/run/auto_discover_lockfile/deno.json create mode 100644 tests/testdata/run/auto_discover_lockfile/deno.lock create mode 100644 tests/testdata/run/auto_discover_lockfile/main.out create mode 100644 tests/testdata/run/auto_discover_lockfile/main.ts create mode 100644 tests/testdata/run/before_unload.js create mode 100644 tests/testdata/run/before_unload.js.out create mode 100644 tests/testdata/run/blob_gc_finalization.js create mode 100644 tests/testdata/run/blob_gc_finalization.js.out create mode 100644 tests/testdata/run/byte_order_mark.out create mode 100644 tests/testdata/run/byte_order_mark.ts create mode 100644 tests/testdata/run/check_js_points_to_ts/bar.ts create mode 100644 tests/testdata/run/check_js_points_to_ts/foo.d.ts create mode 100644 tests/testdata/run/check_js_points_to_ts/foo.js create mode 100644 tests/testdata/run/check_js_points_to_ts/test.js create mode 100644 tests/testdata/run/check_js_points_to_ts/test.js.out create mode 100644 tests/testdata/run/checkjs.tsconfig.json create mode 100644 tests/testdata/run/cjs_imports/commonjs.cjs create mode 100644 tests/testdata/run/cjs_imports/main.out create mode 100644 tests/testdata/run/cjs_imports/main.ts create mode 100644 tests/testdata/run/classic_workers_event_loop.js create mode 100644 tests/testdata/run/classic_workers_event_loop.js.out create mode 100644 tests/testdata/run/colors_without_globalThis.js create mode 100644 tests/testdata/run/complex_error.ts create mode 100644 tests/testdata/run/complex_error.ts.out create mode 100644 tests/testdata/run/complex_permissions_test.ts create mode 100644 tests/testdata/run/config/main.out create mode 100644 tests/testdata/run/config/main.ts create mode 100644 tests/testdata/run/config/tsconfig.json create mode 100644 tests/testdata/run/config_file_lock_boolean/deno.lock create mode 100644 tests/testdata/run/config_file_lock_boolean/false.json create mode 100644 tests/testdata/run/config_file_lock_boolean/false.main.out create mode 100644 tests/testdata/run/config_file_lock_boolean/main.ts create mode 100644 tests/testdata/run/config_file_lock_boolean/true.json create mode 100644 tests/testdata/run/config_file_lock_boolean/true.main.out create mode 100644 tests/testdata/run/config_file_lock_path.json create mode 100644 tests/testdata/run/config_file_lock_path.out create mode 100644 tests/testdata/run/config_json_import.ts create mode 100644 tests/testdata/run/config_json_import.ts.out create mode 100644 tests/testdata/run/config_types/deno.lock create mode 100644 tests/testdata/run/config_types/main.out create mode 100644 tests/testdata/run/config_types/main.ts create mode 100644 tests/testdata/run/config_types/remote.tsconfig.json create mode 100644 tests/testdata/run/config_types/tsconfig.json create mode 100644 tests/testdata/run/config_types/types.d.ts create mode 100644 tests/testdata/run/custom_inspect_url.js create mode 100644 tests/testdata/run/custom_inspect_url.js.out create mode 100644 tests/testdata/run/decorators/experimental/deno.json create mode 100644 tests/testdata/run/decorators/experimental/no_check/main.out create mode 100644 tests/testdata/run/decorators/experimental/no_check/main.ts create mode 100644 tests/testdata/run/decorators/experimental/runtime/main.out create mode 100644 tests/testdata/run/decorators/experimental/runtime/main.ts create mode 100644 tests/testdata/run/decorators/experimental/ts/main.out create mode 100644 tests/testdata/run/decorators/experimental/ts/main.ts create mode 100644 tests/testdata/run/decorators/tc39_proposal/main.out create mode 100644 tests/testdata/run/decorators/tc39_proposal/main.ts create mode 100644 tests/testdata/run/delete_window.js create mode 100644 tests/testdata/run/deno_exit_tampering.ts create mode 100644 tests/testdata/run/deny_all_permission_args.js create mode 100644 tests/testdata/run/deny_all_permission_args.out create mode 100644 tests/testdata/run/deny_some_permission_args.js create mode 100644 tests/testdata/run/deny_some_permission_args.out create mode 100644 tests/testdata/run/disallow_http_from_https.js create mode 100644 tests/testdata/run/disallow_http_from_https.ts create mode 100644 tests/testdata/run/disallow_http_from_https_js.out create mode 100644 tests/testdata/run/disallow_http_from_https_ts.out create mode 100644 tests/testdata/run/dom_exception_formatting.ts create mode 100644 tests/testdata/run/dom_exception_formatting.ts.out create mode 100644 tests/testdata/run/dynamic_import_already_rejected/error_001.ts create mode 100644 tests/testdata/run/dynamic_import_already_rejected/main.out create mode 100644 tests/testdata/run/dynamic_import_already_rejected/main.ts create mode 100644 tests/testdata/run/dynamic_import_async_error/delayed_error.ts create mode 100644 tests/testdata/run/dynamic_import_async_error/main.out create mode 100644 tests/testdata/run/dynamic_import_async_error/main.ts create mode 100644 tests/testdata/run/dynamic_import_concurrent_non_statically_analyzable/main.out create mode 100644 tests/testdata/run/dynamic_import_concurrent_non_statically_analyzable/main.ts create mode 100644 tests/testdata/run/dynamic_import_concurrent_non_statically_analyzable/mod.ts create mode 100644 tests/testdata/run/dynamic_import_conditional.js create mode 100644 tests/testdata/run/dynamic_import_conditional.js.out create mode 100644 tests/testdata/run/dynamic_import_syntax_error.js create mode 100644 tests/testdata/run/dynamic_import_syntax_error.js.out create mode 100644 tests/testdata/run/dynamic_import_syntax_error_import.js create mode 100644 tests/testdata/run/empty.ts create mode 100644 tests/testdata/run/env_file.out create mode 100644 tests/testdata/run/env_file.ts create mode 100644 tests/testdata/run/env_file_missing.out create mode 100644 tests/testdata/run/error_001.ts create mode 100644 tests/testdata/run/error_001.ts.out create mode 100644 tests/testdata/run/error_002.ts create mode 100644 tests/testdata/run/error_002.ts.out create mode 100644 tests/testdata/run/error_003_typescript.ts create mode 100644 tests/testdata/run/error_003_typescript.ts.out create mode 100644 tests/testdata/run/error_004_missing_module.ts create mode 100644 tests/testdata/run/error_004_missing_module.ts.out create mode 100644 tests/testdata/run/error_005_missing_dynamic_import.ts create mode 100644 tests/testdata/run/error_005_missing_dynamic_import.ts.out create mode 100644 tests/testdata/run/error_006_import_ext_failure.ts create mode 100644 tests/testdata/run/error_006_import_ext_failure.ts.out create mode 100644 tests/testdata/run/error_007_any.ts create mode 100644 tests/testdata/run/error_007_any.ts.out create mode 100644 tests/testdata/run/error_008_checkjs.js create mode 100644 tests/testdata/run/error_008_checkjs.js.out create mode 100644 tests/testdata/run/error_009_extensions_error.js create mode 100644 tests/testdata/run/error_009_extensions_error.js.out create mode 100644 tests/testdata/run/error_009_missing_js_module.disabled create mode 100644 tests/testdata/run/error_011_bad_module_specifier.ts create mode 100644 tests/testdata/run/error_011_bad_module_specifier.ts.out create mode 100644 tests/testdata/run/error_012_bad_dynamic_import_specifier.ts create mode 100644 tests/testdata/run/error_012_bad_dynamic_import_specifier.ts.out create mode 100644 tests/testdata/run/error_013_missing_script.out create mode 100644 tests/testdata/run/error_014_catch_dynamic_import_error.js create mode 100644 tests/testdata/run/error_014_catch_dynamic_import_error.js.out create mode 100644 tests/testdata/run/error_015_dynamic_import_permissions.js create mode 100644 tests/testdata/run/error_015_dynamic_import_permissions.out create mode 100644 tests/testdata/run/error_016_dynamic_import_permissions2.js create mode 100644 tests/testdata/run/error_016_dynamic_import_permissions2.out create mode 100644 tests/testdata/run/error_017_hide_long_source_ts.ts create mode 100644 tests/testdata/run/error_017_hide_long_source_ts.ts.out create mode 100644 tests/testdata/run/error_018_hide_long_source_js.js create mode 100644 tests/testdata/run/error_018_hide_long_source_js.js.out create mode 100644 tests/testdata/run/error_019_stack_function.ts create mode 100644 tests/testdata/run/error_019_stack_function.ts.out create mode 100644 tests/testdata/run/error_020_stack_constructor.ts create mode 100644 tests/testdata/run/error_020_stack_constructor.ts.out create mode 100644 tests/testdata/run/error_021_stack_method.ts create mode 100644 tests/testdata/run/error_021_stack_method.ts.out create mode 100644 tests/testdata/run/error_022_stack_custom_error.ts create mode 100644 tests/testdata/run/error_022_stack_custom_error.ts.out create mode 100644 tests/testdata/run/error_023_stack_async.ts create mode 100644 tests/testdata/run/error_023_stack_async.ts.out create mode 100644 tests/testdata/run/error_024_stack_promise_all.ts create mode 100644 tests/testdata/run/error_024_stack_promise_all.ts.out create mode 100644 tests/testdata/run/error_025_tab_indent create mode 100644 tests/testdata/run/error_025_tab_indent.out create mode 100644 tests/testdata/run/error_026_remote_import_error.ts create mode 100644 tests/testdata/run/error_026_remote_import_error.ts.out create mode 100644 tests/testdata/run/error_cause.ts create mode 100644 tests/testdata/run/error_cause.ts.out create mode 100644 tests/testdata/run/error_cause_recursive.ts create mode 100644 tests/testdata/run/error_cause_recursive.ts.out create mode 100644 tests/testdata/run/error_for_await.ts create mode 100644 tests/testdata/run/error_for_await.ts.out create mode 100644 tests/testdata/run/error_import_map_unable_to_load.out create mode 100644 tests/testdata/run/error_local_static_import_from_remote.js create mode 100644 tests/testdata/run/error_local_static_import_from_remote.js.out create mode 100644 tests/testdata/run/error_local_static_import_from_remote.ts create mode 100644 tests/testdata/run/error_local_static_import_from_remote.ts.out create mode 100644 tests/testdata/run/error_missing_module_named_import.ts create mode 100644 tests/testdata/run/error_missing_module_named_import.ts.out create mode 100644 tests/testdata/run/error_name_non_string.js create mode 100644 tests/testdata/run/error_name_non_string.js.out create mode 100644 tests/testdata/run/error_no_check.ts create mode 100644 tests/testdata/run/error_no_check.ts.out create mode 100644 tests/testdata/run/error_syntax.js create mode 100644 tests/testdata/run/error_syntax.js.out create mode 100644 tests/testdata/run/error_syntax_empty_trailing_line.mjs create mode 100644 tests/testdata/run/error_syntax_empty_trailing_line.mjs.out create mode 100644 tests/testdata/run/error_type_definitions.ts create mode 100644 tests/testdata/run/error_type_definitions.ts.out create mode 100644 tests/testdata/run/error_with_errors_prop.js create mode 100644 tests/testdata/run/error_with_errors_prop.js.out create mode 100644 tests/testdata/run/es_private_fields.js create mode 100644 tests/testdata/run/es_private_fields.js.out create mode 100644 tests/testdata/run/eval_context_throw_dom_exception.js create mode 100644 tests/testdata/run/eval_context_throw_dom_exception.js.out create mode 100644 tests/testdata/run/event_listener_error.ts create mode 100644 tests/testdata/run/event_listener_error.ts.out create mode 100644 tests/testdata/run/event_listener_error_handled.ts create mode 100644 tests/testdata/run/event_listener_error_handled.ts.out create mode 100644 tests/testdata/run/event_listener_error_immediate_exit.ts create mode 100644 tests/testdata/run/event_listener_error_immediate_exit.ts.out create mode 100644 tests/testdata/run/event_listener_error_immediate_exit_worker.ts create mode 100644 tests/testdata/run/event_listener_error_immediate_exit_worker.ts.out create mode 100644 tests/testdata/run/exec_path.ts create mode 100644 tests/testdata/run/exit_error42.ts create mode 100644 tests/testdata/run/exit_error42.ts.out create mode 100644 tests/testdata/run/explicit_resource_management/main.out create mode 100644 tests/testdata/run/explicit_resource_management/main.ts create mode 100644 tests/testdata/run/export_type_def.ts create mode 100644 tests/testdata/run/extension_dynamic_import.ts create mode 100644 tests/testdata/run/extension_dynamic_import.ts.out create mode 100644 tests/testdata/run/extension_import.ts create mode 100644 tests/testdata/run/extension_import.ts.out create mode 100644 tests/testdata/run/fetch/hello.txt create mode 100644 tests/testdata/run/fetch/other.ts create mode 100644 tests/testdata/run/fetch/test.ts create mode 100644 tests/testdata/run/fetch_async_error_stack.ts create mode 100644 tests/testdata/run/fetch_async_error_stack.ts.out create mode 100644 tests/testdata/run/fetch_response_finalization.js create mode 100644 tests/testdata/run/fetch_response_finalization.js.out create mode 100644 tests/testdata/run/finalization_registry.js create mode 100644 tests/testdata/run/finalization_registry.js.out create mode 100644 tests/testdata/run/fix_dynamic_import_errors.js create mode 100644 tests/testdata/run/fix_dynamic_import_errors.js.out create mode 100644 tests/testdata/run/fix_emittable_skipped.js create mode 100644 tests/testdata/run/fix_emittable_skipped.ts.out create mode 100644 tests/testdata/run/fix_js_import_js.ts create mode 100644 tests/testdata/run/fix_js_import_js.ts.out create mode 100644 tests/testdata/run/fix_js_imports.ts create mode 100644 tests/testdata/run/fix_js_imports.ts.out create mode 100644 tests/testdata/run/fix_tsc_file_exists.out create mode 100644 tests/testdata/run/fix_worker_dispatchevent.ts create mode 100644 tests/testdata/run/fix_worker_dispatchevent.ts.out create mode 100644 tests/testdata/run/followup_dyn_import_resolves/main.ts create mode 100644 tests/testdata/run/followup_dyn_import_resolves/main.ts.out create mode 100644 tests/testdata/run/followup_dyn_import_resolves/sub1.ts create mode 100644 tests/testdata/run/followup_dyn_import_resolves/sub2.ts create mode 100644 tests/testdata/run/heapstats.js create mode 100644 tests/testdata/run/heapstats.js.out create mode 100644 tests/testdata/run/http2_request_url.ts create mode 100644 tests/testdata/run/https_import.ts create mode 100644 tests/testdata/run/https_import.ts.out create mode 100644 tests/testdata/run/if_main.ts create mode 100644 tests/testdata/run/if_main.ts.out create mode 100644 tests/testdata/run/import_blob_url.ts create mode 100644 tests/testdata/run/import_blob_url.ts.out create mode 100644 tests/testdata/run/import_blob_url_error_stack.ts create mode 100644 tests/testdata/run/import_blob_url_error_stack.ts.out create mode 100644 tests/testdata/run/import_blob_url_import_relative.ts create mode 100644 tests/testdata/run/import_blob_url_import_relative.ts.out create mode 100644 tests/testdata/run/import_blob_url_imports.ts create mode 100644 tests/testdata/run/import_blob_url_imports.ts.out create mode 100644 tests/testdata/run/import_blob_url_jsx.ts create mode 100644 tests/testdata/run/import_blob_url_jsx.ts.out create mode 100644 tests/testdata/run/import_compression/brotli create mode 100644 tests/testdata/run/import_compression/gziped create mode 100644 tests/testdata/run/import_compression/main.out create mode 100644 tests/testdata/run/import_compression/main.ts create mode 100644 tests/testdata/run/import_data_url.ts create mode 100644 tests/testdata/run/import_data_url.ts.out create mode 100644 tests/testdata/run/import_data_url_error_stack.ts create mode 100644 tests/testdata/run/import_data_url_error_stack.ts.out create mode 100644 tests/testdata/run/import_data_url_import_relative.ts create mode 100644 tests/testdata/run/import_data_url_import_relative.ts.out create mode 100644 tests/testdata/run/import_data_url_imports.ts create mode 100644 tests/testdata/run/import_data_url_imports.ts.out create mode 100644 tests/testdata/run/import_data_url_jsx.ts create mode 100644 tests/testdata/run/import_data_url_jsx.ts.out create mode 100644 tests/testdata/run/import_dynamic_data_url.ts create mode 100644 tests/testdata/run/import_dynamic_data_url.ts.out create mode 100644 tests/testdata/run/import_extensionless.ts create mode 100644 tests/testdata/run/import_extensionless.ts.out create mode 100644 tests/testdata/run/import_file_with_colon.ts create mode 100644 tests/testdata/run/import_file_with_colon.ts.out create mode 100644 tests/testdata/run/import_maps/test_data.ts create mode 100644 tests/testdata/run/import_maps/test_data.ts.out create mode 100644 tests/testdata/run/import_meta/importmap.json create mode 100644 tests/testdata/run/import_meta/main.out create mode 100644 tests/testdata/run/import_meta/main.ts create mode 100644 tests/testdata/run/import_meta/other.ts create mode 100644 tests/testdata/run/import_type.ts create mode 100644 tests/testdata/run/import_type.ts.out create mode 100644 tests/testdata/run/inline_js_source_map.ts create mode 100644 tests/testdata/run/inline_js_source_map_2.js create mode 100644 tests/testdata/run/inline_js_source_map_2.js.out create mode 100644 tests/testdata/run/inline_js_source_map_2.ts create mode 100644 tests/testdata/run/inline_js_source_map_2_with_inline_contents.js create mode 100644 tests/testdata/run/inline_js_source_map_2_with_inline_contents.js.out create mode 100644 tests/testdata/run/inline_js_source_map_with_contents_from_graph.js create mode 100644 tests/testdata/run/inline_js_source_map_with_contents_from_graph.js.out create mode 100644 tests/testdata/run/issue13562.ts create mode 100644 tests/testdata/run/issue13562.ts.out create mode 100644 tests/testdata/run/issue9750.js create mode 100644 tests/testdata/run/js_import_detect.ts create mode 100644 tests/testdata/run/js_import_detect.ts.out create mode 100644 tests/testdata/run/js_root_with_ts_check.js create mode 100644 tests/testdata/run/js_root_with_ts_check.js.out create mode 100644 tests/testdata/run/jsx_import_from_ts.App.jsx create mode 100644 tests/testdata/run/jsx_import_from_ts.ts create mode 100644 tests/testdata/run/jsx_import_from_ts.ts.out create mode 100644 tests/testdata/run/jsx_import_source.out create mode 100644 tests/testdata/run/jsx_import_source_dev.out create mode 100644 tests/testdata/run/jsx_import_source_error.out create mode 100644 tests/testdata/run/jsx_import_source_import_map.out create mode 100644 tests/testdata/run/jsx_import_source_import_map_dev.out create mode 100644 tests/testdata/run/jsx_import_source_no_pragma.tsx create mode 100644 tests/testdata/run/jsx_import_source_pragma.tsx create mode 100644 tests/testdata/run/jsx_import_source_pragma_import_map.tsx create mode 100644 tests/testdata/run/jsx_precompile/no_pragma.out create mode 100644 tests/testdata/run/jsx_precompile/no_pragma.tsx create mode 100644 tests/testdata/run/lock_check_err.json create mode 100644 tests/testdata/run/lock_check_err.out create mode 100644 tests/testdata/run/lock_check_err2.json create mode 100644 tests/testdata/run/lock_check_err2.out create mode 100644 tests/testdata/run/lock_check_ok.json create mode 100644 tests/testdata/run/lock_check_ok2.json create mode 100644 tests/testdata/run/lock_dynamic_imports.json create mode 100644 tests/testdata/run/lock_dynamic_imports.out create mode 100644 tests/testdata/run/lock_only_http_and_https/b.ts create mode 100644 tests/testdata/run/lock_only_http_and_https/deno.lock create mode 100644 tests/testdata/run/lock_only_http_and_https/main.out create mode 100644 tests/testdata/run/lock_only_http_and_https/main.ts create mode 100644 tests/testdata/run/lock_v2_check_err.json create mode 100644 tests/testdata/run/lock_v2_check_err.out create mode 100644 tests/testdata/run/lock_v2_check_err2.json create mode 100644 tests/testdata/run/lock_v2_check_err2.out create mode 100644 tests/testdata/run/lock_v2_check_ok.json create mode 100644 tests/testdata/run/lock_v2_check_ok2.json create mode 100644 tests/testdata/run/lock_v2_dynamic_imports.json create mode 100644 tests/testdata/run/lock_v2_dynamic_imports.out create mode 100644 tests/testdata/run/lock_write_fetch/file_exists.ts create mode 100644 tests/testdata/run/lock_write_fetch/main.out create mode 100644 tests/testdata/run/lock_write_fetch/main.ts create mode 100644 tests/testdata/run/long_data_url_formatting.ts create mode 100644 tests/testdata/run/long_data_url_formatting.ts.out create mode 100644 tests/testdata/run/main_module/main.out create mode 100644 tests/testdata/run/main_module/main.ts create mode 100644 tests/testdata/run/main_module/other.ts create mode 100644 tests/testdata/run/mts_dmts_mjs.out create mode 100644 tests/testdata/run/nested_error/main.ts create mode 100644 tests/testdata/run/nested_error/main.ts.out create mode 100644 tests/testdata/run/no_check_imports_not_used_as_values/hello.ts create mode 100644 tests/testdata/run/no_check_imports_not_used_as_values/main.out create mode 100644 tests/testdata/run/no_check_imports_not_used_as_values/main.ts create mode 100644 tests/testdata/run/no_check_imports_not_used_as_values/preserve_imports.tsconfig.json create mode 100644 tests/testdata/run/no_check_remote.ts create mode 100644 tests/testdata/run/no_check_remote.ts.disabled.out create mode 100644 tests/testdata/run/no_check_remote.ts.enabled.out create mode 100644 tests/testdata/run/no_lock_flag/deno.json create mode 100644 tests/testdata/run/no_lock_flag/deno.lock create mode 100644 tests/testdata/run/no_lock_flag/main.out create mode 100644 tests/testdata/run/no_lock_flag/main.ts create mode 100644 tests/testdata/run/no_mem_cache.js create mode 100644 tests/testdata/run/no_mem_cache.js.out create mode 100644 tests/testdata/run/no_prompt.ts create mode 100644 tests/testdata/run/no_validate_asm.js create mode 100644 tests/testdata/run/node_builtin_modules/mod.js create mode 100644 tests/testdata/run/node_builtin_modules/mod.js.out create mode 100644 tests/testdata/run/node_builtin_modules/mod.ts create mode 100644 tests/testdata/run/node_builtin_modules/mod.ts.out create mode 100644 tests/testdata/run/node_env_var_allowlist.ts create mode 100644 tests/testdata/run/node_env_var_allowlist.ts.out create mode 100644 tests/testdata/run/node_prefix_missing/config.json create mode 100644 tests/testdata/run/node_prefix_missing/import_map.json create mode 100644 tests/testdata/run/node_prefix_missing/main.ts create mode 100644 tests/testdata/run/node_prefix_missing/main.ts.out create mode 100644 tests/testdata/run/node_prefix_missing/main.ts.out_feature_enabled create mode 100644 tests/testdata/run/onload/imported.ts create mode 100644 tests/testdata/run/onload/main.out create mode 100644 tests/testdata/run/onload/main.ts create mode 100644 tests/testdata/run/onload/nest_imported.ts create mode 100644 tests/testdata/run/op_exit_op_set_exit_code_in_worker.ts create mode 100644 tests/testdata/run/op_exit_op_set_exit_code_worker.js create mode 100644 tests/testdata/run/permission_args.out create mode 100644 tests/testdata/run/permission_request_long.ts create mode 100644 tests/testdata/run/permission_test.ts create mode 100644 tests/testdata/run/permissions_cache.ts create mode 100644 tests/testdata/run/permissions_prompt_allow_all.ts create mode 100644 tests/testdata/run/permissions_prompt_allow_all_2.ts create mode 100644 tests/testdata/run/private_field_presence.ts create mode 100644 tests/testdata/run/private_field_presence.ts.out create mode 100644 tests/testdata/run/proto_exploit.js create mode 100644 tests/testdata/run/proto_exploit.js.out create mode 100644 tests/testdata/run/queue_microtask_error.ts create mode 100644 tests/testdata/run/queue_microtask_error.ts.out create mode 100644 tests/testdata/run/queue_microtask_error_handled.ts create mode 100644 tests/testdata/run/queue_microtask_error_handled.ts.out create mode 100644 tests/testdata/run/reference_types.ts create mode 100644 tests/testdata/run/reference_types.ts.out create mode 100644 tests/testdata/run/reference_types_error.js create mode 100644 tests/testdata/run/reference_types_error.js.out create mode 100644 tests/testdata/run/reference_types_remote.ts create mode 100644 tests/testdata/run/reference_types_remote.ts.out create mode 100644 tests/testdata/run/rejection_handled.out create mode 100644 tests/testdata/run/rejection_handled.ts create mode 100644 tests/testdata/run/remote_type_error/main.ts create mode 100644 tests/testdata/run/remote_type_error/remote.ts create mode 100644 tests/testdata/run/replace_self.js create mode 100644 tests/testdata/run/replace_self.js.out create mode 100644 tests/testdata/run/report_error.ts create mode 100644 tests/testdata/run/report_error.ts.out create mode 100644 tests/testdata/run/report_error_end_of_program.ts create mode 100644 tests/testdata/run/report_error_end_of_program.ts.out create mode 100644 tests/testdata/run/report_error_handled.ts create mode 100644 tests/testdata/run/report_error_handled.ts.out create mode 100644 tests/testdata/run/resolve_dns.ts create mode 100644 tests/testdata/run/resolve_dns.ts.out create mode 100644 tests/testdata/run/resolve_dns.zone.in create mode 100644 tests/testdata/run/runtime_decorators.ts create mode 100644 tests/testdata/run/runtime_decorators.ts.out create mode 100644 tests/testdata/run/seed_random.js create mode 100644 tests/testdata/run/seed_random.js.out create mode 100644 tests/testdata/run/set_exit_code_0.ts create mode 100644 tests/testdata/run/set_exit_code_1.ts create mode 100644 tests/testdata/run/set_exit_code_2.ts create mode 100644 tests/testdata/run/set_timeout_error.ts create mode 100644 tests/testdata/run/set_timeout_error.ts.out create mode 100644 tests/testdata/run/set_timeout_error_handled.ts create mode 100644 tests/testdata/run/set_timeout_error_handled.ts.out create mode 100644 tests/testdata/run/shebang.ts create mode 100644 tests/testdata/run/shebang.ts.out create mode 100644 tests/testdata/run/shebang2.ts create mode 100644 tests/testdata/run/single_compile_with_reload.ts create mode 100644 tests/testdata/run/single_compile_with_reload.ts.out create mode 100644 tests/testdata/run/single_compile_with_reload_dyn.ts create mode 100644 tests/testdata/run/single_compile_with_reload_worker.ts create mode 100644 tests/testdata/run/spawn_stdout_inherit.ts create mode 100644 tests/testdata/run/spawn_stdout_inherit.ts.out create mode 100644 tests/testdata/run/stdin_read_all.out create mode 100644 tests/testdata/run/stdin_read_all.ts create mode 100644 tests/testdata/run/stdio_streams_are_locked_in_permission_prompt/worker.js create mode 100644 tests/testdata/run/stdout_write_all.out create mode 100644 tests/testdata/run/stdout_write_all.ts create mode 100644 tests/testdata/run/stdout_write_sync_async.out create mode 100644 tests/testdata/run/stdout_write_sync_async.ts create mode 100644 tests/testdata/run/swc_syntax_error.ts create mode 100644 tests/testdata/run/swc_syntax_error.ts.out create mode 100644 tests/testdata/run/test_and_bench_in_run.js create mode 100644 tests/testdata/run/textproto.ts create mode 100644 tests/testdata/run/tls.out create mode 100644 tests/testdata/run/tls_connecttls.js create mode 100644 tests/testdata/run/tls_starttls.js create mode 100644 tests/testdata/run/top_level_await/circular.js create mode 100644 tests/testdata/run/top_level_await/circular.out create mode 100644 tests/testdata/run/top_level_await/loop.js create mode 100644 tests/testdata/run/top_level_await/loop.out create mode 100644 tests/testdata/run/top_level_await/nested.out create mode 100644 tests/testdata/run/top_level_await/nested/a.js create mode 100644 tests/testdata/run/top_level_await/nested/b.js create mode 100644 tests/testdata/run/top_level_await/nested/main.js create mode 100644 tests/testdata/run/top_level_await/order.js create mode 100644 tests/testdata/run/top_level_await/order.out create mode 100644 tests/testdata/run/top_level_await/tla/a.js create mode 100644 tests/testdata/run/top_level_await/tla/b.js create mode 100644 tests/testdata/run/top_level_await/tla/c.js create mode 100644 tests/testdata/run/top_level_await/tla/d.js create mode 100644 tests/testdata/run/top_level_await/tla/order.js create mode 100644 tests/testdata/run/top_level_await/tla/parent.js create mode 100644 tests/testdata/run/top_level_await/tla2/a.js create mode 100644 tests/testdata/run/top_level_await/tla2/b.js create mode 100644 tests/testdata/run/top_level_await/tla3/b.js create mode 100644 tests/testdata/run/top_level_await/tla3/timeout_loop.js create mode 100644 tests/testdata/run/top_level_await/top_level_await.js create mode 100644 tests/testdata/run/top_level_await/top_level_await.out create mode 100644 tests/testdata/run/top_level_await/top_level_await.ts create mode 100644 tests/testdata/run/top_level_await/top_level_for_await.js create mode 100644 tests/testdata/run/top_level_await/top_level_for_await.out create mode 100644 tests/testdata/run/top_level_await/top_level_for_await.ts create mode 100644 tests/testdata/run/top_level_await/unresolved.js create mode 100644 tests/testdata/run/top_level_await/unresolved.out create mode 100644 tests/testdata/run/ts_import_from_js/deps.js create mode 100644 tests/testdata/run/ts_import_from_js/main.js create mode 100644 tests/testdata/run/ts_import_from_js/main.out create mode 100644 tests/testdata/run/ts_type_imports.ts create mode 100644 tests/testdata/run/ts_type_imports.ts.out create mode 100644 tests/testdata/run/ts_type_imports_foo.ts create mode 100644 tests/testdata/run/ts_type_only_import.d.ts create mode 100644 tests/testdata/run/ts_type_only_import.ts create mode 100644 tests/testdata/run/ts_type_only_import.ts.out create mode 100644 tests/testdata/run/tsx_imports/Component.tsx create mode 100644 tests/testdata/run/tsx_imports/tsx_imports.ts create mode 100644 tests/testdata/run/tsx_imports/tsx_imports.ts.out create mode 100644 tests/testdata/run/type_definitions.ts create mode 100644 tests/testdata/run/type_definitions.ts.out create mode 100644 tests/testdata/run/type_definitions_for_export.ts create mode 100644 tests/testdata/run/type_definitions_for_export.ts.out create mode 100644 tests/testdata/run/type_directives_01.ts create mode 100644 tests/testdata/run/type_directives_01.ts.out create mode 100644 tests/testdata/run/type_directives_02.ts create mode 100644 tests/testdata/run/type_directives_02.ts.out create mode 100644 tests/testdata/run/type_directives_js_main.js create mode 100644 tests/testdata/run/type_directives_redirect.ts create mode 100644 tests/testdata/run/type_directives_redirect.ts.out create mode 100644 tests/testdata/run/type_headers_deno_types.ts create mode 100644 tests/testdata/run/type_headers_deno_types.ts.out create mode 100644 tests/testdata/run/unbuffered_stderr.ts create mode 100644 tests/testdata/run/unbuffered_stderr.ts.out create mode 100644 tests/testdata/run/unbuffered_stdout.ts create mode 100644 tests/testdata/run/unbuffered_stdout.ts.out create mode 100644 tests/testdata/run/unhandled_rejection.ts create mode 100644 tests/testdata/run/unhandled_rejection.ts.out create mode 100644 tests/testdata/run/unhandled_rejection_dynamic_import/import.ts create mode 100644 tests/testdata/run/unhandled_rejection_dynamic_import/main.ts create mode 100644 tests/testdata/run/unhandled_rejection_dynamic_import/main.ts.out create mode 100644 tests/testdata/run/unhandled_rejection_dynamic_import2/import.ts create mode 100644 tests/testdata/run/unhandled_rejection_dynamic_import2/main.ts create mode 100644 tests/testdata/run/unhandled_rejection_dynamic_import2/main.ts.out create mode 100644 tests/testdata/run/unhandled_rejection_sync_error.ts create mode 100644 tests/testdata/run/unhandled_rejection_sync_error.ts.out create mode 100644 tests/testdata/run/unsafe_proto/main.js create mode 100644 tests/testdata/run/unsafe_proto/main.out create mode 100644 tests/testdata/run/unsafe_proto/main_with_unsafe_proto_flag.out create mode 100644 tests/testdata/run/unsafe_proto/worker.js create mode 100644 tests/testdata/run/unstable.js create mode 100644 tests/testdata/run/unstable.ts create mode 100644 tests/testdata/run/unstable_broadcast_channel.disabled.out create mode 100644 tests/testdata/run/unstable_broadcast_channel.enabled.out create mode 100644 tests/testdata/run/unstable_broadcast_channel.js create mode 100644 tests/testdata/run/unstable_cron.disabled.out create mode 100644 tests/testdata/run/unstable_cron.enabled.out create mode 100644 tests/testdata/run/unstable_cron.js create mode 100644 tests/testdata/run/unstable_disabled_js.out create mode 100644 tests/testdata/run/unstable_enabled.out create mode 100644 tests/testdata/run/unstable_enabled_js.out create mode 100644 tests/testdata/run/unstable_ffi.disabled.out create mode 100644 tests/testdata/run/unstable_ffi.enabled.out create mode 100644 tests/testdata/run/unstable_ffi.js create mode 100644 tests/testdata/run/unstable_fs.disabled.out create mode 100644 tests/testdata/run/unstable_fs.enabled.out create mode 100644 tests/testdata/run/unstable_fs.js create mode 100644 tests/testdata/run/unstable_http.disabled.out create mode 100644 tests/testdata/run/unstable_http.enabled.out create mode 100644 tests/testdata/run/unstable_http.js create mode 100644 tests/testdata/run/unstable_kv.disabled.out create mode 100644 tests/testdata/run/unstable_kv.enabled.out create mode 100644 tests/testdata/run/unstable_kv.js create mode 100644 tests/testdata/run/unstable_net.disabled.out create mode 100644 tests/testdata/run/unstable_net.enabled.out create mode 100644 tests/testdata/run/unstable_net.js create mode 100644 tests/testdata/run/unstable_temporal_api/main.out create mode 100644 tests/testdata/run/unstable_temporal_api/main.ts create mode 100644 tests/testdata/run/unstable_temporal_api/missing_flag.js create mode 100644 tests/testdata/run/unstable_temporal_api/missing_flag.out create mode 100644 tests/testdata/run/unstable_webgpu.disabled.out create mode 100644 tests/testdata/run/unstable_webgpu.enabled.out create mode 100644 tests/testdata/run/unstable_webgpu.js create mode 100644 tests/testdata/run/unstable_worker.ts create mode 100644 tests/testdata/run/unstable_worker.ts.out create mode 100644 tests/testdata/run/unstable_worker_options.disabled.out create mode 100644 tests/testdata/run/unstable_worker_options.enabled.out create mode 100644 tests/testdata/run/unstable_worker_options.js create mode 100644 tests/testdata/run/unsupported_dynamic_import_scheme.out create mode 100644 tests/testdata/run/v8_flags.js create mode 100644 tests/testdata/run/v8_flags.js.out create mode 100644 tests/testdata/run/v8_flags_unrecognized.out create mode 100644 tests/testdata/run/v8_help.out create mode 100644 tests/testdata/run/warn_on_deprecated_api/main.js create mode 100644 tests/testdata/run/warn_on_deprecated_api/main.out create mode 100644 tests/testdata/run/warn_on_deprecated_api/main.verbose.out create mode 100644 tests/testdata/run/warn_on_deprecated_api/main_disabled_env.out create mode 100644 tests/testdata/run/warn_on_deprecated_api/main_disabled_flag.out create mode 100644 tests/testdata/run/warn_on_deprecated_api/mod.ts create mode 100644 tests/testdata/run/wasm.ts create mode 100644 tests/testdata/run/wasm.ts.out create mode 100644 tests/testdata/run/wasm_async.js create mode 100644 tests/testdata/run/wasm_async.out create mode 100644 tests/testdata/run/wasm_shared.out create mode 100644 tests/testdata/run/wasm_shared.ts create mode 100644 tests/testdata/run/wasm_streaming_panic_test.js create mode 100644 tests/testdata/run/wasm_streaming_panic_test.js.out create mode 100644 tests/testdata/run/wasm_unreachable.js create mode 100644 tests/testdata/run/wasm_unreachable.out create mode 100644 tests/testdata/run/wasm_url.js create mode 100644 tests/testdata/run/wasm_url.out create mode 100644 tests/testdata/run/weakref.ts create mode 100644 tests/testdata/run/weakref.ts.out create mode 100644 tests/testdata/run/websocket_server_idletimeout.ts create mode 100644 tests/testdata/run/websocket_server_multi_field_connection_header_test.ts create mode 100644 tests/testdata/run/websocketstream_ping_test.ts create mode 100644 tests/testdata/run/webstorage/config_a.jsonc create mode 100644 tests/testdata/run/webstorage/config_b.jsonc create mode 100644 tests/testdata/run/webstorage/fixture.ts create mode 100644 tests/testdata/run/webstorage/logger.ts create mode 100644 tests/testdata/run/webstorage/serialization.ts create mode 100644 tests/testdata/run/webstorage/serialization.ts.out create mode 100644 tests/testdata/run/webstorage/setter.ts create mode 100644 tests/testdata/run/with_config/auto_discovery_log.out create mode 100644 tests/testdata/run/with_config/deno.jsonc create mode 100644 tests/testdata/run/with_config/frontend_work.ts create mode 100644 tests/testdata/run/with_config/no_auto_discovery.out create mode 100644 tests/testdata/run/with_config/server_side_work.ts create mode 100644 tests/testdata/run/with_package_json/no_deno_json/main.out create mode 100644 tests/testdata/run/with_package_json/no_deno_json/main.ts create mode 100644 tests/testdata/run/with_package_json/no_deno_json/no_package_json_imports.out create mode 100644 tests/testdata/run/with_package_json/no_deno_json/no_package_json_imports.ts create mode 100644 tests/testdata/run/with_package_json/no_deno_json/noconfig.out create mode 100644 tests/testdata/run/with_package_json/no_deno_json/noconfig.ts create mode 100644 tests/testdata/run/with_package_json/no_deno_json/package.json create mode 100644 tests/testdata/run/with_package_json/no_deno_json/sub_dir/main.js create mode 100644 tests/testdata/run/with_package_json/no_deno_json/sub_dir/main.out create mode 100644 tests/testdata/run/with_package_json/npm_binary/main.out create mode 100644 tests/testdata/run/with_package_json/npm_binary/package.json create mode 100644 tests/testdata/run/with_package_json/with_stop/main.out create mode 100644 tests/testdata/run/with_package_json/with_stop/package.json create mode 100644 tests/testdata/run/with_package_json/with_stop/some/nested/deno.json create mode 100644 tests/testdata/run/with_package_json/with_stop/some/nested/dir/main.ts create mode 100644 tests/testdata/run/worker_close_in_wasm_reactions.js create mode 100644 tests/testdata/run/worker_close_in_wasm_reactions.js.out create mode 100644 tests/testdata/run/worker_close_nested.js create mode 100644 tests/testdata/run/worker_close_nested.js.out create mode 100644 tests/testdata/run/worker_close_race.js create mode 100644 tests/testdata/run/worker_close_race.js.out create mode 100644 tests/testdata/run/worker_drop_handle_race.js create mode 100644 tests/testdata/run/worker_drop_handle_race.js.out create mode 100644 tests/testdata/run/worker_drop_handle_race_terminate.js create mode 100644 tests/testdata/run/worker_drop_handle_race_terminate.js.out create mode 100644 tests/testdata/run/worker_event_handler_test.js create mode 100644 tests/testdata/run/worker_event_handler_test.js.out create mode 100644 tests/testdata/run/worker_message_before_close.js create mode 100644 tests/testdata/run/worker_message_before_close.js.out create mode 100644 tests/testdata/run/workspaces/basic/bar/deno.json create mode 100644 tests/testdata/run/workspaces/basic/bar/fizz/buzz.ts create mode 100644 tests/testdata/run/workspaces/basic/bar/mod.ts create mode 100644 tests/testdata/run/workspaces/basic/bar/some_mod/hello.ts create mode 100644 tests/testdata/run/workspaces/basic/deno.json create mode 100644 tests/testdata/run/workspaces/basic/foo/bar/hello.ts create mode 100644 tests/testdata/run/workspaces/basic/foo/deno.json create mode 100644 tests/testdata/run/workspaces/basic/foo/fizz/buzz.ts create mode 100644 tests/testdata/run/workspaces/basic/foo/mod.ts create mode 100644 tests/testdata/run/workspaces/basic/main.out create mode 100644 tests/testdata/run/workspaces/basic/main.ts create mode 100644 tests/testdata/run/workspaces/member_outside_root_dir/deno.json create mode 100644 tests/testdata/run/workspaces/member_outside_root_dir/foo/bar/hello.ts create mode 100644 tests/testdata/run/workspaces/member_outside_root_dir/foo/deno.json create mode 100644 tests/testdata/run/workspaces/member_outside_root_dir/foo/fizz/buzz.ts create mode 100644 tests/testdata/run/workspaces/member_outside_root_dir/foo/mod.ts create mode 100644 tests/testdata/run/workspaces/member_outside_root_dir/main.out create mode 100644 tests/testdata/run/workspaces/member_outside_root_dir/main.ts create mode 100644 tests/testdata/run/workspaces/nested_member/bar/deno.json create mode 100644 tests/testdata/run/workspaces/nested_member/bar/fizz/buzz.ts create mode 100644 tests/testdata/run/workspaces/nested_member/bar/mod.ts create mode 100644 tests/testdata/run/workspaces/nested_member/bar/some_mod/hello.ts create mode 100644 tests/testdata/run/workspaces/nested_member/deno.json create mode 100644 tests/testdata/run/workspaces/nested_member/foo/bar/deno.json create mode 100644 tests/testdata/run/workspaces/nested_member/foo/bar/hello.ts create mode 100644 tests/testdata/run/workspaces/nested_member/foo/deno.json create mode 100644 tests/testdata/run/workspaces/nested_member/foo/fizz/buzz.ts create mode 100644 tests/testdata/run/workspaces/nested_member/foo/mod.ts create mode 100644 tests/testdata/run/workspaces/nested_member/main.out create mode 100644 tests/testdata/run/workspaces/nested_member/main.ts create mode 100644 tests/testdata/runtime/esm_imports_a.js create mode 100644 tests/testdata/runtime/esm_imports_b.js create mode 100644 tests/testdata/spawn_kill_permissions.ts create mode 100644 tests/testdata/subdir/CAPITALS/main.js create mode 100644 tests/testdata/subdir/amd_like.js create mode 100644 tests/testdata/subdir/auto_print_hello.ts create mode 100644 tests/testdata/subdir/circular1.ts create mode 100644 tests/testdata/subdir/circular2.ts create mode 100644 tests/testdata/subdir/comment.ts create mode 100644 tests/testdata/subdir/config.json create mode 100644 tests/testdata/subdir/emittable.d.ts create mode 100644 tests/testdata/subdir/evil_remote_import.js create mode 100644 tests/testdata/subdir/export_types.ts create mode 100644 tests/testdata/subdir/foo_types.d.ts create mode 100644 tests/testdata/subdir/form_urlencoded.txt create mode 100644 tests/testdata/subdir/import.mts create mode 100644 tests/testdata/subdir/indirect_import_error.js create mode 100644 tests/testdata/subdir/indirect_throws.js create mode 100644 tests/testdata/subdir/json_1.json create mode 100644 tests/testdata/subdir/json_2.json create mode 100644 tests/testdata/subdir/json_3.json create mode 100644 tests/testdata/subdir/jsx_import_source_no_pragma.tsx create mode 100644 tests/testdata/subdir/main.ts create mode 100644 tests/testdata/subdir/mismatch_ext.ts create mode 100644 tests/testdata/subdir/mod.mjs create mode 100644 tests/testdata/subdir/mod1.ts create mode 100644 tests/testdata/subdir/mod2.ts create mode 100644 tests/testdata/subdir/mod3.js create mode 100644 tests/testdata/subdir/mod4.js create mode 100644 tests/testdata/subdir/mod5.mjs create mode 100644 tests/testdata/subdir/mod6.js create mode 100644 tests/testdata/subdir/mod7.js create mode 100644 tests/testdata/subdir/mod8.js create mode 100644 tests/testdata/subdir/more_decorators.ts create mode 100644 tests/testdata/subdir/mt_application_ecmascript.j2.js create mode 100644 tests/testdata/subdir/mt_application_ecmascript_jsx.j2.jsx create mode 100644 tests/testdata/subdir/mt_application_x_javascript.j4.js create mode 100644 tests/testdata/subdir/mt_application_x_javascript_jsx.j4.jsx create mode 100644 tests/testdata/subdir/mt_application_x_typescript.t4.ts create mode 100644 tests/testdata/subdir/mt_application_x_typescript_tsx.t4.tsx create mode 100644 tests/testdata/subdir/mt_javascript.js create mode 100644 tests/testdata/subdir/mt_javascript_jsx.jsx create mode 100644 tests/testdata/subdir/mt_text_ecmascript.j3.js create mode 100644 tests/testdata/subdir/mt_text_ecmascript_jsx.j3.jsx create mode 100644 tests/testdata/subdir/mt_text_javascript.j1.js create mode 100644 tests/testdata/subdir/mt_text_javascript_jsx.j1.jsx create mode 100644 tests/testdata/subdir/mt_text_typescript.t1.ts create mode 100644 tests/testdata/subdir/mt_text_typescript_tsx.t1.tsx create mode 100644 tests/testdata/subdir/mt_video_mp2t.t3.ts create mode 100644 tests/testdata/subdir/mt_video_mp2t_tsx.t3.tsx create mode 100644 tests/testdata/subdir/mt_video_vdn.t2.ts create mode 100644 tests/testdata/subdir/mt_video_vdn_tsx.t2.tsx create mode 100644 tests/testdata/subdir/no_ext create mode 100644 tests/testdata/subdir/no_js_ext create mode 100644 tests/testdata/subdir/polyfill.ts create mode 100644 tests/testdata/subdir/print_hello.ts create mode 100644 tests/testdata/subdir/redirects/a.ts create mode 100644 tests/testdata/subdir/redirects/b.ts create mode 100644 tests/testdata/subdir/redirects/redirect1.js create mode 100644 tests/testdata/subdir/redirects/redirect1.ts create mode 100644 tests/testdata/subdir/redirects/redirect2.js create mode 100644 tests/testdata/subdir/redirects/redirect3.js create mode 100644 tests/testdata/subdir/redirects/redirect4.ts create mode 100644 tests/testdata/subdir/shebang_file.js create mode 100644 tests/testdata/subdir/single_module.ts create mode 100644 tests/testdata/subdir/subdir2/dynamic_import.ts create mode 100644 tests/testdata/subdir/subdir2/mod2.ts create mode 100644 tests/testdata/subdir/test_worker_basic.js create mode 100644 tests/testdata/subdir/throws.js create mode 100644 tests/testdata/subdir/tla.ts create mode 100644 tests/testdata/subdir/type_and_code.ts create mode 100644 tests/testdata/subdir/type_error.ts create mode 100644 tests/testdata/subdir/type_reference.d.ts create mode 100644 tests/testdata/subdir/type_reference.js create mode 100644 tests/testdata/subdir/types.d.mts create mode 100644 tests/testdata/subdir/unknown_ext.deno create mode 120000 tests/testdata/symlink_to_subdir create mode 100644 tests/testdata/task/both/deno.json create mode 100644 tests/testdata/task/both/deno_selected.out create mode 100644 tests/testdata/task/both/echo.out create mode 100644 tests/testdata/task/both/no_args.out create mode 100644 tests/testdata/task/both/package.json create mode 100644 tests/testdata/task/both/package_json_selected.out create mode 100644 tests/testdata/task/both/prefers_deno.out create mode 100644 tests/testdata/task/deno_json/deno.json create mode 100644 tests/testdata/task/deno_json/task_additional_args.out create mode 100644 tests/testdata/task/deno_json/task_additional_args_nested_strings.out create mode 100644 tests/testdata/task/deno_json/task_additional_args_no_logic.out create mode 100644 tests/testdata/task/deno_json/task_additional_args_no_shell_expansion.out create mode 100644 tests/testdata/task/deno_json/task_boolean_logic.out create mode 100644 tests/testdata/task/deno_json/task_cwd.out create mode 100644 tests/testdata/task/deno_json/task_deno_exe_no_env.out create mode 100644 tests/testdata/task/deno_json/task_exit_code_5.out create mode 100644 tests/testdata/task/deno_json/task_init_cwd.out create mode 100644 tests/testdata/task/deno_json/task_init_cwd_already_set.out create mode 100644 tests/testdata/task/deno_json/task_no_args.out create mode 100644 tests/testdata/task/deno_json/task_non_existent.out create mode 100644 tests/testdata/task/deno_json/task_piped_stdin.out create mode 100644 tests/testdata/task/deno_json_pre_post/bin.out create mode 100644 tests/testdata/task/deno_json_pre_post/deno.json create mode 100644 tests/testdata/task/deno_json_pre_post/echo.out create mode 100644 tests/testdata/task/npx/non_existent.out create mode 100644 tests/testdata/task/npx/on_own.out create mode 100644 tests/testdata/task/npx/package.json create mode 100644 tests/testdata/task/package_json/bin.out create mode 100644 tests/testdata/task/package_json/echo.out create mode 100644 tests/testdata/task/package_json/no_args.out create mode 100644 tests/testdata/task/package_json/package.json create mode 100644 tests/testdata/task/package_json_node_modules_dir_false/bin.out create mode 100644 tests/testdata/task/package_json_node_modules_dir_false/deno.json create mode 100644 tests/testdata/task/package_json_node_modules_dir_false/package.json create mode 100644 tests/testdata/task/package_json_post/bin.out create mode 100644 tests/testdata/task/package_json_post/echo.out create mode 100644 tests/testdata/task/package_json_post/package.json create mode 100644 tests/testdata/task/package_json_post_only/bin.out create mode 100644 tests/testdata/task/package_json_post_only/echo.out create mode 100644 tests/testdata/task/package_json_post_only/package.json create mode 100644 tests/testdata/task/package_json_pre/bin.out create mode 100644 tests/testdata/task/package_json_pre/echo.out create mode 100644 tests/testdata/task/package_json_pre/package.json create mode 100644 tests/testdata/task/package_json_pre_only/bin.out create mode 100644 tests/testdata/task/package_json_pre_only/echo.out create mode 100644 tests/testdata/task/package_json_pre_only/package.json create mode 100644 tests/testdata/task/package_json_pre_post/bin.out create mode 100644 tests/testdata/task/package_json_pre_post/echo.out create mode 100644 tests/testdata/task/package_json_pre_post/package.json create mode 100644 tests/testdata/test/aggregate_error.out create mode 100644 tests/testdata/test/aggregate_error.ts create mode 100644 tests/testdata/test/allow_all.out create mode 100644 tests/testdata/test/allow_all.ts create mode 100644 tests/testdata/test/allow_none.out create mode 100644 tests/testdata/test/allow_none.ts create mode 100644 tests/testdata/test/before_unload_prevent_default.out create mode 100644 tests/testdata/test/before_unload_prevent_default.ts create mode 100644 tests/testdata/test/captured_output.ts create mode 100644 tests/testdata/test/captured_output.worker.js create mode 100644 tests/testdata/test/check_local_by_default.out create mode 100644 tests/testdata/test/check_local_by_default.ts create mode 100644 tests/testdata/test/check_local_by_default2.out create mode 100644 tests/testdata/test/check_local_by_default2.ts create mode 100644 tests/testdata/test/clear_timeout.out create mode 100644 tests/testdata/test/clear_timeout.ts create mode 100644 tests/testdata/test/collect.deprecated.out create mode 100644 tests/testdata/test/collect.out create mode 100644 tests/testdata/test/collect/deno.deprecated.jsonc create mode 100644 tests/testdata/test/collect/deno.jsonc create mode 100644 tests/testdata/test/collect/deno.malformed.jsonc create mode 100644 tests/testdata/test/collect/deno2.jsonc create mode 100644 tests/testdata/test/collect/ignore/test.ts create mode 100644 tests/testdata/test/collect/include.ts create mode 100644 tests/testdata/test/collect/include/2_test.ts create mode 100644 tests/testdata/test/collect/include/test.ts create mode 100644 tests/testdata/test/collect/test.ts create mode 100644 tests/testdata/test/collect2.out create mode 100644 tests/testdata/test/collect_with_malformed_config.out create mode 100644 tests/testdata/test/deno.glob.json create mode 100644 tests/testdata/test/deno_custom_jsx.json create mode 100644 tests/testdata/test/doc.out create mode 100644 tests/testdata/test/doc.ts create mode 100644 tests/testdata/test/doc_only.out create mode 100644 tests/testdata/test/doc_only/mod.ts create mode 100644 tests/testdata/test/exit_sanitizer.out create mode 100644 tests/testdata/test/exit_sanitizer.ts create mode 100644 tests/testdata/test/fail.out create mode 100644 tests/testdata/test/fail.ts create mode 100644 tests/testdata/test/fail_fast.out create mode 100644 tests/testdata/test/fail_fast.ts create mode 100644 tests/testdata/test/fail_fast_other.ts create mode 100644 tests/testdata/test/fail_fast_with_val.out create mode 100644 tests/testdata/test/fail_fast_with_val.ts create mode 100644 tests/testdata/test/file_protocol.out create mode 100644 tests/testdata/test/file_protocol.ts create mode 100644 tests/testdata/test/filter.out create mode 100644 tests/testdata/test/filter/a_test.ts create mode 100644 tests/testdata/test/filter/b_test.ts create mode 100644 tests/testdata/test/filter/c_test.ts create mode 100644 tests/testdata/test/filtered_out_only.out create mode 100644 tests/testdata/test/filtered_out_only.ts create mode 100644 tests/testdata/test/finally_timeout.out create mode 100644 tests/testdata/test/finally_timeout.ts create mode 100644 tests/testdata/test/glob/data/tes.ts create mode 100644 tests/testdata/test/glob/data/test1.js create mode 100644 tests/testdata/test/glob/data/test1.ts create mode 100644 tests/testdata/test/glob/data/test12.ts create mode 100644 tests/testdata/test/glob/nested/fizz/bar.ts create mode 100644 tests/testdata/test/glob/nested/fizz/bazz.ts create mode 100644 tests/testdata/test/glob/nested/fizz/fizz.ts create mode 100644 tests/testdata/test/glob/nested/fizz/foo.ts create mode 100644 tests/testdata/test/glob/nested/foo/bar.ts create mode 100644 tests/testdata/test/glob/nested/foo/bazz.ts create mode 100644 tests/testdata/test/glob/nested/foo/fizz.ts create mode 100644 tests/testdata/test/glob/nested/foo/foo.ts create mode 100644 tests/testdata/test/glob/pages/[id].ts create mode 100644 tests/testdata/test/hello_world.out create mode 100644 tests/testdata/test/hello_world.ts create mode 100644 tests/testdata/test/hide_empty_suites.out create mode 100644 tests/testdata/test/ignore.out create mode 100644 tests/testdata/test/ignore.ts create mode 100644 tests/testdata/test/ignore_permissions.out create mode 100644 tests/testdata/test/ignore_permissions.ts create mode 100644 tests/testdata/test/interval.out create mode 100644 tests/testdata/test/interval.ts create mode 100644 tests/testdata/test/load_unload.out create mode 100644 tests/testdata/test/load_unload.ts create mode 100644 tests/testdata/test/markdown.md create mode 100644 tests/testdata/test/markdown.out create mode 100644 tests/testdata/test/markdown_full_block_names.md create mode 100644 tests/testdata/test/markdown_full_block_names.out create mode 100644 tests/testdata/test/markdown_windows.md create mode 100644 tests/testdata/test/markdown_windows.out create mode 100644 tests/testdata/test/markdown_with_comment.md create mode 100644 tests/testdata/test/markdown_with_comment.out create mode 100644 tests/testdata/test/meta.out create mode 100644 tests/testdata/test/meta.ts create mode 100644 tests/testdata/test/no_check.out create mode 100644 tests/testdata/test/no_check.ts create mode 100644 tests/testdata/test/no_color.ts create mode 100644 tests/testdata/test/no_prompt_by_default.out create mode 100644 tests/testdata/test/no_prompt_by_default.ts create mode 100644 tests/testdata/test/no_prompt_with_denied_perms.out create mode 100644 tests/testdata/test/no_prompt_with_denied_perms.ts create mode 100644 tests/testdata/test/no_run.out create mode 100644 tests/testdata/test/no_run.ts create mode 100644 tests/testdata/test/non_error_thrown.out create mode 100644 tests/testdata/test/non_error_thrown.ts create mode 100644 tests/testdata/test/only.out create mode 100644 tests/testdata/test/only.ts create mode 100644 tests/testdata/test/ops_sanitizer_closed_inside_started_before.out create mode 100644 tests/testdata/test/ops_sanitizer_closed_inside_started_before.ts create mode 100644 tests/testdata/test/ops_sanitizer_missing_details.out create mode 100644 tests/testdata/test/ops_sanitizer_missing_details.ts create mode 100644 tests/testdata/test/ops_sanitizer_multiple_timeout_tests.out create mode 100644 tests/testdata/test/ops_sanitizer_multiple_timeout_tests.ts create mode 100644 tests/testdata/test/ops_sanitizer_multiple_timeout_tests_no_trace.out create mode 100644 tests/testdata/test/ops_sanitizer_nexttick.out create mode 100644 tests/testdata/test/ops_sanitizer_nexttick.ts create mode 100644 tests/testdata/test/ops_sanitizer_step_leak.out create mode 100644 tests/testdata/test/ops_sanitizer_step_leak.ts create mode 100644 tests/testdata/test/ops_sanitizer_timeout_failure.out create mode 100644 tests/testdata/test/ops_sanitizer_timeout_failure.ts create mode 100644 tests/testdata/test/ops_sanitizer_unstable.out create mode 100644 tests/testdata/test/ops_sanitizer_unstable.ts create mode 100644 tests/testdata/test/overloads.out create mode 100644 tests/testdata/test/overloads.ts create mode 100644 tests/testdata/test/parallel_output.out create mode 100644 tests/testdata/test/parallel_output.ts create mode 100644 tests/testdata/test/pass.junit.out create mode 100644 tests/testdata/test/pass.out create mode 100644 tests/testdata/test/pass.ts create mode 100644 tests/testdata/test/quiet.out create mode 100644 tests/testdata/test/quiet.ts create mode 100644 tests/testdata/test/recursive_permissions_pledge.js create mode 100644 tests/testdata/test/relative_pattern_dot_slash/deno.json create mode 100644 tests/testdata/test/relative_pattern_dot_slash/output.out create mode 100644 tests/testdata/test/relative_pattern_dot_slash/test/add.mjs create mode 100644 tests/testdata/test/relative_pattern_dot_slash/test/add.test.mjs create mode 100644 tests/testdata/test/replace_timers.js create mode 100644 tests/testdata/test/replace_timers.js.out create mode 100644 tests/testdata/test/report_error.out create mode 100644 tests/testdata/test/report_error.ts create mode 100644 tests/testdata/test/resource_sanitizer.out create mode 100644 tests/testdata/test/resource_sanitizer.ts create mode 100644 tests/testdata/test/short-pass-jobs-flag-warning.out create mode 100644 tests/testdata/test/short-pass.out create mode 100644 tests/testdata/test/short-pass.ts create mode 100644 tests/testdata/test/shuffle.out create mode 100644 tests/testdata/test/shuffle/bar_test.ts create mode 100644 tests/testdata/test/shuffle/baz_test.ts create mode 100644 tests/testdata/test/shuffle/foo_test.ts create mode 100644 tests/testdata/test/sigint_with_hanging_test.out create mode 100644 tests/testdata/test/sigint_with_hanging_test.ts create mode 100644 tests/testdata/test/steps/failing_steps.dot.out create mode 100644 tests/testdata/test/steps/failing_steps.out create mode 100644 tests/testdata/test/steps/failing_steps.tap.out create mode 100644 tests/testdata/test/steps/failing_steps.ts create mode 100644 tests/testdata/test/steps/ignored_steps.dot.out create mode 100644 tests/testdata/test/steps/ignored_steps.out create mode 100644 tests/testdata/test/steps/ignored_steps.tap.out create mode 100644 tests/testdata/test/steps/ignored_steps.ts create mode 100644 tests/testdata/test/steps/invalid_usage.out create mode 100644 tests/testdata/test/steps/invalid_usage.ts create mode 100644 tests/testdata/test/steps/output_within.out create mode 100644 tests/testdata/test/steps/output_within.ts create mode 100644 tests/testdata/test/steps/passing_steps.dot.out create mode 100644 tests/testdata/test/steps/passing_steps.out create mode 100644 tests/testdata/test/steps/passing_steps.tap.out create mode 100644 tests/testdata/test/steps/passing_steps.ts create mode 100644 tests/testdata/test/text.md create mode 100644 tests/testdata/test/text.out create mode 100644 tests/testdata/test/trace_ops_caught_error/main.out create mode 100644 tests/testdata/test/trace_ops_caught_error/main.ts create mode 100644 tests/testdata/test/uncaught_errors.out create mode 100644 tests/testdata/test/uncaught_errors_1.ts create mode 100644 tests/testdata/test/uncaught_errors_2.ts create mode 100644 tests/testdata/test/uncaught_errors_3.ts create mode 100644 tests/testdata/test/unhandled_rejection.out create mode 100644 tests/testdata/test/unhandled_rejection.ts create mode 100644 tests/testdata/test/unresolved_promise.out create mode 100644 tests/testdata/test/unresolved_promise.ts create mode 100644 tests/testdata/tls/README.md create mode 100644 tests/testdata/tls/RootCA.crt create mode 100644 tests/testdata/tls/RootCA.key create mode 100644 tests/testdata/tls/RootCA.pem create mode 100644 tests/testdata/tls/domains.txt create mode 100644 tests/testdata/tls/invalid.crt create mode 100644 tests/testdata/tls/invalid.key create mode 100644 tests/testdata/tls/localhost.crt create mode 100644 tests/testdata/tls/localhost.key create mode 100644 tests/testdata/tsc/a.js create mode 100644 tests/testdata/tsc/d.ts create mode 100644 tests/testdata/tsc/node_modules/b.js create mode 100644 tests/testdata/tsc/node_modules/c.js create mode 100644 tests/testdata/tsc/test.js create mode 100644 tests/testdata/tsc2/file_exportc.ts create mode 100644 tests/testdata/tsc2/file_libref.ts create mode 100644 tests/testdata/tsc2/file_main.ts create mode 100644 tests/testdata/tsc2/file_reexports.ts create mode 100644 tests/testdata/tsc2/https_deno.land-x-a.ts create mode 100644 tests/testdata/tsc2/https_deno.land-x-b.ts create mode 100644 tests/testdata/tsc2/https_deno.land-x-c.d.ts create mode 100644 tests/testdata/tsc2/https_deno.land-x-c.js create mode 100644 tests/testdata/tsc2/https_deno.land-x-mod.ts create mode 100644 tests/testdata/type_definitions/bar.d.ts create mode 100644 tests/testdata/type_definitions/bar.js create mode 100644 tests/testdata/type_definitions/fizz.d.ts create mode 100644 tests/testdata/type_definitions/fizz.js create mode 100644 tests/testdata/type_definitions/foo.d.ts create mode 100644 tests/testdata/type_definitions/foo.js create mode 100644 tests/testdata/type_definitions/qat.ts create mode 100644 tests/testdata/types/types.out create mode 100644 tests/testdata/vendor/dynamic.ts create mode 100644 tests/testdata/vendor/dynamic_non_analyzable.ts create mode 100644 tests/testdata/vendor/dynamic_non_existent.ts create mode 100644 tests/testdata/vendor/dynamic_non_existent.ts.out create mode 100644 tests/testdata/vendor/logger.ts create mode 100644 tests/testdata/vendor/mod.ts create mode 100644 tests/testdata/vendor/npm_and_node_specifier.ts create mode 100644 tests/testdata/vendor/query_reexport.ts create mode 100644 tests/testdata/webcrypto/id_rsaEncryption.pem create mode 100644 tests/testdata/webcrypto/id_rsassaPss.pem create mode 100644 tests/testdata/webcrypto/id_rsassaPss_default.pem create mode 100644 tests/testdata/webcrypto/id_rsassaPss_saltLen_30.pem create mode 100644 tests/testdata/webgpu/computepass_shader.wgsl create mode 100644 tests/testdata/webgpu/hellotriangle.out create mode 100644 tests/testdata/webgpu/hellotriangle_shader.wgsl create mode 100644 tests/testdata/welcome.ts create mode 100644 tests/testdata/workers/async_error.ts create mode 100644 tests/testdata/workers/bench_large_message.ts create mode 100644 tests/testdata/workers/bench_round_robin.ts create mode 100644 tests/testdata/workers/bench_startup.ts create mode 100644 tests/testdata/workers/bench_worker.ts create mode 100644 tests/testdata/workers/broadcast_channel.ts create mode 100644 tests/testdata/workers/busy_worker.js create mode 100644 tests/testdata/workers/close_in_wasm_reactions.js create mode 100644 tests/testdata/workers/close_nested_child.js create mode 100644 tests/testdata/workers/close_nested_parent.js create mode 100644 tests/testdata/workers/close_race_worker.js create mode 100644 tests/testdata/workers/custom_inspect/main.out create mode 100644 tests/testdata/workers/custom_inspect/main.ts create mode 100644 tests/testdata/workers/custom_inspect/worker.ts create mode 100644 tests/testdata/workers/deno_worker.ts create mode 100644 tests/testdata/workers/drop_handle_race.js create mode 100644 tests/testdata/workers/dynamic_remote.ts create mode 100644 tests/testdata/workers/env_read_check_worker.js create mode 100644 tests/testdata/workers/error.ts create mode 100644 tests/testdata/workers/error_event.ts create mode 100644 tests/testdata/workers/error_event.ts.out create mode 100644 tests/testdata/workers/error_worker_permissions_local.ts create mode 100644 tests/testdata/workers/error_worker_permissions_local.ts.out create mode 100644 tests/testdata/workers/error_worker_permissions_remote.ts create mode 100644 tests/testdata/workers/error_worker_permissions_remote.ts.out create mode 100644 tests/testdata/workers/event_worker.js create mode 100644 tests/testdata/workers/event_worker_scope.js create mode 100644 tests/testdata/workers/fetching_worker.js create mode 100644 tests/testdata/workers/http_worker.js create mode 100644 tests/testdata/workers/image_data_worker.ts create mode 100644 tests/testdata/workers/immediately_close_worker.js create mode 100644 tests/testdata/workers/message_before_close.js create mode 100644 tests/testdata/workers/message_handler_error.ts create mode 100644 tests/testdata/workers/message_port.ts create mode 100644 tests/testdata/workers/nested_worker.js create mode 100644 tests/testdata/workers/no_permissions_worker.js create mode 100644 tests/testdata/workers/non_deno_worker.js create mode 100644 tests/testdata/workers/nonexistent_worker.out create mode 100644 tests/testdata/workers/nonexistent_worker.ts create mode 100644 tests/testdata/workers/parent_read_check_worker.js create mode 100644 tests/testdata/workers/permission_echo.js create mode 100644 tests/testdata/workers/permissions_blob_local.ts create mode 100644 tests/testdata/workers/permissions_blob_local.ts.out create mode 100644 tests/testdata/workers/permissions_blob_remote.ts create mode 100644 tests/testdata/workers/permissions_blob_remote.ts.out create mode 100644 tests/testdata/workers/permissions_data_local.ts create mode 100644 tests/testdata/workers/permissions_data_local.ts.out create mode 100644 tests/testdata/workers/permissions_data_remote.ts create mode 100644 tests/testdata/workers/permissions_data_remote.ts.out create mode 100644 tests/testdata/workers/permissions_dynamic_remote.ts create mode 100644 tests/testdata/workers/permissions_dynamic_remote.ts.out create mode 100644 tests/testdata/workers/permissions_remote_remote.ts create mode 100644 tests/testdata/workers/permissions_remote_remote.ts.out create mode 100644 tests/testdata/workers/post_undefined.ts create mode 100644 tests/testdata/workers/racy_worker.js create mode 100644 tests/testdata/workers/read_check_granular_worker.js create mode 100644 tests/testdata/workers/read_check_worker.js create mode 100644 tests/testdata/workers/shared_array_buffer.ts create mode 100644 tests/testdata/workers/sibling_worker.js create mode 100644 tests/testdata/workers/static_remote.ts create mode 100644 tests/testdata/workers/terminate_tla_crash.js create mode 100644 tests/testdata/workers/terminate_tla_crash.js.out create mode 100644 tests/testdata/workers/test_worker.js create mode 100644 tests/testdata/workers/test_worker.ts create mode 100644 tests/testdata/workers/throwing_worker.js create mode 100644 tests/testdata/workers/worker_async_error.ts create mode 100644 tests/testdata/workers/worker_async_error.ts.out create mode 100644 tests/testdata/workers/worker_crypto.js create mode 100644 tests/testdata/workers/worker_doest_stall_event_loop.ts create mode 100644 tests/testdata/workers/worker_doest_stall_event_loop.ts.out create mode 100644 tests/testdata/workers/worker_error.ts create mode 100644 tests/testdata/workers/worker_error.ts.out create mode 100644 tests/testdata/workers/worker_event_handlers.js create mode 100644 tests/testdata/workers/worker_globals.ts create mode 100644 tests/testdata/workers/worker_large_message.js create mode 100644 tests/testdata/workers/worker_location.ts create mode 100644 tests/testdata/workers/worker_message_handler_error.ts create mode 100644 tests/testdata/workers/worker_message_handler_error.ts.out create mode 100644 tests/testdata/workers/worker_navigator.ts create mode 100644 tests/testdata/workers/worker_nested_error.ts create mode 100644 tests/testdata/workers/worker_nested_error.ts.out create mode 100644 tests/testdata/workers/worker_structured_cloning.ts create mode 100644 tests/testdata/workers/worker_types.ts create mode 100644 tests/testdata/workers/worker_unstable.ts create mode 100644 tests/testdata/workers/worker_with_top_level_await.ts create mode 100644 tests/unit/README.md create mode 100644 tests/unit/abort_controller_test.ts create mode 100644 tests/unit/blob_test.ts create mode 100644 tests/unit/body_test.ts create mode 100644 tests/unit/broadcast_channel_test.ts create mode 100644 tests/unit/buffer_test.ts create mode 100644 tests/unit/build_test.ts create mode 100644 tests/unit/cache_api_test.ts create mode 100644 tests/unit/chmod_test.ts create mode 100644 tests/unit/chown_test.ts create mode 100644 tests/unit/command_test.ts create mode 100644 tests/unit/console_test.ts create mode 100644 tests/unit/copy_file_test.ts create mode 100644 tests/unit/cron_test.ts create mode 100644 tests/unit/custom_event_test.ts create mode 100644 tests/unit/dir_test.ts create mode 100644 tests/unit/dom_exception_test.ts create mode 100644 tests/unit/error_stack_test.ts create mode 100644 tests/unit/error_test.ts create mode 100644 tests/unit/esnext_test.ts create mode 100644 tests/unit/event_target_test.ts create mode 100644 tests/unit/event_test.ts create mode 100644 tests/unit/fetch_test.ts create mode 100644 tests/unit/ffi_test.ts create mode 100644 tests/unit/file_test.ts create mode 100644 tests/unit/filereader_test.ts create mode 100644 tests/unit/files_test.ts create mode 100644 tests/unit/flock_test.ts create mode 100644 tests/unit/fs_events_test.ts create mode 100644 tests/unit/get_random_values_test.ts create mode 100644 tests/unit/globals_test.ts create mode 100644 tests/unit/headers_test.ts create mode 100644 tests/unit/http_test.ts create mode 100644 tests/unit/image_bitmap_test.ts create mode 100644 tests/unit/image_data_test.ts create mode 100644 tests/unit/internals_test.ts create mode 100644 tests/unit/intl_test.ts create mode 100644 tests/unit/io_test.ts create mode 100644 tests/unit/jupyter_test.ts create mode 100644 tests/unit/kv_queue_test.ts create mode 100644 tests/unit/kv_queue_test_no_db_close.ts create mode 100644 tests/unit/kv_queue_undelivered_test.ts create mode 100644 tests/unit/kv_test.ts create mode 100644 tests/unit/link_test.ts create mode 100644 tests/unit/make_temp_test.ts create mode 100644 tests/unit/message_channel_test.ts create mode 100644 tests/unit/mkdir_test.ts create mode 100644 tests/unit/navigator_test.ts create mode 100644 tests/unit/net_test.ts create mode 100644 tests/unit/network_interfaces_test.ts create mode 100644 tests/unit/ops_test.ts create mode 100644 tests/unit/os_test.ts create mode 100644 tests/unit/path_from_url_test.ts create mode 100644 tests/unit/performance_test.ts create mode 100644 tests/unit/permissions_test.ts create mode 100644 tests/unit/process_test.ts create mode 100644 tests/unit/progressevent_test.ts create mode 100644 tests/unit/promise_hooks_test.ts create mode 100644 tests/unit/read_dir_test.ts create mode 100644 tests/unit/read_file_test.ts create mode 100644 tests/unit/read_link_test.ts create mode 100644 tests/unit/read_text_file_test.ts create mode 100644 tests/unit/real_path_test.ts create mode 100644 tests/unit/ref_unref_test.ts create mode 100644 tests/unit/remove_test.ts create mode 100644 tests/unit/rename_test.ts create mode 100644 tests/unit/request_test.ts create mode 100644 tests/unit/resources_test.ts create mode 100644 tests/unit/response_test.ts create mode 100644 tests/unit/serve_test.ts create mode 100644 tests/unit/signal_test.ts create mode 100644 tests/unit/stat_test.ts create mode 100644 tests/unit/stdio_test.ts create mode 100644 tests/unit/streams_test.ts create mode 100644 tests/unit/structured_clone_test.ts create mode 100644 tests/unit/symbol_test.ts create mode 100644 tests/unit/symlink_test.ts create mode 100644 tests/unit/sync_test.ts create mode 100644 tests/unit/test_util.ts create mode 100644 tests/unit/testing_test.ts create mode 100644 tests/unit/text_encoding_test.ts create mode 100644 tests/unit/timers_test.ts create mode 100644 tests/unit/tls_test.ts create mode 100644 tests/unit/truncate_test.ts create mode 100644 tests/unit/tty_color_test.ts create mode 100644 tests/unit/tty_test.ts create mode 100644 tests/unit/umask_test.ts create mode 100644 tests/unit/url_search_params_test.ts create mode 100644 tests/unit/url_test.ts create mode 100644 tests/unit/urlpattern_test.ts create mode 100644 tests/unit/utime_test.ts create mode 100644 tests/unit/version_test.ts create mode 100644 tests/unit/wasm_test.ts create mode 100644 tests/unit/webcrypto_test.ts create mode 100644 tests/unit/webgpu_test.ts create mode 100644 tests/unit/websocket_test.ts create mode 100644 tests/unit/websocketstream_test.ts.disabled create mode 100644 tests/unit/webstorage_test.ts create mode 100644 tests/unit/worker_permissions_test.ts create mode 100644 tests/unit/worker_test.ts create mode 100644 tests/unit/write_file_test.ts create mode 100644 tests/unit/write_text_file_test.ts create mode 100644 tests/unit_node/_fs/_fs_access_test.ts create mode 100644 tests/unit_node/_fs/_fs_appendFile_test.ts create mode 100644 tests/unit_node/_fs/_fs_chmod_test.ts create mode 100644 tests/unit_node/_fs/_fs_chown_test.ts create mode 100644 tests/unit_node/_fs/_fs_close_test.ts create mode 100644 tests/unit_node/_fs/_fs_copy_test.ts create mode 100644 tests/unit_node/_fs/_fs_dir_test.ts create mode 100644 tests/unit_node/_fs/_fs_dirent_test.ts create mode 100644 tests/unit_node/_fs/_fs_exists_test.ts create mode 100644 tests/unit_node/_fs/_fs_fdatasync_test.ts create mode 100644 tests/unit_node/_fs/_fs_fstat_test.ts create mode 100644 tests/unit_node/_fs/_fs_fsync_test.ts create mode 100644 tests/unit_node/_fs/_fs_ftruncate_test.ts create mode 100644 tests/unit_node/_fs/_fs_futimes_test.ts create mode 100644 tests/unit_node/_fs/_fs_handle_test.ts create mode 100644 tests/unit_node/_fs/_fs_link_test.ts create mode 100644 tests/unit_node/_fs/_fs_lstat_test.ts create mode 100644 tests/unit_node/_fs/_fs_mkdir_test.ts create mode 100644 tests/unit_node/_fs/_fs_mkdtemp_test.ts create mode 100644 tests/unit_node/_fs/_fs_open_test.ts create mode 100644 tests/unit_node/_fs/_fs_opendir_test.ts create mode 100644 tests/unit_node/_fs/_fs_readFile_test.ts create mode 100644 tests/unit_node/_fs/_fs_read_test.ts create mode 100644 tests/unit_node/_fs/_fs_readdir_test.ts create mode 100644 tests/unit_node/_fs/_fs_readlink_test.ts create mode 100644 tests/unit_node/_fs/_fs_realpath_test.ts create mode 100644 tests/unit_node/_fs/_fs_rename_test.ts create mode 100644 tests/unit_node/_fs/_fs_rm_test.ts create mode 100644 tests/unit_node/_fs/_fs_rmdir_test.ts create mode 100644 tests/unit_node/_fs/_fs_stat_test.ts create mode 100644 tests/unit_node/_fs/_fs_symlink_test.ts create mode 100644 tests/unit_node/_fs/_fs_truncate_test.ts create mode 100644 tests/unit_node/_fs/_fs_unlink_test.ts create mode 100644 tests/unit_node/_fs/_fs_utimes_test.ts create mode 100644 tests/unit_node/_fs/_fs_watch_test.ts create mode 100644 tests/unit_node/_fs/_fs_writeFile_test.ts create mode 100644 tests/unit_node/_fs/_fs_write_test.ts create mode 100644 tests/unit_node/_fs/testdata/hello.txt create mode 100644 tests/unit_node/_test_utils.ts create mode 100644 tests/unit_node/assertion_error_test.ts create mode 100644 tests/unit_node/async_hooks_test.ts create mode 100644 tests/unit_node/buffer_test.ts create mode 100644 tests/unit_node/child_process_test.ts create mode 100644 tests/unit_node/console_test.ts create mode 100644 tests/unit_node/crypto/crypto_cipher_gcm_test.ts create mode 100644 tests/unit_node/crypto/crypto_cipher_test.ts create mode 100644 tests/unit_node/crypto/crypto_hash_test.ts create mode 100644 tests/unit_node/crypto/crypto_key_test.ts create mode 100644 tests/unit_node/crypto/crypto_sign_test.ts create mode 100644 tests/unit_node/crypto/ec_private_secp256r1.pem create mode 100644 tests/unit_node/crypto/gcmEncryptExtIV128.json create mode 100644 tests/unit_node/crypto/gcmEncryptExtIV256.json create mode 100644 tests/unit_node/dgram_test.ts create mode 100644 tests/unit_node/events_test.ts create mode 100644 tests/unit_node/fs_test.ts create mode 100644 tests/unit_node/http2_test.ts create mode 100644 tests/unit_node/http_test.ts create mode 100644 tests/unit_node/internal/_randomBytes_test.ts create mode 100644 tests/unit_node/internal/_randomFill_test.ts create mode 100644 tests/unit_node/internal/_randomInt_test.ts create mode 100644 tests/unit_node/internal/pbkdf2_test.ts create mode 100644 tests/unit_node/internal/scrypt_test.ts create mode 100644 tests/unit_node/module_test.ts create mode 100644 tests/unit_node/net_test.ts create mode 100644 tests/unit_node/os_test.ts create mode 100644 tests/unit_node/path_test.ts create mode 100644 tests/unit_node/perf_hooks_test.ts create mode 100644 tests/unit_node/process_test.ts create mode 100644 tests/unit_node/querystring_test.ts create mode 100644 tests/unit_node/readline_test.ts create mode 100644 tests/unit_node/repl_test.ts create mode 100644 tests/unit_node/stream_test.ts create mode 100644 tests/unit_node/string_decoder_test.ts create mode 100644 tests/unit_node/testdata/add_global_property.js create mode 100644 tests/unit_node/testdata/add_global_property_run_main.js create mode 100644 tests/unit_node/testdata/binary_stdio.js create mode 100644 tests/unit_node/testdata/child_process_stdio.js create mode 100644 tests/unit_node/testdata/child_process_stdio_012.js create mode 100644 tests/unit_node/testdata/child_process_unref.js create mode 100644 tests/unit_node/testdata/exec_file_text_error.js create mode 100644 tests/unit_node/testdata/exec_file_text_output.js create mode 100644 tests/unit_node/testdata/infinite_loop.js create mode 100644 tests/unit_node/testdata/lorem_ipsum.txt create mode 100644 tests/unit_node/testdata/node_modules/foo/index.js create mode 100644 tests/unit_node/testdata/node_modules/foo/package.json create mode 100644 tests/unit_node/testdata/process_exit.ts create mode 100644 tests/unit_node/testdata/process_exit2.ts create mode 100644 tests/unit_node/testdata/process_really_exit.ts create mode 100644 tests/unit_node/testdata/process_stdin.ts create mode 100644 tests/unit_node/testdata/process_stdin_dummy.txt create mode 100644 tests/unit_node/testdata/rsa_private.pem create mode 100644 tests/unit_node/testdata/rsa_private_pkcs1.pem create mode 100644 tests/unit_node/testdata/rsa_public.pem create mode 100644 tests/unit_node/testdata/worker_module/index.js create mode 100644 tests/unit_node/testdata/worker_module/other_file.js create mode 100644 tests/unit_node/testdata/worker_module/package.json create mode 100644 tests/unit_node/testdata/worker_threads.mjs create mode 100644 tests/unit_node/timers_test.ts create mode 100644 tests/unit_node/tls_test.ts create mode 100644 tests/unit_node/tty_test.ts create mode 100644 tests/unit_node/util_test.ts create mode 100644 tests/unit_node/v8_test.ts create mode 100644 tests/unit_node/vm_test.ts create mode 100644 tests/unit_node/worker_threads_test.ts create mode 100644 tests/unit_node/zlib_test.ts (limited to 'tests') diff --git a/tests/Cargo.toml b/tests/Cargo.toml new file mode 100644 index 000000000..578aaf47b --- /dev/null +++ b/tests/Cargo.toml @@ -0,0 +1,52 @@ +# Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +[package] +name = "cli_tests" +version = "0.0.0" +authors.workspace = true +autotests = false +edition.workspace = true +license.workspace = true +repository.workspace = true + +[lib] +path = "lib.rs" + +[features] +run = [] + +[[test]] +name = "integration_tests" +path = "integration_tests.rs" +required-features = ["run"] + +[dev-dependencies] +bytes.workspace = true +deno_ast.workspace = true +deno_bench_util.workspace = true +deno_cache_dir = { workspace = true } +deno_core = { workspace = true, features = ["include_js_files_for_snapshotting", "unsafe_use_unprotected_platform"] } +deno_fetch.workspace = true +deno_lockfile.workspace = true +deno_tls.workspace = true +fastwebsockets = { workspace = true, features = ["upgrade", "unstable-split"] } +flaky_test = "=0.1.0" +http.workspace = true +http-body-util.workspace = true +hyper.workspace = true +hyper-util.workspace = true +once_cell.workspace = true +os_pipe.workspace = true +pretty_assertions.workspace = true +serde.workspace = true +serde_repr.workspace = true +test_util.workspace = true +tokio.workspace = true +tokio-util.workspace = true +tower-lsp.workspace = true +trust-dns-client = "=0.22.0" +trust-dns-server = "=0.22.1" +url.workspace = true + +[target.'cfg(unix)'.dev-dependencies] +nix.workspace = true diff --git a/tests/config/deno.json b/tests/config/deno.json new file mode 100644 index 000000000..ec93111fd --- /dev/null +++ b/tests/config/deno.json @@ -0,0 +1,5 @@ +{ + "imports": { + "@test_util/": "../../test_util/" + } +} diff --git a/tests/integration/bench_tests.rs b/tests/integration/bench_tests.rs new file mode 100644 index 000000000..f92006eb9 --- /dev/null +++ b/tests/integration/bench_tests.rs @@ -0,0 +1,285 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +use deno_core::url::Url; +use test_util as util; +use util::assert_contains; +use util::assert_not_contains; +use util::env_vars_for_npm_tests; +use util::TestContext; + +itest!(overloads { + args: "bench bench/overloads.ts", + exit_code: 0, + output: "bench/overloads.out", +}); + +itest!(meta { + args: "bench bench/meta.ts", + exit_code: 0, + output: "bench/meta.out", +}); + +itest!(pass { + args: "bench bench/pass.ts", + exit_code: 0, + output: "bench/pass.out", +}); + +itest!(ignore { + args: "bench bench/ignore.ts", + exit_code: 0, + output: "bench/ignore.out", +}); + +itest!(ignore_permissions { + args: "bench bench/ignore_permissions.ts", + exit_code: 0, + output: "bench/ignore_permissions.out", +}); + +itest!(fail { + args: "bench bench/fail.ts", + exit_code: 1, + output: "bench/fail.out", +}); + +itest!(bench_formatting { + args: "bench bench/bench_formatting.ts", + exit_code: 0, + output: "bench/bench_formatting.out", +}); + +itest!(collect { + args: "bench --ignore=bench/collect/ignore bench/collect", + exit_code: 0, + output: "bench/collect.out", +}); + +itest!(load_unload { + args: "bench bench/load_unload.ts", + exit_code: 0, + output: "bench/load_unload.out", +}); + +itest!(interval { + args: "bench bench/interval.ts", + exit_code: 0, + output: "bench/interval.out", +}); + +itest!(quiet { + args: "bench --quiet bench/quiet.ts", + exit_code: 0, + output: "bench/quiet.out", +}); + +itest!(only { + args: "bench bench/only.ts", + exit_code: 1, + output: "bench/only.out", +}); + +itest!(multifile_summary { + args: "bench bench/group_baseline.ts bench/pass.ts bench/multiple_group.ts", + exit_code: 0, + output: "bench/multifile_summary.out", +}); + +itest!(no_check { + args: "bench --no-check bench/no_check.ts", + exit_code: 1, + output: "bench/no_check.out", +}); + +itest!(allow_all { + args: "bench --allow-all bench/allow_all.ts", + exit_code: 0, + output: "bench/allow_all.out", +}); + +itest!(allow_none { + args: "bench bench/allow_none.ts", + exit_code: 1, + output: "bench/allow_none.out", +}); + +itest!(exit_sanitizer { + args: "bench bench/exit_sanitizer.ts", + output: "bench/exit_sanitizer.out", + exit_code: 1, +}); + +itest!(clear_timeout { + args: "bench bench/clear_timeout.ts", + exit_code: 0, + output: "bench/clear_timeout.out", +}); + +itest!(finally_timeout { + args: "bench bench/finally_timeout.ts", + exit_code: 1, + output: "bench/finally_timeout.out", +}); + +itest!(before_unload_prevent_default { + args: "bench --quiet bench/before_unload_prevent_default.ts", + output: "bench/before_unload_prevent_default.out", +}); + +itest!(group_baseline { + args: "bench bench/group_baseline.ts", + exit_code: 0, + output: "bench/group_baseline.out", +}); + +itest!(unresolved_promise { + args: "bench bench/unresolved_promise.ts", + exit_code: 1, + output: "bench/unresolved_promise.out", +}); + +itest!(unhandled_rejection { + args: "bench bench/unhandled_rejection.ts", + exit_code: 1, + output: "bench/unhandled_rejection.out", +}); + +itest!(filter { + args: "bench --filter=foo bench/filter", + exit_code: 0, + output: "bench/filter.out", +}); + +itest!(no_run { + args: "bench --no-run bench/no_run.ts", + output: "bench/no_run.out", + exit_code: 1, +}); + +itest!(no_prompt_by_default { + args: "bench --quiet bench/no_prompt_by_default.ts", + exit_code: 1, + output: "bench/no_prompt_by_default.out", +}); + +itest!(no_prompt_with_denied_perms { + args: "bench --quiet --allow-read bench/no_prompt_with_denied_perms.ts", + exit_code: 1, + output: "bench/no_prompt_with_denied_perms.out", +}); + +itest!(check_local_by_default { + args: "bench --quiet bench/check_local_by_default.ts", + output: "bench/check_local_by_default.out", + http_server: true, +}); + +itest!(check_local_by_default2 { + args: "bench --quiet bench/check_local_by_default2.ts", + output: "bench/check_local_by_default2.out", + http_server: true, + exit_code: 1, +}); + +itest!(bench_explicit_start_end { + args: "bench --quiet -A bench/explicit_start_and_end.ts", + output: "bench/explicit_start_and_end.out", + exit_code: 1, +}); + +itest_flaky!(bench_explicit_start_end_low_precision { + args: "bench --quiet -A bench/explicit_start_and_end_low_precision.ts", + output: "bench/explicit_start_and_end_low_precision.out", +}); + +itest!(bench_with_config { + args: "bench --config bench/collect/deno.jsonc bench/collect", + exit_code: 0, + output: "bench/collect.out", +}); + +itest!(bench_with_config2 { + args: "bench --config bench/collect/deno2.jsonc bench/collect", + exit_code: 0, + output: "bench/collect2.out", +}); + +itest!(bench_with_malformed_config { + args: "bench --config bench/collect/deno.malformed.jsonc", + exit_code: 1, + output: "bench/collect_with_malformed_config.out", +}); + +itest!(json_output { + args: "bench --json bench/pass.ts", + exit_code: 0, + output: "bench/pass.json.out", +}); + +#[test] +fn recursive_permissions_pledge() { + let context = TestContext::default(); + let output = context + .new_command() + .args("bench bench/recursive_permissions_pledge.js") + .run(); + output.assert_exit_code(1); + assert_contains!( + output.combined_output(), + "pledge test permissions called before restoring previous pledge" + ); +} + +#[test] +fn file_protocol() { + let file_url = + Url::from_file_path(util::testdata_path().join("bench/file_protocol.ts")) + .unwrap() + .to_string(); + let context = TestContext::default(); + context + .new_command() + .args(format!("bench bench/file_protocol.ts {file_url}")) + .run() + .assert_matches_file("bench/file_protocol.out"); +} + +itest!(package_json_basic { + args: "bench", + output: "package_json/basic/lib.bench.out", + envs: env_vars_for_npm_tests(), + http_server: true, + cwd: Some("package_json/basic"), + copy_temp_dir: Some("package_json/basic"), + exit_code: 0, +}); + +itest!(bench_lock { + args: "bench", + http_server: true, + cwd: Some("lockfile/basic"), + exit_code: 10, + output: "lockfile/basic/fail.out", +}); + +itest!(bench_no_lock { + args: "bench --no-lock", + http_server: true, + cwd: Some("lockfile/basic"), + output: "lockfile/basic/bench.nolock.out", +}); + +#[test] +fn conditionally_loads_type_graph() { + let context = TestContext::default(); + let output = context + .new_command() + .args("bench --reload -L debug run/type_directives_js_main.js") + .run(); + output.assert_matches_text("[WILDCARD] - FileFetcher::fetch() - specifier: file:///[WILDCARD]/subdir/type_reference.d.ts[WILDCARD]"); + let output = context + .new_command() + .args("bench --reload -L debug --no-check run/type_directives_js_main.js") + .run(); + assert_not_contains!(output.combined_output(), "type_reference.d.ts"); +} diff --git a/tests/integration/bundle_tests.rs b/tests/integration/bundle_tests.rs new file mode 100644 index 000000000..08e3fb06a --- /dev/null +++ b/tests/integration/bundle_tests.rs @@ -0,0 +1,482 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +use test_util as util; +use test_util::assert_contains; +use test_util::assert_ends_with; +use test_util::TempDir; + +#[test] +fn bundle_exports() { + // First we have to generate a bundle of some module that has exports. + let mod1 = util::testdata_path().join("subdir/mod1.ts"); + assert!(mod1.is_file()); + let t = TempDir::new(); + let bundle = t.path().join("mod1.bundle.js"); + let mut deno = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("bundle") + .arg(mod1) + .arg(&bundle) + .spawn() + .unwrap(); + let status = deno.wait().unwrap(); + assert!(status.success()); + assert!(bundle.is_file()); + + // Now we try to use that bundle from another module. + let test = t.path().join("test.js"); + std::fs::write( + &test, + " + import { printHello3 } from \"./mod1.bundle.js\"; + printHello3(); ", + ) + .unwrap(); + + let output = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg(&test) + .output() + .unwrap(); + // check the output of the test.ts program. + assert_ends_with!( + std::str::from_utf8(&output.stdout).unwrap().trim(), + "Hello", + ); + assert_eq!(output.stderr, b""); +} + +#[test] +fn bundle_exports_no_check() { + // First we have to generate a bundle of some module that has exports. + let mod1 = util::testdata_path().join("subdir/mod1.ts"); + assert!(mod1.is_file()); + let t = TempDir::new(); + let bundle = t.path().join("mod1.bundle.js"); + let mut deno = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("bundle") + .arg(mod1) + .arg(&bundle) + .spawn() + .unwrap(); + let status = deno.wait().unwrap(); + assert!(status.success()); + assert!(bundle.is_file()); + + // Now we try to use that bundle from another module. + let test = t.path().join("test.js"); + std::fs::write( + &test, + " + import { printHello3 } from \"./mod1.bundle.js\"; + printHello3(); ", + ) + .unwrap(); + + let output = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg(&test) + .output() + .unwrap(); + // check the output of the test.ts program. + assert_ends_with!( + std::str::from_utf8(&output.stdout).unwrap().trim(), + "Hello", + ); + assert_eq!(output.stderr, b""); +} + +#[test] +fn bundle_circular() { + // First we have to generate a bundle of some module that has exports. + let circular1_path = util::testdata_path().join("subdir/circular1.ts"); + assert!(circular1_path.is_file()); + let t = TempDir::new(); + let bundle_path = t.path().join("circular1.bundle.js"); + + // run this twice to ensure it works even when cached + for _ in 0..2 { + let mut deno = util::deno_cmd_with_deno_dir(&t) + .current_dir(util::testdata_path()) + .arg("bundle") + .arg(&circular1_path) + .arg(&bundle_path) + .spawn() + .unwrap(); + let status = deno.wait().unwrap(); + assert!(status.success()); + assert!(bundle_path.is_file()); + } + + let output = util::deno_cmd_with_deno_dir(&t) + .current_dir(util::testdata_path()) + .arg("run") + .arg(&bundle_path) + .output() + .unwrap(); + // check the output of the the bundle program. + assert_ends_with!( + std::str::from_utf8(&output.stdout).unwrap().trim(), + "f2\nf1", + ); + assert_eq!(output.stderr, b""); +} + +#[test] +fn bundle_single_module() { + // First we have to generate a bundle of some module that has exports. + let single_module = util::testdata_path().join("subdir/single_module.ts"); + assert!(single_module.is_file()); + let t = TempDir::new(); + let bundle = t.path().join("single_module.bundle.js"); + let mut deno = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("bundle") + .arg(single_module) + .arg(&bundle) + .spawn() + .unwrap(); + let status = deno.wait().unwrap(); + assert!(status.success()); + assert!(bundle.is_file()); + + let output = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg(&bundle) + .output() + .unwrap(); + // check the output of the the bundle program. + assert_ends_with!( + std::str::from_utf8(&output.stdout).unwrap().trim(), + "Hello world!", + ); + assert_eq!(output.stderr, b""); +} + +#[test] +fn bundle_tla() { + // First we have to generate a bundle of some module that has exports. + let tla_import = util::testdata_path().join("subdir/tla.ts"); + assert!(tla_import.is_file()); + let t = TempDir::new(); + let bundle = t.path().join("tla.bundle.js"); + let mut deno = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("bundle") + .arg(tla_import) + .arg(&bundle) + .spawn() + .unwrap(); + let status = deno.wait().unwrap(); + assert!(status.success()); + assert!(bundle.is_file()); + + // Now we try to use that bundle from another module. + let test = t.path().join("test.js"); + std::fs::write( + &test, + " + import { foo } from \"./tla.bundle.js\"; + console.log(foo); ", + ) + .unwrap(); + + let output = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg(&test) + .output() + .unwrap(); + // check the output of the test.ts program. + assert_ends_with!( + std::str::from_utf8(&output.stdout).unwrap().trim(), + "Hello", + ); + assert_eq!(output.stderr, b""); +} + +#[test] +fn bundle_js() { + // First we have to generate a bundle of some module that has exports. + let mod6 = util::testdata_path().join("subdir/mod6.js"); + assert!(mod6.is_file()); + let t = TempDir::new(); + let bundle = t.path().join("mod6.bundle.js"); + let mut deno = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("bundle") + .arg(mod6) + .arg(&bundle) + .spawn() + .unwrap(); + let status = deno.wait().unwrap(); + assert!(status.success()); + assert!(bundle.is_file()); + + let output = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg(&bundle) + .output() + .unwrap(); + // check that nothing went to stderr + assert_eq!(output.stderr, b""); +} + +#[test] +fn bundle_dynamic_import() { + let _g = util::http_server(); + let dynamic_import = util::testdata_path().join("bundle/dynamic_import.ts"); + assert!(dynamic_import.is_file()); + let t = TempDir::new(); + let output_path = t.path().join("bundle_dynamic_import.bundle.js"); + let mut deno = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("bundle") + .arg(dynamic_import) + .arg(&output_path) + .spawn() + .unwrap(); + let status = deno.wait().unwrap(); + assert!(status.success()); + assert!(output_path.is_file()); + + let output = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg("--allow-net") + .arg("--quiet") + .arg(&output_path) + .output() + .unwrap(); + // check the output of the test.ts program. + assert_ends_with!( + std::str::from_utf8(&output.stdout).unwrap().trim(), + "Hello", + ); + assert_eq!(output.stderr, b""); +} + +#[test] +fn bundle_import_map() { + let import = util::testdata_path().join("bundle/import_map/main.ts"); + let import_map_path = + util::testdata_path().join("bundle/import_map/import_map.json"); + assert!(import.is_file()); + let t = TempDir::new(); + let output_path = t.path().join("import_map.bundle.js"); + let mut deno = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("bundle") + .arg("--import-map") + .arg(import_map_path) + .arg(import) + .arg(&output_path) + .spawn() + .unwrap(); + let status = deno.wait().unwrap(); + assert!(status.success()); + assert!(output_path.is_file()); + + // Now we try to use that bundle from another module. + let test = t.path().join("test.js"); + std::fs::write( + &test, + " + import { printHello3 } from \"./import_map.bundle.js\"; + printHello3(); ", + ) + .unwrap(); + + let output = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg("--check") + .arg(&test) + .output() + .unwrap(); + // check the output of the test.ts program. + assert_ends_with!( + std::str::from_utf8(&output.stdout).unwrap().trim(), + "Hello", + ); + assert_eq!(output.stderr, b""); +} + +#[test] +fn bundle_import_map_no_check() { + let import = util::testdata_path().join("bundle/import_map/main.ts"); + let import_map_path = + util::testdata_path().join("bundle/import_map/import_map.json"); + assert!(import.is_file()); + let t = TempDir::new(); + let output_path = t.path().join("import_map.bundle.js"); + let mut deno = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("bundle") + .arg("--import-map") + .arg(import_map_path) + .arg(import) + .arg(&output_path) + .spawn() + .unwrap(); + let status = deno.wait().unwrap(); + assert!(status.success()); + assert!(output_path.is_file()); + + // Now we try to use that bundle from another module. + let test = t.path().join("test.js"); + std::fs::write( + &test, + " + import { printHello3 } from \"./import_map.bundle.js\"; + printHello3(); ", + ) + .unwrap(); + + let output = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg(&test) + .output() + .unwrap(); + // check the output of the test.ts program. + assert_ends_with!( + std::str::from_utf8(&output.stdout).unwrap().trim(), + "Hello", + ); + assert_eq!(output.stderr, b""); +} + +#[test] +fn bundle_json_module() { + // First we have to generate a bundle of some module that has exports. + let mod7 = util::testdata_path().join("subdir/mod7.js"); + assert!(mod7.is_file()); + let t = TempDir::new(); + let bundle = t.path().join("mod7.bundle.js"); + let mut deno = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("bundle") + .arg(mod7) + .arg(&bundle) + .spawn() + .unwrap(); + let status = deno.wait().unwrap(); + assert!(status.success()); + assert!(bundle.is_file()); + + let output = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg(&bundle) + .output() + .unwrap(); + // check that nothing went to stderr + assert_eq!(output.stderr, b""); + // ensure the output looks right + assert_contains!(String::from_utf8(output.stdout).unwrap(), "with space",); +} + +#[test] +fn bundle_json_module_escape_sub() { + // First we have to generate a bundle of some module that has exports. + let mod8 = util::testdata_path().join("subdir/mod8.js"); + assert!(mod8.is_file()); + let t = TempDir::new(); + let bundle = t.path().join("mod8.bundle.js"); + let mut deno = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("bundle") + .arg(mod8) + .arg(&bundle) + .spawn() + .unwrap(); + let status = deno.wait().unwrap(); + assert!(status.success()); + assert!(bundle.is_file()); + + let output = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg(&bundle) + .output() + .unwrap(); + // check that nothing went to stderr + assert_eq!(output.stderr, b""); + // make sure the output looks right and the escapes were effective + assert_contains!( + String::from_utf8(output.stdout).unwrap(), + "${globalThis}`and string literal`", + ); +} + +itest!(lockfile_check_error { + args: "bundle --lock=bundle/lockfile/check_error.json http://127.0.0.1:4545/subdir/mod1.ts", + output: "bundle/lockfile/check_error.out", + exit_code: 10, + http_server: true, +}); + +itest!(bundle { + args: "bundle subdir/mod1.ts", + output: "bundle/bundle.test.out", +}); + +itest!(bundle_jsx { + args: "bundle run/jsx_import_from_ts.ts", + output: "bundle/jsx.out", +}); + +itest!(error_bundle_with_bare_import { + args: "bundle bundle/bare_imports/error_with_bare_import.ts", + output: "bundle/bare_imports/error_with_bare_import.ts.out", + exit_code: 1, +}); + +itest!(ts_decorators_bundle { + args: "bundle bundle/decorators/ts_decorators.ts", + output: "bundle/decorators/ts_decorators.out", +}); + +itest!(bundle_export_specifier_with_alias { + args: "bundle bundle/file_tests-fixture16.ts", + output: "bundle/fixture16.out", +}); + +itest!(bundle_ignore_directives { + args: "bundle subdir/mod1.ts", + output: "bundle/ignore_directives.test.out", +}); + +itest!(check_local_by_default_no_errors { + args: "bundle --quiet bundle/check_local_by_default/no_errors.ts", + output: "bundle/check_local_by_default/no_errors.out", + http_server: true, +}); + +itest!(check_local_by_default_type_error { + args: "bundle --quiet bundle/check_local_by_default/type_error.ts", + output: "bundle/check_local_by_default/type_error.out", + http_server: true, + exit_code: 1, +}); + +itest!(ts_without_extension { + args: "bundle --ext ts file_extensions/ts_without_extension", + output: "bundle/file_extensions/ts_without_extension.out", +}); + +itest!(js_without_extension { + args: "bundle --ext js file_extensions/js_without_extension", + output: "bundle/file_extensions/js_without_extension.out", +}); + +itest!(bundle_shebang_file { + args: "bundle subdir/shebang_file.js", + output: "bundle/shebang_file.bundle.out", +}); diff --git a/tests/integration/cache_tests.rs b/tests/integration/cache_tests.rs new file mode 100644 index 000000000..2aa0f9d8b --- /dev/null +++ b/tests/integration/cache_tests.rs @@ -0,0 +1,186 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +use test_util::env_vars_for_npm_tests; +use test_util::TestContext; +use test_util::TestContextBuilder; + +itest!(_036_import_map_fetch { + args: + "cache --quiet --reload --import-map=import_maps/import_map.json import_maps/test.ts", + output: "cache/036_import_map_fetch.out", + }); + +itest!(_037_fetch_multiple { + args: "cache --reload --check=all run/fetch/test.ts run/fetch/other.ts", + http_server: true, + output: "cache/037_fetch_multiple.out", +}); + +itest!(_095_cache_with_bare_import { + args: "cache cache/095_cache_with_bare_import.ts", + output: "cache/095_cache_with_bare_import.ts.out", + exit_code: 1, +}); + +itest!(cache_extensionless { + args: "cache --reload --check=all http://localhost:4545/subdir/no_js_ext", + output: "cache/cache_extensionless.out", + http_server: true, +}); + +itest!(cache_random_extension { + args: + "cache --reload --check=all http://localhost:4545/subdir/no_js_ext@1.0.0", + output: "cache/cache_random_extension.out", + http_server: true, +}); + +itest!(performance_stats { + args: "cache --reload --check=all --log-level debug run/002_hello.ts", + output: "cache/performance_stats.out", +}); + +itest!(redirect_cache { + http_server: true, + args: + "cache --reload --check=all http://localhost:4548/subdir/redirects/a.ts", + output: "cache/redirect_cache.out", +}); + +itest!(ignore_require { + args: "cache --reload --no-check cache/ignore_require.js", + output_str: Some(""), + exit_code: 0, +}); + +// This test only runs on linux, because it hardcodes the XDG_CACHE_HOME env var +// which is only used on linux. +#[cfg(target_os = "linux")] +#[test] +fn xdg_cache_home_dir() { + let context = TestContext::with_http_server(); + let deno_dir = context.temp_dir(); + let xdg_cache_home = deno_dir.path().join("cache"); + context + .new_command() + .env_remove("HOME") + .env_remove("DENO_DIR") + .env_clear() + .env("XDG_CACHE_HOME", &xdg_cache_home) + .args( + "cache --reload --no-check http://localhost:4548/subdir/redirects/a.ts", + ) + .run() + .skip_output_check() + .assert_exit_code(0); + assert!(xdg_cache_home.read_dir().count() > 0); +} + +itest!(check_local_by_default { + args: "cache --quiet cache/check_local_by_default.ts", + output: "cache/check_local_by_default.out", + http_server: true, +}); + +itest!(check_local_by_default2 { + args: "cache --quiet cache/check_local_by_default2.ts", + output: "cache/check_local_by_default2.out", + http_server: true, +}); + +itest!(json_import { + // should not error + args: "cache --quiet cache/json_import/main.ts", +}); + +itest!(package_json_basic { + args: "cache main.ts", + output: "package_json/basic/main.cache.out", + envs: env_vars_for_npm_tests(), + http_server: true, + cwd: Some("package_json/basic"), + copy_temp_dir: Some("package_json/basic"), + exit_code: 0, +}); + +#[test] +fn cache_matching_package_json_dep_should_not_install_all() { + let context = TestContextBuilder::for_npm().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + temp_dir.write( + "package.json", + r#"{ "dependencies": { "@types/node": "18.8.2", "@denotest/esm-basic": "*" } }"#, + ); + let output = context + .new_command() + .args("cache npm:@types/node@18.8.2") + .run(); + output.assert_matches_text(concat!( + "Download http://localhost:4545/npm/registry/@types/node\n", + "Download http://localhost:4545/npm/registry/@types/node/node-18.8.2.tgz\n", + "Initialize @types/node@18.8.2\n", + )); +} + +// Regression test for https://github.com/denoland/deno/issues/17299 +#[test] +fn cache_put_overwrite() { + let test_context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = test_context.temp_dir(); + + let part_one = r#" + const req = new Request('http://localhost/abc'); + const res1 = new Response('res1'); + const res2 = new Response('res2'); + + const cache = await caches.open('test'); + + await cache.put(req, res1); + await cache.put(req, res2); + + const res = await cache.match(req).then((res) => res?.text()); + console.log(res); + "#; + + let part_two = r#" + const req = new Request("http://localhost/abc"); + const res1 = new Response("res1"); + const res2 = new Response("res2"); + + const cache = await caches.open("test"); + + // Swap the order of put() calls. + await cache.put(req, res2); + await cache.put(req, res1); + + const res = await cache.match(req).then((res) => res?.text()); + console.log(res); + "#; + + temp_dir.write("cache_put.js", part_one); + + let run_command = + test_context.new_command().args_vec(["run", "cache_put.js"]); + + let output = run_command.run(); + output.assert_matches_text("res2\n"); + output.assert_exit_code(0); + + // The wait will surface the bug as we check last written time + // when we overwrite a response. + std::thread::sleep(std::time::Duration::from_secs(1)); + + temp_dir.write("cache_put.js", part_two); + let output = run_command.run(); + output.assert_matches_text("res1\n"); + output.assert_exit_code(0); +} + +#[test] +fn loads_type_graph() { + let output = TestContext::default() + .new_command() + .args("cache --reload -L debug run/type_directives_js_main.js") + .run(); + output.assert_matches_text("[WILDCARD] - FileFetcher::fetch() - specifier: file:///[WILDCARD]/subdir/type_reference.d.ts[WILDCARD]"); +} diff --git a/tests/integration/cert_tests.rs b/tests/integration/cert_tests.rs new file mode 100644 index 000000000..9e89a9f3e --- /dev/null +++ b/tests/integration/cert_tests.rs @@ -0,0 +1,299 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +use deno_tls::rustls; +use deno_tls::rustls_pemfile; +use deno_tls::rustls_tokio_stream::TlsStream; +use std::io::BufReader; +use std::io::Cursor; +use std::io::Read; +use std::sync::Arc; +use test_util as util; +use url::Url; +use util::testdata_path; +use util::TestContext; + +itest_flaky!(cafile_url_imports { + args: "run --quiet --reload --cert tls/RootCA.pem cert/cafile_url_imports.ts", + output: "cert/cafile_url_imports.ts.out", + http_server: true, +}); + +itest_flaky!(cafile_ts_fetch { + args: + "run --quiet --reload --allow-net --cert tls/RootCA.pem cert/cafile_ts_fetch.ts", + output: "cert/cafile_ts_fetch.ts.out", + http_server: true, +}); + +itest_flaky!(cafile_eval { + args: "eval --cert tls/RootCA.pem fetch('https://localhost:5545/cert/cafile_ts_fetch.ts.out').then(r=>r.text()).then(t=>console.log(t.trimEnd()))", + output: "cert/cafile_ts_fetch.ts.out", + http_server: true, +}); + +itest_flaky!(cafile_info { + args: + "info --quiet --cert tls/RootCA.pem https://localhost:5545/cert/cafile_info.ts", + output: "cert/cafile_info.ts.out", + http_server: true, +}); + +itest_flaky!(cafile_url_imports_unsafe_ssl { + args: "run --quiet --reload --unsafely-ignore-certificate-errors=localhost cert/cafile_url_imports.ts", + output: "cert/cafile_url_imports_unsafe_ssl.ts.out", + http_server: true, +}); + +itest_flaky!(cafile_ts_fetch_unsafe_ssl { + args: + "run --quiet --reload --allow-net --unsafely-ignore-certificate-errors cert/cafile_ts_fetch.ts", + output: "cert/cafile_ts_fetch_unsafe_ssl.ts.out", + http_server: true, +}); + +// TODO(bartlomieju): reenable, this test was flaky on macOS CI during 1.30.3 release +// itest!(deno_land_unsafe_ssl { +// args: +// "run --quiet --reload --allow-net --unsafely-ignore-certificate-errors=deno.land cert/deno_land_unsafe_ssl.ts", +// output: "cert/deno_land_unsafe_ssl.ts.out", +// }); + +itest!(ip_address_unsafe_ssl { + args: + "run --quiet --reload --allow-net --unsafely-ignore-certificate-errors=1.1.1.1 cert/ip_address_unsafe_ssl.ts", + output: "cert/ip_address_unsafe_ssl.ts.out", +}); + +itest!(localhost_unsafe_ssl { + args: "run --quiet --reload --allow-net --unsafely-ignore-certificate-errors=deno.land cert/cafile_url_imports.ts", + output: "cert/localhost_unsafe_ssl.ts.out", + http_server: true, + exit_code: 1, +}); + +#[flaky_test::flaky_test] +fn cafile_env_fetch() { + let module_url = + Url::parse("https://localhost:5545/cert/cafile_url_imports.ts").unwrap(); + let context = TestContext::with_http_server(); + let cafile = testdata_path().join("tls/RootCA.pem"); + + context + .new_command() + .args(format!("cache {module_url}")) + .env("DENO_CERT", cafile) + .run() + .assert_exit_code(0) + .skip_output_check(); +} + +#[flaky_test::flaky_test] +fn cafile_fetch() { + let module_url = + Url::parse("http://localhost:4545/cert/cafile_url_imports.ts").unwrap(); + let context = TestContext::with_http_server(); + let cafile = testdata_path().join("tls/RootCA.pem"); + context + .new_command() + .args(format!("cache --quiet --cert {} {}", cafile, module_url,)) + .run() + .assert_exit_code(0) + .assert_matches_text(""); +} + +#[test] +fn cafile_compile() { + let context = TestContext::with_http_server(); + let temp_dir = context.temp_dir().path(); + let output_exe = if cfg!(windows) { + temp_dir.join("cert.exe") + } else { + temp_dir.join("cert") + }; + let output = context.new_command() + .args(format!("compile --quiet --cert ./tls/RootCA.pem --allow-net --output {} ./cert/cafile_ts_fetch.ts", output_exe)) + .run(); + output.skip_output_check(); + + context + .new_command() + .name(output_exe) + .run() + .assert_matches_text("[WILDCARD]\nHello\n"); +} + +#[flaky_test::flaky_test] +fn cafile_install_remote_module() { + let context = TestContext::with_http_server(); + let temp_dir = context.temp_dir(); + let bin_dir = temp_dir.path().join("bin"); + bin_dir.create_dir_all(); + let cafile = util::testdata_path().join("tls/RootCA.pem"); + + let install_output = context + .new_command() + .args_vec([ + "install", + "--cert", + &cafile.to_string_lossy(), + "--root", + &temp_dir.path().to_string_lossy(), + "-n", + "echo_test", + "https://localhost:5545/echo.ts", + ]) + .split_output() + .run(); + println!("{}", install_output.stdout()); + eprintln!("{}", install_output.stderr()); + install_output.assert_exit_code(0); + + let mut echo_test_path = bin_dir.join("echo_test"); + if cfg!(windows) { + echo_test_path = echo_test_path.with_extension("cmd"); + } + assert!(echo_test_path.exists()); + + let output = context + .new_command() + .name(echo_test_path) + .args("foo") + .env("PATH", util::target_dir()) + .run(); + output.assert_matches_text("[WILDCARD]foo"); +} + +#[flaky_test::flaky_test] +fn cafile_bundle_remote_exports() { + let context = TestContext::with_http_server(); + + // First we have to generate a bundle of some remote module that has exports. + let mod1 = "https://localhost:5545/subdir/mod1.ts"; + let cafile = util::testdata_path().join("tls/RootCA.pem"); + let t = context.temp_dir(); + let bundle = t.path().join("mod1.bundle.js"); + context + .new_command() + .args_vec([ + "bundle", + "--cert", + &cafile.to_string_lossy(), + mod1, + &bundle.to_string_lossy(), + ]) + .run() + .skip_output_check() + .assert_exit_code(0); + + assert!(bundle.is_file()); + + // Now we try to use that bundle from another module. + let test = t.path().join("test.js"); + test.write( + "import { printHello3 } from \"./mod1.bundle.js\"; +printHello3();", + ); + + context + .new_command() + .args_vec(["run", "--quiet", "--check", &test.to_string_lossy()]) + .run() + .assert_matches_text("[WILDCARD]Hello\n") + .assert_exit_code(0); +} + +#[tokio::test] +async fn listen_tls_alpn() { + let mut child = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg("--unstable") + .arg("--quiet") + .arg("--allow-net") + .arg("--allow-read") + .arg("./cert/listen_tls_alpn.ts") + .arg("4504") + .stdout_piped() + .spawn() + .unwrap(); + let stdout = child.stdout.as_mut().unwrap(); + let mut msg = [0; 5]; + let read = stdout.read(&mut msg).unwrap(); + assert_eq!(read, 5); + assert_eq!(&msg, b"READY"); + + let mut reader = &mut BufReader::new(Cursor::new(include_bytes!( + "../testdata/tls/RootCA.crt" + ))); + let certs = rustls_pemfile::certs(&mut reader).unwrap(); + let mut root_store = rustls::RootCertStore::empty(); + root_store.add_parsable_certificates(&certs); + let mut cfg = rustls::ClientConfig::builder() + .with_safe_defaults() + .with_root_certificates(root_store) + .with_no_client_auth(); + cfg.alpn_protocols.push(b"foobar".to_vec()); + let cfg = Arc::new(cfg); + + let hostname = rustls::ServerName::try_from("localhost").unwrap(); + + let tcp_stream = tokio::net::TcpStream::connect("localhost:4504") + .await + .unwrap(); + let mut tls_stream = + TlsStream::new_client_side(tcp_stream, cfg, hostname, None); + + let handshake = tls_stream.handshake().await.unwrap(); + + assert_eq!(handshake.alpn, Some(b"foobar".to_vec())); + + let status = child.wait().unwrap(); + assert!(status.success()); +} + +#[tokio::test] +async fn listen_tls_alpn_fail() { + let mut child = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg("--unstable") + .arg("--quiet") + .arg("--allow-net") + .arg("--allow-read") + .arg("./cert/listen_tls_alpn_fail.ts") + .arg("4505") + .stdout_piped() + .spawn() + .unwrap(); + let stdout = child.stdout.as_mut().unwrap(); + let mut msg = [0; 5]; + let read = stdout.read(&mut msg).unwrap(); + assert_eq!(read, 5); + assert_eq!(&msg, b"READY"); + + let mut reader = &mut BufReader::new(Cursor::new(include_bytes!( + "../testdata/tls/RootCA.crt" + ))); + let certs = rustls_pemfile::certs(&mut reader).unwrap(); + let mut root_store = rustls::RootCertStore::empty(); + root_store.add_parsable_certificates(&certs); + let mut cfg = rustls::ClientConfig::builder() + .with_safe_defaults() + .with_root_certificates(root_store) + .with_no_client_auth(); + cfg.alpn_protocols.push(b"boofar".to_vec()); + let cfg = Arc::new(cfg); + + let hostname = rustls::ServerName::try_from("localhost").unwrap(); + + let tcp_stream = tokio::net::TcpStream::connect("localhost:4505") + .await + .unwrap(); + let mut tls_stream = + TlsStream::new_client_side(tcp_stream, cfg, hostname, None); + + tls_stream.handshake().await.unwrap_err(); + + let status = child.wait().unwrap(); + assert!(status.success()); +} diff --git a/tests/integration/check_tests.rs b/tests/integration/check_tests.rs new file mode 100644 index 000000000..f836957ce --- /dev/null +++ b/tests/integration/check_tests.rs @@ -0,0 +1,419 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +use test_util as util; +use util::env_vars_for_npm_tests; +use util::TestContext; +use util::TestContextBuilder; + +itest!(_095_check_with_bare_import { + args: "check cache/095_cache_with_bare_import.ts", + output: "cache/095_cache_with_bare_import.ts.out", + exit_code: 1, +}); + +itest!(check_extensionless { + args: "check --reload http://localhost:4545/subdir/no_js_ext", + output: "cache/cache_extensionless.out", + http_server: true, +}); + +itest!(check_random_extension { + args: "check --reload http://localhost:4545/subdir/no_js_ext@1.0.0", + output: "cache/cache_random_extension.out", + http_server: true, +}); + +itest!(check_all { + args: "check --quiet --all check/all/check_all.ts", + output: "check/all/check_all.out", + http_server: true, + exit_code: 1, +}); + +itest!(check_all_local { + args: "check --quiet check/all/check_all.ts", + output_str: Some(""), + http_server: true, +}); + +itest!(module_detection_force { + args: "check --quiet check/module_detection_force/main.ts", + output_str: Some(""), +}); + +// Regression test for https://github.com/denoland/deno/issues/14937. +itest!(declaration_header_file_with_no_exports { + args: "check --quiet check/declaration_header_file_with_no_exports.ts", + output_str: Some(""), +}); + +itest!(check_jsximportsource_importmap_config { + args: "check --quiet --config check/jsximportsource_importmap_config/deno.json check/jsximportsource_importmap_config/main.tsx", + output_str: Some(""), +}); + +itest!(bundle_jsximportsource_importmap_config { + args: "bundle --quiet --config check/jsximportsource_importmap_config/deno.json check/jsximportsource_importmap_config/main.tsx", + output: "check/jsximportsource_importmap_config/main.bundle.js", +}); + +itest!(jsx_not_checked { + args: "check check/jsx_not_checked/main.jsx", + output: "check/jsx_not_checked/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, + exit_code: 1, +}); + +itest!(check_npm_install_diagnostics { + args: "check --quiet check/npm_install_diagnostics/main.ts", + output: "check/npm_install_diagnostics/main.out", + envs: vec![("NO_COLOR".to_string(), "1".to_string())], + exit_code: 1, +}); + +itest!(check_export_equals_declaration_file { + args: "check --quiet check/export_equals_declaration_file/main.ts", + exit_code: 0, +}); + +itest!(check_static_response_json { + args: "check --quiet check/response_json.ts", + exit_code: 0, +}); + +itest!(check_node_builtin_modules_ts { + args: "check --quiet check/node_builtin_modules/mod.ts", + output: "check/node_builtin_modules/mod.ts.out", + envs: env_vars_for_npm_tests(), + exit_code: 1, + http_server: true, +}); + +itest!(check_node_builtin_modules_js { + args: "check --quiet check/node_builtin_modules/mod.js", + output: "check/node_builtin_modules/mod.js.out", + envs: env_vars_for_npm_tests(), + exit_code: 1, + http_server: true, +}); + +itest!(check_no_error_truncation { + args: "check --quiet check/no_error_truncation/main.ts --config check/no_error_truncation/deno.json", + output: "check/no_error_truncation/main.out", + envs: vec![("NO_COLOR".to_string(), "1".to_string())], + exit_code: 1, +}); + +itest!(check_broadcast_channel { + args: "check --quiet check/broadcast_channel.ts", + exit_code: 0, +}); + +itest!(check_deno_not_found { + args: "check --quiet check/deno_not_found/main.ts", + output: "check/deno_not_found/main.out", + exit_code: 1, +}); + +itest!(check_with_exclude_option_by_dir { + args: + "check --quiet --config check/exclude_option/deno.exclude_dir.json check/exclude_option/ignored/index.ts", + output_str: Some(""), + exit_code: 0, +}); + +itest!(check_with_exclude_option_by_glob { + args: + "check --quiet --config check/exclude_option/deno.exclude_glob.json check/exclude_option/ignored/index.ts", + output_str: Some(""), + exit_code: 0, +}); + +itest!(check_without_exclude_option { + args: + "check --quiet --config check/exclude_option/deno.json check/exclude_option/ignored/index.ts", + output: "check/exclude_option/exclude_option.ts.error.out", + exit_code: 1, +}); + +itest!(check_imported_files_listed_in_exclude_option { + args: + "check --quiet --config check/exclude_option/deno.exclude_dir.json check/exclude_option/index.ts", + output: "check/exclude_option/exclude_option.ts.error.out", + exit_code: 1, +}); + +itest!(check_with_excluded_file_specified { + args: "check lib/types.d.ts", + cwd: Some("check/excluded_file_specified/"), + output: "check/excluded_file_specified/check.out", +}); + +#[test] +fn cache_switching_config_then_no_config() { + let context = TestContext::default(); + + assert!(does_type_checking(&context, true)); + assert!(does_type_checking(&context, false)); + + // should now not do type checking even when it changes + // configs because it previously did + assert!(!does_type_checking(&context, true)); + assert!(!does_type_checking(&context, false)); + + fn does_type_checking(context: &TestContext, with_config: bool) -> bool { + let mut args = vec![ + "check".to_string(), + "check/cache_config_on_off/main.ts".to_string(), + ]; + if with_config { + let mut slice = vec![ + "--config".to_string(), + "check/cache_config_on_off/deno.json".to_string(), + ]; + args.append(&mut slice); + } + + let output = context.new_command().args_vec(args).split_output().run(); + + output.assert_exit_code(0); + + let stderr = output.stderr(); + stderr.contains("Check") + } +} + +#[test] +fn reload_flag() { + // should do type checking whenever someone specifies --reload + let context = TestContext::default(); + + assert!(does_type_checking(&context, false)); + assert!(!does_type_checking(&context, false)); + assert!(does_type_checking(&context, true)); + assert!(does_type_checking(&context, true)); + assert!(!does_type_checking(&context, false)); + + fn does_type_checking(context: &TestContext, reload: bool) -> bool { + let mut args = vec![ + "check".to_string(), + "check/cache_config_on_off/main.ts".to_string(), + ]; + if reload { + let mut slice = vec!["--reload".to_string()]; + args.append(&mut slice); + } + let output = context.new_command().args_vec(args).split_output().run(); + output.assert_exit_code(0); + + let stderr = output.stderr(); + stderr.contains("Check") + } +} + +#[test] +fn typecheck_declarations_ns() { + let context = TestContext::default(); + let args = vec![ + "test".to_string(), + "--doc".to_string(), + util::root_path() + .join("cli/tsc/dts/lib.deno.ns.d.ts") + .to_string_lossy() + .into_owned(), + ]; + let output = context.new_command().args_vec(args).split_output().run(); + + println!("stdout: {}", output.stdout()); + println!("stderr: {}", output.stderr()); + output.assert_exit_code(0); +} + +#[test] +fn typecheck_declarations_unstable() { + let context = TestContext::default(); + let args = vec![ + "test".to_string(), + "--doc".to_string(), + "--unstable".to_string(), + util::root_path() + .join("cli/tsc/dts/lib.deno.unstable.d.ts") + .to_string_lossy() + .into_owned(), + ]; + let output = context.new_command().args_vec(args).split_output().run(); + + println!("stdout: {}", output.stdout()); + println!("stderr: {}", output.stderr()); + output.assert_exit_code(0); +} + +#[test] +fn ts_no_recheck_on_redirect() { + let test_context = TestContext::default(); + let check_command = test_context.new_command().args_vec([ + "run", + "--check", + "run/017_import_redirect.ts", + ]); + + // run once + let output = check_command.run(); + output.assert_matches_text("[WILDCARD]Check file://[WILDCARD]"); + + // run again + let output = check_command.run(); + output.assert_matches_text("Hello\n"); +} + +itest!(check_dts { + args: "check --quiet check/dts/check_dts.d.ts", + output: "check/dts/check_dts.out", + exit_code: 1, +}); + +itest!(check_types_dts { + args: "check main.ts", + cwd: Some("check/types_dts/"), + output: "check/types_dts/main.out", + exit_code: 0, +}); + +itest!(package_json_basic { + args: "check main.ts", + output: "package_json/basic/main.check.out", + envs: env_vars_for_npm_tests(), + http_server: true, + cwd: Some("package_json/basic"), + copy_temp_dir: Some("package_json/basic"), + exit_code: 0, +}); + +itest!(package_json_fail_check { + args: "check --quiet fail_check.ts", + output: "package_json/basic/fail_check.check.out", + envs: env_vars_for_npm_tests(), + http_server: true, + cwd: Some("package_json/basic"), + copy_temp_dir: Some("package_json/basic"), + exit_code: 1, +}); + +itest!(package_json_with_deno_json { + args: "check --quiet main.ts", + output: "package_json/deno_json/main.check.out", + cwd: Some("package_json/deno_json/"), + copy_temp_dir: Some("package_json/deno_json/"), + envs: env_vars_for_npm_tests(), + http_server: true, + exit_code: 1, +}); + +#[test] +fn check_error_in_dep_then_fix() { + let test_context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = test_context.temp_dir(); + let correct_code = + "export function greet(name: string) {\n return `Hello ${name}`;\n}\n"; + let incorrect_code = + "export function greet(name: number) {\n return `Hello ${name}`;\n}\n"; + + temp_dir.write( + "main.ts", + "import { greet } from './greet.ts';\n\nconsole.log(greet('world'));\n", + ); + temp_dir.write("greet.ts", incorrect_code); + + let check_command = test_context.new_command().args_vec(["check", "main.ts"]); + + let output = check_command.run(); + output.assert_matches_text("Check [WILDCARD]main.ts\nerror: TS234[WILDCARD]"); + output.assert_exit_code(1); + + temp_dir.write("greet.ts", correct_code); + let output = check_command.run(); + output.assert_matches_text("Check [WILDCARD]main.ts\n"); + + temp_dir.write("greet.ts", incorrect_code); + let output = check_command.run(); + output.assert_matches_text("Check [WILDCARD]main.ts\nerror: TS234[WILDCARD]"); + output.assert_exit_code(1); +} + +#[test] +fn json_module_check_then_error() { + let test_context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = test_context.temp_dir(); + let correct_code = "{ \"foo\": \"bar\" }"; + let incorrect_code = "{ \"foo2\": \"bar\" }"; + + temp_dir.write( + "main.ts", + "import test from './test.json' assert { type: 'json' }; console.log(test.foo);\n", + ); + temp_dir.write("test.json", correct_code); + + let check_command = test_context.new_command().args_vec(["check", "main.ts"]); + + check_command.run().assert_exit_code(0).skip_output_check(); + + temp_dir.write("test.json", incorrect_code); + check_command + .run() + .assert_matches_text("Check [WILDCARD]main.ts\nerror: TS2551[WILDCARD]") + .assert_exit_code(1); +} + +#[test] +fn npm_module_check_then_error() { + let test_context = TestContextBuilder::new() + .use_temp_cwd() + .add_npm_env_vars() + .use_http_server() + .build(); + let temp_dir = test_context.temp_dir(); + temp_dir.write("deno.json", "{}"); // so the lockfile gets loaded + + // get the lockfiles values first (this is necessary because the test + // server generates different tarballs based on the operating system) + test_context + .new_command() + .args_vec([ + "cache", + "npm:@denotest/breaking-change-between-versions@1.0.0", + "npm:@denotest/breaking-change-between-versions@2.0.0", + ]) + .run() + .skip_output_check(); + let lockfile = temp_dir.path().join("deno.lock"); + let mut lockfile_content = + lockfile.read_json::(); + + // make the specifier resolve to version 1 + lockfile_content.packages.specifiers.insert( + "npm:@denotest/breaking-change-between-versions".to_string(), + "npm:@denotest/breaking-change-between-versions@1.0.0".to_string(), + ); + lockfile.write_json(&lockfile_content); + temp_dir.write( + "main.ts", + "import { oldName } from 'npm:@denotest/breaking-change-between-versions'; console.log(oldName());\n", + ); + + let check_command = test_context.new_command().args_vec(["check", "main.ts"]); + check_command.run().assert_exit_code(0).skip_output_check(); + + // now update the lockfile to use version 2 instead, which should cause a + // type checking error because the oldName no longer exists + lockfile_content.packages.specifiers.insert( + "npm:@denotest/breaking-change-between-versions".to_string(), + "npm:@denotest/breaking-change-between-versions@2.0.0".to_string(), + ); + lockfile.write_json(&lockfile_content); + + check_command + .run() + .assert_matches_text("Check [WILDCARD]main.ts\nerror: TS2305[WILDCARD]has no exported member 'oldName'[WILDCARD]") + .assert_exit_code(1); +} diff --git a/tests/integration/compile_tests.rs b/tests/integration/compile_tests.rs new file mode 100644 index 000000000..fbf924fbb --- /dev/null +++ b/tests/integration/compile_tests.rs @@ -0,0 +1,1180 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +use test_util as util; +use util::assert_contains; +use util::assert_not_contains; +use util::testdata_path; +use util::TestContext; +use util::TestContextBuilder; + +#[test] +fn compile_basic() { + let context = TestContextBuilder::new().build(); + let dir = context.temp_dir(); + let exe = if cfg!(windows) { + dir.path().join("welcome.exe") + } else { + dir.path().join("welcome") + }; + // try this twice to ensure it works with the cache + for _ in 0..2 { + let output = context + .new_command() + .args_vec([ + "compile", + "--output", + &exe.to_string_lossy(), + "../../tests/testdata/welcome.ts", + ]) + .run(); + output.assert_exit_code(0); + output.skip_output_check(); + let output = context.new_command().name(&exe).run(); + output.assert_matches_text("Welcome to Deno!\n"); + } + + // now ensure this works when the deno_dir is readonly + let readonly_dir = dir.path().join("readonly"); + readonly_dir.make_dir_readonly(); + let readonly_sub_dir = readonly_dir.join("sub"); + + let output = context + .new_command() + // it should fail creating this, but still work + .env("DENO_DIR", readonly_sub_dir) + .name(exe) + .run(); + output.assert_matches_text("Welcome to Deno!\n"); +} + +#[test] +fn standalone_args() { + let context = TestContextBuilder::new().build(); + let dir = context.temp_dir(); + let exe = if cfg!(windows) { + dir.path().join("args.exe") + } else { + dir.path().join("args") + }; + context + .new_command() + .args_vec([ + "compile", + "--output", + &exe.to_string_lossy(), + "./compile/args.ts", + "a", + "b", + ]) + .run() + .skip_output_check() + .assert_exit_code(0); + context + .new_command() + .name(&exe) + .args("foo --bar --unstable") + .run() + .assert_matches_text("a\nb\nfoo\n--bar\n--unstable\n") + .assert_exit_code(0); +} + +#[test] +fn standalone_error() { + let context = TestContextBuilder::new().build(); + let dir = context.temp_dir(); + let exe = if cfg!(windows) { + dir.path().join("error.exe") + } else { + dir.path().join("error") + }; + context + .new_command() + .args_vec([ + "compile", + "--output", + &exe.to_string_lossy(), + "./compile/standalone_error.ts", + ]) + .run() + .skip_output_check() + .assert_exit_code(0); + + let output = context.new_command().name(&exe).split_output().run(); + output.assert_exit_code(1); + output.assert_stdout_matches_text(""); + let stderr = output.stderr(); + // On Windows, we cannot assert the file path (because '\'). + // Instead we just check for relevant output. + assert_contains!(stderr, "error: Uncaught (in promise) Error: boom!"); + assert_contains!(stderr, "throw new Error(\"boom!\");"); + assert_contains!(stderr, "\n at boom (file://"); + assert_contains!(stderr, "standalone_error.ts:2:9"); + assert_contains!(stderr, "at foo (file://"); + assert_contains!(stderr, "standalone_error.ts:5:3"); + assert_contains!(stderr, "standalone_error.ts:7:1"); +} + +#[test] +fn standalone_error_module_with_imports() { + let context = TestContextBuilder::new().build(); + let dir = context.temp_dir(); + let exe = if cfg!(windows) { + dir.path().join("error.exe") + } else { + dir.path().join("error") + }; + context + .new_command() + .args_vec([ + "compile", + "--output", + &exe.to_string_lossy(), + "./compile/standalone_error_module_with_imports_1.ts", + ]) + .run() + .skip_output_check() + .assert_exit_code(0); + + let output = context + .new_command() + .name(&exe) + .env("NO_COLOR", "1") + .split_output() + .run(); + output.assert_stdout_matches_text("hello\n"); + let stderr = output.stderr(); + // On Windows, we cannot assert the file path (because '\'). + // Instead we just check for relevant output. + assert_contains!(stderr, "error: Uncaught (in promise) Error: boom!"); + assert_contains!(stderr, "throw new Error(\"boom!\");"); + assert_contains!(stderr, "\n at file://"); + assert_contains!(stderr, "standalone_error_module_with_imports_2.ts:2:7"); + output.assert_exit_code(1); +} + +#[test] +fn standalone_load_datauri() { + let context = TestContextBuilder::new().build(); + let dir = context.temp_dir(); + let exe = if cfg!(windows) { + dir.path().join("load_datauri.exe") + } else { + dir.path().join("load_datauri") + }; + context + .new_command() + .args_vec([ + "compile", + "--output", + &exe.to_string_lossy(), + "./compile/standalone_import_datauri.ts", + ]) + .run() + .skip_output_check() + .assert_exit_code(0); + context + .new_command() + .name(&exe) + .run() + .assert_matches_text("Hello Deno!\n") + .assert_exit_code(0); +} + +// https://github.com/denoland/deno/issues/13704 +#[test] +fn standalone_follow_redirects() { + let context = TestContextBuilder::new().build(); + let dir = context.temp_dir(); + let exe = if cfg!(windows) { + dir.path().join("follow_redirects.exe") + } else { + dir.path().join("follow_redirects") + }; + context + .new_command() + .args_vec([ + "compile", + "--output", + &exe.to_string_lossy(), + "./compile/standalone_follow_redirects.ts", + ]) + .run() + .skip_output_check() + .assert_exit_code(0); + context + .new_command() + .name(&exe) + .run() + .assert_matches_text("Hello\n") + .assert_exit_code(0); +} + +#[test] +fn compile_with_file_exists_error() { + let context = TestContextBuilder::new().build(); + let dir = context.temp_dir(); + let output_path = if cfg!(windows) { + dir.path().join(r"args\") + } else { + dir.path().join("args/") + }; + let file_path = dir.path().join("args"); + file_path.write(""); + context + .new_command() + .args_vec([ + "compile", + "--output", + &output_path.to_string_lossy(), + "./compile/args.ts", + ]) + .run() + .assert_matches_text(&format!( + concat!( + "[WILDCARD]error: Could not compile to file '{}' because its parent directory ", + "is an existing file. You can use the `--output ` flag to ", + "provide an alternative name.\n", + ), + file_path, + )) + .assert_exit_code(1); +} + +#[test] +fn compile_with_directory_exists_error() { + let context = TestContextBuilder::new().build(); + let dir = context.temp_dir(); + let exe = if cfg!(windows) { + dir.path().join("args.exe") + } else { + dir.path().join("args") + }; + std::fs::create_dir(&exe).unwrap(); + context.new_command() + .args_vec([ + "compile", + "--output", + &exe.to_string_lossy(), + "./compile/args.ts" + ]).run() + .assert_matches_text(&format!( + concat!( + "[WILDCARD]error: Could not compile to file '{}' because a directory exists with ", + "the same name. You can use the `--output ` flag to ", + "provide an alternative name.\n" + ), + exe + )) + .assert_exit_code(1); +} + +#[test] +fn compile_with_conflict_file_exists_error() { + let context = TestContextBuilder::new().build(); + let dir = context.temp_dir(); + let exe = if cfg!(windows) { + dir.path().join("args.exe") + } else { + dir.path().join("args") + }; + std::fs::write(&exe, b"SHOULD NOT BE OVERWRITTEN").unwrap(); + context.new_command() + .args_vec([ + "compile", + "--output", + &exe.to_string_lossy(), + "./compile/args.ts" + ]).run() + .assert_matches_text(&format!( + concat!( + "[WILDCARD]error: Could not compile to file '{}' because the file already exists ", + "and cannot be overwritten. Please delete the existing file or ", + "use the `--output ` flag to provide an alternative name.\n" + ), + exe + )) + .assert_exit_code(1); + exe.assert_matches_text("SHOULD NOT BE OVERWRITTEN"); +} + +#[test] +fn compile_and_overwrite_file() { + let context = TestContextBuilder::new().build(); + let dir = context.temp_dir(); + let exe = if cfg!(windows) { + dir.path().join("args.exe") + } else { + dir.path().join("args") + }; + + // do this twice + for _ in 0..2 { + context + .new_command() + .args_vec([ + "compile", + "--output", + &exe.to_string_lossy(), + "./compile/args.ts", + ]) + .run() + .skip_output_check() + .assert_exit_code(0); + assert!(&exe.exists()); + } +} + +#[test] +fn standalone_runtime_flags() { + let context = TestContextBuilder::new().build(); + let dir = context.temp_dir(); + let exe = if cfg!(windows) { + dir.path().join("flags.exe") + } else { + dir.path().join("flags") + }; + context + .new_command() + .args_vec([ + "compile", + "--allow-read", + "--seed", + "1", + "--output", + &exe.to_string_lossy(), + "./compile/standalone_runtime_flags.ts", + ]) + .run() + .skip_output_check() + .assert_exit_code(0); + context + .new_command() + .env("NO_COLOR", "1") + .name(&exe) + .split_output() + .run() + .assert_stdout_matches_text("0.147205063401058\n") + .assert_stderr_matches_text( + "[WILDCARD]PermissionDenied: Requires write access to[WILDCARD]", + ) + .assert_exit_code(1); +} + +#[test] +fn standalone_ext_flag_ts() { + let context = TestContextBuilder::new().build(); + let dir = context.temp_dir(); + let exe = if cfg!(windows) { + dir.path().join("ext_flag_ts.exe") + } else { + dir.path().join("ext_flag_ts") + }; + context + .new_command() + .args_vec([ + "compile", + "--ext", + "ts", + "--output", + &exe.to_string_lossy(), + "./file_extensions/ts_without_extension", + ]) + .run() + .skip_output_check() + .assert_exit_code(0); + context + .new_command() + .env("NO_COLOR", "1") + .name(&exe) + .run() + .assert_matches_text("executing typescript with no extension\n") + .assert_exit_code(0); +} + +#[test] +fn standalone_ext_flag_js() { + let context = TestContextBuilder::new().build(); + let dir = context.temp_dir(); + let exe = if cfg!(windows) { + dir.path().join("ext_flag_js.exe") + } else { + dir.path().join("ext_flag_js") + }; + context + .new_command() + .args_vec([ + "compile", + "--ext", + "js", + "--output", + &exe.to_string_lossy(), + "./file_extensions/js_without_extension", + ]) + .run() + .skip_output_check() + .assert_exit_code(0); + context + .new_command() + .env("NO_COLOR", "1") + .name(&exe) + .run() + .assert_matches_text("executing javascript with no extension\n"); +} + +#[test] +fn standalone_import_map() { + let context = TestContextBuilder::new().build(); + let dir = context.temp_dir(); + let exe = if cfg!(windows) { + dir.path().join("import_map.exe") + } else { + dir.path().join("import_map") + }; + context + .new_command() + .args_vec([ + "compile", + "--allow-read", + "--import-map", + "compile/standalone_import_map.json", + "--output", + &exe.to_string_lossy(), + "./compile/standalone_import_map.ts", + ]) + .run() + .skip_output_check() + .assert_exit_code(0); + context + .new_command() + .name(&exe) + .run() + .skip_output_check() + .assert_exit_code(0); +} + +#[test] +fn standalone_import_map_config_file() { + let context = TestContextBuilder::new().build(); + let dir = context.temp_dir(); + let exe = if cfg!(windows) { + dir.path().join("import_map.exe") + } else { + dir.path().join("import_map") + }; + context + .new_command() + .args_vec([ + "compile", + "--allow-read", + "--config", + "compile/standalone_import_map_config.json", + "--output", + &exe.to_string_lossy(), + "./compile/standalone_import_map.ts", + ]) + .run() + .skip_output_check() + .assert_exit_code(0); + context + .new_command() + .name(&exe) + .run() + .skip_output_check() + .assert_exit_code(0); +} + +#[test] +// https://github.com/denoland/deno/issues/12670 +fn skip_rebundle() { + let context = TestContextBuilder::new().build(); + let dir = context.temp_dir(); + let exe = if cfg!(windows) { + dir.path().join("hello_world.exe") + } else { + dir.path().join("hello_world") + }; + let output = context + .new_command() + .args_vec([ + "compile", + "--output", + &exe.to_string_lossy(), + "./run/001_hello.js", + ]) + .run(); + + //no "Bundle testdata_path/run/001_hello.js" in output + assert_not_contains!(output.combined_output(), "Bundle"); + + context + .new_command() + .name(&exe) + .run() + .assert_matches_text("Hello World\n") + .assert_exit_code(0); +} + +#[test] +fn check_local_by_default() { + let context = TestContext::with_http_server(); + let dir = context.temp_dir(); + let exe = if cfg!(windows) { + dir.path().join("welcome.exe") + } else { + dir.path().join("welcome") + }; + context + .new_command() + .args_vec([ + "compile", + "--output", + &exe.to_string_lossy(), + "./compile/check_local_by_default.ts", + ]) + .run() + .skip_output_check() + .assert_exit_code(0); +} + +#[test] +fn check_local_by_default2() { + let context = TestContext::with_http_server(); + let dir = context.temp_dir(); + let exe = if cfg!(windows) { + dir.path().join("welcome.exe") + } else { + dir.path().join("welcome") + }; + context + .new_command() + .args_vec([ + "compile", + "--output", + &exe.to_string_lossy(), + "./compile/check_local_by_default2.ts" + ]) + .run() + .assert_matches_text( + r#"[WILDCARD]error: TS2322 [ERROR]: Type '12' is not assignable to type '"b"'.[WILDCARD]"#, + ) + .assert_exit_code(1); +} + +#[test] +fn workers_basic() { + let context = TestContext::with_http_server(); + let dir = context.temp_dir(); + let exe = if cfg!(windows) { + dir.path().join("basic.exe") + } else { + dir.path().join("basic") + }; + context + .new_command() + .args_vec([ + "compile", + "--no-check", + "--output", + &exe.to_string_lossy(), + "./compile/workers/basic.ts", + ]) + .run() + .skip_output_check() + .assert_exit_code(0); + + context + .new_command() + .name(&exe) + .run() + .assert_matches_file("./compile/workers/basic.out") + .assert_exit_code(0); +} + +#[test] +fn workers_not_in_module_map() { + let context = TestContext::with_http_server(); + let temp_dir = context.temp_dir(); + let exe = if cfg!(windows) { + temp_dir.path().join("not_in_module_map.exe") + } else { + temp_dir.path().join("not_in_module_map") + }; + let output = context + .new_command() + .args_vec([ + "compile", + "--output", + &exe.to_string_lossy(), + "./compile/workers/not_in_module_map.ts", + ]) + .run(); + output.assert_exit_code(0); + output.skip_output_check(); + + let output = context.new_command().name(exe).env("NO_COLOR", "").run(); + output.assert_exit_code(1); + output.assert_matches_text(concat!( + "error: Uncaught (in worker \"\") Module not found: [WILDCARD]", + "error: Uncaught (in promise) Error: Unhandled error in child worker.\n[WILDCARD]" + )); +} + +#[test] +fn workers_with_include_flag() { + let context = TestContext::with_http_server(); + let dir = context.temp_dir(); + let exe = if cfg!(windows) { + dir.path().join("workers_with_include_flag.exe") + } else { + dir.path().join("workers_with_include_flag") + }; + context + .new_command() + .args_vec([ + "compile", + "--output", + &exe.to_string_lossy(), + "--include", + "./compile/workers/worker.ts", + "./compile/workers/not_in_module_map.ts", + ]) + .run() + .skip_output_check() + .assert_exit_code(0); + + context + .new_command() + .name(&exe) + .env("NO_COLOR", "") + .run() + .assert_matches_text("Hello from worker!\nReceived 42\nClosing\n"); +} + +#[test] +fn dynamic_import() { + let context = TestContext::with_http_server(); + let dir = context.temp_dir(); + let exe = if cfg!(windows) { + dir.path().join("dynamic_import.exe") + } else { + dir.path().join("dynamic_import") + }; + context + .new_command() + .args_vec([ + "compile", + "--output", + &exe.to_string_lossy(), + "./compile/dynamic_imports/main.ts", + ]) + .run() + .skip_output_check() + .assert_exit_code(0); + + context + .new_command() + .name(&exe) + .env("NO_COLOR", "") + .run() + .assert_matches_file("./compile/dynamic_imports/main.out") + .assert_exit_code(0); +} + +#[test] +fn dynamic_import_unanalyzable() { + let context = TestContext::with_http_server(); + let dir = context.temp_dir(); + let exe = if cfg!(windows) { + dir.path().join("dynamic_import_unanalyzable.exe") + } else { + dir.path().join("dynamic_import_unanalyzable") + }; + context + .new_command() + .args_vec([ + "compile", + "--allow-read", + "--include", + "./compile/dynamic_imports/import1.ts", + "--output", + &exe.to_string_lossy(), + "./compile/dynamic_imports/main_unanalyzable.ts", + ]) + .run() + .skip_output_check() + .assert_exit_code(0); + + context + .new_command() + .current_dir(util::root_path()) + .name(&exe) + .env("NO_COLOR", "") + .run() + .assert_matches_file("./compile/dynamic_imports/main.out") + .assert_exit_code(0); +} + +#[test] +fn compile_npm_specifiers() { + let context = TestContextBuilder::for_npm().use_temp_cwd().build(); + + let temp_dir = context.temp_dir(); + temp_dir.write( + "main.ts", + concat!( + "import path from 'node:path';\n", + "import { getValue, setValue } from 'npm:@denotest/esm-basic';\n", + "import getValueDefault from 'npm:@denotest/esm-import-cjs-default';\n", + "setValue(2);\n", + "console.log(path.join('testing', 'this'));", + "console.log(getValue());", + "console.log(getValueDefault());", + ), + ); + + let binary_path = if cfg!(windows) { + temp_dir.path().join("binary.exe") + } else { + temp_dir.path().join("binary") + }; + + // try with and without --node-modules-dir + let compile_commands = &[ + "compile --output binary main.ts", + "compile --node-modules-dir --output binary main.ts", + ]; + + for compile_command in compile_commands { + let output = context.new_command().args(compile_command).run(); + output.assert_exit_code(0); + output.skip_output_check(); + + let output = context.new_command().name(&binary_path).run(); + output.assert_matches_text( + r#"Node esm importing node cjs +=========================== +{ + default: [Function (anonymous)], + named: [Function (anonymous)], + MyClass: [class MyClass] +} +{ default: [Function (anonymous)], named: [Function (anonymous)] } +[Module: null prototype] { + MyClass: [class MyClass], + __esModule: true, + default: { + default: [Function (anonymous)], + named: [Function (anonymous)], + MyClass: [class MyClass] + }, + named: [Function (anonymous)] +} +[Module: null prototype] { + __esModule: true, + default: { default: [Function (anonymous)], named: [Function (anonymous)] }, + named: [Function (anonymous)] +} +=========================== +static method +testing[WILDCARD]this +2 +5 +"#, + ); + } + + // try with a package.json + temp_dir.remove_dir_all("node_modules"); + temp_dir.write( + "main.ts", + concat!( + "import { getValue, setValue } from '@denotest/esm-basic';\n", + "setValue(2);\n", + "console.log(getValue());", + ), + ); + temp_dir.write( + "package.json", + r#"{ "dependencies": { "@denotest/esm-basic": "1" } }"#, + ); + + context + .new_command() + .args("compile --output binary main.ts") + .run() + .assert_exit_code(0) + .skip_output_check(); + + context + .new_command() + .name(&binary_path) + .run() + .assert_matches_text("2\n"); + + // now try with byonm + temp_dir.remove_dir_all("node_modules"); + temp_dir.write("deno.json", r#"{"unstable":["byonm"]}"#); + context.run_npm("install"); + + context + .new_command() + .args("compile --output binary main.ts") + .run() + .assert_exit_code(0) + .assert_matches_text("Check file:///[WILDCARD]/main.ts\nCompile file:///[WILDCARD]/main.ts to binary[WILDCARD]\n"); + + context + .new_command() + .name(&binary_path) + .run() + .assert_matches_text("2\n"); +} + +#[test] +fn compile_npm_file_system() { + run_npm_bin_compile_test(RunNpmBinCompileOptions { + input_specifier: "compile/npm_fs/main.ts", + compile_args: vec!["-A"], + run_args: vec![], + output_file: "compile/npm_fs/main.out", + node_modules_dir: true, + input_name: Some("binary"), + expected_name: "binary", + exit_code: 0, + }); +} + +#[test] +fn compile_npm_bin_esm() { + run_npm_bin_compile_test(RunNpmBinCompileOptions { + input_specifier: "npm:@denotest/bin/cli-esm", + compile_args: vec![], + run_args: vec!["this", "is", "a", "test"], + output_file: "npm/deno_run_esm.out", + node_modules_dir: false, + input_name: None, + expected_name: "cli-esm", + exit_code: 0, + }); +} + +#[test] +fn compile_npm_bin_cjs() { + run_npm_bin_compile_test(RunNpmBinCompileOptions { + input_specifier: "npm:@denotest/bin/cli-cjs", + compile_args: vec![], + run_args: vec!["this", "is", "a", "test"], + output_file: "npm/deno_run_cjs.out", + node_modules_dir: false, + input_name: None, + expected_name: "cli-cjs", + exit_code: 0, + }); +} + +#[test] +fn compile_npm_cowsay_main() { + run_npm_bin_compile_test(RunNpmBinCompileOptions { + input_specifier: "npm:cowsay@1.5.0", + compile_args: vec!["--allow-read"], + run_args: vec!["Hello"], + output_file: "npm/deno_run_cowsay.out", + node_modules_dir: false, + input_name: None, + expected_name: "cowsay", + exit_code: 0, + }); +} + +#[test] +fn compile_npm_vfs_implicit_read_permissions() { + run_npm_bin_compile_test(RunNpmBinCompileOptions { + input_specifier: "compile/vfs_implicit_read_permission/main.ts", + compile_args: vec![], + run_args: vec![], + output_file: "compile/vfs_implicit_read_permission/main.out", + node_modules_dir: false, + input_name: Some("binary"), + expected_name: "binary", + exit_code: 0, + }); +} + +#[test] +fn compile_npm_no_permissions() { + run_npm_bin_compile_test(RunNpmBinCompileOptions { + input_specifier: "npm:cowsay@1.5.0", + compile_args: vec![], + run_args: vec!["Hello"], + output_file: "npm/deno_run_cowsay_no_permissions.out", + node_modules_dir: false, + input_name: None, + expected_name: "cowsay", + exit_code: 1, + }); +} + +#[test] +fn compile_npm_cowsay_explicit() { + run_npm_bin_compile_test(RunNpmBinCompileOptions { + input_specifier: "npm:cowsay@1.5.0/cowsay", + compile_args: vec!["--allow-read"], + run_args: vec!["Hello"], + output_file: "npm/deno_run_cowsay.out", + node_modules_dir: false, + input_name: None, + expected_name: "cowsay", + exit_code: 0, + }); +} + +#[test] +fn compile_npm_cowthink() { + run_npm_bin_compile_test(RunNpmBinCompileOptions { + input_specifier: "npm:cowsay@1.5.0/cowthink", + compile_args: vec!["--allow-read"], + run_args: vec!["Hello"], + output_file: "npm/deno_run_cowthink.out", + node_modules_dir: false, + input_name: None, + expected_name: "cowthink", + exit_code: 0, + }); +} + +struct RunNpmBinCompileOptions<'a> { + input_specifier: &'a str, + node_modules_dir: bool, + output_file: &'a str, + input_name: Option<&'a str>, + expected_name: &'a str, + run_args: Vec<&'a str>, + compile_args: Vec<&'a str>, + exit_code: i32, +} + +fn run_npm_bin_compile_test(opts: RunNpmBinCompileOptions) { + let context = TestContextBuilder::for_npm().use_temp_cwd().build(); + + let temp_dir = context.temp_dir(); + let main_specifier = if opts.input_specifier.starts_with("npm:") { + opts.input_specifier.to_string() + } else { + testdata_path().join(opts.input_specifier).to_string() + }; + + let mut args = vec!["compile".to_string()]; + + args.extend(opts.compile_args.iter().map(|s| s.to_string())); + + if opts.node_modules_dir { + args.push("--node-modules-dir".to_string()); + } + + if let Some(bin_name) = opts.input_name { + args.push("--output".to_string()); + args.push(bin_name.to_string()); + } + + args.push(main_specifier); + + // compile + let output = context.new_command().args_vec(args).run(); + output.assert_exit_code(0); + output.skip_output_check(); + + // delete the npm folder in the DENO_DIR to ensure it's not using it + context.deno_dir().remove_dir_all("./npm"); + + // run + let binary_path = if cfg!(windows) { + temp_dir.path().join(format!("{}.exe", opts.expected_name)) + } else { + temp_dir.path().join(opts.expected_name) + }; + let output = context + .new_command() + .name(binary_path) + .args_vec(opts.run_args) + .run(); + output.assert_matches_file(opts.output_file); + output.assert_exit_code(opts.exit_code); +} + +#[test] +fn compile_node_modules_symlink_outside() { + let context = TestContextBuilder::for_npm() + .use_copy_temp_dir("compile/node_modules_symlink_outside") + .cwd("compile/node_modules_symlink_outside") + .build(); + + let temp_dir = context.temp_dir(); + let project_dir = temp_dir + .path() + .join("compile") + .join("node_modules_symlink_outside"); + temp_dir.create_dir_all(project_dir.join("node_modules")); + temp_dir.create_dir_all(project_dir.join("some_folder")); + temp_dir.write(project_dir.join("test.txt"), "5"); + + // create a symlink in the node_modules directory that points to a folder in the cwd + temp_dir.symlink_dir( + project_dir.join("some_folder"), + project_dir.join("node_modules").join("some_folder"), + ); + // compile folder + let output = context + .new_command() + .args("compile --allow-read --node-modules-dir --output bin main.ts") + .run(); + output.assert_exit_code(0); + output.assert_matches_file( + "compile/node_modules_symlink_outside/main_compile_folder.out", + ); + assert!(project_dir.join("node_modules/some_folder").exists()); + + // Cleanup and remove the folder. The folder test is done separately from + // the file symlink test because different systems would traverse + // the directory items in different order. + temp_dir.remove_dir_all(project_dir.join("node_modules/some_folder")); + + // create a symlink in the node_modules directory that points to a file in the cwd + temp_dir.symlink_file( + project_dir.join("test.txt"), + project_dir.join("node_modules").join("test.txt"), + ); + assert!(project_dir.join("node_modules/test.txt").exists()); + + // compile + let output = context + .new_command() + .args("compile --allow-read --node-modules-dir --output bin main.ts") + .run(); + output.assert_exit_code(0); + output.assert_matches_file( + "compile/node_modules_symlink_outside/main_compile_file.out", + ); + + // run + let binary_path = + project_dir.join(if cfg!(windows) { "bin.exe" } else { "bin" }); + let output = context.new_command().name(binary_path).run(); + output.assert_matches_file("compile/node_modules_symlink_outside/main.out"); +} + +#[test] +fn compile_node_modules_symlink_non_existent() { + let context = TestContextBuilder::for_npm().use_temp_cwd().build(); + let temp_dir = context.temp_dir().path(); + temp_dir.join("main.ts").write( + r#"import { getValue, setValue } from "npm:@denotest/esm-basic"; +setValue(4); +console.log(getValue());"#, + ); + let node_modules_dir = temp_dir.join("node_modules"); + node_modules_dir.create_dir_all(); + // create a symlink that points to a non_existent file + node_modules_dir.symlink_dir("non_existent", "folder"); + // compile folder + let output = context + .new_command() + .args("compile --allow-read --node-modules-dir --output bin main.ts") + .run(); + output.assert_exit_code(0); + output.assert_matches_text( + r#"Download http://localhost:4545/npm/registry/@denotest/esm-basic +Download http://localhost:4545/npm/registry/@denotest/esm-basic/1.0.0.tgz +Initialize @denotest/esm-basic@1.0.0 +Check file:///[WILDCARD]/main.ts +Compile file:///[WILDCARD]/main.ts to [WILDCARD] +Warning Failed resolving symlink. Ignoring. + Path: [WILDCARD] + Message: [WILDCARD]) +"#, + ); + + // run + let binary_path = + temp_dir.join(if cfg!(windows) { "bin.exe" } else { "bin" }); + let output = context.new_command().name(binary_path).run(); + output.assert_matches_text("4\n"); +} + +#[test] +fn dynamic_imports_tmp_lit() { + let context = TestContextBuilder::new().build(); + let dir = context.temp_dir(); + let exe = if cfg!(windows) { + dir.path().join("app.exe") + } else { + dir.path().join("app") + }; + let output = context + .new_command() + .args_vec([ + "compile", + "--output", + &exe.to_string_lossy(), + "./compile/dynamic_imports_tmp_lit/main.js", + ]) + .run(); + output.assert_exit_code(0); + output.skip_output_check(); + let output = context.new_command().name(&exe).run(); + output.assert_matches_text("a\nb\n{ data: 5 }\n{ data: 1 }\n"); +} + +#[test] +fn granular_unstable_features() { + let context = TestContextBuilder::new().build(); + let dir = context.temp_dir(); + let exe = if cfg!(windows) { + dir.path().join("app.exe") + } else { + dir.path().join("app") + }; + let output = context + .new_command() + .args_vec([ + "compile", + "--output", + &exe.to_string_lossy(), + "--unstable-kv", + "./compile/unstable_features.ts", + ]) + .run(); + output.assert_exit_code(0); + output.skip_output_check(); + let output = context.new_command().name(&exe).run(); + output.assert_exit_code(0); + output.assert_matches_text("Kv {}\n"); +} + +#[test] +fn dynamic_import_bad_data_uri() { + let context = TestContextBuilder::new().build(); + let dir = context.temp_dir(); + let exe = if cfg!(windows) { + dir.path().join("app.exe") + } else { + dir.path().join("app") + }; + let file = dir.path().join("bad_data_uri.ts"); + file.write("await import('data:application/')"); + let output = context + .new_command() + .args_vec([ + "compile", + "--output", + &exe.to_string_lossy(), + &file.to_string_lossy(), + ]) + .run(); + output.assert_exit_code(0); + output.skip_output_check(); + let output = context.new_command().name(&exe).run(); + output.assert_exit_code(1); + output.assert_matches_text( + "[WILDCARD]TypeError: Unable to decode data url.[WILDCARD]", + ); +} diff --git a/tests/integration/coverage_tests.rs b/tests/integration/coverage_tests.rs new file mode 100644 index 000000000..804f9b578 --- /dev/null +++ b/tests/integration/coverage_tests.rs @@ -0,0 +1,638 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +use deno_core::serde_json; +use std::fs; +use test_util as util; +use test_util::TempDir; +use util::assert_starts_with; +use util::env_vars_for_npm_tests; +use util::TestContext; +use util::TestContextBuilder; + +#[test] +fn branch() { + run_coverage_text("branch", "ts"); +} + +#[test] +fn complex() { + run_coverage_text("complex", "ts"); +} + +#[test] +fn final_blankline() { + run_coverage_text("final_blankline", "js"); +} + +#[test] +fn no_snaps() { + no_snaps_included("no_snaps_included", "ts"); +} + +// TODO(mmastrac): The exclusion to make this test pass doesn't seem to work on windows. +#[cfg_attr(windows, ignore)] +#[test] +fn no_tests() { + no_tests_included("foo", "mts"); + no_tests_included("foo", "ts"); + no_tests_included("foo", "js"); +} + +#[test] +fn error_if_invalid_cache() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir_path = context.temp_dir().path(); + let other_temp_dir = TempDir::new(); + let other_tempdir = other_temp_dir.path().join("cov"); + + let invalid_cache_path = util::testdata_path().join("coverage/invalid_cache"); + let mod_before_path = util::testdata_path() + .join(&invalid_cache_path) + .join("mod_before.ts"); + let mod_after_path = util::testdata_path() + .join(&invalid_cache_path) + .join("mod_after.ts"); + let mod_test_path = util::testdata_path() + .join(&invalid_cache_path) + .join("mod.test.ts"); + + let mod_temp_path = temp_dir_path.join("mod.ts"); + let mod_test_temp_path = temp_dir_path.join("mod.test.ts"); + + // Write the initial mod.ts file + std::fs::copy(mod_before_path, &mod_temp_path).unwrap(); + // And the test file + std::fs::copy(mod_test_path, mod_test_temp_path).unwrap(); + + // Generate coverage + let output = context + .new_command() + .args_vec(vec![ + "test".to_string(), + "--quiet".to_string(), + format!("--coverage={}", other_tempdir), + ]) + .run(); + + output.assert_exit_code(0); + output.skip_output_check(); + + // Modify the file between deno test and deno coverage, thus invalidating the cache + std::fs::copy(mod_after_path, mod_temp_path).unwrap(); + + let output = context + .new_command() + .args_vec(vec!["coverage".to_string(), format!("{}/", other_tempdir)]) + .run(); + + output.assert_exit_code(1); + let out = output.combined_output(); + + // Expect error + let error = util::strip_ansi_codes(out).to_string(); + assert!(error.contains("error: Missing transpiled source code")); + assert!(error.contains("Before generating coverage report, run `deno test --coverage` to ensure consistent state.")); +} + +fn run_coverage_text(test_name: &str, extension: &str) { + let context = TestContext::default(); + let tempdir = context.temp_dir(); + let tempdir = tempdir.path().join("cov"); + + let output = context + .new_command() + .args_vec(vec![ + "test".to_string(), + "-A".to_string(), + "--quiet".to_string(), + format!("--coverage={}", tempdir), + format!("coverage/{test_name}_test.{extension}"), + ]) + .run(); + + output.assert_exit_code(0); + output.skip_output_check(); + + let output = context + .new_command() + .args_vec(vec![ + "coverage".to_string(), + "--detailed".to_string(), + format!("{}/", tempdir), + ]) + .split_output() + .run(); + + // Verify there's no "Check" being printed + assert!(output.stderr().is_empty()); + + let actual = util::strip_ansi_codes(output.stdout()).to_string(); + + let expected = fs::read_to_string( + util::testdata_path().join(format!("coverage/{test_name}_expected.out")), + ) + .unwrap(); + + if !util::wildcard_match(&expected, &actual) { + println!("OUTPUT\n{actual}\nOUTPUT"); + println!("EXPECTED\n{expected}\nEXPECTED"); + panic!("pattern match failed"); + } + + output.assert_exit_code(0); + + let output = context + .new_command() + .args_vec(vec![ + "coverage".to_string(), + "--quiet".to_string(), + "--lcov".to_string(), + format!("{}/", tempdir), + ]) + .run(); + + let actual = util::strip_ansi_codes(output.combined_output()).to_string(); + + let expected = fs::read_to_string( + util::testdata_path().join(format!("coverage/{test_name}_expected.lcov")), + ) + .unwrap(); + + if !util::wildcard_match(&expected, &actual) { + println!("OUTPUT\n{actual}\nOUTPUT"); + println!("EXPECTED\n{expected}\nEXPECTED"); + panic!("pattern match failed"); + } + + output.assert_exit_code(0); +} + +#[test] +fn multifile_coverage() { + let context = TestContext::default(); + let tempdir = context.temp_dir(); + let tempdir = tempdir.path().join("cov"); + + let output = context + .new_command() + .args_vec(vec![ + "test".to_string(), + "--quiet".to_string(), + format!("--coverage={}", tempdir), + format!("coverage/multifile/"), + ]) + .run(); + + output.assert_exit_code(0); + output.skip_output_check(); + + let output = context + .new_command() + .args_vec(vec![ + "coverage".to_string(), + "--detailed".to_string(), + format!("{}/", tempdir), + ]) + .split_output() + .run(); + + // Verify there's no "Check" being printed + assert!(output.stderr().is_empty()); + + let actual = util::strip_ansi_codes(output.stdout()).to_string(); + + let expected = fs::read_to_string( + util::testdata_path().join("coverage/multifile/expected.out"), + ) + .unwrap(); + + if !util::wildcard_match(&expected, &actual) { + println!("OUTPUT\n{actual}\nOUTPUT"); + println!("EXPECTED\n{expected}\nEXPECTED"); + panic!("pattern match failed"); + } + output.assert_exit_code(0); + + let output = context + .new_command() + .args_vec(vec![ + "coverage".to_string(), + "--quiet".to_string(), + "--lcov".to_string(), + format!("{}/", tempdir), + ]) + .run(); + + let actual = util::strip_ansi_codes(output.combined_output()).to_string(); + + let expected = fs::read_to_string( + util::testdata_path().join("coverage/multifile/expected.lcov"), + ) + .unwrap(); + + if !util::wildcard_match(&expected, &actual) { + println!("OUTPUT\n{actual}\nOUTPUT"); + println!("EXPECTED\n{expected}\nEXPECTED"); + panic!("pattern match failed"); + } + + output.assert_exit_code(0); +} + +fn no_snaps_included(test_name: &str, extension: &str) { + let context = TestContext::default(); + let tempdir = context.temp_dir(); + let tempdir = tempdir.path().join("cov"); + + let output = context + .new_command() + .args_vec(vec![ + "test".to_string(), + "--quiet".to_string(), + "--allow-read".to_string(), + format!("--coverage={}", tempdir), + format!("coverage/no_snaps_included/{test_name}_test.{extension}"), + ]) + .run(); + + output.assert_exit_code(0); + output.skip_output_check(); + + let output = context + .new_command() + .args_vec(vec![ + "coverage".to_string(), + "--include=no_snaps_included.ts".to_string(), + "--detailed".to_string(), + format!("{}/", tempdir), + ]) + .split_output() + .run(); + + // Verify there's no "Check" being printed + assert!(output.stderr().is_empty()); + + let actual = util::strip_ansi_codes(output.stdout()).to_string(); + + let expected = fs::read_to_string( + util::testdata_path().join("coverage/no_snaps_included/expected.out"), + ) + .unwrap(); + + if !util::wildcard_match(&expected, &actual) { + println!("OUTPUT\n{actual}\nOUTPUT"); + println!("EXPECTED\n{expected}\nEXPECTED"); + panic!("pattern match failed"); + } + + output.assert_exit_code(0); +} + +fn no_tests_included(test_name: &str, extension: &str) { + let context = TestContext::default(); + let tempdir = context.temp_dir(); + let tempdir = tempdir.path().join("cov"); + + let output = context + .new_command() + .args_vec(vec![ + "test".to_string(), + "--quiet".to_string(), + "--allow-read".to_string(), + format!("--coverage={}", tempdir), + format!("coverage/no_tests_included/{test_name}.test.{extension}"), + ]) + .run(); + + output.assert_exit_code(0); + output.skip_output_check(); + + let output = context + .new_command() + .args_vec(vec![ + "coverage".to_string(), + format!("--exclude={}", util::std_path().canonicalize()), + "--detailed".to_string(), + format!("{}/", tempdir), + ]) + .split_output() + .run(); + + // Verify there's no "Check" being printed + assert!(output.stderr().is_empty()); + + let actual = util::strip_ansi_codes(output.stdout()).to_string(); + + let expected = fs::read_to_string( + util::testdata_path().join("coverage/no_tests_included/expected.out"), + ) + .unwrap(); + + if !util::wildcard_match(&expected, &actual) { + println!("OUTPUT\n{actual}\nOUTPUT"); + println!("EXPECTED\n{expected}\nEXPECTED"); + panic!("pattern match failed"); + } + + output.assert_exit_code(0); +} + +#[test] +fn no_npm_cache_coverage() { + let context = TestContext::with_http_server(); + let tempdir = context.temp_dir(); + let tempdir = tempdir.path().join("cov"); + + let output = context + .new_command() + .args_vec(vec![ + "test".to_string(), + "--quiet".to_string(), + "--allow-read".to_string(), + format!("--coverage={}", tempdir), + format!("coverage/no_npm_coverage/no_npm_coverage_test.ts"), + ]) + .envs(env_vars_for_npm_tests()) + .run(); + + output.assert_exit_code(0); + output.skip_output_check(); + + let output = context + .new_command() + .args_vec(vec![ + "coverage".to_string(), + "--detailed".to_string(), + format!("{}/", tempdir), + ]) + .split_output() + .run(); + + // Verify there's no "Check" being printed + assert!(output.stderr().is_empty()); + + let actual = util::strip_ansi_codes(output.stdout()).to_string(); + + let expected = fs::read_to_string( + util::testdata_path().join("coverage/no_npm_coverage/expected.out"), + ) + .unwrap(); + + if !util::wildcard_match(&expected, &actual) { + println!("OUTPUT\n{actual}\nOUTPUT"); + println!("EXPECTED\n{expected}\nEXPECTED"); + panic!("pattern match failed"); + } + + output.assert_exit_code(0); +} + +#[test] +fn no_transpiled_lines() { + let context = TestContext::default(); + let tempdir = context.temp_dir(); + let tempdir = tempdir.path().join("cov"); + + let output = context + .new_command() + .args_vec(vec![ + "test".to_string(), + "--quiet".to_string(), + format!("--coverage={}", tempdir), + "coverage/no_transpiled_lines/".to_string(), + ]) + .run(); + + output.assert_exit_code(0); + output.skip_output_check(); + + let output = context + .new_command() + .args_vec(vec![ + "coverage".to_string(), + "--include=no_transpiled_lines/index.ts".to_string(), + "--detailed".to_string(), + format!("{}/", tempdir), + ]) + .run(); + + let actual = util::strip_ansi_codes(output.combined_output()).to_string(); + + let expected = fs::read_to_string( + util::testdata_path().join("coverage/no_transpiled_lines/expected.out"), + ) + .unwrap(); + + if !util::wildcard_match(&expected, &actual) { + println!("OUTPUT\n{actual}\nOUTPUT"); + println!("EXPECTED\n{expected}\nEXPECTED"); + panic!("pattern match failed"); + } + + output.assert_exit_code(0); + + let output = context + .new_command() + .args_vec(vec![ + "coverage".to_string(), + "--lcov".to_string(), + "--include=no_transpiled_lines/index.ts".to_string(), + format!("{}/", tempdir), + ]) + .run(); + + let actual = util::strip_ansi_codes(output.combined_output()).to_string(); + + let expected = fs::read_to_string( + util::testdata_path().join("coverage/no_transpiled_lines/expected.lcov"), + ) + .unwrap(); + + if !util::wildcard_match(&expected, &actual) { + println!("OUTPUT\n{actual}\nOUTPUT"); + println!("EXPECTED\n{expected}\nEXPECTED"); + panic!("pattern match failed"); + } + + output.assert_exit_code(0); +} + +#[test] +fn no_internal_code() { + let context = TestContext::default(); + let tempdir = context.temp_dir(); + let tempdir = tempdir.path().join("cov"); + + let output = context + .new_command() + .args_vec(vec![ + "test".to_string(), + "--quiet".to_string(), + format!("--coverage={}", tempdir), + "coverage/no_internal_code_test.ts".to_string(), + ]) + .run(); + + output.assert_exit_code(0); + output.skip_output_check(); + + // Check that coverage files contain no internal urls + let paths = fs::read_dir(tempdir).unwrap(); + for path in paths { + let unwrapped = path.unwrap().path(); + let data = fs::read_to_string(&unwrapped.clone()).unwrap(); + + let value: serde_json::Value = serde_json::from_str(&data).unwrap(); + let url = value["url"].as_str().unwrap(); + assert_starts_with!(url, "file:"); + } +} + +#[test] +fn no_internal_node_code() { + let context = TestContext::default(); + let tempdir = context.temp_dir(); + let tempdir = tempdir.path().join("cov"); + + let output = context + .new_command() + .args_vec(vec![ + "test".to_string(), + "--quiet".to_string(), + "--no-check".to_string(), + format!("--coverage={}", tempdir), + "coverage/no_internal_node_code_test.ts".to_string(), + ]) + .run(); + + output.assert_exit_code(0); + output.skip_output_check(); + + // Check that coverage files contain no internal urls + let paths = fs::read_dir(tempdir).unwrap(); + for path in paths { + let unwrapped = path.unwrap().path(); + let data = fs::read_to_string(&unwrapped.clone()).unwrap(); + + let value: serde_json::Value = serde_json::from_str(&data).unwrap(); + let url = value["url"].as_str().unwrap(); + assert_starts_with!(url, "file:"); + } +} + +#[test] +fn test_html_reporter() { + let context = TestContext::default(); + let tempdir = context.temp_dir(); + let tempdir = tempdir.path().join("cov"); + + let output = context + .new_command() + .args_vec(vec![ + "test".to_string(), + "--quiet".to_string(), + format!("--coverage={}", tempdir), + "coverage/multisource".to_string(), + ]) + .run(); + + output.assert_exit_code(0); + output.skip_output_check(); + + let output = context + .new_command() + .args_vec(vec![ + "coverage".to_string(), + "--html".to_string(), + format!("{}/", tempdir), + ]) + .run(); + + output.assert_exit_code(0); + output.assert_matches_text("HTML coverage report has been generated at [WILDCARD]/cov/html/index.html\n"); + + let index_html = + fs::read_to_string(tempdir.join("html").join("index.html")).unwrap(); + assert!(index_html.contains("

Coverage report for all files

")); + assert!(index_html.contains("baz/")); + assert!(index_html.contains("href='baz/index.html'")); + assert!(index_html.contains("foo.ts")); + assert!(index_html.contains("href='foo.ts.html'")); + assert!(index_html.contains("bar.ts")); + assert!(index_html.contains("href='bar.ts.html'")); + + let foo_ts_html = + fs::read_to_string(tempdir.join("html").join("foo.ts.html")).unwrap(); + assert!(foo_ts_html.contains("

Coverage report for foo.ts

")); + + let bar_ts_html = + fs::read_to_string(tempdir.join("html").join("bar.ts.html")).unwrap(); + assert!(bar_ts_html.contains("

Coverage report for bar.ts

")); + // Check in source code is escaped to <T> + assert!(bar_ts_html.contains("<T>")); + + let baz_index_html = + fs::read_to_string(tempdir.join("html").join("baz").join("index.html")) + .unwrap(); + assert!(baz_index_html.contains("

Coverage report for baz/

")); + assert!(baz_index_html.contains("qux.ts")); + assert!(baz_index_html.contains("href='qux.ts.html'")); + assert!(baz_index_html.contains("quux.ts")); + assert!(baz_index_html.contains("href='quux.ts.html'")); + + let baz_qux_ts_html = + fs::read_to_string(tempdir.join("html").join("baz").join("qux.ts.html")) + .unwrap(); + assert!(baz_qux_ts_html.contains("

Coverage report for baz/qux.ts

")); + + let baz_quux_ts_html = + fs::read_to_string(tempdir.join("html").join("baz").join("quux.ts.html")) + .unwrap(); + assert!(baz_quux_ts_html.contains("

Coverage report for baz/quux.ts

")); +} + +#[test] +fn test_summary_reporter() { + let context = TestContext::default(); + let tempdir = context.temp_dir(); + let tempdir = tempdir.path().join("cov"); + + let output = context + .new_command() + .args_vec(vec![ + "test".to_string(), + "--quiet".to_string(), + format!("--coverage={}", tempdir), + "coverage/multisource".to_string(), + ]) + .run(); + + output.assert_exit_code(0); + output.skip_output_check(); + + let output = context + .new_command() + .args_vec(vec!["coverage".to_string(), format!("{}/", tempdir)]) + .run(); + + output.assert_exit_code(0); + output.assert_matches_text( + "---------------------------------- +File | Branch % | Line % | +---------------------------------- + bar.ts | 0.0 | 57.1 | + baz/quux.ts | 0.0 | 28.6 | + baz/qux.ts | 100.0 | 100.0 | + foo.ts | 50.0 | 76.9 | +---------------------------------- + All files | 40.0 | 61.0 | +---------------------------------- +", + ); +} + +itest!(no_files_found { + args: "coverage doesnt_exist.js", + exit_code: 1, + output: "coverage/doesnt_exist.out", +}); diff --git a/tests/integration/doc_tests.rs b/tests/integration/doc_tests.rs new file mode 100644 index 000000000..62fd2a5b4 --- /dev/null +++ b/tests/integration/doc_tests.rs @@ -0,0 +1,152 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +use test_util as util; +use util::assert_contains; +use util::TestContext; + +itest!(deno_doc_builtin { + args: "doc", + output: "doc/deno_doc_builtin.out", +}); + +#[test] +fn deno_doc() { + let context = TestContext::default(); + // try this twice to ensure it works with the cache + for _ in 0..2 { + let output = context + .new_command() + .env("NO_COLOR", "1") + .args("doc doc/deno_doc.ts doc/deno_doc2.ts") + .split_output() + .run(); + + output.assert_exit_code(0); + assert_contains!(output.stdout(), "function foo"); + assert_contains!(output.stdout(), "function bar"); + } +} + +itest!(deno_doc_import_map { + args: "doc --import-map=doc/import_map.json doc/use_import_map.js", + output: "doc/use_import_map.out", +}); + +itest!(deno_doc_types_hint { + args: "doc doc/types_hint.ts", + output: "doc/types_hint.out", +}); + +itest!(deno_doc_types_ref { + args: "doc doc/types_ref.js", + output: "doc/types_ref.out", +}); + +itest!(deno_doc_types_header { + args: "doc --reload doc/types_header.ts", + output: "doc/types_header.out", + http_server: true, +}); + +itest!(deno_doc_referenced_private_types { + args: "doc doc/referenced_private_types.ts", + output: "doc/referenced_private_types.out", +}); + +itest!(deno_doc_lint_referenced_private_types_error { + args: "doc --lint doc/referenced_private_types.ts", + exit_code: 1, + output: "doc/referenced_private_types_lint.out", +}); + +itest!(deno_doc_lint_referenced_private_types_fixed { + args: "doc --lint doc/referenced_private_types_fixed.ts", + output: "doc/referenced_private_types_fixed.out", +}); + +itest!(deno_doc_html_lint_referenced_private_types_fixed { + args: "doc --lint --html --name=Library doc/referenced_private_types.ts", + exit_code: 1, + output: "doc/referenced_private_types_lint.out", +}); + +itest!(deno_doc_lint_success { + args: "doc --lint doc/lint_success.ts", + output: "doc/lint_success.out", +}); + +itest!(deno_doc_lint_json_success { + args: "doc --lint --json doc/lint_success.ts", + output: "doc/lint_success_json.out", +}); + +itest!(deno_doc_lint_html_success { + args: "doc --lint --html --name=Library lint_success.ts", + copy_temp_dir: Some("doc"), + cwd: Some("doc"), + output: "doc/lint_success_html.out", +}); + +itest!(_060_deno_doc_displays_all_overloads_in_details_view { + args: + "doc --filter NS.test doc/060_deno_doc_displays_all_overloads_in_details_view.ts", + output: "doc/060_deno_doc_displays_all_overloads_in_details_view.ts.out", +}); + +itest!(deno_doc_types_header_direct { + args: "doc --reload http://127.0.0.1:4545/xTypeScriptTypes.js", + output: "doc/types_header.out", + http_server: true, +}); + +itest!(deno_doc_invalid_url { + args: "doc https://raw.githubusercontent.com%2Fdyedgreen%2Fdeno-sqlite%2Frework_api%2Fmod.ts", + output: "doc/invalid_url.out", + exit_code: 1, +}); + +itest!(doc_lock { + args: "doc main.ts", + http_server: true, + cwd: Some("lockfile/basic"), + exit_code: 10, + output: "lockfile/basic/fail.out", +}); + +itest!(doc_no_lock { + args: "doc --no-lock main.ts", + http_server: true, + cwd: Some("lockfile/basic"), + output: "lockfile/basic/doc.nolock.out", +}); + +#[test] +fn deno_doc_html() { + let context = TestContext::default(); + let temp_dir = context.temp_dir(); + let output = context + .new_command() + .env("NO_COLOR", "1") + .args_vec(vec![ + "doc", + "--html", + "--name=MyLib", + &format!("--output={}", temp_dir.path().to_string_lossy()), + "doc/referenced_private_types_fixed.ts", + ]) + .split_output() + .run(); + + output.assert_exit_code(0); + assert_contains!(output.stderr(), "Written 10 files to"); + assert!(temp_dir.path().join("all_symbols.html").exists()); + assert!(temp_dir.path().join("index.html").exists()); + assert!(temp_dir.path().join("fuse.js").exists()); + assert!(temp_dir.path().join("page.css").exists()); + assert!(temp_dir.path().join("search.js").exists()); + assert!(temp_dir.path().join("search_index.js").exists()); + assert!(temp_dir.path().join("styles.css").exists()); + assert!(temp_dir.path().join("~/MyInterface.html").exists()); + assert!(temp_dir.path().join("~/MyClass.html").exists()); + assert!(temp_dir.path().join("~/index.html").exists()); +} diff --git a/tests/integration/eval_tests.rs b/tests/integration/eval_tests.rs new file mode 100644 index 000000000..1ae65e49e --- /dev/null +++ b/tests/integration/eval_tests.rs @@ -0,0 +1,89 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +use test_util as util; + +#[test] +fn eval_p() { + let output = util::deno_cmd() + .arg("eval") + .arg("-p") + .arg("1+2") + .stdout_piped() + .spawn() + .unwrap() + .wait_with_output() + .unwrap(); + assert!(output.status.success()); + let stdout_str = + util::strip_ansi_codes(std::str::from_utf8(&output.stdout).unwrap().trim()); + assert_eq!("3", stdout_str); +} + +// Make sure that snapshot flags don't affect runtime. +#[test] +fn eval_randomness() { + let mut numbers = Vec::with_capacity(10); + for _ in 0..10 { + let output = util::deno_cmd() + .arg("eval") + .arg("-p") + .arg("Math.random()") + .stdout_piped() + .spawn() + .unwrap() + .wait_with_output() + .unwrap(); + assert!(output.status.success()); + let stdout_str = util::strip_ansi_codes( + std::str::from_utf8(&output.stdout).unwrap().trim(), + ); + numbers.push(stdout_str.to_string()); + } + numbers.dedup(); + assert!(numbers.len() > 1); +} + +itest!(eval_basic { + args: "eval console.log(\"hello\")", + output_str: Some("hello\n"), +}); + +// Ugly parentheses due to whitespace delimiting problem. +itest!(eval_ts { + args: "eval --quiet --ext=ts console.log((123)as(number))", // 'as' is a TS keyword only + output_str: Some("123\n"), +}); + +itest!(dyn_import_eval { + args: "eval import('./subdir/mod4.js').then(console.log)", + output: "eval/dyn_import_eval.out", +}); + +// Cannot write the expression to evaluate as "console.log(typeof gc)" +// because itest! splits args on whitespace. +itest!(v8_flags_eval { + args: "eval --v8-flags=--expose-gc console.log(typeof(gc))", + output: "run/v8_flags.js.out", +}); + +itest!(check_local_by_default { + args: "eval --quiet import('http://localhost:4545/subdir/type_error.ts').then(console.log);", + output: "eval/check_local_by_default.out", + http_server: true, +}); + +itest!(check_local_by_default2 { + args: "eval --quiet import('./eval/check_local_by_default2.ts').then(console.log);", + output: "eval/check_local_by_default2.out", + http_server: true, +}); + +itest!(env_file { + args: "eval --env=env console.log(Deno.env.get(\"ANOTHER_FOO\"))", + output_str: Some("ANOTHER_BAR\n"), +}); + +itest!(env_file_missing { + args: "eval --env=missing console.log(Deno.env.get(\"ANOTHER_FOO\"))", + output: "eval/env_file_missing.out", +}); diff --git a/tests/integration/flags_tests.rs b/tests/integration/flags_tests.rs new file mode 100644 index 000000000..a22cb0548 --- /dev/null +++ b/tests/integration/flags_tests.rs @@ -0,0 +1,86 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +use test_util as util; +use util::assert_contains; + +#[test] +fn help_flag() { + let status = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("--help") + .spawn() + .unwrap() + .wait() + .unwrap(); + assert!(status.success()); +} + +#[test] +fn help_output() { + let output = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("--help") + .run(); + + let stdout = output.combined_output(); + let subcommand_descriptions = vec![ + "Run a JavaScript or TypeScript program", + "Run benchmarks", + "Bundle module and dependencies into single file", + "Cache the dependencies", + "Type-check the dependencies", + "Compile the script into a self contained executable", + "Generate shell completions", + "Print coverage reports", + "Show documentation for a module", + "Eval script", + "Format source files", + "Initialize a new project", + "Show info about cache or info related to source file", + "Install script as an executable", + "Uninstall a script previously installed with deno install", + "Start the language server", + "Lint source files", + "Read Eval Print Loop", + "Run a task defined in the configuration file", + "Run tests", + "Print runtime TypeScript declarations", + #[cfg(feature = "upgrade")] + "Upgrade deno executable to given version", + "Vendor remote modules into a local directory", + "Print this message or the help of the given subcommand(s)", + ]; + + for description in subcommand_descriptions { + assert_contains!(stdout, description); + } +} + +#[test] +fn version_short_flag() { + let status = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("-V") + .spawn() + .unwrap() + .wait() + .unwrap(); + assert!(status.success()); +} + +#[test] +fn version_long_flag() { + let status = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("--version") + .spawn() + .unwrap() + .wait() + .unwrap(); + assert!(status.success()); +} + +itest!(types { + args: "types", + output: "types/types.out", +}); diff --git a/tests/integration/fmt_tests.rs b/tests/integration/fmt_tests.rs new file mode 100644 index 000000000..94eca295e --- /dev/null +++ b/tests/integration/fmt_tests.rs @@ -0,0 +1,352 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +use test_util as util; +use util::assert_contains; +use util::PathRef; +use util::TestContext; +use util::TestContextBuilder; + +#[test] +fn fmt_test() { + let context = TestContext::default(); + let t = context.deno_dir(); + let testdata_fmt_dir = util::testdata_path().join("fmt"); + let fixed_js = testdata_fmt_dir.join("badly_formatted_fixed.js"); + let badly_formatted_original_js = + testdata_fmt_dir.join("badly_formatted.mjs"); + let badly_formatted_js = t.path().join("badly_formatted.js"); + badly_formatted_original_js.copy(&badly_formatted_js); + + let fixed_md = testdata_fmt_dir.join("badly_formatted_fixed.md"); + let badly_formatted_original_md = testdata_fmt_dir.join("badly_formatted.md"); + let badly_formatted_md = t.path().join("badly_formatted.md"); + badly_formatted_original_md.copy(&badly_formatted_md); + + let fixed_json = testdata_fmt_dir.join("badly_formatted_fixed.json"); + let badly_formatted_original_json = + testdata_fmt_dir.join("badly_formatted.json"); + let badly_formatted_json = t.path().join("badly_formatted.json"); + badly_formatted_original_json.copy(&badly_formatted_json); + + let fixed_ipynb = testdata_fmt_dir.join("badly_formatted_fixed.ipynb"); + let badly_formatted_original_ipynb = + testdata_fmt_dir.join("badly_formatted.ipynb"); + let badly_formatted_ipynb = t.path().join("badly_formatted.ipynb"); + badly_formatted_original_ipynb.copy(&badly_formatted_ipynb); + + // First, check formatting by ignoring the badly formatted file. + let output = context + .new_command() + .current_dir(&testdata_fmt_dir) + .args_vec(vec![ + "fmt".to_string(), + format!( + "--ignore={badly_formatted_js},{badly_formatted_md},{badly_formatted_json},{badly_formatted_ipynb}", + ), + format!( + "--check {badly_formatted_js} {badly_formatted_md} {badly_formatted_json} {badly_formatted_ipynb}", + ), + ]) + .run(); + + // No target files found + output.assert_exit_code(1); + output.skip_output_check(); + + // Check without ignore. + let output = context + .new_command() + .current_dir(&testdata_fmt_dir) + .args_vec(vec![ + "fmt".to_string(), + "--check".to_string(), + badly_formatted_js.to_string(), + badly_formatted_md.to_string(), + badly_formatted_json.to_string(), + badly_formatted_ipynb.to_string(), + ]) + .run(); + + output.assert_exit_code(1); + output.skip_output_check(); + + // Format the source file. + let output = context + .new_command() + .current_dir(&testdata_fmt_dir) + .args_vec(vec![ + "fmt".to_string(), + badly_formatted_js.to_string(), + badly_formatted_md.to_string(), + badly_formatted_json.to_string(), + badly_formatted_ipynb.to_string(), + ]) + .run(); + + output.assert_exit_code(0); + output.skip_output_check(); + + let expected_js = fixed_js.read_to_string(); + let expected_md = fixed_md.read_to_string(); + let expected_json = fixed_json.read_to_string(); + let expected_ipynb = fixed_ipynb.read_to_string(); + let actual_js = badly_formatted_js.read_to_string(); + let actual_md = badly_formatted_md.read_to_string(); + let actual_json = badly_formatted_json.read_to_string(); + let actual_ipynb = badly_formatted_ipynb.read_to_string(); + assert_eq!(expected_js, actual_js); + assert_eq!(expected_md, actual_md); + assert_eq!(expected_json, actual_json); + assert_eq!(expected_ipynb, actual_ipynb); +} + +#[test] +fn fmt_stdin_syntax_error() { + let output = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("fmt") + .arg("-") + .stdin_text("import { example }") + .split_output() + .run(); + assert!(output.stdout().is_empty()); + assert!(!output.stderr().is_empty()); + output.assert_exit_code(1); +} + +#[test] +fn fmt_ignore_unexplicit_files() { + let context = TestContext::default(); + let output = context + .new_command() + .env("NO_COLOR", "1") + .args("fmt --check --ignore=./") + .run(); + + output.assert_exit_code(1); + assert_eq!(output.combined_output(), "error: No target files found.\n"); +} + +#[test] +fn fmt_auto_ignore_git_and_node_modules() { + fn create_bad_json(t: PathRef) { + let bad_json_path = t.join("bad.json"); + bad_json_path.write("bad json\n"); + } + + let context = TestContext::default(); + let temp_dir = context.temp_dir(); + let t = temp_dir.path().join("target"); + let nest_git = t.join("nest").join(".git"); + let git_dir = t.join(".git"); + let nest_node_modules = t.join("nest").join("node_modules"); + let node_modules_dir = t.join("node_modules"); + nest_git.create_dir_all(); + git_dir.create_dir_all(); + nest_node_modules.create_dir_all(); + node_modules_dir.create_dir_all(); + create_bad_json(nest_git); + create_bad_json(git_dir); + create_bad_json(nest_node_modules); + create_bad_json(node_modules_dir); + + let output = context + .new_command() + .current_dir(t) + .env("NO_COLOR", "1") + .args("fmt") + .run(); + + output.assert_exit_code(1); + assert_eq!(output.combined_output(), "error: No target files found.\n"); +} + +itest!(fmt_quiet_check_fmt_dir { + args: "fmt --check --quiet fmt/regular/", + output_str: Some(""), + exit_code: 0, +}); + +itest!(fmt_check_formatted_files { + args: "fmt --check fmt/regular/formatted1.js fmt/regular/formatted2.ts fmt/regular/formatted3.markdown fmt/regular/formatted4.jsonc", + output: "fmt/expected_fmt_check_formatted_files.out", + exit_code: 0, +}); + +itest!(fmt_check_ignore { + args: "fmt --check --ignore=fmt/regular/formatted1.js fmt/regular/", + output: "fmt/expected_fmt_check_ignore.out", + exit_code: 0, +}); + +itest!(fmt_check_parse_error { + args: "fmt --check fmt/parse_error/parse_error.ts", + output: "fmt/fmt_check_parse_error.out", + exit_code: 1, +}); + +itest!(fmt_check_invalid_data { + args: "fmt --check fmt/invalid_data.json", + output: "fmt/invalid_data.out", + exit_code: 1, +}); + +itest!(fmt_stdin { + args: "fmt -", + input: Some("const a = 1\n"), + output_str: Some("const a = 1;\n"), +}); + +itest!(fmt_stdin_markdown { + args: "fmt --ext=md -", + input: Some("# Hello Markdown\n```ts\nconsole.log( \"text\")\n```\n\n```cts\nconsole.log( 5 )\n```"), + output_str: Some("# Hello Markdown\n\n```ts\nconsole.log(\"text\");\n```\n\n```cts\nconsole.log(5);\n```\n"), +}); + +itest!(fmt_stdin_json { + args: "fmt --ext=json -", + input: Some("{ \"key\": \"value\"}"), + output_str: Some("{ \"key\": \"value\" }\n"), +}); + +itest!(fmt_stdin_ipynb { + args: "fmt --ext=ipynb -", + input: Some(include_str!("../testdata/fmt/badly_formatted.ipynb")), + output_str: Some(include_str!("../testdata/fmt/badly_formatted_fixed.ipynb")), +}); + +itest!(fmt_stdin_check_formatted { + args: "fmt --check -", + input: Some("const a = 1;\n"), + output_str: Some(""), +}); + +itest!(fmt_stdin_check_not_formatted { + args: "fmt --check -", + input: Some("const a = 1\n"), + output_str: Some("Not formatted stdin\n"), +}); + +itest!(fmt_with_config { + args: "fmt --config fmt/with_config/deno.jsonc fmt/with_config/subdir", + output: "fmt/fmt_with_config.out", +}); + +itest!(fmt_with_deprecated_config { + args: + "fmt --config fmt/with_config/deno.deprecated.jsonc fmt/with_config/subdir", + output: "fmt/fmt_with_deprecated_config.out", +}); + +itest!(fmt_with_config_default { + args: "fmt fmt/with_config/subdir", + output: "fmt/fmt_with_config.out", +}); + +// Check if CLI flags take precedence +itest!(fmt_with_config_and_flags { + args: "fmt --config fmt/with_config/deno.jsonc --ignore=fmt/with_config/subdir/a.ts,fmt/with_config/subdir/b.ts", + output: "fmt/fmt_with_config_and_flags.out", +}); + +itest!(fmt_with_malformed_config { + args: "fmt --config fmt/deno.malformed.jsonc", + output: "fmt/fmt_with_malformed_config.out", + exit_code: 1, +}); + +itest!(fmt_with_malformed_config2 { + args: "fmt --config fmt/deno.malformed2.jsonc", + output: "fmt/fmt_with_malformed_config2.out", + exit_code: 1, +}); + +#[test] +fn fmt_with_glob_config() { + let context = TestContextBuilder::new().cwd("fmt").build(); + + let cmd_output = context + .new_command() + .args("fmt --check --config deno.glob.json") + .run(); + + cmd_output.assert_exit_code(1); + + let output = cmd_output.combined_output(); + if cfg!(windows) { + assert_contains!(output, r"glob\nested\fizz\fizz.ts"); + assert_contains!(output, r"glob\pages\[id].ts"); + assert_contains!(output, r"glob\nested\fizz\bar.ts"); + assert_contains!(output, r"glob\nested\foo\foo.ts"); + assert_contains!(output, r"glob\data\test1.js"); + assert_contains!(output, r"glob\nested\foo\bar.ts"); + assert_contains!(output, r"glob\nested\foo\fizz.ts"); + assert_contains!(output, r"glob\nested\fizz\foo.ts"); + assert_contains!(output, r"glob\data\test1.ts"); + } else { + assert_contains!(output, "glob/nested/fizz/fizz.ts"); + assert_contains!(output, "glob/pages/[id].ts"); + assert_contains!(output, "glob/nested/fizz/bar.ts"); + assert_contains!(output, "glob/nested/foo/foo.ts"); + assert_contains!(output, "glob/data/test1.js"); + assert_contains!(output, "glob/nested/foo/bar.ts"); + assert_contains!(output, "glob/nested/foo/fizz.ts"); + assert_contains!(output, "glob/nested/fizz/foo.ts"); + assert_contains!(output, "glob/data/test1.ts"); + } + + assert_contains!(output, "Found 9 not formatted files in 9 files"); +} + +#[test] +fn fmt_with_glob_config_and_flags() { + let context = TestContextBuilder::new().cwd("fmt").build(); + + let cmd_output = context + .new_command() + .args("fmt --check --config deno.glob.json --ignore=glob/nested/**/bar.ts") + .run(); + + cmd_output.assert_exit_code(1); + + let output = cmd_output.combined_output(); + if cfg!(windows) { + assert_contains!(output, r"glob\nested\fizz\fizz.ts"); + assert_contains!(output, r"glob\pages\[id].ts"); + assert_contains!(output, r"glob\nested\fizz\bazz.ts"); + assert_contains!(output, r"glob\nested\foo\foo.ts"); + assert_contains!(output, r"glob\data\test1.js"); + assert_contains!(output, r"glob\nested\foo\bazz.ts"); + assert_contains!(output, r"glob\nested\foo\fizz.ts"); + assert_contains!(output, r"glob\nested\fizz\foo.ts"); + assert_contains!(output, r"glob\data\test1.ts"); + } else { + assert_contains!(output, "glob/nested/fizz/fizz.ts"); + assert_contains!(output, "glob/pages/[id].ts"); + assert_contains!(output, "glob/nested/fizz/bazz.ts"); + assert_contains!(output, "glob/nested/foo/foo.ts"); + assert_contains!(output, "glob/data/test1.js"); + assert_contains!(output, "glob/nested/foo/bazz.ts"); + assert_contains!(output, "glob/nested/foo/fizz.ts"); + assert_contains!(output, "glob/nested/fizz/foo.ts"); + assert_contains!(output, "glob/data/test1.ts"); + } + assert_contains!(output, "Found 9 not formatted files in 9 files"); + let cmd_output = context + .new_command() + .args("fmt --check --config deno.glob.json glob/data/test1.?s") + .run(); + + cmd_output.assert_exit_code(1); + + let output = cmd_output.combined_output(); + if cfg!(windows) { + assert_contains!(output, r"glob\data\test1.js"); + assert_contains!(output, r"glob\data\test1.ts"); + } else { + assert_contains!(output, "glob/data/test1.js"); + assert_contains!(output, "glob/data/test1.ts"); + } + + assert_contains!(output, "Found 2 not formatted files in 2 files"); +} diff --git a/tests/integration/info_tests.rs b/tests/integration/info_tests.rs new file mode 100644 index 000000000..922fcee06 --- /dev/null +++ b/tests/integration/info_tests.rs @@ -0,0 +1,162 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +use test_util as util; +use util::env_vars_for_npm_tests; +use util::TestContextBuilder; + +#[test] +fn info_with_compiled_source() { + let context = TestContextBuilder::new().use_http_server().build(); + let module_path = "http://127.0.0.1:4545/run/048_media_types_jsx.ts"; + + let output = context + .new_command() + .current_dir(util::testdata_path()) + .args_vec(["cache", module_path]) + .run(); + output.assert_exit_code(0); + output.skip_output_check(); + + let output = context + .new_command() + .current_dir(util::testdata_path()) + .args_vec(["info", module_path]) + .split_output() + .run(); + + // check the output of the test.ts program. + assert!(output.stdout().trim().contains("emit: ")); + assert_eq!(output.stderr(), ""); +} + +itest!(multiple_imports { + args: "info http://127.0.0.1:4545/run/019_media_types.ts", + output: "info/multiple_imports.out", + http_server: true, +}); + +itest!(info_ts_error { + args: "info info/031_info_ts_error.ts", + output: "info/031_info_ts_error.out", +}); + +itest!(info_flag { + args: "info", + output: "info/041_info_flag.out", +}); + +itest!(info_flag_location { + args: "info --location https://deno.land", + output: "info/041_info_flag_location.out", +}); + +itest!(info_json { + args: "info --json", + output: "info/info_json.out", +}); + +itest!(info_json_location { + args: "info --json --location https://deno.land", + output: "info/info_json_location.out", +}); + +itest!(info_flag_script_jsx { + args: "info http://127.0.0.1:4545/run/048_media_types_jsx.ts", + output: "info/049_info_flag_script_jsx.out", + http_server: true, +}); + +itest!(json_file { + args: "info --quiet --json info/json_output/main.ts", + output: "info/json_output/main.out", + exit_code: 0, +}); + +itest!(import_map_info { + args: + "info --quiet --import-map=import_maps/import_map.json import_maps/test.ts", + output: "info/065_import_map_info.out", +}); + +itest!(info_json_deps_order { + args: "info --json info/076_info_json_deps_order.ts", + output: "info/076_info_json_deps_order.out", +}); + +itest!(info_missing_module { + args: "info info/error_009_missing_js_module.js", + output: "info/info_missing_module.out", +}); + +itest!(info_lock { + args: "info main.ts", + http_server: true, + cwd: Some("lockfile/basic"), + exit_code: 10, + output: "lockfile/basic/fail.out", +}); + +itest!(info_no_lock { + args: "info --no-lock main.ts", + http_server: true, + cwd: Some("lockfile/basic"), + output: "lockfile/basic/info.nolock.out", +}); + +itest!(info_recursive_modules { + args: "info --quiet info/info_recursive_imports_test.ts", + output: "info/info_recursive_imports_test.out", + exit_code: 0, +}); + +itest!(info_type_import { + args: "info info/info_type_import.ts", + output: "info/info_type_import.out", +}); + +itest!(_054_info_local_imports { + args: "info --quiet run/005_more_imports.ts", + output: "info/054_info_local_imports.out", + exit_code: 0, +}); + +// Tests for AssertionError where "data" is unexpectedly null when +// a file contains only triple slash references (#11196) +itest!(data_null_error { + args: "info info/data_null_error/mod.ts", + output: "info/data_null_error/data_null_error.out", +}); + +itest!(types_header_direct { + args: "info --reload run/type_directives_01.ts", + output: "info/types_header.out", + http_server: true, +}); + +itest!(with_config_override { + args: "info info/with_config/test.ts --config info/with_config/deno-override.json --import-map info/with_config/import_map.json", + output: "info/with_config/with_config.out", +}); + +itest!(package_json_basic { + args: "info --quiet main.ts", + output: "package_json/basic/main.info.out", + envs: env_vars_for_npm_tests(), + http_server: true, + cwd: Some("package_json/basic"), + copy_temp_dir: Some("package_json/basic"), + exit_code: 0, +}); + +itest!(info_import_map { + args: "info preact/debug", + output: "info/with_import_map/with_import_map.out", + cwd: Some("info/with_import_map"), + exit_code: 0, +}); + +itest!(info_dynamic_imports_tmpl_lit { + args: "info compile/dynamic_imports_tmp_lit/main.js", + output: "compile/dynamic_imports_tmp_lit/main.info.out", + exit_code: 0, +}); diff --git a/tests/integration/init_tests.rs b/tests/integration/init_tests.rs new file mode 100644 index 000000000..d3908eae4 --- /dev/null +++ b/tests/integration/init_tests.rs @@ -0,0 +1,171 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +use test_util as util; +use util::assert_contains; +use util::TestContextBuilder; + +#[test] +fn init_subcommand_without_dir() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let cwd = context.temp_dir().path(); + + let output = context.new_command().args("init").split_output().run(); + + output.assert_exit_code(0); + + let stderr = output.stderr(); + assert_contains!(stderr, "Project initialized"); + assert!(!stderr.contains("cd")); + assert_contains!(stderr, "deno run main.ts"); + assert_contains!(stderr, "deno task dev"); + assert_contains!(stderr, "deno test"); + + assert!(cwd.join("deno.json").exists()); + + let output = context + .new_command() + .env("NO_COLOR", "1") + .args("run main.ts") + .split_output() + .run(); + + output.assert_exit_code(0); + assert_eq!(output.stdout().as_bytes(), b"Add 2 + 3 = 5\n"); + + let output = context + .new_command() + .env("NO_COLOR", "1") + .args("test") + .split_output() + .run(); + + output.assert_exit_code(0); + assert_contains!(output.stdout(), "1 passed"); + output.skip_output_check(); +} + +#[test] +fn init_subcommand_with_dir_arg() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let cwd = context.temp_dir().path(); + + let output = context + .new_command() + .args("init my_dir") + .split_output() + .run(); + + output.assert_exit_code(0); + + let stderr = output.stderr(); + assert_contains!(stderr, "Project initialized"); + assert_contains!(stderr, "cd my_dir"); + assert_contains!(stderr, "deno run main.ts"); + assert_contains!(stderr, "deno task dev"); + assert_contains!(stderr, "deno test"); + + assert!(cwd.join("my_dir/deno.json").exists()); + + let output = context + .new_command() + .env("NO_COLOR", "1") + .args("run my_dir/main.ts") + .split_output() + .run(); + + output.assert_exit_code(0); + + assert_eq!(output.stdout().as_bytes(), b"Add 2 + 3 = 5\n"); + output.skip_output_check(); + + let output = context + .new_command() + .env("NO_COLOR", "1") + .args("test my_dir/main_test.ts") + .split_output() + .run(); + + output.assert_exit_code(0); + assert_contains!(output.stdout(), "1 passed"); + output.skip_output_check(); +} + +#[test] +fn init_subcommand_with_quiet_arg() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let cwd = context.temp_dir().path(); + + let output = context + .new_command() + .args("init --quiet") + .split_output() + .run(); + + output.assert_exit_code(0); + + assert_eq!(output.stdout(), ""); + assert!(cwd.join("deno.json").exists()); + + let output = context + .new_command() + .env("NO_COLOR", "1") + .args("run main.ts") + .split_output() + .run(); + + output.assert_exit_code(0); + assert_eq!(output.stdout().as_bytes(), b"Add 2 + 3 = 5\n"); + output.skip_output_check(); + + let output = context + .new_command() + .env("NO_COLOR", "1") + .args("test") + .split_output() + .run(); + + output.assert_exit_code(0); + assert_contains!(output.stdout(), "1 passed"); + output.skip_output_check(); +} + +#[test] +fn init_subcommand_with_existing_file() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let cwd = context.temp_dir().path(); + + cwd + .join("main.ts") + .write("console.log('Log from main.ts that already exists');"); + + let output = context.new_command().args("init").split_output().run(); + + output.assert_exit_code(0); + output.assert_stderr_matches_text( + "ℹ️ Skipped creating main.ts as it already exists +✅ Project initialized + +Run these commands to get started + + # Run the program + deno run main.ts + + # Run the program and watch for file changes + deno task dev + + # Run the tests + deno test +", + ); + + assert!(cwd.join("deno.json").exists()); + + let output = context + .new_command() + .env("NO_COLOR", "1") + .args("run main.ts") + .run(); + + output.assert_exit_code(0); + output.assert_matches_text("Log from main.ts that already exists\n"); +} diff --git a/tests/integration/inspector_tests.rs b/tests/integration/inspector_tests.rs new file mode 100644 index 000000000..bbe70ae5e --- /dev/null +++ b/tests/integration/inspector_tests.rs @@ -0,0 +1,1440 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +use bytes::Bytes; +use deno_core::anyhow::anyhow; +use deno_core::error::AnyError; +use deno_core::serde_json; +use deno_core::serde_json::json; +use deno_core::url; +use deno_fetch::reqwest; +use fastwebsockets::FragmentCollector; +use fastwebsockets::Frame; +use fastwebsockets::WebSocket; +use hyper::body::Incoming; +use hyper::upgrade::Upgraded; +use hyper::Request; +use hyper::Response; +use hyper_util::rt::TokioIo; +use std::io::BufRead; +use std::time::Duration; +use test_util as util; +use tokio::net::TcpStream; +use tokio::time::timeout; +use url::Url; +use util::assert_starts_with; +use util::DenoChild; +use util::TestContextBuilder; + +struct SpawnExecutor; + +impl hyper::rt::Executor for SpawnExecutor +where + Fut: std::future::Future + Send + 'static, + Fut::Output: Send + 'static, +{ + fn execute(&self, fut: Fut) { + deno_core::unsync::spawn(fut); + } +} + +async fn connect_to_ws( + uri: Url, +) -> (WebSocket>, Response) { + let domain = &uri.host().unwrap().to_string(); + let port = &uri.port().unwrap_or(match uri.scheme() { + "wss" | "https" => 443, + _ => 80, + }); + let addr = format!("{domain}:{port}"); + + let stream = TcpStream::connect(addr).await.unwrap(); + + let host = uri.host_str().unwrap(); + + let req = Request::builder() + .method("GET") + .uri(uri.path()) + .header("Host", host) + .header(hyper::header::UPGRADE, "websocket") + .header(hyper::header::CONNECTION, "Upgrade") + .header( + "Sec-WebSocket-Key", + fastwebsockets::handshake::generate_key(), + ) + .header("Sec-WebSocket-Version", "13") + .body(http_body_util::Empty::::new()) + .unwrap(); + + fastwebsockets::handshake::client(&SpawnExecutor, req, stream) + .await + .unwrap() +} + +struct InspectorTester { + socket: FragmentCollector>, + notification_filter: Box bool + 'static>, + child: DenoChild, + stderr_lines: Box>, + stdout_lines: Box>, +} + +impl Drop for InspectorTester { + fn drop(&mut self) { + _ = self.child.kill(); + } +} + +fn ignore_script_parsed(msg: &str) -> bool { + !msg.starts_with(r#"{"method":"Debugger.scriptParsed","#) +} + +impl InspectorTester { + async fn create(mut child: DenoChild, notification_filter: F) -> Self + where + F: FnMut(&str) -> bool + 'static, + { + let stdout = child.stdout.take().unwrap(); + let stdout_lines = + std::io::BufReader::new(stdout).lines().map(|r| r.unwrap()); + + let stderr = child.stderr.take().unwrap(); + let mut stderr_lines = + std::io::BufReader::new(stderr).lines().map(|r| r.unwrap()); + + let uri = extract_ws_url_from_stderr(&mut stderr_lines); + + let (socket, response) = connect_to_ws(uri).await; + + assert_eq!(response.status(), 101); // Switching protocols. + + Self { + socket: FragmentCollector::new(socket), + notification_filter: Box::new(notification_filter), + child, + stderr_lines: Box::new(stderr_lines), + stdout_lines: Box::new(stdout_lines), + } + } + + async fn send_many(&mut self, messages: &[serde_json::Value]) { + // TODO(bartlomieju): add graceful error handling + for msg in messages { + let result = self + .socket + .write_frame(Frame::text(msg.to_string().into_bytes().into())) + .await + .map_err(|e| anyhow!(e)); + self.handle_error(result); + } + } + + async fn send(&mut self, message: serde_json::Value) { + self.send_many(&[message]).await; + } + + fn handle_error(&mut self, result: Result) -> T { + match result { + Ok(result) => result, + Err(err) => { + let mut stdout = vec![]; + for line in self.stdout_lines.by_ref() { + stdout.push(line); + } + let mut stderr = vec![]; + for line in self.stderr_lines.by_ref() { + stderr.push(line); + } + let stdout = stdout.join("\n"); + let stderr = stderr.join("\n"); + self.child.kill().unwrap(); + + panic!( + "Inspector test failed with error: {err:?}.\nstdout:\n{stdout}\nstderr:\n{stderr}" + ); + } + } + } + + async fn recv(&mut self) -> String { + loop { + // In the rare case this locks up, don't wait longer than one minute + let result = timeout(Duration::from_secs(60), self.socket.read_frame()) + .await + .expect("recv() timeout") + .map_err(|e| anyhow!(e)); + let message = + String::from_utf8(self.handle_error(result).payload.to_vec()).unwrap(); + if (self.notification_filter)(&message) { + return message; + } + } + } + + async fn recv_as_json(&mut self) -> serde_json::Value { + let msg = self.recv().await; + serde_json::from_str(&msg).unwrap() + } + + async fn assert_received_messages( + &mut self, + responses: &[&str], + notifications: &[&str], + ) { + let expected_messages = responses.len() + notifications.len(); + let mut responses_idx = 0; + let mut notifications_idx = 0; + + for _ in 0..expected_messages { + let msg = self.recv().await; + + if msg.starts_with(r#"{"id":"#) { + assert!( + msg.starts_with(responses[responses_idx]), + "Doesn't start with {}, instead received {}", + responses[responses_idx], + msg + ); + responses_idx += 1; + } else { + assert!( + msg.starts_with(notifications[notifications_idx]), + "Doesn't start with {}, instead received {}", + notifications[notifications_idx], + msg + ); + notifications_idx += 1; + } + } + } + + fn stderr_line(&mut self) -> String { + self.stderr_lines.next().unwrap() + } + + fn stdout_line(&mut self) -> String { + self.stdout_lines.next().unwrap() + } + + fn assert_stderr_for_inspect(&mut self) { + assert_stderr( + &mut self.stderr_lines, + &["Visit chrome://inspect to connect to the debugger."], + ); + } + + fn assert_stderr_for_inspect_brk(&mut self) { + assert_stderr( + &mut self.stderr_lines, + &[ + "Visit chrome://inspect to connect to the debugger.", + "Deno is waiting for debugger to connect.", + ], + ); + } +} + +fn assert_stderr( + stderr_lines: &mut impl std::iter::Iterator, + expected_lines: &[&str], +) { + let mut expected_index = 0; + + loop { + let line = skip_check_line(stderr_lines); + + assert_eq!(line, expected_lines[expected_index]); + expected_index += 1; + + if expected_index >= expected_lines.len() { + break; + } + } +} + +fn inspect_flag_with_unique_port(flag_prefix: &str) -> String { + use std::sync::atomic::AtomicU16; + use std::sync::atomic::Ordering; + static PORT: AtomicU16 = AtomicU16::new(9229); + let port = PORT.fetch_add(1, Ordering::Relaxed); + format!("{flag_prefix}=127.0.0.1:{port}") +} + +fn extract_ws_url_from_stderr( + stderr_lines: &mut impl std::iter::Iterator, +) -> url::Url { + let stderr_first_line = skip_check_line(stderr_lines); + assert_starts_with!(&stderr_first_line, "Debugger listening on "); + let v: Vec<_> = stderr_first_line.match_indices("ws:").collect(); + assert_eq!(v.len(), 1); + let ws_url_index = v[0].0; + let ws_url = &stderr_first_line[ws_url_index..]; + url::Url::parse(ws_url).unwrap() +} + +fn skip_check_line( + stderr_lines: &mut impl std::iter::Iterator, +) -> String { + loop { + let mut line = stderr_lines.next().unwrap(); + line = util::strip_ansi_codes(&line).to_string(); + + if line.starts_with("Check") || line.starts_with("Download") { + continue; + } + + return line; + } +} + +#[tokio::test] +async fn inspector_connect() { + let script = util::testdata_path().join("inspector/inspector1.js"); + let mut child = util::deno_cmd() + .arg("run") + .arg(inspect_flag_with_unique_port("--inspect")) + .arg(script) + .stderr_piped() + .spawn() + .unwrap(); + + let stderr = child.stderr.as_mut().unwrap(); + let mut stderr_lines = + std::io::BufReader::new(stderr).lines().map(|r| r.unwrap()); + let ws_url = extract_ws_url_from_stderr(&mut stderr_lines); + + let (_socket, response) = connect_to_ws(ws_url).await; + assert_eq!("101 Switching Protocols", response.status().to_string()); + child.kill().unwrap(); + child.wait().unwrap(); +} + +#[tokio::test] +async fn inspector_break_on_first_line() { + let script = util::testdata_path().join("inspector/inspector2.js"); + let child = util::deno_cmd() + .arg("run") + .arg(inspect_flag_with_unique_port("--inspect-brk")) + .arg(script) + .piped_output() + .spawn() + .unwrap(); + + let mut tester = InspectorTester::create(child, ignore_script_parsed).await; + + tester.assert_stderr_for_inspect_brk(); + + tester + .send_many(&[ + json!({"id":1,"method":"Runtime.enable"}), + json!({"id":2,"method":"Debugger.enable"}), + ]) + .await; + tester.assert_received_messages( + &[ + r#"{"id":1,"result":{}}"#, + r#"{"id":2,"result":{"debuggerId":"#, + ], + &[ + r#"{"method":"Runtime.executionContextCreated","params":{"context":{"id":1,"#, + ], + ) + .await; + + tester + .send(json!({"id":3,"method":"Runtime.runIfWaitingForDebugger"})) + .await; + tester + .assert_received_messages( + &[r#"{"id":3,"result":{}}"#], + &[r#"{"method":"Debugger.paused","#], + ) + .await; + + tester + .send(json!({ + "id":4, + "method":"Runtime.evaluate", + "params":{ + "expression":"Deno[Deno.internal].core.print(\"hello from the inspector\\n\")", + "contextId":1, + "includeCommandLineAPI":true, + "silent":false, + "returnByValue":true + } + })) + .await; + tester + .assert_received_messages( + &[r#"{"id":4,"result":{"result":{"type":"object","subtype":"null","value":null}}}"#], + &[], + ) + .await; + + assert_eq!( + &tester.stdout_lines.next().unwrap(), + "hello from the inspector" + ); + + tester + .send(json!({"id":5,"method":"Debugger.resume"})) + .await; + tester + .assert_received_messages(&[r#"{"id":5,"result":{}}"#], &[]) + .await; + + assert_eq!( + &tester.stdout_lines.next().unwrap(), + "hello from the script" + ); + + tester.child.kill().unwrap(); + tester.child.wait().unwrap(); +} + +#[tokio::test] +async fn inspector_pause() { + let script = util::testdata_path().join("inspector/inspector1.js"); + let child = util::deno_cmd() + .arg("run") + .arg(inspect_flag_with_unique_port("--inspect")) + .arg(script) + .piped_output() + .spawn() + .unwrap(); + + let mut tester = InspectorTester::create(child, ignore_script_parsed).await; + + tester + .send(json!({"id":6,"method":"Debugger.enable"})) + .await; + tester + .assert_received_messages(&[r#"{"id":6,"result":{"debuggerId":"#], &[]) + .await; + + tester + .send(json!({"id":31,"method":"Debugger.pause"})) + .await; + + tester + .assert_received_messages(&[r#"{"id":31,"result":{}}"#], &[]) + .await; + + tester.child.kill().unwrap(); +} + +#[tokio::test] +async fn inspector_port_collision() { + // Skip this test on WSL, which allows multiple processes to listen on the + // same port, rather than making `bind()` fail with `EADDRINUSE`. We also + // skip this test on Windows because it will occasionally flake, possibly + // due to a similar issue. + if (cfg!(target_os = "linux") + && std::env::var_os("WSL_DISTRO_NAME").is_some()) + || cfg!(windows) + { + return; + } + + let script = util::testdata_path().join("inspector/inspector1.js"); + let inspect_flag = inspect_flag_with_unique_port("--inspect"); + + let mut child1 = util::deno_cmd() + .arg("run") + .arg(&inspect_flag) + .arg(script.clone()) + .stderr_piped() + .spawn() + .unwrap(); + + let stderr_1 = child1.stderr.as_mut().unwrap(); + let mut stderr_1_lines = std::io::BufReader::new(stderr_1) + .lines() + .map(|r| r.unwrap()); + let _ = extract_ws_url_from_stderr(&mut stderr_1_lines); + + let mut child2 = util::deno_cmd() + .arg("run") + .arg(&inspect_flag) + .arg(script) + .stderr_piped() + .spawn() + .unwrap(); + + let stderr_2 = child2.stderr.as_mut().unwrap(); + let stderr_2_error_message = std::io::BufReader::new(stderr_2) + .lines() + .map(|r| r.unwrap()) + .inspect(|line| assert!(!line.contains("Debugger listening"))) + .find(|line| line.contains("Cannot start inspector server")); + assert!(stderr_2_error_message.is_some()); + + child1.kill().unwrap(); + child1.wait().unwrap(); + child2.wait().unwrap(); +} + +#[tokio::test] +async fn inspector_does_not_hang() { + let script = util::testdata_path().join("inspector/inspector3.js"); + let child = util::deno_cmd() + .arg("run") + .arg(inspect_flag_with_unique_port("--inspect-brk")) + .env("NO_COLOR", "1") + .arg(script) + .piped_output() + .spawn() + .unwrap(); + + let mut tester = InspectorTester::create(child, ignore_script_parsed).await; + + tester.assert_stderr_for_inspect_brk(); + + tester + .send_many(&[ + json!({"id":1,"method":"Runtime.enable"}), + json!({"id":2,"method":"Debugger.enable"}), + ]) + .await; + tester.assert_received_messages( + &[ + r#"{"id":1,"result":{}}"#, + r#"{"id":2,"result":{"debuggerId":"# + ], + &[ + r#"{"method":"Runtime.executionContextCreated","params":{"context":{"id":1,"# + ], + ) + .await; + + tester + .send(json!({"id":3,"method":"Runtime.runIfWaitingForDebugger"})) + .await; + tester + .assert_received_messages( + &[r#"{"id":3,"result":{}}"#], + &[r#"{"method":"Debugger.paused","#], + ) + .await; + + tester + .send(json!({"id":4,"method":"Debugger.resume"})) + .await; + tester + .assert_received_messages( + &[r#"{"id":4,"result":{}}"#], + &[r#"{"method":"Debugger.resumed","params":{}}"#], + ) + .await; + + for i in 0..128u32 { + let request_id = i + 10; + // Expect the number {i} on stdout. + let s = i.to_string(); + assert_eq!(tester.stdout_lines.next().unwrap(), s); + + tester + .assert_received_messages( + &[], + &[ + r#"{"method":"Runtime.consoleAPICalled","#, + r#"{"method":"Debugger.paused","#, + ], + ) + .await; + + tester + .send(json!({"id":request_id,"method":"Debugger.resume"})) + .await; + tester + .assert_received_messages( + &[&format!(r#"{{"id":{request_id},"result":{{}}}}"#)], + &[r#"{"method":"Debugger.resumed","params":{}}"#], + ) + .await; + } + + // Check that we can gracefully close the websocket connection. + tester + .socket + .write_frame(Frame::close_raw(vec![].into())) + .await + .unwrap(); + + assert_eq!(&tester.stdout_lines.next().unwrap(), "done"); + assert!(tester.child.wait().unwrap().success()); +} + +#[tokio::test] +async fn inspector_without_brk_runs_code() { + let script = util::testdata_path().join("inspector/inspector4.js"); + let mut child = util::deno_cmd() + .arg("run") + .arg(inspect_flag_with_unique_port("--inspect")) + .arg(script) + .piped_output() + .spawn() + .unwrap(); + + let stderr = child.stderr.as_mut().unwrap(); + let mut stderr_lines = + std::io::BufReader::new(stderr).lines().map(|r| r.unwrap()); + let _ = extract_ws_url_from_stderr(&mut stderr_lines); + + // Check that inspector actually runs code without waiting for inspector + // connection. + let stdout = child.stdout.as_mut().unwrap(); + let mut stdout_lines = + std::io::BufReader::new(stdout).lines().map(|r| r.unwrap()); + let stdout_first_line = stdout_lines.next().unwrap(); + assert_eq!(stdout_first_line, "hello"); + + child.kill().unwrap(); + child.wait().unwrap(); +} + +#[tokio::test] +async fn inspector_runtime_evaluate_does_not_crash() { + let child = util::deno_cmd() + .arg("repl") + .arg("--allow-read") + .arg(inspect_flag_with_unique_port("--inspect")) + .stdin(std::process::Stdio::piped()) + .piped_output() + .spawn() + .unwrap(); + + let mut tester = InspectorTester::create(child, ignore_script_parsed).await; + + let stdin = tester.child.stdin.take().unwrap(); + + tester.assert_stderr_for_inspect(); + assert_starts_with!(&tester.stdout_line(), "Deno"); + assert_eq!( + &tester.stdout_line(), + "exit using ctrl+d, ctrl+c, or close()" + ); + assert_eq!(&tester.stderr_line(), "Debugger session started."); + + tester + .send_many(&[ + json!({"id":1,"method":"Runtime.enable"}), + json!({"id":2,"method":"Debugger.enable"}), + ]) + .await; + tester.assert_received_messages( + &[ + r#"{"id":1,"result":{}}"#, + r#"{"id":2,"result":{"debuggerId":"#, + ], + &[ + r#"{"method":"Runtime.executionContextCreated","params":{"context":{"id":1,"#, + ], + ) + .await; + + tester + .send(json!({ + "id":3, + "method":"Runtime.compileScript", + "params":{ + "expression":"Deno.cwd()", + "sourceURL":"", + "persistScript":false, + "executionContextId":1 + } + })) + .await; + tester + .assert_received_messages(&[r#"{"id":3,"result":{}}"#], &[]) + .await; + tester + .send(json!({ + "id":4, + "method":"Runtime.evaluate", + "params":{ + "expression":"Deno.cwd()", + "objectGroup":"console", + "includeCommandLineAPI":true, + "silent":false, + "contextId":1, + "returnByValue":true, + "generatePreview":true, + "userGesture":true, + "awaitPromise":false, + "replMode":true + } + })) + .await; + tester + .assert_received_messages( + &[r#"{"id":4,"result":{"result":{"type":"string","value":""#], + &[], + ) + .await; + tester + .send(json!({ + "id":5, + "method":"Runtime.evaluate", + "params":{ + "expression":"console.error('done');", + "objectGroup":"console", + "includeCommandLineAPI":true, + "silent":false, + "contextId":1, + "returnByValue":true, + "generatePreview":true, + "userGesture":true, + "awaitPromise":false, + "replMode":true + } + })) + .await; + tester + .assert_received_messages( + &[r#"{"id":5,"result":{"result":{"type":"undefined"}}}"#], + &[r#"{"method":"Runtime.consoleAPICalled"#], + ) + .await; + assert_eq!(&tester.stderr_line(), "done"); + drop(stdin); + tester.child.wait().unwrap(); +} + +#[tokio::test] +async fn inspector_json() { + let script = util::testdata_path().join("inspector/inspector1.js"); + let mut child = util::deno_cmd() + .arg("run") + .arg(inspect_flag_with_unique_port("--inspect")) + .arg(script) + .stderr_piped() + .spawn() + .unwrap(); + + let stderr = child.stderr.as_mut().unwrap(); + let mut stderr_lines = + std::io::BufReader::new(stderr).lines().map(|r| r.unwrap()); + let ws_url = extract_ws_url_from_stderr(&mut stderr_lines); + let mut url = ws_url.clone(); + let _ = url.set_scheme("http"); + url.set_path("/json"); + let client = reqwest::Client::new(); + + // Ensure that the webSocketDebuggerUrl matches the host header + for (host, expected) in [ + (None, ws_url.as_str()), + (Some("some.random.host"), "ws://some.random.host/"), + (Some("some.random.host:1234"), "ws://some.random.host:1234/"), + (Some("[::1]:1234"), "ws://[::1]:1234/"), + ] { + let mut req = reqwest::Request::new(reqwest::Method::GET, url.clone()); + if let Some(host) = host { + req.headers_mut().insert( + reqwest::header::HOST, + reqwest::header::HeaderValue::from_static(host), + ); + } + let resp = client.execute(req).await.unwrap(); + assert_eq!(resp.status(), reqwest::StatusCode::OK); + let endpoint_list: Vec = + serde_json::from_str(&resp.text().await.unwrap()).unwrap(); + let matching_endpoint = endpoint_list.iter().find(|e| { + e["webSocketDebuggerUrl"] + .as_str() + .unwrap() + .contains(expected) + }); + assert!(matching_endpoint.is_some()); + } + + child.kill().unwrap(); +} + +#[tokio::test] +async fn inspector_json_list() { + let script = util::testdata_path().join("inspector/inspector1.js"); + let mut child = util::deno_cmd() + .arg("run") + .arg(inspect_flag_with_unique_port("--inspect")) + .arg(script) + .stderr_piped() + .spawn() + .unwrap(); + + let stderr = child.stderr.as_mut().unwrap(); + let mut stderr_lines = + std::io::BufReader::new(stderr).lines().map(|r| r.unwrap()); + let ws_url = extract_ws_url_from_stderr(&mut stderr_lines); + let mut url = ws_url.clone(); + let _ = url.set_scheme("http"); + url.set_path("/json/list"); + let resp = reqwest::get(url).await.unwrap(); + assert_eq!(resp.status(), reqwest::StatusCode::OK); + let endpoint_list: Vec = + serde_json::from_str(&resp.text().await.unwrap()).unwrap(); + let matching_endpoint = endpoint_list + .iter() + .find(|e| e["webSocketDebuggerUrl"] == ws_url.as_str()); + assert!(matching_endpoint.is_some()); + child.kill().unwrap(); +} + +#[tokio::test] +async fn inspector_connect_non_ws() { + // https://github.com/denoland/deno/issues/11449 + // Verify we don't panic if non-WS connection is being established + let script = util::testdata_path().join("inspector/inspector1.js"); + let mut child = util::deno_cmd() + .arg("run") + .arg(inspect_flag_with_unique_port("--inspect")) + .arg(script) + .stderr_piped() + .spawn() + .unwrap(); + + let stderr = child.stderr.as_mut().unwrap(); + let mut stderr_lines = + std::io::BufReader::new(stderr).lines().map(|r| r.unwrap()); + let mut ws_url = extract_ws_url_from_stderr(&mut stderr_lines); + // Change scheme to URL and try send a request. We're not interested + // in the request result, just that the process doesn't panic. + ws_url.set_scheme("http").unwrap(); + let resp = reqwest::get(ws_url).await.unwrap(); + assert_eq!("400 Bad Request", resp.status().to_string()); + child.kill().unwrap(); + child.wait().unwrap(); +} + +#[tokio::test] +async fn inspector_break_on_first_line_in_test() { + let script = util::testdata_path().join("inspector/inspector_test.js"); + let child = util::deno_cmd() + .arg("test") + .arg("--quiet") + .arg(inspect_flag_with_unique_port("--inspect-brk")) + .arg(script) + .env("NO_COLOR", "1") + .piped_output() + .spawn() + .unwrap(); + + let mut tester = InspectorTester::create(child, ignore_script_parsed).await; + + tester.assert_stderr_for_inspect_brk(); + + tester + .send_many(&[ + json!({"id":1,"method":"Runtime.enable"}), + json!({"id":2,"method":"Debugger.enable"}), + ]) + .await; + tester.assert_received_messages( + &[ + r#"{"id":1,"result":{}}"#, + r#"{"id":2,"result":{"debuggerId":"#, + ], + &[ + r#"{"method":"Runtime.executionContextCreated","params":{"context":{"id":1,"#, + ], + ) + .await; + + tester + .send(json!({"id":3,"method":"Runtime.runIfWaitingForDebugger"})) + .await; + tester + .assert_received_messages( + &[r#"{"id":3,"result":{}}"#], + &[r#"{"method":"Debugger.paused","#], + ) + .await; + + tester + .send(json!({ + "id":4, + "method":"Runtime.evaluate", + "params":{ + "expression":"1 + 1", + "contextId":1, + "includeCommandLineAPI":true, + "silent":false, + "returnByValue":true + } + })) + .await; + tester.assert_received_messages( + &[r#"{"id":4,"result":{"result":{"type":"number","value":2,"description":"2"}}}"#], + &[], + ) + .await; + + tester + .send(json!({"id":5,"method":"Debugger.resume"})) + .await; + tester + .assert_received_messages(&[r#"{"id":5,"result":{}}"#], &[]) + .await; + + assert_starts_with!(&tester.stdout_line(), "running 1 test from"); + let line = tester.stdout_line(); + assert!( + &line.contains("basic test ... ok"), + "Missing content: {line}" + ); + + tester.child.kill().unwrap(); + tester.child.wait().unwrap(); +} + +#[tokio::test] +async fn inspector_with_ts_files() { + let script = util::testdata_path().join("inspector/test.ts"); + let child = util::deno_cmd() + .arg("run") + .arg("--check") + .arg(inspect_flag_with_unique_port("--inspect-brk")) + .arg(script) + .piped_output() + .spawn() + .unwrap(); + + fn notification_filter(msg: &str) -> bool { + (msg.starts_with(r#"{"method":"Debugger.scriptParsed","#) + && msg.contains("testdata/inspector")) + || !msg.starts_with(r#"{"method":"Debugger.scriptParsed","#) + } + + let mut tester = InspectorTester::create(child, notification_filter).await; + + tester.assert_stderr_for_inspect_brk(); + + tester + .send_many(&[ + json!({"id":1,"method":"Runtime.enable"}), + json!({"id":2,"method":"Debugger.enable"}), + ]) + .await; + tester.assert_received_messages( + &[ + r#"{"id":1,"result":{}}"#, + ], + &[ + r#"{"method":"Runtime.executionContextCreated","params":{"context":{"id":1,"#, + ], + ) + .await; + + // receive messages with sources from this test + let script1 = tester.recv().await; + assert!(script1.contains("testdata/inspector/test.ts")); + let script1_id = { + let v: serde_json::Value = serde_json::from_str(&script1).unwrap(); + v["params"]["scriptId"].as_str().unwrap().to_string() + }; + let script2 = tester.recv().await; + assert!(script2.contains("testdata/inspector/foo.ts")); + let script2_id = { + let v: serde_json::Value = serde_json::from_str(&script2).unwrap(); + v["params"]["scriptId"].as_str().unwrap().to_string() + }; + let script3 = tester.recv().await; + assert!(script3.contains("testdata/inspector/bar.js")); + let script3_id = { + let v: serde_json::Value = serde_json::from_str(&script3).unwrap(); + v["params"]["scriptId"].as_str().unwrap().to_string() + }; + + tester + .assert_received_messages(&[r#"{"id":2,"result":{"debuggerId":"#], &[]) + .await; + + tester + .send(json!({"id":3,"method":"Runtime.runIfWaitingForDebugger"})) + .await; + tester + .assert_received_messages( + &[r#"{"id":3,"result":{}}"#], + &[r#"{"method":"Debugger.paused","#], + ) + .await; + + tester.send_many( + &[ + json!({"id":4,"method":"Debugger.getScriptSource","params":{"scriptId":script1_id.as_str()}}), + json!({"id":5,"method":"Debugger.getScriptSource","params":{"scriptId":script2_id.as_str()}}), + json!({"id":6,"method":"Debugger.getScriptSource","params":{"scriptId":script3_id.as_str()}}), + ]) + .await; + tester.assert_received_messages( + &[ + r#"{"id":4,"result":{"scriptSource":"import { foo } from \"./foo.ts\";\nimport { bar } from \"./bar.js\";\nconsole.log(foo());\nconsole.log(bar());\n//# sourceMappingURL=data:application/json;base64,"#, + r#"{"id":5,"result":{"scriptSource":"class Foo {\n hello() {\n return \"hello\";\n }\n}\nexport function foo() {\n const f = new Foo();\n return f.hello();\n}\n//# sourceMappingURL=data:application/json;base64,"#, + r#"{"id":6,"result":{"scriptSource":"export function bar() {\n return \"world\";\n}\n"#, + ], + &[], + ) + .await; + + tester + .send(json!({"id":7,"method":"Debugger.resume"})) + .await; + tester + .assert_received_messages(&[r#"{"id":7,"result":{}}"#], &[]) + .await; + + assert_eq!(&tester.stdout_line(), "hello"); + assert_eq!(&tester.stdout_line(), "world"); + + tester.assert_received_messages( + &[], + &[ + r#"{"method":"Debugger.resumed","params":{}}"#, + r#"{"method":"Runtime.consoleAPICalled","#, + r#"{"method":"Runtime.consoleAPICalled","#, + r#"{"method":"Runtime.executionContextDestroyed","params":{"executionContextId":1"#, + ], + ) + .await; + + assert_eq!( + &tester.stdout_line(), + "Program finished. Waiting for inspector to disconnect to exit the process..." + ); + + tester.child.kill().unwrap(); + tester.child.wait().unwrap(); +} + +#[tokio::test] +async fn inspector_memory() { + let script = util::testdata_path().join("inspector/memory.js"); + let child = util::deno_cmd() + .arg("run") + .arg(inspect_flag_with_unique_port("--inspect-brk")) + .arg(script) + .piped_output() + .spawn() + .unwrap(); + + let mut tester = InspectorTester::create(child, ignore_script_parsed).await; + + tester.assert_stderr_for_inspect_brk(); + + tester + .send_many(&[ + json!({"id":1,"method":"Runtime.enable"}), + json!({"id":2,"method":"Debugger.enable"}), + ]) + .await; + tester.assert_received_messages( + &[ + r#"{"id":1,"result":{}}"#, + r#"{"id":2,"result":{"debuggerId":"#, + ], + &[ + r#"{"method":"Runtime.executionContextCreated","params":{"context":{"id":1,"#, + ], + ) + .await; + + tester + .send_many(&[ + json!({"id":3,"method":"Runtime.runIfWaitingForDebugger"}), + json!({"id":4,"method":"HeapProfiler.enable"}), + ]) + .await; + tester + .assert_received_messages( + &[r#"{"id":3,"result":{}}"#, r#"{"id":4,"result":{}}"#], + &[r#"{"method":"Debugger.paused","#], + ) + .await; + + tester + .send(json!({"id":5,"method":"Runtime.getHeapUsage", "params": {}})) + .await; + + let json_msg = tester.recv_as_json().await; + assert_eq!(json_msg["id"].as_i64().unwrap(), 5); + let result = &json_msg["result"]; + assert!( + result["usedSize"].as_i64().unwrap() + <= result["totalSize"].as_i64().unwrap() + ); + + tester + .send(json!({ + "id":6, + "method":"HeapProfiler.takeHeapSnapshot", + "params": { + "reportProgress": true, + "treatGlobalObjectsAsRoots": true, + "captureNumberValue": false + } + })) + .await; + + let mut progress_report_completed = false; + loop { + let msg = tester.recv().await; + + // TODO(bartlomieju): can be abstracted + if !progress_report_completed + && msg.starts_with( + r#"{"method":"HeapProfiler.reportHeapSnapshotProgress","params""#, + ) + { + let json_msg: serde_json::Value = serde_json::from_str(&msg).unwrap(); + if let Some(finished) = json_msg["params"].get("finished") { + progress_report_completed = finished.as_bool().unwrap(); + } + continue; + } + + if msg.starts_with(r#"{"method":"HeapProfiler.reportHeapSnapshotProgress","params":{"done":"#,) { + continue; + } + + if msg.starts_with(r#"{"id":6,"result":{}}"#) { + assert!(progress_report_completed); + break; + } + } + + tester.child.kill().unwrap(); + tester.child.wait().unwrap(); +} + +#[tokio::test] +async fn inspector_profile() { + let script = util::testdata_path().join("inspector/memory.js"); + let child = util::deno_cmd() + .arg("run") + .arg(inspect_flag_with_unique_port("--inspect-brk")) + .arg(script) + .piped_output() + .spawn() + .unwrap(); + + let mut tester = InspectorTester::create(child, ignore_script_parsed).await; + + tester.assert_stderr_for_inspect_brk(); + + tester + .send_many(&[ + json!({"id":1,"method":"Runtime.enable"}), + json!({"id":2,"method":"Debugger.enable"}), + ]) + .await; + tester.assert_received_messages( + &[ + r#"{"id":1,"result":{}}"#, + r#"{"id":2,"result":{"debuggerId":"#, + ], + &[ + r#"{"method":"Runtime.executionContextCreated","params":{"context":{"id":1,"#, + ], + ) + .await; + + tester + .send_many(&[ + json!({"id":3,"method":"Runtime.runIfWaitingForDebugger"}), + json!({"id":4,"method":"Profiler.enable"}), + ]) + .await; + tester + .assert_received_messages( + &[r#"{"id":3,"result":{}}"#, r#"{"id":4,"result":{}}"#], + &[r#"{"method":"Debugger.paused","#], + ) + .await; + + tester.send_many( + &[ + json!({"id":5,"method":"Profiler.setSamplingInterval","params":{"interval": 100}}), + json!({"id":6,"method":"Profiler.start","params":{}}), + ], + ).await; + tester + .assert_received_messages( + &[r#"{"id":5,"result":{}}"#, r#"{"id":6,"result":{}}"#], + &[], + ) + .await; + + tokio::time::sleep(tokio::time::Duration::from_millis(500)).await; + + tester + .send(json!({"id":7,"method":"Profiler.stop", "params": {}})) + .await; + let json_msg = tester.recv_as_json().await; + assert_eq!(json_msg["id"].as_i64().unwrap(), 7); + let result = &json_msg["result"]; + let profile = &result["profile"]; + assert!( + profile["startTime"].as_i64().unwrap() + < profile["endTime"].as_i64().unwrap() + ); + profile["samples"].as_array().unwrap(); + profile["nodes"].as_array().unwrap(); + + tester.child.kill().unwrap(); + tester.child.wait().unwrap(); +} + +// TODO(bartlomieju): this test became flaky on CI after wiring up "ext/node" +// compatibility layer. Can't reproduce this problem locally for either Mac M1 +// or Linux. Ignoring for now to unblock further integration of "ext/node". +#[ignore] +#[tokio::test] +async fn inspector_break_on_first_line_npm_esm() { + let context = TestContextBuilder::for_npm().build(); + let child = context + .new_command() + .args_vec([ + "run", + "--quiet", + &inspect_flag_with_unique_port("--inspect-brk"), + "npm:@denotest/bin/cli-esm", + "this", + "is", + "a", + "test", + ]) + .spawn_with_piped_output(); + + let mut tester = InspectorTester::create(child, ignore_script_parsed).await; + + tester.assert_stderr_for_inspect_brk(); + + tester + .send_many(&[ + json!({"id":1,"method":"Runtime.enable"}), + json!({"id":2,"method":"Debugger.enable"}), + ]) + .await; + tester.assert_received_messages( + &[ + r#"{"id":1,"result":{}}"#, + r#"{"id":2,"result":{"debuggerId":"#, + ], + &[ + r#"{"method":"Runtime.executionContextCreated","params":{"context":{"id":1,"#, + ], + ) + .await; + + tester + .send(json!({"id":3,"method":"Runtime.runIfWaitingForDebugger"})) + .await; + tester + .assert_received_messages( + &[r#"{"id":3,"result":{}}"#], + &[r#"{"method":"Debugger.paused","#], + ) + .await; + + tester + .send(json!({"id":4,"method":"Debugger.resume"})) + .await; + tester + .assert_received_messages(&[r#"{"id":4,"result":{}}"#], &[]) + .await; + + assert_eq!(&tester.stdout_line(), "this"); + assert_eq!(&tester.stdout_line(), "is"); + assert_eq!(&tester.stdout_line(), "a"); + assert_eq!(&tester.stdout_line(), "test"); + + tester.child.kill().unwrap(); + tester.child.wait().unwrap(); +} + +// TODO(bartlomieju): this test became flaky on CI after wiring up "ext/node" +// compatibility layer. Can't reproduce this problem locally for either Mac M1 +// or Linux. Ignoring for now to unblock further integration of "ext/node". +#[ignore] +#[tokio::test] +async fn inspector_break_on_first_line_npm_cjs() { + let context = TestContextBuilder::for_npm().build(); + let child = context + .new_command() + .args_vec([ + "run", + "--quiet", + &inspect_flag_with_unique_port("--inspect-brk"), + "npm:@denotest/bin/cli-cjs", + "this", + "is", + "a", + "test", + ]) + .spawn_with_piped_output(); + + let mut tester = InspectorTester::create(child, ignore_script_parsed).await; + + tester.assert_stderr_for_inspect_brk(); + + tester + .send_many(&[ + json!({"id":1,"method":"Runtime.enable"}), + json!({"id":2,"method":"Debugger.enable"}), + ]) + .await; + tester.assert_received_messages( + &[ + r#"{"id":1,"result":{}}"#, + r#"{"id":2,"result":{"debuggerId":"#, + ], + &[ + r#"{"method":"Runtime.executionContextCreated","params":{"context":{"id":1,"#, + ], + ) + .await; + + tester + .send(json!({"id":3,"method":"Runtime.runIfWaitingForDebugger"})) + .await; + tester + .assert_received_messages( + &[r#"{"id":3,"result":{}}"#], + &[r#"{"method":"Debugger.paused","#], + ) + .await; + + tester + .send(json!({"id":4,"method":"Debugger.resume"})) + .await; + tester + .assert_received_messages(&[r#"{"id":4,"result":{}}"#], &[]) + .await; + + assert_eq!(&tester.stdout_line(), "this"); + assert_eq!(&tester.stdout_line(), "is"); + assert_eq!(&tester.stdout_line(), "a"); + assert_eq!(&tester.stdout_line(), "test"); + + tester.child.kill().unwrap(); + tester.child.wait().unwrap(); +} + +// TODO(bartlomieju): this test became flaky on CI after wiring up "ext/node" +// compatibility layer. Can't reproduce this problem locally for either Mac M1 +// or Linux. Ignoring for now to unblock further integration of "ext/node". +#[ignore] +#[tokio::test] +async fn inspector_error_with_npm_import() { + let script = util::testdata_path().join("inspector/error_with_npm_import.js"); + let context = TestContextBuilder::for_npm().build(); + let child = context + .new_command() + .args_vec([ + "run", + "--quiet", + "-A", + &inspect_flag_with_unique_port("--inspect-brk"), + &script.to_string_lossy(), + ]) + .spawn_with_piped_output(); + + let mut tester = InspectorTester::create(child, ignore_script_parsed).await; + + tester.assert_stderr_for_inspect_brk(); + + tester + .send_many(&[ + json!({"id":1,"method":"Runtime.enable"}), + json!({"id":2,"method":"Debugger.enable"}), + ]) + .await; + tester.assert_received_messages( + &[ + r#"{"id":1,"result":{}}"#, + r#"{"id":2,"result":{"debuggerId":"#, + ], + &[ + r#"{"method":"Runtime.executionContextCreated","params":{"context":{"id":1,"#, + ], + ) + .await; + + tester + .send(json!({"id":3,"method":"Runtime.runIfWaitingForDebugger"})) + .await; + tester + .assert_received_messages( + &[r#"{"id":3,"result":{}}"#], + &[r#"{"method":"Debugger.paused","#], + ) + .await; + + tester + .send(json!({"id":4,"method":"Debugger.resume"})) + .await; + tester + .assert_received_messages( + &[r#"{"id":4,"result":{}}"#], + &[r#"{"method":"Runtime.exceptionThrown","#], + ) + .await; + assert_eq!(&tester.stderr_line(), "Debugger session started."); + assert_eq!(&tester.stderr_line(), "error: Uncaught Error: boom!"); + + assert_eq!(tester.child.wait().unwrap().code(), Some(1)); +} + +#[tokio::test] +async fn inspector_wait() { + let script = util::testdata_path().join("inspector/inspect_wait.js"); + let test_context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = test_context.temp_dir(); + + let child = test_context + .new_command() + .args_vec([ + "run", + "--quiet", + "-A", + &inspect_flag_with_unique_port("--inspect-wait"), + &script.to_string_lossy(), + ]) + .spawn_with_piped_output(); + + tokio::time::sleep(tokio::time::Duration::from_millis(300)).await; + assert!(!temp_dir.path().join("hello.txt").exists()); + + let mut tester = InspectorTester::create(child, ignore_script_parsed).await; + + tester.assert_stderr_for_inspect_brk(); + tester + .send_many(&[ + json!({"id":1,"method":"Runtime.enable"}), + json!({"id":2,"method":"Debugger.enable"}), + ]) + .await; + tester.assert_received_messages( + &[ + r#"{"id":1,"result":{}}"#, + r#"{"id":2,"result":{"debuggerId":"#, + ], + &[ + r#"{"method":"Runtime.executionContextCreated","params":{"context":{"id":1,"#, + ], + ) + .await; + // TODO(bartlomieju): ideally this shouldn't be needed, but currently there's + // no way to express that in inspector code. Most clients always send this + // message anyway. + tester + .send(json!({"id":3,"method":"Runtime.runIfWaitingForDebugger"})) + .await; + tester + .assert_received_messages(&[r#"{"id":3,"result":{}}"#], &[]) + .await; + assert_eq!(&tester.stderr_line(), "Debugger session started."); + tokio::time::sleep(tokio::time::Duration::from_millis(300)).await; + assert_eq!(&tester.stderr_line(), "did run"); + assert!(temp_dir.path().join("hello.txt").exists()); + tester.child.kill().unwrap(); +} diff --git a/tests/integration/install_tests.rs b/tests/integration/install_tests.rs new file mode 100644 index 000000000..54df82549 --- /dev/null +++ b/tests/integration/install_tests.rs @@ -0,0 +1,250 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +use test_util as util; +use test_util::assert_contains; +use util::TestContext; +use util::TestContextBuilder; + +#[test] +fn install_basic() { + let context = TestContextBuilder::new() + .use_http_server() + .use_temp_cwd() + .build(); + let temp_dir = context.temp_dir(); + let temp_dir_str = temp_dir.path().to_string(); + + // ensure a lockfile doesn't get created or updated locally + temp_dir.write("deno.json", "{}"); + + context + .new_command() + .args("install --check --name echo_test http://localhost:4545/echo.ts") + .envs([ + ("HOME", temp_dir_str.as_str()), + ("USERPROFILE", temp_dir_str.as_str()), + ("DENO_INSTALL_ROOT", ""), + ]) + .run() + .skip_output_check() + .assert_exit_code(0); + + // no lockfile should be created locally + assert!(!temp_dir.path().join("deno.lock").exists()); + + let mut file_path = temp_dir.path().join(".deno/bin/echo_test"); + assert!(file_path.exists()); + + if cfg!(windows) { + file_path = file_path.with_extension("cmd"); + } + + let content = file_path.read_to_string(); + // ensure there's a trailing newline so the shell script can be + // more versatile. + assert_eq!(content.chars().last().unwrap(), '\n'); + + if cfg!(windows) { + assert_contains!( + content, + r#""run" "--check" "--no-config" "http://localhost:4545/echo.ts""# + ); + } else { + assert_contains!( + content, + r#"run --check --no-config 'http://localhost:4545/echo.ts'"# + ); + } + + // now uninstall + context + .new_command() + .args("uninstall echo_test") + .envs([ + ("HOME", temp_dir_str.as_str()), + ("USERPROFILE", temp_dir_str.as_str()), + ("DENO_INSTALL_ROOT", ""), + ]) + .run() + .skip_output_check() + .assert_exit_code(0); + + // ensure local lockfile still doesn't exist + assert!(!temp_dir.path().join("deno.lock").exists()); + // ensure uninstall occurred + assert!(!file_path.exists()); +} + +#[test] +fn install_custom_dir_env_var() { + let context = TestContext::with_http_server(); + let temp_dir = context.temp_dir(); + let temp_dir_str = temp_dir.path().to_string(); + + context + .new_command() + .current_dir(util::root_path()) // different cwd + .args("install --check --name echo_test http://localhost:4545/echo.ts") + .envs([ + ("HOME", temp_dir_str.as_str()), + ("USERPROFILE", temp_dir_str.as_str()), + ("DENO_INSTALL_ROOT", temp_dir_str.as_str()), + ]) + .run() + .skip_output_check() + .assert_exit_code(0); + + let mut file_path = temp_dir.path().join("bin/echo_test"); + assert!(file_path.exists()); + + if cfg!(windows) { + file_path = file_path.with_extension("cmd"); + } + + let content = file_path.read_to_string(); + if cfg!(windows) { + assert_contains!( + content, + r#""run" "--check" "--no-config" "http://localhost:4545/echo.ts""# + ); + } else { + assert_contains!( + content, + r#"run --check --no-config 'http://localhost:4545/echo.ts'"# + ); + } +} + +#[test] +fn installer_test_local_module_run() { + let context = TestContext::with_http_server(); + let temp_dir = context.temp_dir(); + let temp_dir_str = temp_dir.path().to_string(); + let echo_ts_str = util::testdata_path().join("echo.ts").to_string(); + + context + .new_command() + .current_dir(util::root_path()) + .args_vec([ + "install", + "--name", + "echo_test", + "--root", + temp_dir_str.as_str(), + echo_ts_str.as_str(), + "hello", + ]) + .envs([ + ("HOME", temp_dir_str.as_str()), + ("USERPROFILE", temp_dir_str.as_str()), + ("DENO_INSTALL_ROOT", ""), + ]) + .run() + .skip_output_check() + .assert_exit_code(0); + + let bin_dir = temp_dir.path().join("bin"); + let mut file_path = bin_dir.join("echo_test"); + if cfg!(windows) { + file_path = file_path.with_extension("cmd"); + } + assert!(file_path.exists()); + let output = context + .new_command() + .name(&file_path) + .current_dir(temp_dir.path()) + .args("foo") + .env("PATH", util::target_dir()) + .run(); + output.assert_matches_text("hello, foo"); + output.assert_exit_code(0); +} + +#[test] +fn installer_test_remote_module_run() { + let context = TestContextBuilder::new() + .use_http_server() + .use_temp_cwd() + .build(); + let temp_dir = context.temp_dir(); + let root_dir = temp_dir.path().join("root"); + let bin_dir = root_dir.join("bin"); + context + .new_command() + .args("install --name echo_test --root ./root http://localhost:4545/echo.ts hello") + .run() + .skip_output_check() + .assert_exit_code(0); + let mut bin_file_path = bin_dir.join("echo_test"); + if cfg!(windows) { + bin_file_path = bin_file_path.with_extension("cmd"); + } + assert!(bin_file_path.exists()); + let output = context + .new_command() + .name(&bin_file_path) + .current_dir(root_dir) + .args("foo") + .env("PATH", util::target_dir()) + .run(); + output.assert_matches_text("hello, foo"); + output.assert_exit_code(0); + + // now uninstall with the relative path + context + .new_command() + .args("uninstall --root ./root echo_test") + .run() + .skip_output_check() + .assert_exit_code(0); + assert!(!bin_file_path.exists()); +} + +#[test] +fn check_local_by_default() { + let context = TestContextBuilder::new() + .use_http_server() + .use_temp_cwd() + .build(); + let temp_dir = context.temp_dir(); + let temp_dir_str = temp_dir.path().to_string(); + let script_path = + util::testdata_path().join("./install/check_local_by_default.ts"); + let script_path_str = script_path.to_string_lossy().to_string(); + context + .new_command() + .args_vec(["install", script_path_str.as_str()]) + .envs([ + ("HOME", temp_dir_str.as_str()), + ("USERPROFILE", temp_dir_str.as_str()), + ("DENO_INSTALL_ROOT", ""), + ]) + .run() + .skip_output_check() + .assert_exit_code(0); +} + +#[test] +fn check_local_by_default2() { + let context = TestContextBuilder::new() + .use_http_server() + .use_temp_cwd() + .build(); + let temp_dir = context.temp_dir(); + let temp_dir_str = temp_dir.path().to_string(); + let script_path = + util::testdata_path().join("./install/check_local_by_default2.ts"); + let script_path_str = script_path.to_string_lossy().to_string(); + context + .new_command() + .args_vec(["install", script_path_str.as_str()]) + .envs([ + ("HOME", temp_dir_str.as_str()), + ("NO_COLOR", "1"), + ("USERPROFILE", temp_dir_str.as_str()), + ("DENO_INSTALL_ROOT", ""), + ]) + .run() + .skip_output_check() + .assert_exit_code(0); +} diff --git a/tests/integration/js_unit_tests.rs b/tests/integration/js_unit_tests.rs new file mode 100644 index 000000000..16aebd8c4 --- /dev/null +++ b/tests/integration/js_unit_tests.rs @@ -0,0 +1,201 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +use std::io::BufRead; +use std::io::BufReader; +use std::time::Duration; +use std::time::Instant; +use test_util as util; + +util::unit_test_factory!( + js_unit_test, + "../tests/unit", + "*.ts", + [ + abort_controller_test, + blob_test, + body_test, + broadcast_channel_test, + buffer_test, + build_test, + cache_api_test, + chmod_test, + chown_test, + command_test, + console_test, + copy_file_test, + custom_event_test, + cron_test, + dir_test, + dom_exception_test, + error_stack_test, + error_test, + esnext_test, + event_target_test, + event_test, + fetch_test, + ffi_test, + file_test, + filereader_test, + files_test, + flock_test, + fs_events_test, + get_random_values_test, + globals_test, + headers_test, + http_test, + image_bitmap_test, + image_data_test, + internals_test, + intl_test, + io_test, + jupyter_test, + kv_test, + kv_queue_test_no_db_close, + kv_queue_test, + kv_queue_undelivered_test, + link_test, + make_temp_test, + message_channel_test, + mkdir_test, + navigator_test, + net_test, + network_interfaces_test, + os_test, + ops_test, + path_from_url_test, + performance_test, + permissions_test, + process_test, + progressevent_test, + promise_hooks_test, + read_dir_test, + read_file_test, + read_link_test, + read_text_file_test, + real_path_test, + ref_unref_test, + remove_test, + rename_test, + request_test, + resources_test, + response_test, + serve_test, + signal_test, + stat_test, + stdio_test, + streams_test, + structured_clone_test, + symbol_test, + symlink_test, + sync_test, + test_util, + testing_test, + text_encoding_test, + timers_test, + tls_test, + truncate_test, + tty_color_test, + tty_test, + umask_test, + url_search_params_test, + url_test, + urlpattern_test, + utime_test, + version_test, + wasm_test, + webcrypto_test, + webgpu_test, + websocket_test, + webstorage_test, + worker_permissions_test, + worker_test, + write_file_test, + write_text_file_test, + ] +); + +fn js_unit_test(test: String) { + let _g = util::http_server(); + + let deno = util::deno_cmd() + .current_dir(util::root_path()) + .arg("test") + .arg("--config") + .arg("tests/config/deno.json") + .arg("--no-lock") + .arg("--unstable") + .arg("--location=http://127.0.0.1:4545/") + .arg("--no-prompt"); + + // TODO(mmastrac): it would be better to just load a test CA for all tests + let deno = if test == "websocket_test" { + deno.arg("--unsafely-ignore-certificate-errors") + } else { + deno + }; + + let mut deno = deno + .arg("-A") + .arg(util::tests_path().join("unit").join(format!("{test}.ts"))) + .piped_output() + .spawn() + .expect("failed to spawn script"); + + let now = Instant::now(); + let stdout = deno.stdout.take().unwrap(); + let test_name = test.clone(); + let stdout = std::thread::spawn(move || { + let reader = BufReader::new(stdout); + for line in reader.lines() { + if let Ok(line) = line { + println!("[{test_name} {:0>6.2}] {line}", now.elapsed().as_secs_f32()); + } else { + break; + } + } + }); + + let now = Instant::now(); + let stderr = deno.stderr.take().unwrap(); + let test_name = test.clone(); + let stderr = std::thread::spawn(move || { + let reader = BufReader::new(stderr); + for line in reader.lines() { + if let Ok(line) = line { + eprintln!("[{test_name} {:0>6.2}] {line}", now.elapsed().as_secs_f32()); + } else { + break; + } + } + }); + + const PER_TEST_TIMEOUT: Duration = Duration::from_secs(3 * 60); + + let now = Instant::now(); + let status = loop { + if now.elapsed() > PER_TEST_TIMEOUT { + // Last-ditch kill + _ = deno.kill(); + panic!("Test {test} failed to complete in time"); + } + if let Some(status) = deno + .try_wait() + .expect("failed to wait for the child process") + { + break status; + } + std::thread::sleep(Duration::from_millis(100)); + }; + + #[cfg(unix)] + assert_eq!( + std::os::unix::process::ExitStatusExt::signal(&status), + None, + "Deno should not have died with a signal" + ); + assert_eq!(Some(0), status.code(), "Deno should have exited cleanly"); + + stdout.join().unwrap(); + stderr.join().unwrap(); + + assert!(status.success()); +} diff --git a/tests/integration/jsr_tests.rs b/tests/integration/jsr_tests.rs new file mode 100644 index 000000000..2de4f0056 --- /dev/null +++ b/tests/integration/jsr_tests.rs @@ -0,0 +1,183 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +use deno_core::serde_json::Value; +use deno_lockfile::Lockfile; +use test_util as util; +use url::Url; +use util::env_vars_for_jsr_tests; +use util::TestContextBuilder; + +itest!(no_module_graph_run { + args: "run jsr/no_module_graph/main.ts", + output: "jsr/no_module_graph/main.out", + envs: env_vars_for_jsr_tests(), + http_server: true, +}); + +itest!(no_module_graph_info { + args: "info jsr/no_module_graph/main.ts", + output: "jsr/no_module_graph/main_info.out", + envs: env_vars_for_jsr_tests(), + http_server: true, +}); + +itest!(same_package_multiple_versions { + args: "run --quiet jsr/no_module_graph/multiple.ts", + output: "jsr/no_module_graph/multiple.out", + envs: env_vars_for_jsr_tests(), + http_server: true, +}); + +itest!(module_graph_run { + args: "run jsr/module_graph/main.ts", + output: "jsr/module_graph/main.out", + envs: env_vars_for_jsr_tests(), + http_server: true, +}); + +itest!(module_graph_info { + args: "info jsr/module_graph/main.ts", + output: "jsr/module_graph/main_info.out", + envs: env_vars_for_jsr_tests(), + http_server: true, +}); + +itest!(deps_run { + args: "run jsr/deps/main.ts", + output: "jsr/deps/main.out", + envs: env_vars_for_jsr_tests(), + http_server: true, +}); + +itest!(deps_info { + args: "info jsr/deps/main.ts", + output: "jsr/deps/main_info.out", + envs: env_vars_for_jsr_tests(), + http_server: true, +}); + +itest!(subset_type_graph { + args: "check --all jsr/subset_type_graph/main.ts", + output: "jsr/subset_type_graph/main.check.out", + envs: env_vars_for_jsr_tests(), + http_server: true, + exit_code: 1, +}); + +itest!(version_not_found { + args: "run jsr/version_not_found/main.ts", + output: "jsr/version_not_found/main.out", + envs: env_vars_for_jsr_tests(), + http_server: true, + exit_code: 1, +}); + +#[test] +fn specifiers_in_lockfile() { + let test_context = TestContextBuilder::for_jsr().use_temp_cwd().build(); + let temp_dir = test_context.temp_dir(); + + temp_dir.write( + "main.ts", + r#"import version from "jsr:@denotest/no_module_graph@0.1"; + +console.log(version);"#, + ); + temp_dir.write("deno.json", "{}"); // to automatically create a lockfile + + test_context + .new_command() + .args("run --quiet main.ts") + .run() + .assert_matches_text("0.1.1\n"); + + let lockfile_path = temp_dir.path().join("deno.lock"); + let mut lockfile = Lockfile::new(lockfile_path.to_path_buf(), false).unwrap(); + *lockfile + .content + .packages + .specifiers + .get_mut("jsr:@denotest/no_module_graph@0.1") + .unwrap() = "jsr:@denotest/no_module_graph@0.1.0".to_string(); + lockfile_path.write(lockfile.as_json_string()); + + test_context + .new_command() + .args("run --quiet main.ts") + .run() + .assert_matches_text("0.1.0\n"); +} + +#[test] +fn reload_info_not_found_cache_but_exists_remote() { + fn remove_version(registry_json: &mut Value, version: &str) { + registry_json + .as_object_mut() + .unwrap() + .get_mut("versions") + .unwrap() + .as_object_mut() + .unwrap() + .remove(version); + } + + fn remove_version_for_package( + deno_dir: &util::TempDir, + package: &str, + version: &str, + ) { + let specifier = + Url::parse(&format!("http://127.0.0.1:4250/{}/meta.json", package)) + .unwrap(); + let registry_json_path = deno_dir + .path() + .join("deps") + .join(deno_cache_dir::url_to_filename(&specifier).unwrap()); + let mut registry_json = registry_json_path.read_json_value(); + remove_version(&mut registry_json, version); + registry_json_path.write_json(®istry_json); + } + + // This tests that when a local machine doesn't have a version + // specified in a dependency that exists in the npm registry + let test_context = TestContextBuilder::for_jsr().use_temp_cwd().build(); + let deno_dir = test_context.deno_dir(); + let temp_dir = test_context.temp_dir(); + temp_dir.write( + "main.ts", + "import { add } from 'jsr:@denotest/add@1'; console.log(add(1, 2));", + ); + + // cache successfully to the deno_dir + let output = test_context.new_command().args("cache main.ts").run(); + output.assert_matches_text(concat!( + "Download http://127.0.0.1:4250/@denotest/add/meta.json\n", + "Download http://127.0.0.1:4250/@denotest/add/1.0.0_meta.json\n", + "Download http://127.0.0.1:4250/@denotest/add/1.0.0/mod.ts\n", + )); + + // modify the package information in the cache to remove the latest version + remove_version_for_package(deno_dir, "@denotest/add", "1.0.0"); + + // should error when `--cache-only` is used now because the version is not in the cache + let output = test_context + .new_command() + .args("run --cached-only main.ts") + .run(); + output.assert_exit_code(1); + output.assert_matches_text("error: Failed to resolve version constraint. Try running again without --cached-only + at file:///[WILDCARD]main.ts:1:21 +"); + + // now try running without it, it should download the package now + test_context + .new_command() + .args("run main.ts") + .run() + .assert_matches_text(concat!( + "Download http://127.0.0.1:4250/@denotest/add/meta.json\n", + "Download http://127.0.0.1:4250/@denotest/add/1.0.0_meta.json\n", + "3\n", + )) + .assert_exit_code(0); +} diff --git a/tests/integration/jupyter_tests.rs b/tests/integration/jupyter_tests.rs new file mode 100644 index 000000000..59c247e5d --- /dev/null +++ b/tests/integration/jupyter_tests.rs @@ -0,0 +1,8 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +itest!(jupyter_install_command_not_exists { + args: "jupyter --install", + output: "jupyter/install_command_not_exists.out", + envs: vec![("PATH".to_string(), "".to_string())], + exit_code: 1, +}); diff --git a/tests/integration/lint_tests.rs b/tests/integration/lint_tests.rs new file mode 100644 index 000000000..b266fb5b7 --- /dev/null +++ b/tests/integration/lint_tests.rs @@ -0,0 +1,211 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +use test_util::assert_contains; +use test_util::TestContextBuilder; + +itest!(ignore_unexplicit_files { + args: "lint --ignore=./", + output_str: Some("error: No target files found.\n"), + exit_code: 1, +}); + +itest!(all { + args: "lint lint/without_config/file1.js lint/without_config/file2.ts lint/without_config/ignored_file.ts", + output: "lint/expected.out", + exit_code: 1, +}); + +itest!(quiet { + args: "lint --quiet lint/without_config/file1.js", + output: "lint/expected_quiet.out", + exit_code: 1, +}); + +itest!(json { + args: + "lint --json lint/without_config/file1.js lint/without_config/file2.ts lint/without_config/ignored_file.ts lint/without_config/malformed.js", + output: "lint/expected_json.out", + exit_code: 1, +}); + +itest!(compact { + args: + "lint --compact lint/without_config/file1.js lint/without_config/ignored_file.tss", + output: "lint/expected_compact.out", + exit_code: 1, +}); + +itest!(ignore { + args: + "lint --ignore=lint/without_config/file1.js,lint/without_config/malformed.js,lint/without_config/lint_with_config/ lint/without_config/", + output: "lint/expected_ignore.out", + exit_code: 1, +}); + +itest!(glob { + args: "lint --ignore=lint/without_config/malformed.js,lint/with_config/ lint/without_config/", + output: "lint/expected_glob.out", + exit_code: 1, +}); + +itest!(stdin { + args: "lint -", + input: Some("let _a: any;"), + output: "lint/expected_from_stdin.out", + exit_code: 1, +}); + +itest!(stdin_json { + args: "lint --json -", + input: Some("let _a: any;"), + output: "lint/expected_from_stdin_json.out", + exit_code: 1, +}); + +itest!(rules { + args: "lint --rules", + output: "lint/expected_rules.out", + exit_code: 0, +}); + +// Make sure that the rules are printed if quiet option is enabled. +itest!(rules_quiet { + args: "lint --rules -q", + output: "lint/expected_rules.out", + exit_code: 0, +}); + +itest!(lint_with_config { + args: "lint --config lint/Deno.jsonc lint/with_config/", + output: "lint/with_config.out", + exit_code: 1, +}); + +itest!(lint_with_report_config { + args: "lint --config lint/Deno.compact.format.jsonc lint/with_config/", + output: "lint/with_report_config_compact.out", + exit_code: 1, +}); + +// Check if CLI flags take precedence +itest!(lint_with_report_config_override { + args: "lint --config lint/Deno.compact.format.jsonc lint/with_config/ --json", + output: "lint/with_report_config_override.out", + exit_code: 1, +}); + +itest!(lint_with_config_and_flags { + args: "lint --config lint/Deno.jsonc --ignore=lint/with_config/a.ts", + output: "lint/with_config_and_flags.out", + exit_code: 1, +}); + +itest!(lint_with_config_without_tags { + args: "lint --config lint/Deno.no_tags.jsonc lint/with_config/", + output: "lint/with_config_without_tags.out", + exit_code: 1, +}); + +itest!(lint_with_malformed_config { + args: "lint --config lint/Deno.malformed.jsonc", + output: "lint/with_malformed_config.out", + exit_code: 1, +}); + +itest!(lint_with_malformed_config2 { + args: "lint --config lint/Deno.malformed2.jsonc", + output: "lint/with_malformed_config2.out", + exit_code: 1, +}); + +#[test] +fn lint_with_glob_config() { + let context = TestContextBuilder::new().cwd("lint").build(); + + let cmd_output = context + .new_command() + .args("lint --config deno.glob.json") + .run(); + + cmd_output.assert_exit_code(1); + + let output = cmd_output.combined_output(); + if cfg!(windows) { + assert_contains!(output, r"glob\nested\fizz\fizz.ts:1:10"); + assert_contains!(output, r"glob\pages\[id].ts:1:10"); + assert_contains!(output, r"glob\nested\fizz\bar.ts:1:10"); + assert_contains!(output, r"glob\nested\foo\foo.ts:1:10"); + assert_contains!(output, r"glob\data\test1.js:1:10"); + assert_contains!(output, r"glob\nested\foo\bar.ts:1:10"); + assert_contains!(output, r"glob\nested\foo\fizz.ts:1:10"); + assert_contains!(output, r"glob\nested\fizz\foo.ts:1:10"); + assert_contains!(output, r"glob\data\test1.ts:1:10"); + } else { + assert_contains!(output, "glob/nested/fizz/fizz.ts:1:10"); + assert_contains!(output, "glob/pages/[id].ts:1:10"); + assert_contains!(output, "glob/nested/fizz/bar.ts:1:10"); + assert_contains!(output, "glob/nested/foo/foo.ts:1:10"); + assert_contains!(output, "glob/data/test1.js:1:10"); + assert_contains!(output, "glob/nested/foo/bar.ts:1:10"); + assert_contains!(output, "glob/nested/foo/fizz.ts:1:10"); + assert_contains!(output, "glob/nested/fizz/foo.ts:1:10"); + assert_contains!(output, "glob/data/test1.ts:1:10"); + } + assert_contains!(output, "Found 9 problems"); + assert_contains!(output, "Checked 9 files"); +} + +#[test] +fn lint_with_glob_config_and_flags() { + let context = TestContextBuilder::new().cwd("lint").build(); + + let cmd_output = context + .new_command() + .args("lint --config deno.glob.json --ignore=glob/nested/**/bar.ts") + .run(); + + cmd_output.assert_exit_code(1); + + let output = cmd_output.combined_output(); + if cfg!(windows) { + assert_contains!(output, r"glob\nested\fizz\fizz.ts:1:10"); + assert_contains!(output, r"glob\pages\[id].ts:1:10"); + assert_contains!(output, r"glob\nested\fizz\bazz.ts:1:10"); + assert_contains!(output, r"glob\nested\foo\foo.ts:1:10"); + assert_contains!(output, r"glob\data\test1.js:1:10"); + assert_contains!(output, r"glob\nested\foo\bazz.ts:1:10"); + assert_contains!(output, r"glob\nested\foo\fizz.ts:1:10"); + assert_contains!(output, r"glob\nested\fizz\foo.ts:1:10"); + assert_contains!(output, r"glob\data\test1.ts:1:10"); + } else { + assert_contains!(output, "glob/nested/fizz/fizz.ts:1:10"); + assert_contains!(output, "glob/pages/[id].ts:1:10"); + assert_contains!(output, "glob/nested/fizz/bazz.ts:1:10"); + assert_contains!(output, "glob/nested/foo/foo.ts:1:10"); + assert_contains!(output, "glob/data/test1.js:1:10"); + assert_contains!(output, "glob/nested/foo/bazz.ts:1:10"); + assert_contains!(output, "glob/nested/foo/fizz.ts:1:10"); + assert_contains!(output, "glob/nested/fizz/foo.ts:1:10"); + assert_contains!(output, "glob/data/test1.ts:1:10"); + } + assert_contains!(output, "Found 9 problems"); + assert_contains!(output, "Checked 9 files"); + + let cmd_output = context + .new_command() + .args("lint --config deno.glob.json glob/data/test1.?s") + .run(); + + cmd_output.assert_exit_code(1); + + let output = cmd_output.combined_output(); + if cfg!(windows) { + assert_contains!(output, r"glob\data\test1.js:1:10"); + assert_contains!(output, r"glob\data\test1.ts:1:10"); + } else { + assert_contains!(output, "glob/data/test1.js:1:10"); + assert_contains!(output, "glob/data/test1.ts:1:10"); + } + assert_contains!(output, "Found 2 problems"); + assert_contains!(output, "Checked 2 files"); +} diff --git a/tests/integration/lsp_tests.rs b/tests/integration/lsp_tests.rs new file mode 100644 index 000000000..c9abae241 --- /dev/null +++ b/tests/integration/lsp_tests.rs @@ -0,0 +1,11240 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +use deno_ast::ModuleSpecifier; +use deno_core::serde::Deserialize; +use deno_core::serde_json; +use deno_core::serde_json::json; +use deno_core::serde_json::Value; +use deno_core::url::Url; +use pretty_assertions::assert_eq; +use std::fs; +use test_util::assert_starts_with; +use test_util::deno_cmd_with_deno_dir; +use test_util::env_vars_for_npm_tests; +use test_util::lsp::LspClient; +use test_util::testdata_path; +use test_util::TestContextBuilder; +use tower_lsp::lsp_types as lsp; + +#[test] +fn lsp_startup_shutdown() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.shutdown(); +} + +#[test] +fn lsp_init_tsconfig() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + + temp_dir.write( + "lib.tsconfig.json", + r#"{ + "compilerOptions": { + "lib": ["deno.ns", "deno.unstable", "dom"] + } +}"#, + ); + + let mut client = context.new_lsp_command().build(); + client.initialize(|builder| { + builder.set_config("lib.tsconfig.json"); + }); + + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "location.pathname;\n" + } + })); + + assert_eq!(diagnostics.all().len(), 0); + + client.shutdown(); +} + +#[test] +fn lsp_tsconfig_types() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + + temp_dir.write( + "types.tsconfig.json", + r#"{ + "compilerOptions": { + "types": ["./a.d.ts"] + }, + "lint": { + "rules": { + "tags": [] + } + } +}"#, + ); + let a_dts = "// deno-lint-ignore-file no-var\ndeclare var a: string;"; + temp_dir.write("a.d.ts", a_dts); + + let mut client = context.new_lsp_command().build(); + client.initialize(|builder| { + builder.set_config("types.tsconfig.json"); + }); + + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": Url::from_file_path(temp_dir.path().join("test.ts")).unwrap(), + "languageId": "typescript", + "version": 1, + "text": "console.log(a);\n" + } + })); + + assert_eq!(diagnostics.all().len(), 0); + + client.shutdown(); +} + +#[test] +fn lsp_tsconfig_bad_config_path() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize(|builder| { + builder + .set_config("bad_tsconfig.json") + .set_maybe_root_uri(None); + }); + let (method, maybe_params) = client.read_notification(); + assert_eq!(method, "window/showMessage"); + assert_eq!(maybe_params, Some(lsp::ShowMessageParams { + typ: lsp::MessageType::WARNING, + message: "The path to the configuration file (\"bad_tsconfig.json\") is not resolvable.".to_string() + })); + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "console.log(Deno.args);\n" + } + })); + assert_eq!(diagnostics.all().len(), 0); +} + +#[test] +fn lsp_triple_slash_types() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + let a_dts = "// deno-lint-ignore-file no-var\ndeclare var a: string;"; + temp_dir.write("a.d.ts", a_dts); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": temp_dir.uri().join("test.ts").unwrap(), + "languageId": "typescript", + "version": 1, + "text": "/// \n\nconsole.log(a);\n" + } + })); + + assert_eq!(diagnostics.all().len(), 0); + + client.shutdown(); +} + +#[test] +fn lsp_import_map() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + let import_map = r#"{ + "imports": { + "/~/": "./lib/" + } +}"#; + temp_dir.write("import-map.json", import_map); + temp_dir.create_dir_all("lib"); + temp_dir.write("lib/b.ts", r#"export const b = "b";"#); + + let mut client = context.new_lsp_command().build(); + client.initialize(|builder| { + builder.set_import_map("import-map.json"); + }); + + let uri = Url::from_file_path(temp_dir.path().join("a.ts")).unwrap(); + + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": uri, + "languageId": "typescript", + "version": 1, + "text": "import { b } from \"/~/b.ts\";\n\nconsole.log(b);\n" + } + })); + + assert_eq!(diagnostics.all().len(), 0); + + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": uri + }, + "position": { "line": 2, "character": 12 } + }), + ); + assert_eq!( + res, + json!({ + "contents": [ + { + "language": "typescript", + "value":"(alias) const b: \"b\"\nimport b" + }, + "" + ], + "range": { + "start": { "line": 2, "character": 12 }, + "end": { "line": 2, "character": 13 } + } + }) + ); + client.shutdown(); +} + +#[test] +fn lsp_import_map_remote() { + let context = TestContextBuilder::new() + .use_http_server() + .use_temp_cwd() + .build(); + let temp_dir = context.temp_dir(); + temp_dir.write( + "deno.json", + json!({ + "importMap": "http://localhost:4545/import_maps/import_map.json", + }) + .to_string(), + ); + temp_dir.write( + "file.ts", + r#" + import { printHello } from "print_hello"; + printHello(); + "#, + ); + let mut client = context.new_lsp_command().build(); + client.initialize(|builder| { + builder.set_import_map("http://localhost:4545/import_maps/import_map.json"); + }); + client.write_request( + "workspace/executeCommand", + json!({ + "command": "deno.cache", + "arguments": [[], temp_dir.uri().join("file.ts").unwrap()], + }), + ); + + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": temp_dir.uri().join("file.ts").unwrap(), + "languageId": "typescript", + "version": 1, + "text": temp_dir.read_to_string("file.ts"), + } + })); + assert_eq!(diagnostics.all(), vec![]); + client.shutdown(); +} + +#[test] +fn lsp_import_map_data_url() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize(|builder| { + builder.set_import_map("data:application/json;utf8,{\"imports\": { \"example\": \"https://deno.land/x/example/mod.ts\" }}"); + }); + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "import example from \"example\";\n" + } + })); + + // This indicates that the import map is applied correctly. + assert!(diagnostics.all().iter().any(|diagnostic| diagnostic.code + == Some(lsp::NumberOrString::String("no-cache".to_string())) + && diagnostic + .message + .contains("https://deno.land/x/example/mod.ts"))); + client.shutdown(); +} + +#[test] +fn lsp_import_map_config_file() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + temp_dir.write( + "deno.import_map.jsonc", + r#"{ + "importMap": "import-map.json" +}"#, + ); + temp_dir.write( + "import-map.json", + r#"{ + "imports": { + "/~/": "./lib/" + } +}"#, + ); + temp_dir.create_dir_all("lib"); + temp_dir.write("lib/b.ts", r#"export const b = "b";"#); + + let mut client = context.new_lsp_command().build(); + client.initialize(|builder| { + builder.set_config("./deno.import_map.jsonc"); + }); + + let uri = temp_dir.uri().join("a.ts").unwrap(); + + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": uri, + "languageId": "typescript", + "version": 1, + "text": "import { b } from \"/~/b.ts\";\n\nconsole.log(b);\n" + } + })); + + assert_eq!(diagnostics.all().len(), 0); + + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": uri + }, + "position": { "line": 2, "character": 12 } + }), + ); + assert_eq!( + res, + json!({ + "contents": [ + { + "language": "typescript", + "value":"(alias) const b: \"b\"\nimport b" + }, + "" + ], + "range": { + "start": { "line": 2, "character": 12 }, + "end": { "line": 2, "character": 13 } + } + }) + ); + client.shutdown(); +} + +#[test] +fn lsp_import_map_embedded_in_config_file() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + temp_dir.write( + "deno.embedded_import_map.jsonc", + r#"{ + "imports": { + "/~/": "./lib/" + } +}"#, + ); + temp_dir.create_dir_all("lib"); + temp_dir.write("lib/b.ts", r#"export const b = "b";"#); + + let mut client = context.new_lsp_command().build(); + client.initialize(|builder| { + builder.set_config("./deno.embedded_import_map.jsonc"); + }); + + let uri = temp_dir.uri().join("a.ts").unwrap(); + + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": uri, + "languageId": "typescript", + "version": 1, + "text": "import { b } from \"/~/b.ts\";\n\nconsole.log(b);\n" + } + })); + + assert_eq!(diagnostics.all().len(), 0); + + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": uri + }, + "position": { "line": 2, "character": 12 } + }), + ); + assert_eq!( + res, + json!({ + "contents": [ + { + "language": "typescript", + "value":"(alias) const b: \"b\"\nimport b" + }, + "" + ], + "range": { + "start": { "line": 2, "character": 12 }, + "end": { "line": 2, "character": 13 } + } + }) + ); + client.shutdown(); +} + +#[test] +fn lsp_import_map_embedded_in_config_file_after_initialize() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + temp_dir.write("deno.embedded_import_map.jsonc", "{}"); + temp_dir.create_dir_all("lib"); + temp_dir.write("lib/b.ts", r#"export const b = "b";"#); + + let mut client = context.new_lsp_command().build(); + client.initialize(|builder| { + builder.set_config("./deno.embedded_import_map.jsonc"); + }); + + let uri = temp_dir.uri().join("a.ts").unwrap(); + + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": uri, + "languageId": "typescript", + "version": 1, + "text": "import { b } from \"/~/b.ts\";\n\nconsole.log(b);\n" + } + })); + + assert_eq!(diagnostics.all().len(), 1); + + // update the import map + temp_dir.write( + "deno.embedded_import_map.jsonc", + r#"{ + "imports": { + "/~/": "./lib/" + } +}"#, + ); + + client.did_change_watched_files(json!({ + "changes": [{ + "uri": temp_dir.uri().join("deno.embedded_import_map.jsonc").unwrap(), + "type": 2 + }] + })); + + assert_eq!(client.read_diagnostics().all().len(), 0); + + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": uri + }, + "position": { "line": 2, "character": 12 } + }), + ); + assert_eq!( + res, + json!({ + "contents": [ + { + "language": "typescript", + "value":"(alias) const b: \"b\"\nimport b" + }, + "" + ], + "range": { + "start": { "line": 2, "character": 12 }, + "end": { "line": 2, "character": 13 } + } + }) + ); + client.shutdown(); +} + +#[test] +fn lsp_import_map_config_file_auto_discovered() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + temp_dir.create_dir_all("lib"); + temp_dir.write("lib/b.ts", r#"export const b = "b";"#); + + let mut client = context.new_lsp_command().capture_stderr().build(); + client.initialize_default(); + + // add the deno.json + temp_dir.write("deno.jsonc", r#"{ "imports": { "/~/": "./lib/" } }"#); + client.did_change_watched_files(json!({ + "changes": [{ + "uri": temp_dir.uri().join("deno.jsonc").unwrap(), + "type": 2 + }] + })); + client.wait_until_stderr_line(|line| { + line.contains("Auto-resolved configuration file:") + }); + + let uri = temp_dir.uri().join("a.ts").unwrap(); + + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": uri, + "languageId": "typescript", + "version": 1, + "text": "import { b } from \"/~/b.ts\";\n\nconsole.log(b);\n" + } + })); + + assert_eq!(diagnostics.all().len(), 0); + + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": uri + }, + "position": { "line": 2, "character": 12 } + }), + ); + assert_eq!( + res, + json!({ + "contents": [ + { + "language": "typescript", + "value":"(alias) const b: \"b\"\nimport b" + }, + "" + ], + "range": { + "start": { "line": 2, "character": 12 }, + "end": { "line": 2, "character": 13 } + } + }) + ); + + // now cause a syntax error + temp_dir.write("deno.jsonc", r#",,#,#,,"#); + client.did_change_watched_files(json!({ + "changes": [{ + "uri": temp_dir.uri().join("deno.jsonc").unwrap(), + "type": 2 + }] + })); + assert_eq!(client.read_diagnostics().all().len(), 1); + + // now fix it, and things should work again + temp_dir.write("deno.jsonc", r#"{ "imports": { "/~/": "./lib/" } }"#); + client.did_change_watched_files(json!({ + "changes": [{ + "uri": temp_dir.uri().join("deno.jsonc").unwrap(), + "type": 2 + }] + })); + client.wait_until_stderr_line(|line| { + line.contains("Auto-resolved configuration file:") + }); + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": uri + }, + "position": { "line": 2, "character": 12 } + }), + ); + assert_eq!( + res, + json!({ + "contents": [ + { + "language": "typescript", + "value":"(alias) const b: \"b\"\nimport b" + }, + "" + ], + "range": { + "start": { "line": 2, "character": 12 }, + "end": { "line": 2, "character": 13 } + } + }) + ); + assert_eq!(client.read_diagnostics().all().len(), 0); + + client.shutdown(); +} + +#[test] +fn lsp_import_map_config_file_auto_discovered_symlink() { + let context = TestContextBuilder::new() + // DO NOT COPY THIS CODE. Very rare case where we want to force the temp + // directory on the CI to not be a symlinked directory because we are + // testing a scenario with a symlink to a non-symlink in the same directory + // tree. Generally you want to ensure your code works in symlinked directories + // so don't use this unless you have a similar scenario. + .temp_dir_path(std::env::temp_dir().canonicalize().unwrap()) + .use_temp_cwd() + .build(); + let temp_dir = context.temp_dir(); + temp_dir.create_dir_all("lib"); + temp_dir.write("lib/b.ts", r#"export const b = "b";"#); + + let mut client = context.new_lsp_command().capture_stderr().build(); + client.initialize_default(); + + // now create a symlink in the current directory to a subdir/deno.json + // and ensure the watched files notification still works + temp_dir.create_dir_all("subdir"); + temp_dir.write("subdir/deno.json", r#"{ }"#); + temp_dir.symlink_file( + temp_dir.path().join("subdir").join("deno.json"), + temp_dir.path().join("deno.json"), + ); + client.did_change_watched_files(json!({ + "changes": [{ + // the client will give a watched file changed event for the symlink's target + "uri": temp_dir.path().join("subdir/deno.json").canonicalize().uri_file(), + "type": 2 + }] + })); + + // this will discover the deno.json in the root + let search_line = format!( + "Auto-resolved configuration file: \"{}\"", + temp_dir.uri().join("deno.json").unwrap().as_str() + ); + client.wait_until_stderr_line(|line| line.contains(&search_line)); + + // now open a file which will cause a diagnostic because the import map is empty + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": temp_dir.uri().join("a.ts").unwrap(), + "languageId": "typescript", + "version": 1, + "text": "import { b } from \"/~/b.ts\";\n\nconsole.log(b);\n" + } + })); + assert_eq!(diagnostics.all().len(), 1); + + // update the import map to have the imports now + temp_dir.write("subdir/deno.json", r#"{ "imports": { "/~/": "./lib/" } }"#); + client.did_change_watched_files(json!({ + "changes": [{ + // now still say that the target path has changed + "uri": temp_dir.path().join("subdir/deno.json").canonicalize().uri_file(), + "type": 2 + }] + })); + assert_eq!(client.read_diagnostics().all().len(), 0); + + client.shutdown(); +} + +#[test] +fn lsp_import_map_node_specifiers() { + let context = TestContextBuilder::for_npm().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + + temp_dir.write("deno.json", r#"{ "imports": { "fs": "node:fs" } }"#); + + // cache @types/node + context + .new_command() + .args("cache npm:@types/node") + .run() + .skip_output_check() + .assert_exit_code(0); + + let mut client = context.new_lsp_command().build(); + client.initialize(|builder| { + builder.set_config("./deno.json"); + }); + + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": temp_dir.uri().join("a.ts").unwrap(), + "languageId": "typescript", + "version": 1, + "text": "import fs from \"fs\";\nconsole.log(fs);" + } + })); + assert_eq!(diagnostics.all(), vec![]); + + client.shutdown(); +} + +#[test] +fn lsp_format_vendor_path() { + let context = TestContextBuilder::new() + .use_http_server() + .use_temp_cwd() + .build(); + let temp_dir = context.temp_dir(); + temp_dir.write("deno.json", json!({ "vendor": true }).to_string()); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": r#"import "http://localhost:4545/run/002_hello.ts";"#, + }, + })); + client.write_request( + "workspace/executeCommand", + json!({ + "command": "deno.cache", + "arguments": [[], "file:///a/file.ts"], + }), + ); + assert!(temp_dir + .path() + .join("vendor/http_localhost_4545/run/002_hello.ts") + .exists()); + client.did_open(json!({ + "textDocument": { + "uri": temp_dir.uri().join("vendor/http_localhost_4545/run/002_hello.ts").unwrap(), + "languageId": "typescript", + "version": 1, + "text": r#"console.log("Hello World");"#, + }, + })); + let res = client.write_request( + "textDocument/formatting", + json!({ + "textDocument": { + "uri": temp_dir.uri().join("vendor/http_localhost_4545/run/002_hello.ts").unwrap(), + }, + "options": { + "tabSize": 2, + "insertSpaces": true, + } + }), + ); + assert_eq!( + res, + json!([{ + "range": { + "start": { + "line": 0, + "character": 27, + }, + "end": { + "line": 0, + "character": 27, + }, + }, + "newText": "\n", + }]), + ); + client.shutdown(); +} + +// Regression test for https://github.com/denoland/deno/issues/19802. +// Disable the `workspace/configuration` capability. Ensure the LSP falls back +// to using `enablePaths` from the `InitializationOptions`. +#[test] +fn lsp_workspace_enable_paths_no_workspace_configuration() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + temp_dir.write("main_disabled.ts", "Date.now()"); + temp_dir.write("main_enabled.ts", "Date.now()"); + + let mut client = context.new_lsp_command().build(); + client.initialize(|builder| { + builder.with_capabilities(|capabilities| { + capabilities.workspace.as_mut().unwrap().configuration = Some(false); + }); + builder.set_workspace_folders(vec![lsp::WorkspaceFolder { + uri: temp_dir.uri(), + name: "project".to_string(), + }]); + builder.set_root_uri(temp_dir.uri()); + builder.set_enable_paths(vec!["./main_enabled.ts".to_string()]); + }); + + client.did_open(json!({ + "textDocument": { + "uri": temp_dir.uri().join("main_disabled.ts").unwrap(), + "languageId": "typescript", + "version": 1, + "text": temp_dir.read_to_string("main_disabled.ts"), + } + })); + + client.did_open(json!({ + "textDocument": { + "uri": temp_dir.uri().join("main_enabled.ts").unwrap(), + "languageId": "typescript", + "version": 1, + "text": temp_dir.read_to_string("main_enabled.ts"), + } + })); + + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": temp_dir.uri().join("main_disabled.ts").unwrap(), + }, + "position": { "line": 0, "character": 5 } + }), + ); + assert_eq!(res, json!(null)); + + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": temp_dir.uri().join("main_enabled.ts").unwrap(), + }, + "position": { "line": 0, "character": 5 } + }), + ); + assert_eq!( + res, + json!({ + "contents": [ + { + "language": "typescript", + "value": "(method) DateConstructor.now(): number", + }, + "Returns the number of milliseconds elapsed since midnight, January 1, 1970 Universal Coordinated Time (UTC)." + ], + "range": { + "start": { "line": 0, "character": 5, }, + "end": { "line": 0, "character": 8, } + } + }) + ); + + client.shutdown(); +} + +#[test] +fn lsp_did_change_deno_configuration_notification() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + + temp_dir.write("deno.json", json!({}).to_string()); + client.did_change_watched_files(json!({ + "changes": [{ + "uri": temp_dir.uri().join("deno.json").unwrap(), + "type": 1, + }], + })); + let res = client + .read_notification_with_method::("deno/didChangeDenoConfiguration"); + assert_eq!( + res, + Some(json!({ + "changes": [{ + "scopeUri": temp_dir.uri(), + "fileUri": temp_dir.uri().join("deno.json").unwrap(), + "type": "added", + "configurationType": "denoJson" + }], + })) + ); + + temp_dir.write( + "deno.json", + json!({ "fmt": { "semiColons": false } }).to_string(), + ); + client.did_change_watched_files(json!({ + "changes": [{ + "uri": temp_dir.uri().join("deno.json").unwrap(), + "type": 2, + }], + })); + let res = client + .read_notification_with_method::("deno/didChangeDenoConfiguration"); + assert_eq!( + res, + Some(json!({ + "changes": [{ + "scopeUri": temp_dir.uri(), + "fileUri": temp_dir.uri().join("deno.json").unwrap(), + "type": "changed", + "configurationType": "denoJson" + }], + })) + ); + + temp_dir.remove_file("deno.json"); + client.did_change_watched_files(json!({ + "changes": [{ + "uri": temp_dir.uri().join("deno.json").unwrap(), + "type": 3, + }], + })); + let res = client + .read_notification_with_method::("deno/didChangeDenoConfiguration"); + assert_eq!( + res, + Some(json!({ + "changes": [{ + "scopeUri": temp_dir.uri(), + "fileUri": temp_dir.uri().join("deno.json").unwrap(), + "type": "removed", + "configurationType": "denoJson" + }], + })) + ); + + temp_dir.write("package.json", json!({}).to_string()); + client.did_change_watched_files(json!({ + "changes": [{ + "uri": temp_dir.uri().join("package.json").unwrap(), + "type": 1, + }], + })); + let res = client + .read_notification_with_method::("deno/didChangeDenoConfiguration"); + assert_eq!( + res, + Some(json!({ + "changes": [{ + "scopeUri": temp_dir.uri(), + "fileUri": temp_dir.uri().join("package.json").unwrap(), + "type": "added", + "configurationType": "packageJson" + }], + })) + ); + + temp_dir.write("package.json", json!({ "type": "module" }).to_string()); + client.did_change_watched_files(json!({ + "changes": [{ + "uri": temp_dir.uri().join("package.json").unwrap(), + "type": 2, + }], + })); + let res = client + .read_notification_with_method::("deno/didChangeDenoConfiguration"); + assert_eq!( + res, + Some(json!({ + "changes": [{ + "scopeUri": temp_dir.uri(), + "fileUri": temp_dir.uri().join("package.json").unwrap(), + "type": "changed", + "configurationType": "packageJson" + }], + })) + ); + + temp_dir.remove_file("package.json"); + client.did_change_watched_files(json!({ + "changes": [{ + "uri": temp_dir.uri().join("package.json").unwrap(), + "type": 3, + }], + })); + let res = client + .read_notification_with_method::("deno/didChangeDenoConfiguration"); + assert_eq!( + res, + Some(json!({ + "changes": [{ + "scopeUri": temp_dir.uri(), + "fileUri": temp_dir.uri().join("package.json").unwrap(), + "type": "removed", + "configurationType": "packageJson" + }], + })) + ); +} + +#[test] +fn lsp_deno_task() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + temp_dir.write( + "deno.jsonc", + r#"{ + "tasks": { + "build": "deno test", + "some:test": "deno bundle mod.ts" + } + }"#, + ); + + let mut client = context.new_lsp_command().build(); + client.initialize(|builder| { + builder.set_config("./deno.jsonc"); + }); + + let res = client.write_request("deno/task", json!(null)); + + assert_eq!( + res, + json!([ + { + "name": "build", + "detail": "deno test", + "sourceUri": temp_dir.uri().join("deno.jsonc").unwrap(), + }, { + "name": "some:test", + "detail": "deno bundle mod.ts", + "sourceUri": temp_dir.uri().join("deno.jsonc").unwrap(), + } + ]) + ); +} + +#[test] +fn lsp_reload_import_registries_command() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + let res = client.write_request( + "workspace/executeCommand", + json!({ "command": "deno.reloadImportRegistries" }), + ); + assert_eq!(res, json!(true)); +} + +#[test] +fn lsp_import_attributes() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize(|builder| { + builder.set_import_map("data:application/json;utf8,{\"imports\": { \"example\": \"https://deno.land/x/example/mod.ts\" }}"); + }); + client.change_configuration(json!({ + "deno": { + "enable": true, + "codeLens": { + "test": true, + }, + }, + })); + + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/test.json", + "languageId": "json", + "version": 1, + "text": "{\"a\":1}", + }, + })); + + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": "file:///a/a.ts", + "languageId": "typescript", + "version": 1, + "text": "import a from \"./test.json\";\n\nconsole.log(a);\n" + } + })); + + assert_eq!( + json!( + diagnostics + .messages_with_file_and_source("file:///a/a.ts", "deno") + .diagnostics + ), + json!([ + { + "range": { + "start": { "line": 0, "character": 14 }, + "end": { "line": 0, "character": 27 } + }, + "severity": 1, + "code": "no-attribute-type", + "source": "deno", + "message": "The module is a JSON module and not being imported with an import attribute. Consider adding `with { type: \"json\" }` to the import statement." + } + ]) + ); + + let res = client + .write_request( + "textDocument/codeAction", + json!({ + "textDocument": { + "uri": "file:///a/a.ts" + }, + "range": { + "start": { "line": 0, "character": 14 }, + "end": { "line": 0, "character": 27 } + }, + "context": { + "diagnostics": [{ + "range": { + "start": { "line": 0, "character": 14 }, + "end": { "line": 0, "character": 27 } + }, + "severity": 1, + "code": "no-attribute-type", + "source": "deno", + "message": "The module is a JSON module and not being imported with an import attribute. Consider adding `with { type: \"json\" }` to the import statement." + }], + "only": ["quickfix"] + } + }), + ); + assert_eq!( + res, + json!([{ + "title": "Insert import attribute.", + "kind": "quickfix", + "diagnostics": [ + { + "range": { + "start": { "line": 0, "character": 14 }, + "end": { "line": 0, "character": 27 } + }, + "severity": 1, + "code": "no-attribute-type", + "source": "deno", + "message": "The module is a JSON module and not being imported with an import attribute. Consider adding `with { type: \"json\" }` to the import statement." + } + ], + "edit": { + "changes": { + "file:///a/a.ts": [ + { + "range": { + "start": { "line": 0, "character": 27 }, + "end": { "line": 0, "character": 27 } + }, + "newText": " with { type: \"json\" }" + } + ] + } + } + }]) + ); + client.shutdown(); +} + +#[test] +fn lsp_import_map_import_completions() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + temp_dir.write( + "import-map.json", + r#"{ + "imports": { + "/~/": "./lib/", + "fs": "https://example.com/fs/index.js", + "std/": "https://example.com/std@0.123.0/" + } +}"#, + ); + temp_dir.create_dir_all("lib"); + temp_dir.write("lib/b.ts", r#"export const b = "b";"#); + + let mut client = context.new_lsp_command().build(); + client.initialize(|builder| { + builder.set_import_map("import-map.json"); + }); + + let uri = temp_dir.uri().join("a.ts").unwrap(); + + client.did_open(json!({ + "textDocument": { + "uri": uri, + "languageId": "typescript", + "version": 1, + "text": "import * as a from \"/~/b.ts\";\nimport * as b from \"\"" + } + })); + + let res = client.get_completion( + &uri, + (1, 20), + json!({ + "triggerKind": 2, + "triggerCharacter": "\"" + }), + ); + assert_eq!( + json!(res), + json!({ + "isIncomplete": false, + "items": [ + { + "label": ".", + "kind": 19, + "detail": "(local)", + "sortText": "1", + "insertText": ".", + "commitCharacters": ["\"", "'"], + }, { + "label": "..", + "kind": 19, + "detail": "(local)", + "sortText": "1", + "insertText": "..", + "commitCharacters": ["\"", "'"], + }, { + "label": "std", + "kind": 19, + "detail": "(import map)", + "sortText": "std", + "insertText": "std", + "commitCharacters": ["\"", "'"], + }, { + "label": "fs", + "kind": 17, + "detail": "(import map)", + "sortText": "fs", + "insertText": "fs", + "commitCharacters": ["\"", "'"], + }, { + "label": "/~", + "kind": 19, + "detail": "(import map)", + "sortText": "/~", + "insertText": "/~", + "commitCharacters": ["\"", "'"], + } + ] + }) + ); + + client.write_notification( + "textDocument/didChange", + json!({ + "textDocument": { + "uri": uri, + "version": 2 + }, + "contentChanges": [ + { + "range": { + "start": { "line": 1, "character": 20 }, + "end": { "line": 1, "character": 20 } + }, + "text": "/~/" + } + ] + }), + ); + + let res = client.get_completion( + uri, + (1, 23), + json!({ + "triggerKind": 2, + "triggerCharacter": "/" + }), + ); + assert_eq!( + json!(res), + json!({ + "isIncomplete": false, + "items": [ + { + "label": "b.ts", + "kind": 9, + "detail": "(import map)", + "sortText": "1", + "filterText": "/~/b.ts", + "textEdit": { + "range": { + "start": { "line": 1, "character": 20 }, + "end": { "line": 1, "character": 23 } + }, + "newText": "/~/b.ts" + }, + "commitCharacters": ["\"", "'"], + } + ] + }) + ); + + client.shutdown(); +} + +#[test] +fn lsp_hover() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "console.log(Deno.args);\n" + } + })); + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "position": { "line": 0, "character": 19 } + }), + ); + assert_eq!( + res, + json!({ + "contents": [ + { + "language": "typescript", + "value": "const Deno.args: string[]" + }, + "Returns the script arguments to the program.\n\nGive the following command line invocation of Deno:\n\n```sh\ndeno run --allow-read https://examples.deno.land/command-line-arguments.ts Sushi\n```\n\nThen `Deno.args` will contain:\n\n```ts\n[ \"Sushi\" ]\n```\n\nIf you are looking for a structured way to parse arguments, there is the\n[`std/flags`](https://deno.land/std/flags) module as part of the Deno\nstandard library.", + "\n\n*@category* - Runtime Environment", + ], + "range": { + "start": { "line": 0, "character": 17 }, + "end": { "line": 0, "character": 21 } + } + }) + ); + client.shutdown(); +} + +#[test] +fn lsp_hover_asset() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "console.log(Date.now());\n" + } + })); + client.write_request( + "textDocument/definition", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "position": { "line": 0, "character": 14 } + }), + ); + client.write_request( + "deno/virtualTextDocument", + json!({ + "textDocument": { + "uri": "deno:/asset/lib.deno.shared_globals.d.ts" + } + }), + ); + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": "deno:/asset/lib.es2015.symbol.wellknown.d.ts" + }, + "position": { "line": 111, "character": 13 } + }), + ); + assert_eq!( + res, + json!({ + "contents": [ + { + "language": "typescript", + "value": "interface Date", + }, + "Enables basic storage and retrieval of dates and times." + ], + "range": { + "start": { "line": 111, "character": 10, }, + "end": { "line": 111, "character": 14, } + } + }) + ); + client.shutdown(); +} + +#[test] +fn lsp_hover_disabled() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize(|builder| { + builder.set_deno_enable(false); + }); + client.change_configuration(json!({ "deno": { "enable": false } })); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "console.log(Date.now());\n", + }, + })); + + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "position": { "line": 0, "character": 19 } + }), + ); + assert_eq!(res, json!(null)); + client.shutdown(); +} + +#[test] +fn lsp_inlay_hints() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize(|builder| { + builder.enable_inlay_hints(); + }); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": r#"function a(b: string) { + return b; + } + + a("foo"); + + enum C { + A, + } + + parseInt("123", 8); + + const d = Date.now(); + + class E { + f = Date.now(); + } + + ["a"].map((v) => v + v); + "# + } + })); + let res = client.write_request( + "textDocument/inlayHint", + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + }, + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 19, "character": 0, } + } + }), + ); + assert_eq!( + res, + json!([ + { + "position": { "line": 0, "character": 21 }, + "label": ": string", + "kind": 1, + "paddingLeft": true + }, { + "position": { "line": 4, "character": 10 }, + "label": "b:", + "kind": 2, + "paddingRight": true + }, { + "position": { "line": 7, "character": 11 }, + "label": "= 0", + "paddingLeft": true + }, { + "position": { "line": 10, "character": 17 }, + "label": "string:", + "kind": 2, + "paddingRight": true + }, { + "position": { "line": 10, "character": 24 }, + "label": "radix:", + "kind": 2, + "paddingRight": true + }, { + "position": { "line": 12, "character": 15 }, + "label": ": number", + "kind": 1, + "paddingLeft": true + }, { + "position": { "line": 15, "character": 11 }, + "label": ": number", + "kind": 1, + "paddingLeft": true + }, { + "position": { "line": 18, "character": 18 }, + "label": "callbackfn:", + "kind": 2, + "paddingRight": true + }, { + "position": { "line": 18, "character": 20 }, + "label": ": string", + "kind": 1, + "paddingLeft": true + }, { + "position": { "line": 18, "character": 21 }, + "label": ": string", + "kind": 1, + "paddingLeft": true + } + ]) + ); +} + +#[test] +fn lsp_inlay_hints_not_enabled() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": r#"function a(b: string) { + return b; + } + + a("foo"); + + enum C { + A, + } + + parseInt("123", 8); + + const d = Date.now(); + + class E { + f = Date.now(); + } + + ["a"].map((v) => v + v); + "# + } + })); + let res = client.write_request( + "textDocument/inlayHint", + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + }, + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 19, "character": 0, } + } + }), + ); + assert_eq!(res, json!(null)); +} + +#[test] +fn lsp_workspace_disable_enable_paths() { + fn run_test(use_trailing_slash: bool) { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + temp_dir.create_dir_all("worker"); + temp_dir.write("worker/shared.ts", "export const a = 1"); + temp_dir.write("worker/other.ts", "import { a } from './shared.ts';\na;"); + temp_dir.write("worker/node.ts", "Buffer.alloc(1);"); + + let root_specifier = temp_dir.uri(); + + let mut client = context.new_lsp_command().build(); + client.initialize_with_config( + |builder| { + builder + .set_disable_paths(vec!["./worker/node.ts".to_string()]) + .set_enable_paths(vec!["./worker".to_string()]) + .set_root_uri(root_specifier.clone()) + .set_workspace_folders(vec![lsp::WorkspaceFolder { + uri: if use_trailing_slash { + root_specifier.clone() + } else { + ModuleSpecifier::parse( + root_specifier.as_str().strip_suffix('/').unwrap(), + ) + .unwrap() + }, + name: "project".to_string(), + }]) + .set_deno_enable(false); + }, + json!({ "deno": { + "enable": false, + "disablePaths": ["./worker/node.ts"], + "enablePaths": ["./worker"], + } }), + ); + + client.did_open(json!({ + "textDocument": { + "uri": root_specifier.join("./file.ts").unwrap(), + "languageId": "typescript", + "version": 1, + "text": "console.log(Date.now());\n" + } + })); + + client.did_open(json!({ + "textDocument": { + "uri": root_specifier.join("./other/file.ts").unwrap(), + "languageId": "typescript", + "version": 1, + "text": "console.log(Date.now());\n" + } + })); + + client.did_open(json!({ + "textDocument": { + "uri": root_specifier.join("./worker/file.ts").unwrap(), + "languageId": "typescript", + "version": 1, + "text": concat!( + "console.log(Date.now());\n", + "import { a } from './shared.ts';\n", + "a;\n", + ), + } + })); + + client.did_open(json!({ + "textDocument": { + "uri": root_specifier.join("./worker/subdir/file.ts").unwrap(), + "languageId": "typescript", + "version": 1, + "text": "console.log(Date.now());\n" + } + })); + + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": root_specifier.join("./file.ts").unwrap(), + }, + "position": { "line": 0, "character": 19 } + }), + ); + assert_eq!(res, json!(null)); + + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": root_specifier.join("./other/file.ts").unwrap(), + }, + "position": { "line": 0, "character": 19 } + }), + ); + assert_eq!(res, json!(null)); + + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": root_specifier.join("./worker/node.ts").unwrap(), + }, + "position": { "line": 0, "character": 0 } + }), + ); + assert_eq!(res, json!(null)); + + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": root_specifier.join("./worker/file.ts").unwrap(), + }, + "position": { "line": 0, "character": 19 } + }), + ); + assert_eq!( + res, + json!({ + "contents": [ + { + "language": "typescript", + "value": "(method) DateConstructor.now(): number", + }, + "Returns the number of milliseconds elapsed since midnight, January 1, 1970 Universal Coordinated Time (UTC)." + ], + "range": { + "start": { "line": 0, "character": 17, }, + "end": { "line": 0, "character": 20, } + } + }) + ); + + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": root_specifier.join("./worker/subdir/file.ts").unwrap(), + }, + "position": { "line": 0, "character": 19 } + }), + ); + assert_eq!( + res, + json!({ + "contents": [ + { + "language": "typescript", + "value": "(method) DateConstructor.now(): number", + }, + "Returns the number of milliseconds elapsed since midnight, January 1, 1970 Universal Coordinated Time (UTC)." + ], + "range": { + "start": { "line": 0, "character": 17, }, + "end": { "line": 0, "character": 20, } + } + }) + ); + + // check that the file system documents were auto-discovered + // via the enabled paths + let res = client.write_request( + "textDocument/references", + json!({ + "textDocument": { + "uri": root_specifier.join("./worker/file.ts").unwrap(), + }, + "position": { "line": 2, "character": 0 }, + "context": { + "includeDeclaration": true + } + }), + ); + + assert_eq!( + res, + json!([{ + "uri": root_specifier.join("./worker/file.ts").unwrap(), + "range": { + "start": { "line": 1, "character": 9 }, + "end": { "line": 1, "character": 10 } + } + }, { + "uri": root_specifier.join("./worker/file.ts").unwrap(), + "range": { + "start": { "line": 2, "character": 0 }, + "end": { "line": 2, "character": 1 } + } + }, { + "uri": root_specifier.join("./worker/shared.ts").unwrap(), + "range": { + "start": { "line": 0, "character": 13 }, + "end": { "line": 0, "character": 14 } + } + }, { + "uri": root_specifier.join("./worker/other.ts").unwrap(), + "range": { + "start": { "line": 0, "character": 9 }, + "end": { "line": 0, "character": 10 } + } + }, { + "uri": root_specifier.join("./worker/other.ts").unwrap(), + "range": { + "start": { "line": 1, "character": 0 }, + "end": { "line": 1, "character": 1 } + } + }]) + ); + + client.shutdown(); + } + + run_test(true); + run_test(false); +} + +#[test] +fn lsp_exclude_config() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + temp_dir.create_dir_all("other"); + temp_dir.write( + "other/shared.ts", + // this should not be found in the "find references" since this file is excluded + "import { a } from '../worker/shared.ts'; console.log(a);", + ); + temp_dir.create_dir_all("worker"); + temp_dir.write("worker/shared.ts", "export const a = 1"); + temp_dir.write( + "deno.json", + r#"{ + "exclude": ["other"], +}"#, + ); + let root_specifier = temp_dir.uri(); + + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + + client.did_open(json!({ + "textDocument": { + "uri": root_specifier.join("./other/file.ts").unwrap(), + "languageId": "typescript", + "version": 1, + "text": "console.log(Date.now());\n" + } + })); + + client.did_open(json!({ + "textDocument": { + "uri": root_specifier.join("./worker/file.ts").unwrap(), + "languageId": "typescript", + "version": 1, + "text": concat!( + "console.log(Date.now());\n", + "import { a } from './shared.ts';\n", + "a;\n", + ), + } + })); + + client.did_open(json!({ + "textDocument": { + "uri": root_specifier.join("./worker/subdir/file.ts").unwrap(), + "languageId": "typescript", + "version": 1, + "text": "console.log(Date.now());\n" + } + })); + + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": root_specifier.join("./other/file.ts").unwrap(), + }, + "position": { "line": 0, "character": 19 } + }), + ); + assert_eq!(res, json!(null)); + + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": root_specifier.join("./worker/file.ts").unwrap(), + }, + "position": { "line": 0, "character": 19 } + }), + ); + assert_eq!( + res, + json!({ + "contents": [ + { + "language": "typescript", + "value": "(method) DateConstructor.now(): number", + }, + "Returns the number of milliseconds elapsed since midnight, January 1, 1970 Universal Coordinated Time (UTC)." + ], + "range": { + "start": { "line": 0, "character": 17, }, + "end": { "line": 0, "character": 20, } + } + }) + ); + + // check that the file system documents were auto-discovered + let res = client.write_request( + "textDocument/references", + json!({ + "textDocument": { + "uri": root_specifier.join("./worker/file.ts").unwrap(), + }, + "position": { "line": 2, "character": 0 }, + "context": { + "includeDeclaration": true + } + }), + ); + + assert_eq!( + res, + json!([{ + "uri": root_specifier.join("./worker/file.ts").unwrap(), + "range": { + "start": { "line": 1, "character": 9 }, + "end": { "line": 1, "character": 10 } + } + }, { + "uri": root_specifier.join("./worker/file.ts").unwrap(), + "range": { + "start": { "line": 2, "character": 0 }, + "end": { "line": 2, "character": 1 } + } + }, { + "uri": root_specifier.join("./worker/shared.ts").unwrap(), + "range": { + "start": { "line": 0, "character": 13 }, + "end": { "line": 0, "character": 14 } + } + }]) + ); + + client.shutdown(); +} + +#[test] +fn lsp_hover_unstable_always_enabled() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + // IMPORTANT: If you change this API due to stabilization, also change it + // in the enabled test below. + "text": "type _ = Deno.ForeignLibraryInterface;\n" + } + })); + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "position": { "line": 0, "character": 14 } + }), + ); + assert_eq!( + res, + json!({ + "contents":[ + { + "language":"typescript", + "value":"interface Deno.ForeignLibraryInterface" + }, + "**UNSTABLE**: New API, yet to be vetted.\n\nA foreign library interface descriptor.", + "\n\n*@category* - FFI", + ], + "range":{ + "start":{ "line":0, "character":14 }, + "end":{ "line":0, "character":37 } + } + }) + ); + client.shutdown(); +} + +#[test] +fn lsp_hover_unstable_enabled() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize(|builder| { + // NOTE(bartlomieju): this is effectively not used anymore. + builder.set_unstable(true); + }); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "type _ = Deno.ForeignLibraryInterface;\n" + } + })); + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "position": { "line": 0, "character": 14 } + }), + ); + assert_eq!( + res, + json!({ + "contents":[ + { + "language":"typescript", + "value":"interface Deno.ForeignLibraryInterface" + }, + "**UNSTABLE**: New API, yet to be vetted.\n\nA foreign library interface descriptor.", + "\n\n*@category* - FFI", + ], + "range":{ + "start":{ "line":0, "character":14 }, + "end":{ "line":0, "character":37 } + } + }) + ); + client.shutdown(); +} + +#[test] +fn lsp_hover_change_mbc() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open( + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "const a = `编写软件很难`;\nconst b = `👍🦕😃`;\nconsole.log(a, b);\n" + } + }), + ); + client.write_notification( + "textDocument/didChange", + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "version": 2 + }, + "contentChanges": [ + { + "range": { + "start": { "line": 1, "character": 11 }, + "end": { + "line": 1, + // the LSP uses utf16 encoded characters indexes, so + // after the deno emoji is character index 15 + "character": 15 + } + }, + "text": "" + } + ] + }), + ); + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "position": { "line": 2, "character": 15 } + }), + ); + assert_eq!( + res, + json!({ + "contents": [ + { + "language": "typescript", + "value": "const b: \"😃\"", + }, + "", + ], + "range": { + "start": { "line": 2, "character": 15, }, + "end": { "line": 2, "character": 16, }, + } + }) + ); + client.shutdown(); +} + +#[test] +fn lsp_hover_closed_document() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + temp_dir.write("a.ts", r#"export const a = "a";"#); + temp_dir.write("b.ts", r#"export * from "./a.ts";"#); + temp_dir.write("c.ts", "import { a } from \"./b.ts\";\nconsole.log(a);\n"); + + let b_specifier = temp_dir.uri().join("b.ts").unwrap(); + let c_specifier = temp_dir.uri().join("c.ts").unwrap(); + + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": b_specifier, + "languageId": "typescript", + "version": 1, + "text": r#"export * from "./a.ts";"# + } + })); + + client.did_open(json!({ + "textDocument": { + "uri": c_specifier, + "languageId": "typescript", + "version": 1, + "text": "import { a } from \"./b.ts\";\nconsole.log(a);\n", + } + })); + + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": c_specifier, + }, + "position": { "line": 0, "character": 10 } + }), + ); + assert_eq!( + res, + json!({ + "contents": [ + { + "language": "typescript", + "value": "(alias) const a: \"a\"\nimport a" + }, + "" + ], + "range": { + "start": { "line": 0, "character": 9 }, + "end": { "line": 0, "character": 10 } + } + }) + ); + client.write_notification( + "textDocument/didClose", + json!({ + "textDocument": { + "uri": b_specifier, + } + }), + ); + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": c_specifier, + }, + "position": { "line": 0, "character": 10 } + }), + ); + assert_eq!( + res, + json!({ + "contents": [ + { + "language": "typescript", + "value": "(alias) const a: \"a\"\nimport a" + }, + "" + ], + "range": { + "start": { "line": 0, "character": 9 }, + "end": { "line": 0, "character": 10 } + } + }) + ); + client.shutdown(); +} + +#[test] +fn lsp_hover_dependency() { + let context = TestContextBuilder::new() + .use_http_server() + .use_temp_cwd() + .build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file_01.ts", + "languageId": "typescript", + "version": 1, + "text": "export const a = \"a\";\n", + } + })); + client.did_open( + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "import * as a from \"http://127.0.0.1:4545/xTypeScriptTypes.js\";\n// @deno-types=\"http://127.0.0.1:4545/type_definitions/foo.d.ts\"\nimport * as b from \"http://127.0.0.1:4545/type_definitions/foo.js\";\nimport * as c from \"http://127.0.0.1:4545/subdir/type_reference.js\";\nimport * as d from \"http://127.0.0.1:4545/subdir/mod1.ts\";\nimport * as e from \"data:application/typescript;base64,ZXhwb3J0IGNvbnN0IGEgPSAiYSI7CgpleHBvcnQgZW51bSBBIHsKICBBLAogIEIsCiAgQywKfQo=\";\nimport * as f from \"./file_01.ts\";\nimport * as g from \"http://localhost:4545/x/a/mod.ts\";\n\nconsole.log(a, b, c, d, e, f, g);\n" + } + }), + ); + client.write_request( + "workspace/executeCommand", + json!({ + "command": "deno.cache", + "arguments": [[], "file:///a/file.ts"], + }), + ); + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + }, + "position": { "line": 0, "character": 28 } + }), + ); + assert_eq!( + res, + json!({ + "contents": { + "kind": "markdown", + "value": "**Resolved Dependency**\n\n**Code**: http​://127.0.0.1:4545/xTypeScriptTypes.js\n\n**Types**: http​://127.0.0.1:4545/xTypeScriptTypes.d.ts\n" + }, + "range": { + "start": { "line": 0, "character": 19 }, + "end":{ "line": 0, "character": 62 } + } + }) + ); + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + }, + "position": { "line": 3, "character": 28 } + }), + ); + assert_eq!( + res, + json!({ + "contents": { + "kind": "markdown", + "value": "**Resolved Dependency**\n\n**Code**: http​://127.0.0.1:4545/subdir/type_reference.js\n\n**Types**: http​://127.0.0.1:4545/subdir/type_reference.d.ts\n" + }, + "range": { + "start": { "line": 3, "character": 19 }, + "end":{ "line": 3, "character": 67 } + } + }) + ); + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + }, + "position": { "line": 4, "character": 28 } + }), + ); + assert_eq!( + res, + json!({ + "contents": { + "kind": "markdown", + "value": "**Resolved Dependency**\n\n**Code**: http​://127.0.0.1:4545/subdir/mod1.ts\n" + }, + "range": { + "start": { "line": 4, "character": 19 }, + "end":{ "line": 4, "character": 57 } + } + }) + ); + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + }, + "position": { "line": 5, "character": 28 } + }), + ); + assert_eq!( + res, + json!({ + "contents": { + "kind": "markdown", + "value": "**Resolved Dependency**\n\n**Code**: _(a data url)_\n" + }, + "range": { + "start": { "line": 5, "character": 19 }, + "end":{ "line": 5, "character": 132 } + } + }) + ); + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + }, + "position": { "line": 6, "character": 28 } + }), + ); + assert_eq!( + res, + json!({ + "contents": { + "kind": "markdown", + "value": "**Resolved Dependency**\n\n**Code**: file​:///a/file_01.ts\n" + }, + "range": { + "start": { "line": 6, "character": 19 }, + "end":{ "line": 6, "character": 33 } + } + }) + ); +} + +// This tests for a regression covered by denoland/deno#12753 where the lsp was +// unable to resolve dependencies when there was an invalid syntax in the module +#[test] +fn lsp_hover_deps_preserved_when_invalid_parse() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file1.ts", + "languageId": "typescript", + "version": 1, + "text": "export type Foo = { bar(): string };\n" + } + })); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file2.ts", + "languageId": "typescript", + "version": 1, + "text": "import { Foo } from './file1.ts'; declare const f: Foo; f\n" + } + })); + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": "file:///a/file2.ts" + }, + "position": { "line": 0, "character": 56 } + }), + ); + assert_eq!( + res, + json!({ + "contents": [ + { + "language": "typescript", + "value": "const f: Foo", + }, + "" + ], + "range": { + "start": { "line": 0, "character": 56, }, + "end": { "line": 0, "character": 57, } + } + }) + ); + client.write_notification( + "textDocument/didChange", + json!({ + "textDocument": { + "uri": "file:///a/file2.ts", + "version": 2 + }, + "contentChanges": [ + { + "range": { + "start": { "line": 0, "character": 57 }, + "end": { "line": 0, "character": 58 } + }, + "text": "." + } + ] + }), + ); + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": "file:///a/file2.ts" + }, + "position": { "line": 0, "character": 56 } + }), + ); + assert_eq!( + res, + json!({ + "contents": [ + { + "language": "typescript", + "value": "const f: Foo", + }, + "" + ], + "range": { + "start": { "line": 0, "character": 56, }, + "end": { "line": 0, "character": 57, } + } + }) + ); + client.shutdown(); +} + +#[test] +fn lsp_hover_typescript_types() { + let context = TestContextBuilder::new() + .use_http_server() + .use_temp_cwd() + .build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open( + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "import * as a from \"http://127.0.0.1:4545/xTypeScriptTypes.js\";\n\nconsole.log(a.foo);\n", + } + }), + ); + client.write_request( + "workspace/executeCommand", + json!({ + "command": "deno.cache", + "arguments": [ + ["http://127.0.0.1:4545/xTypeScriptTypes.js"], + "file:///a/file.ts", + ], + }), + ); + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "position": { "line": 0, "character": 24 } + }), + ); + assert_eq!( + res, + json!({ + "contents": { + "kind": "markdown", + "value": "**Resolved Dependency**\n\n**Code**: http​://127.0.0.1:4545/xTypeScriptTypes.js\n\n**Types**: http​://127.0.0.1:4545/xTypeScriptTypes.d.ts\n" + }, + "range": { + "start": { "line": 0, "character": 19 }, + "end": { "line": 0, "character": 62 } + } + }) + ); + client.shutdown(); +} + +#[test] +fn lsp_hover_jsdoc_symbol_link() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/b.ts", + "languageId": "typescript", + "version": 1, + "text": "export function hello() {}\n" + } + })); + client.did_open( + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "import { hello } from \"./b.ts\";\n\nhello();\n\nconst b = \"b\";\n\n/** JSDoc {@link hello} and {@linkcode b} */\nfunction a() {}\n" + } + }), + ); + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "position": { "line": 7, "character": 10 } + }), + ); + assert_eq!( + res, + json!({ + "contents": [ + { + "language": "typescript", + "value": "function a(): void" + }, + "JSDoc [hello](file:///a/file.ts#L1,10) and [`b`](file:///a/file.ts#L5,7)" + ], + "range": { + "start": { "line": 7, "character": 9 }, + "end": { "line": 7, "character": 10 } + } + }) + ); + client.shutdown(); +} + +#[test] +fn lsp_goto_type_definition() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open( + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "interface A {\n a: string;\n}\n\nexport class B implements A {\n a = \"a\";\n log() {\n console.log(this.a);\n }\n}\n\nconst b = new B();\nb;\n", + } + }), + ); + let res = client.write_request( + "textDocument/typeDefinition", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "position": { "line": 12, "character": 1 } + }), + ); + assert_eq!( + res, + json!([ + { + "targetUri": "file:///a/file.ts", + "targetRange": { + "start": { "line": 4, "character": 0 }, + "end": { "line": 9, "character": 1 } + }, + "targetSelectionRange": { + "start": { "line": 4, "character": 13 }, + "end": { "line": 4, "character": 14 } + } + } + ]) + ); + client.shutdown(); +} + +#[test] +fn lsp_call_hierarchy() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open( + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "function foo() {\n return false;\n}\n\nclass Bar {\n baz() {\n return foo();\n }\n}\n\nfunction main() {\n const bar = new Bar();\n bar.baz();\n}\n\nmain();" + } + }), + ); + let res = client.write_request( + "textDocument/prepareCallHierarchy", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "position": { "line": 5, "character": 3 } + }), + ); + assert_eq!( + res, + json!([{ + "name": "baz", + "kind": 6, + "detail": "Bar", + "uri": "file:///a/file.ts", + "range": { + "start": { "line": 5, "character": 2 }, + "end": { "line": 7, "character": 3 } + }, + "selectionRange": { + "start": { "line": 5, "character": 2 }, + "end": { "line": 5, "character": 5 } + } + }]) + ); + let res = client.write_request( + "callHierarchy/incomingCalls", + json!({ + "item": { + "name": "baz", + "kind": 6, + "detail": "Bar", + "uri": "file:///a/file.ts", + "range": { + "start": { "line": 5, "character": 2 }, + "end": { "line": 7, "character": 3 } + }, + "selectionRange": { + "start": { "line": 5, "character": 2 }, + "end": { "line": 5, "character": 5 } + } + } + }), + ); + assert_eq!( + res, + json!([{ + "from": { + "name": "main", + "kind": 12, + "detail": "", + "uri": "file:///a/file.ts", + "range": { + "start": { "line": 10, "character": 0 }, + "end": { "line": 13, "character": 1 } + }, + "selectionRange": { + "start": { "line": 10, "character": 9 }, + "end": { "line": 10, "character": 13 } + } + }, + "fromRanges": [ + { + "start": { "line": 12, "character": 6 }, + "end": { "line": 12, "character": 9 } + } + ] + }]) + ); + let res = client.write_request( + "callHierarchy/outgoingCalls", + json!({ + "item": { + "name": "baz", + "kind": 6, + "detail": "Bar", + "uri": "file:///a/file.ts", + "range": { + "start": { "line": 5, "character": 2 }, + "end": { "line": 7, "character": 3 } + }, + "selectionRange": { + "start": { "line": 5, "character": 2 }, + "end": { "line": 5, "character": 5 } + } + } + }), + ); + assert_eq!( + res, + json!([{ + "to": { + "name": "foo", + "kind": 12, + "detail": "", + "uri": "file:///a/file.ts", + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 2, "character": 1 } + }, + "selectionRange": { + "start": { "line": 0, "character": 9 }, + "end": { "line": 0, "character": 12 } + } + }, + "fromRanges": [{ + "start": { "line": 6, "character": 11 }, + "end": { "line": 6, "character": 14 } + }] + }]) + ); + client.shutdown(); +} + +#[test] +fn lsp_large_doc_changes() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + let large_file_text = + fs::read_to_string(testdata_path().join("lsp").join("large_file.txt")) + .unwrap(); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "javascript", + "version": 1, + "text": large_file_text, + } + })); + client.write_notification( + "textDocument/didChange", + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "version": 2 + }, + "contentChanges": [ + { + "range": { + "start": { "line": 444, "character": 11 }, + "end": { "line": 444, "character": 14 } + }, + "text": "+++" + } + ] + }), + ); + client.write_notification( + "textDocument/didChange", + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "version": 2 + }, + "contentChanges": [ + { + "range": { + "start": { "line": 445, "character": 4 }, + "end": { "line": 445, "character": 4 } + }, + "text": "// " + } + ] + }), + ); + client.write_notification( + "textDocument/didChange", + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "version": 2 + }, + "contentChanges": [ + { + "range": { + "start": { "line": 477, "character": 4 }, + "end": { "line": 477, "character": 9 } + }, + "text": "error" + } + ] + }), + ); + client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "position": { "line": 421, "character": 30 } + }), + ); + client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "position": { "line": 444, "character": 6 } + }), + ); + client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "position": { "line": 461, "character": 34 } + }), + ); + client.shutdown(); + + assert!(client.duration().as_millis() <= 15000); +} + +#[test] +fn lsp_document_symbol() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open( + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "interface IFoo {\n foo(): boolean;\n}\n\nclass Bar implements IFoo {\n constructor(public x: number) { }\n foo() { return true; }\n /** @deprecated */\n baz() { return false; }\n get value(): number { return 0; }\n set value(_newValue: number) { return; }\n static staticBar = new Bar(0);\n private static getStaticBar() { return Bar.staticBar; }\n}\n\nenum Values { value1, value2 }\n\nvar bar: IFoo = new Bar(3);" + } + }), + ); + let res = client.write_request( + "textDocument/documentSymbol", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + } + }), + ); + assert_eq!( + res, + json!([{ + "name": "bar", + "kind": 13, + "range": { + "start": { "line": 17, "character": 4 }, + "end": { "line": 17, "character": 26 } + }, + "selectionRange": { + "start": { "line": 17, "character": 4 }, + "end": { "line": 17, "character": 7 } + } + }, { + "name": "Bar", + "kind": 5, + "range": { + "start": { "line": 4, "character": 0 }, + "end": { "line": 13, "character": 1 } + }, + "selectionRange": { + "start": { "line": 4, "character": 6 }, + "end": { "line": 4, "character": 9 } + }, + "children": [{ + "name": "constructor", + "kind": 9, + "range": { + "start": { "line": 5, "character": 2 }, + "end": { "line": 5, "character": 35 } + }, + "selectionRange": { + "start": { "line": 5, "character": 2 }, + "end": { "line": 5, "character": 35 } + } + }, { + "name": "baz", + "kind": 6, + "tags": [1], + "range": { + "start": { "line": 8, "character": 2 }, + "end": { "line": 8, "character": 25 } + }, + "selectionRange": { + "start": { "line": 8, "character": 2 }, + "end": { "line": 8, "character": 5 } + } + }, { + "name": "foo", + "kind": 6, + "range": { + "start": { "line": 6, "character": 2 }, + "end": { "line": 6, "character": 24 } + }, + "selectionRange": { + "start": { "line": 6, "character": 2 }, + "end": { "line": 6, "character": 5 } + } + }, { + "name": "getStaticBar", + "kind": 6, + "range": { + "start": { "line": 12, "character": 2 }, + "end": { "line": 12, "character": 57 } + }, + "selectionRange": { + "start": { "line": 12, "character": 17 }, + "end": { "line": 12, "character": 29 } + } + }, { + "name": "staticBar", + "kind": 8, + "range": { + "start": { "line": 11, "character": 2 }, + "end": { "line": 11, "character": 32 } + }, + "selectionRange": { + "start": { "line": 11, "character": 9 }, + "end": { "line": 11, "character": 18 } + } + }, { + "name": "(get) value", + "kind": 8, + "range": { + "start": { "line": 9, "character": 2 }, + "end": { "line": 9, "character": 35 } + }, + "selectionRange": { + "start": { "line": 9, "character": 6 }, + "end": { "line": 9, "character": 11 } + } + }, { + "name": "(set) value", + "kind": 8, + "range": { + "start": { "line": 10, "character": 2 }, + "end": { "line": 10, "character": 42 } + }, + "selectionRange": { + "start": { "line": 10, "character": 6 }, + "end": { "line": 10, "character": 11 } + } + }, { + "name": "x", + "kind": 8, + "range": { + "start": { "line": 5, "character": 14 }, + "end": { "line": 5, "character": 30 } + }, + "selectionRange": { + "start": { "line": 5, "character": 21 }, + "end": { "line": 5, "character": 22 } + } + }] + }, { + "name": "IFoo", + "kind": 11, + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 2, "character": 1 } + }, + "selectionRange": { + "start": { "line": 0, "character": 10 }, + "end": { "line": 0, "character": 14 } + }, + "children": [{ + "name": "foo", + "kind": 6, + "range": { + "start": { "line": 1, "character": 2 }, + "end": { "line": 1, "character": 17 } + }, + "selectionRange": { + "start": { "line": 1, "character": 2 }, + "end": { "line": 1, "character": 5 } + } + }] + }, { + "name": "Values", + "kind": 10, + "range": { + "start": { "line": 15, "character": 0 }, + "end": { "line": 15, "character": 30 } + }, + "selectionRange": { + "start": { "line": 15, "character": 5 }, + "end": { "line": 15, "character": 11 } + }, + "children": [{ + "name": "value1", + "kind": 22, + "range": { + "start": { "line": 15, "character": 14 }, + "end": { "line": 15, "character": 20 } + }, + "selectionRange": { + "start": { "line": 15, "character": 14 }, + "end": { "line": 15, "character": 20 } + } + }, { + "name": "value2", + "kind": 22, + "range": { + "start": { "line": 15, "character": 22 }, + "end": { "line": 15, "character": 28 } + }, + "selectionRange": { + "start": { "line": 15, "character": 22 }, + "end": { "line": 15, "character": 28 } + } + }] + }] + ) + ); + client.shutdown(); +} + +#[test] +fn lsp_folding_range() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open( + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "// #region 1\n/*\n * Some comment\n */\nclass Foo {\n bar(a, b) {\n if (a === b) {\n return true;\n }\n return false;\n }\n}\n// #endregion" + } + }), + ); + let res = client.write_request( + "textDocument/foldingRange", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + } + }), + ); + assert_eq!( + res, + json!([{ + "startLine": 0, + "endLine": 12, + "kind": "region" + }, { + "startLine": 1, + "endLine": 3, + "kind": "comment" + }, { + "startLine": 4, + "endLine": 10 + }, { + "startLine": 5, + "endLine": 9 + }, { + "startLine": 6, + "endLine": 7 + }]) + ); + client.shutdown(); +} + +#[test] +fn lsp_rename() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open( + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + // this should not rename in comments and strings + "text": "let variable = 'a'; // variable\nconsole.log(variable);\n\"variable\";\n" + } + }), + ); + let res = client.write_request( + "textDocument/rename", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "position": { "line": 0, "character": 4 }, + "newName": "variable_modified" + }), + ); + assert_eq!( + res, + json!({ + "documentChanges": [{ + "textDocument": { + "uri": "file:///a/file.ts", + "version": 1 + }, + "edits": [{ + "range": { + "start": { "line": 0, "character": 4 }, + "end": { "line": 0, "character": 12 } + }, + "newText": "variable_modified" + }, { + "range": { + "start": { "line": 1, "character": 12 }, + "end": { "line": 1, "character": 20 } + }, + "newText": "variable_modified" + }] + }] + }) + ); + client.shutdown(); +} + +#[test] +fn lsp_selection_range() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open( + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "class Foo {\n bar(a, b) {\n if (a === b) {\n return true;\n }\n return false;\n }\n}" + } + }), + ); + let res = client.write_request( + "textDocument/selectionRange", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "positions": [{ "line": 2, "character": 8 }] + }), + ); + assert_eq!( + res, + json!([{ + "range": { + "start": { "line": 2, "character": 8 }, + "end": { "line": 2, "character": 9 } + }, + "parent": { + "range": { + "start": { "line": 2, "character": 8 }, + "end": { "line": 2, "character": 15 } + }, + "parent": { + "range": { + "start": { "line": 2, "character": 4 }, + "end": { "line": 4, "character": 5 } + }, + "parent": { + "range": { + "start": { "line": 1, "character": 13 }, + "end": { "line": 6, "character": 2 } + }, + "parent": { + "range": { + "start": { "line": 1, "character": 12 }, + "end": { "line": 6, "character": 3 } + }, + "parent": { + "range": { + "start": { "line": 1, "character": 2 }, + "end": { "line": 6, "character": 3 } + }, + "parent": { + "range": { + "start": { "line": 0, "character": 11 }, + "end": { "line": 7, "character": 0 } + }, + "parent": { + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 7, "character": 1 } + } + } + } + } + } + } + } + } + }]) + ); + client.shutdown(); +} + +#[test] +fn lsp_semantic_tokens() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open( + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "enum Values { value1, value2 }\n\nasync function baz(s: string): Promise {\n const r = s.slice(0);\n return r;\n}\n\ninterface IFoo {\n readonly x: number;\n foo(): boolean;\n}\n\nclass Bar implements IFoo {\n constructor(public readonly x: number) { }\n foo() { return true; }\n static staticBar = new Bar(0);\n private static getStaticBar() { return Bar.staticBar; }\n}\n" + } + }), + ); + let res = client.write_request( + "textDocument/semanticTokens/full", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + } + }), + ); + assert_eq!( + res, + json!({ + "data": [ + 0, 5, 6, 1, 1, 0, 9, 6, 8, 9, 0, 8, 6, 8, 9, 2, 15, 3, 10, 5, 0, 4, 1, + 6, 1, 0, 12, 7, 2, 16, 1, 8, 1, 7, 41, 0, 4, 1, 6, 0, 0, 2, 5, 11, 16, + 1, 9, 1, 7, 40, 3, 10, 4, 2, 1, 1, 11, 1, 9, 9, 1, 2, 3, 11, 1, 3, 6, 3, + 0, 1, 0, 15, 4, 2, 0, 1, 30, 1, 6, 9, 1, 2, 3, 11,1, 1, 9, 9, 9, 3, 0, + 16, 3, 0, 0, 1, 17, 12, 11, 3, 0, 24, 3, 0, 0, 0, 4, 9, 9, 2 + ] + }) + ); + let res = client.write_request( + "textDocument/semanticTokens/range", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 6, "character": 0 } + } + }), + ); + assert_eq!( + res, + json!({ + "data": [ + 0, 5, 6, 1, 1, 0, 9, 6, 8, 9, 0, 8, 6, 8, 9, 2, 15, 3, 10, 5, 0, 4, 1, + 6, 1, 0, 12, 7, 2, 16, 1, 8, 1, 7, 41, 0, 4, 1, 6, 0, 0, 2, 5, 11, 16, + 1, 9, 1, 7, 40 + ] + }) + ); + client.shutdown(); +} + +#[test] +fn lsp_code_lens() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": concat!( + "class A {\n", + " a = \"a\";\n", + "\n", + " b() {\n", + " console.log(this.a);\n", + " }\n", + "\n", + " c() {\n", + " this.a = \"c\";\n", + " }\n", + "}\n", + "\n", + "const a = new A();\n", + "a.b();\n", + "const b = 2;\n", + "const c = 3;\n", + "c; c;", + ), + } + })); + let res = client.write_request( + "textDocument/codeLens", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + } + }), + ); + assert_eq!( + res, + json!([{ + "range": { + "start": { "line": 0, "character": 6 }, + "end": { "line": 0, "character": 7 } + }, + "data": { + "specifier": "file:///a/file.ts", + "source": "references" + } + }, { + "range": { + "start": { "line": 1, "character": 2 }, + "end": { "line": 1, "character": 3 } + }, + "data": { + "specifier": "file:///a/file.ts", + "source": "references" + } + }]) + ); + let res = client.write_request( + "codeLens/resolve", + json!({ + "range": { + "start": { "line": 0, "character": 6 }, + "end": { "line": 0, "character": 7 } + }, + "data": { + "specifier": "file:///a/file.ts", + "source": "references" + } + }), + ); + assert_eq!( + res, + json!({ + "range": { + "start": { "line": 0, "character": 6 }, + "end": { "line": 0, "character": 7 } + }, + "command": { + "title": "1 reference", + "command": "deno.client.showReferences", + "arguments": [ + "file:///a/file.ts", + { "line": 0, "character": 6 }, + [{ + "uri": "file:///a/file.ts", + "range": { + "start": { "line": 12, "character": 14 }, + "end": { "line": 12, "character": 15 } + } + }] + ] + } + }) + ); + + // 0 references + let res = client.write_request( + "codeLens/resolve", + json!({ + "range": { + "start": { "line": 14, "character": 6 }, + "end": { "line": 14, "character": 7 } + }, + "data": { + "specifier": "file:///a/file.ts", + "source": "references" + } + }), + ); + assert_eq!( + res, + json!({ + "range": { + "start": { "line": 14, "character": 6 }, + "end": { "line": 14, "character": 7 } + }, + "command": { + "title": "0 references", + "command": "", + } + }) + ); + + // 2 references + let res = client.write_request( + "codeLens/resolve", + json!({ + "range": { + "start": { "line": 15, "character": 6 }, + "end": { "line": 15, "character": 7 } + }, + "data": { + "specifier": "file:///a/file.ts", + "source": "references" + } + }), + ); + assert_eq!( + res, + json!({ + "range": { + "start": { "line": 15, "character": 6 }, + "end": { "line": 15, "character": 7 } + }, + "command": { + "title": "2 references", + "command": "deno.client.showReferences", + "arguments": [ + "file:///a/file.ts", + { "line": 15, "character": 6 }, + [{ + "uri": "file:///a/file.ts", + "range": { + "start": { "line": 16, "character": 0 }, + "end": { "line": 16, "character": 1 } + } + },{ + "uri": "file:///a/file.ts", + "range": { + "start": { "line": 16, "character": 3 }, + "end": { "line": 16, "character": 4 } + } + }] + ] + } + }) + ); + + client.shutdown(); +} + +#[test] +fn lsp_code_lens_impl() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open( + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "interface A {\n b(): void;\n}\n\nclass B implements A {\n b() {\n console.log(\"b\");\n }\n}\n\ninterface C {\n c: string;\n}\n" + } + }), + ); + let res = client.write_request( + "textDocument/codeLens", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + } + }), + ); + assert_eq!( + res, + json!([ { + "range": { + "start": { "line": 0, "character": 10 }, + "end": { "line": 0, "character": 11 } + }, + "data": { + "specifier": "file:///a/file.ts", + "source": "implementations" + } + }, { + "range": { + "start": { "line": 0, "character": 10 }, + "end": { "line": 0, "character": 11 } + }, + "data": { + "specifier": "file:///a/file.ts", + "source": "references" + } + }, { + "range": { + "start": { "line": 4, "character": 6 }, + "end": { "line": 4, "character": 7 } + }, + "data": { + "specifier": "file:///a/file.ts", + "source": "references" + } + }, { + "range": { + "start": { "line": 10, "character": 10 }, + "end": { "line": 10, "character": 11 } + }, + "data": { + "specifier": "file:///a/file.ts", + "source": "implementations" + } + }, { + "range": { + "start": { "line": 10, "character": 10 }, + "end": { "line": 10, "character": 11 } + }, + "data": { + "specifier": "file:///a/file.ts", + "source": "references" + } + }, { + "range": { + "start": { "line": 11, "character": 2 }, + "end": { "line": 11, "character": 3 } + }, + "data": { + "specifier": "file:///a/file.ts", + "source": "references" + } + }]) + ); + let res = client.write_request( + "codeLens/resolve", + json!({ + "range": { + "start": { "line": 0, "character": 10 }, + "end": { "line": 0, "character": 11 } + }, + "data": { + "specifier": "file:///a/file.ts", + "source": "implementations" + } + }), + ); + assert_eq!( + res, + json!({ + "range": { + "start": { "line": 0, "character": 10 }, + "end": { "line": 0, "character": 11 } + }, + "command": { + "title": "1 implementation", + "command": "deno.client.showReferences", + "arguments": [ + "file:///a/file.ts", + { "line": 0, "character": 10 }, + [{ + "uri": "file:///a/file.ts", + "range": { + "start": { "line": 4, "character": 6 }, + "end": { "line": 4, "character": 7 } + } + }] + ] + } + }) + ); + let res = client.write_request( + "codeLens/resolve", + json!({ + "range": { + "start": { "line": 10, "character": 10 }, + "end": { "line": 10, "character": 11 } + }, + "data": { + "specifier": "file:///a/file.ts", + "source": "implementations" + } + }), + ); + assert_eq!( + res, + json!({ + "range": { + "start": { "line": 10, "character": 10 }, + "end": { "line": 10, "character": 11 } + }, + "command": { + "title": "0 implementations", + "command": "" + } + }) + ); + client.shutdown(); +} + +#[test] +fn lsp_code_lens_test() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize(|builder| { + builder.disable_testing_api().set_code_lens(None); + }); + client.did_open( + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "const { test } = Deno;\nconst { test: test2 } = Deno;\nconst test3 = Deno.test;\n\nDeno.test(\"test a\", () => {});\nDeno.test({\n name: \"test b\",\n fn() {},\n});\ntest({\n name: \"test c\",\n fn() {},\n});\ntest(\"test d\", () => {});\ntest2({\n name: \"test e\",\n fn() {},\n});\ntest2(\"test f\", () => {});\ntest3({\n name: \"test g\",\n fn() {},\n});\ntest3(\"test h\", () => {});\n" + } + }), + ); + let res = client.write_request( + "textDocument/codeLens", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + } + }), + ); + assert_eq!( + res, + json!([{ + "range": { + "start": { "line": 4, "character": 5 }, + "end": { "line": 4, "character": 9 } + }, + "command": { + "title": "▶︎ Run Test", + "command": "deno.client.test", + "arguments": [ + "file:///a/file.ts", + "test a", + { "inspect": false } + ] + } + }, { + "range": { + "start": { "line": 4, "character": 5 }, + "end": { "line": 4, "character": 9 } + }, + "command": { + "title": "Debug", + "command": "deno.client.test", + "arguments": [ + "file:///a/file.ts", + "test a", + { "inspect": true } + ] + } + }, { + "range": { + "start": { "line": 5, "character": 5 }, + "end": { "line": 5, "character": 9 } + }, + "command": { + "title": "▶︎ Run Test", + "command": "deno.client.test", + "arguments": [ + "file:///a/file.ts", + "test b", + { "inspect": false } + ] + } + }, { + "range": { + "start": { "line": 5, "character": 5 }, + "end": { "line": 5, "character": 9 } + }, + "command": { + "title": "Debug", + "command": "deno.client.test", + "arguments": [ + "file:///a/file.ts", + "test b", + { "inspect": true } + ] + } + }, { + "range": { + "start": { "line": 9, "character": 0 }, + "end": { "line": 9, "character": 4 } + }, + "command": { + "title": "▶︎ Run Test", + "command": "deno.client.test", + "arguments": [ + "file:///a/file.ts", + "test c", + { "inspect": false } + ] + } + }, { + "range": { + "start": { "line": 9, "character": 0 }, + "end": { "line": 9, "character": 4 } + }, + "command": { + "title": "Debug", + "command": "deno.client.test", + "arguments": [ + "file:///a/file.ts", + "test c", + { "inspect": true } + ] + } + }, { + "range": { + "start": { "line": 13, "character": 0 }, + "end": { "line": 13, "character": 4 } + }, + "command": { + "title": "▶︎ Run Test", + "command": "deno.client.test", + "arguments": [ + "file:///a/file.ts", + "test d", + { "inspect": false } + ] + } + }, { + "range": { + "start": { "line": 13, "character": 0 }, + "end": { "line": 13, "character": 4 } + }, + "command": { + "title": "Debug", + "command": "deno.client.test", + "arguments": [ + "file:///a/file.ts", + "test d", + { "inspect": true } + ] + } + }, { + "range": { + "start": { "line": 14, "character": 0 }, + "end": { "line": 14, "character": 5 } + }, + "command": { + "title": "▶︎ Run Test", + "command": "deno.client.test", + "arguments": [ + "file:///a/file.ts", + "test e", + { "inspect": false } + ] + } + }, { + "range": { + "start": { "line": 14, "character": 0 }, + "end": { "line": 14, "character": 5 } + }, + "command": { + "title": "Debug", + "command": "deno.client.test", + "arguments": [ + "file:///a/file.ts", + "test e", + { "inspect": true } + ] + } + }, { + "range": { + "start": { "line": 18, "character": 0 }, + "end": { "line": 18, "character": 5 } + }, + "command": { + "title": "▶︎ Run Test", + "command": "deno.client.test", + "arguments": [ + "file:///a/file.ts", + "test f", + { "inspect": false } + ] + } + }, { + "range": { + "start": { "line": 18, "character": 0 }, + "end": { "line": 18, "character": 5 } + }, + "command": { + "title": "Debug", + "command": "deno.client.test", + "arguments": [ + "file:///a/file.ts", + "test f", + { "inspect": true } + ] + } + }, { + "range": { + "start": { "line": 19, "character": 0 }, + "end": { "line": 19, "character": 5 } + }, + "command": { + "title": "▶︎ Run Test", + "command": "deno.client.test", + "arguments": [ + "file:///a/file.ts", + "test g", + { "inspect": false } + ] + } + }, { + "range": { + "start": { "line": 19, "character": 0 }, + "end": { "line": 19, "character": 5 } + }, + "command": { + "title": "Debug", + "command": "deno.client.test", + "arguments": [ + "file:///a/file.ts", + "test g", + { "inspect": true } + ] + } + }, { + "range": { + "start": { "line": 23, "character": 0 }, + "end": { "line": 23, "character": 5 } + }, + "command": { + "title": "▶︎ Run Test", + "command": "deno.client.test", + "arguments": [ + "file:///a/file.ts", + "test h", + { "inspect": false } + ] + } + }, { + "range": { + "start": { "line": 23, "character": 0 }, + "end": { "line": 23, "character": 5 } + }, + "command": { + "title": "Debug", + "command": "deno.client.test", + "arguments": [ + "file:///a/file.ts", + "test h", + { "inspect": true } + ] + } + }]) + ); + client.shutdown(); +} + +#[test] +fn lsp_code_lens_test_disabled() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize(|builder| { + builder.disable_testing_api().set_code_lens(Some(json!({ + "implementations": true, + "references": true, + "test": false + }))); + }); + client.change_configuration(json!({ + "deno": { + "enable": true, + "codeLens": { + "test": false, + }, + }, + })); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "const { test } = Deno;\nconst { test: test2 } = Deno;\nconst test3 = Deno.test;\n\nDeno.test(\"test a\", () => {});\nDeno.test({\n name: \"test b\",\n fn() {},\n});\ntest({\n name: \"test c\",\n fn() {},\n});\ntest(\"test d\", () => {});\ntest2({\n name: \"test e\",\n fn() {},\n});\ntest2(\"test f\", () => {});\ntest3({\n name: \"test g\",\n fn() {},\n});\ntest3(\"test h\", () => {});\n" + }, + })); + let res = client.write_request( + "textDocument/codeLens", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + } + }), + ); + assert_eq!(res, json!(null)); + client.shutdown(); +} + +#[test] +fn lsp_code_lens_non_doc_nav_tree() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "console.log(Date.now());\n" + } + })); + client.write_request( + "textDocument/references", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "position": { "line": 0, "character": 3 }, + "context": { + "includeDeclaration": true + } + }), + ); + client.write_request( + "deno/virtualTextDocument", + json!({ + "textDocument": { + "uri": "deno:/asset/lib.deno.shared_globals.d.ts" + } + }), + ); + let res = client.write_request_with_res_as::>( + "textDocument/codeLens", + json!({ + "textDocument": { + "uri": "deno:/asset/lib.deno.shared_globals.d.ts" + } + }), + ); + assert!(res.len() > 50); + client.write_request_with_res_as::( + "codeLens/resolve", + json!({ + "range": { + "start": { "line": 416, "character": 12 }, + "end": { "line": 416, "character": 19 } + }, + "data": { + "specifier": "asset:///lib.deno.shared_globals.d.ts", + "source": "references" + } + }), + ); + client.shutdown(); +} + +#[test] +fn lsp_nav_tree_updates() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open( + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "interface A {\n b(): void;\n}\n\nclass B implements A {\n b() {\n console.log(\"b\");\n }\n}\n\ninterface C {\n c: string;\n}\n" + } + }), + ); + let res = client.write_request( + "textDocument/codeLens", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + } + }), + ); + assert_eq!( + res, + json!([ { + "range": { + "start": { "line": 0, "character": 10 }, + "end": { "line": 0, "character": 11 } + }, + "data": { + "specifier": "file:///a/file.ts", + "source": "implementations" + } + }, { + "range": { + "start": { "line": 0, "character": 10 }, + "end": { "line": 0, "character": 11 } + }, + "data": { + "specifier": "file:///a/file.ts", + "source": "references" + } + }, { + "range": { + "start": { "line": 4, "character": 6 }, + "end": { "line": 4, "character": 7 } + }, + "data": { + "specifier": "file:///a/file.ts", + "source": "references" + } + }, { + "range": { + "start": { "line": 10, "character": 10 }, + "end": { "line": 10, "character": 11 } + }, + "data": { + "specifier": "file:///a/file.ts", + "source": "implementations" + } + }, { + "range": { + "start": { "line": 10, "character": 10 }, + "end": { "line": 10, "character": 11 } + }, + "data": { + "specifier": "file:///a/file.ts", + "source": "references" + } + }, { + "range": { + "start": { "line": 11, "character": 2 }, + "end": { "line": 11, "character": 3 } + }, + "data": { + "specifier": "file:///a/file.ts", + "source": "references" + } + }]) + ); + client.write_notification( + "textDocument/didChange", + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "version": 2 + }, + "contentChanges": [ + { + "range": { + "start": { "line": 10, "character": 0 }, + "end": { "line": 13, "character": 0 } + }, + "text": "" + } + ] + }), + ); + let res = client.write_request( + "textDocument/codeLens", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + } + }), + ); + assert_eq!( + res, + json!([{ + "range": { + "start": { "line": 0, "character": 10 }, + "end": { "line": 0, "character": 11 } + }, + "data": { + "specifier": "file:///a/file.ts", + "source": "implementations" + } + }, { + "range": { + "start": { "line": 0, "character": 10 }, + "end": { "line": 0, "character": 11 } + }, + "data": { + "specifier": "file:///a/file.ts", + "source": "references" + } + }, { + "range": { + "start": { "line": 4, "character": 6 }, + "end": { "line": 4, "character": 7 } + }, + "data": { + "specifier": "file:///a/file.ts", + "source": "references" + } + }]) + ); + client.shutdown(); +} + +#[test] +fn lsp_find_references() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/mod.ts", + "languageId": "typescript", + "version": 1, + "text": r"export const a = 1;\nconst b = 2;" + } + })); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/mod.test.ts", + "languageId": "typescript", + "version": 1, + "text": r#"import { a } from './mod.ts'; console.log(a);"# + } + })); + + // test without including the declaration + let res = client.write_request( + "textDocument/references", + json!({ + "textDocument": { + "uri": "file:///a/mod.ts", + }, + "position": { "line": 0, "character": 13 }, + "context": { + "includeDeclaration": false + } + }), + ); + + assert_eq!( + res, + json!([{ + "uri": "file:///a/mod.test.ts", + "range": { + "start": { "line": 0, "character": 9 }, + "end": { "line": 0, "character": 10 } + } + }, { + "uri": "file:///a/mod.test.ts", + "range": { + "start": { "line": 0, "character": 42 }, + "end": { "line": 0, "character": 43 } + } + }]) + ); + + // test with including the declaration + let res = client.write_request( + "textDocument/references", + json!({ + "textDocument": { + "uri": "file:///a/mod.ts", + }, + "position": { "line": 0, "character": 13 }, + "context": { + "includeDeclaration": true + } + }), + ); + + assert_eq!( + res, + json!([{ + "uri": "file:///a/mod.ts", + "range": { + "start": { "line": 0, "character": 13 }, + "end": { "line": 0, "character": 14 } + } + }, { + "uri": "file:///a/mod.test.ts", + "range": { + "start": { "line": 0, "character": 9 }, + "end": { "line": 0, "character": 10 } + } + }, { + "uri": "file:///a/mod.test.ts", + "range": { + "start": { "line": 0, "character": 42 }, + "end": { "line": 0, "character": 43 } + } + }]) + ); + + // test 0 references + let res = client.write_request( + "textDocument/references", + json!({ + "textDocument": { + "uri": "file:///a/mod.ts", + }, + "position": { "line": 1, "character": 6 }, + "context": { + "includeDeclaration": false + } + }), + ); + + assert_eq!(res, json!(null)); // seems it always returns null for this, which is ok + + client.shutdown(); +} + +#[test] +fn lsp_signature_help() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open( + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "/**\n * Adds two numbers.\n * @param a This is a first number.\n * @param b This is a second number.\n */\nfunction add(a: number, b: number) {\n return a + b;\n}\n\nadd(" + } + }), + ); + let res = client.write_request( + "textDocument/signatureHelp", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "position": { "character": 4, "line": 9 }, + "context": { + "triggerKind": 2, + "triggerCharacter": "(", + "isRetrigger": false + } + }), + ); + assert_eq!( + res, + json!({ + "signatures": [ + { + "label": "add(a: number, b: number): number", + "documentation": { + "kind": "markdown", + "value": "Adds two numbers." + }, + "parameters": [ + { + "label": "a: number", + "documentation": { + "kind": "markdown", + "value": "This is a first number." + } + }, { + "label": "b: number", + "documentation": { + "kind": "markdown", + "value": "This is a second number." + } + } + ] + } + ], + "activeSignature": 0, + "activeParameter": 0 + }) + ); + client.write_notification( + "textDocument/didChange", + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "version": 2 + }, + "contentChanges": [ + { + "range": { + "start": { "line": 9, "character": 4 }, + "end": { "line": 9, "character": 4 } + }, + "text": "123, " + } + ] + }), + ); + let res = client.write_request( + "textDocument/signatureHelp", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "position": { "character": 8, "line": 9 } + }), + ); + assert_eq!( + res, + json!({ + "signatures": [ + { + "label": "add(a: number, b: number): number", + "documentation": { + "kind": "markdown", + "value": "Adds two numbers." + }, + "parameters": [ + { + "label": "a: number", + "documentation": { + "kind": "markdown", + "value": "This is a first number." + } + }, { + "label": "b: number", + "documentation": { + "kind": "markdown", + "value": "This is a second number." + } + } + ] + } + ], + "activeSignature": 0, + "activeParameter": 1 + }) + ); + client.shutdown(); +} + +#[test] +fn lsp_code_actions() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open( + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "export function a(): void {\n await Promise.resolve(\"a\");\n}\n\nexport function b(): void {\n await Promise.resolve(\"b\");\n}\n" + } + }), + ); + let res = client + .write_request( "textDocument/codeAction", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "range": { + "start": { "line": 1, "character": 2 }, + "end": { "line": 1, "character": 7 } + }, + "context": { + "diagnostics": [{ + "range": { + "start": { "line": 1, "character": 2 }, + "end": { "line": 1, "character": 7 } + }, + "severity": 1, + "code": 1308, + "source": "deno-ts", + "message": "'await' expressions are only allowed within async functions and at the top levels of modules.", + "relatedInformation": [] + }], + "only": ["quickfix"] + } + }), + ) + ; + assert_eq!( + res, + json!([{ + "title": "Add async modifier to containing function", + "kind": "quickfix", + "diagnostics": [{ + "range": { + "start": { "line": 1, "character": 2 }, + "end": { "line": 1, "character": 7 } + }, + "severity": 1, + "code": 1308, + "source": "deno-ts", + "message": "'await' expressions are only allowed within async functions and at the top levels of modules.", + "relatedInformation": [] + }], + "edit": { + "documentChanges": [{ + "textDocument": { + "uri": "file:///a/file.ts", + "version": 1 + }, + "edits": [{ + "range": { + "start": { "line": 0, "character": 7 }, + "end": { "line": 0, "character": 7 } + }, + "newText": "async " + }, { + "range": { + "start": { "line": 0, "character": 21 }, + "end": { "line": 0, "character": 25 } + }, + "newText": "Promise" + }] + }] + } + }, { + "title": "Add all missing 'async' modifiers", + "kind": "quickfix", + "diagnostics": [{ + "range": { + "start": { "line": 1, "character": 2 }, + "end": { "line": 1, "character": 7 } + }, + "severity": 1, + "code": 1308, + "source": "deno-ts", + "message": "'await' expressions are only allowed within async functions and at the top levels of modules.", + "relatedInformation": [] + }], + "data": { + "specifier": "file:///a/file.ts", + "fixId": "fixAwaitInSyncFunction" + } + }]) + ); + let res = client + .write_request( "codeAction/resolve", + json!({ + "title": "Add all missing 'async' modifiers", + "kind": "quickfix", + "diagnostics": [{ + "range": { + "start": { "line": 1, "character": 2 }, + "end": { "line": 1, "character": 7 } + }, + "severity": 1, + "code": 1308, + "source": "deno-ts", + "message": "'await' expressions are only allowed within async functions and at the top levels of modules.", + "relatedInformation": [] + }], + "data": { + "specifier": "file:///a/file.ts", + "fixId": "fixAwaitInSyncFunction" + } + }), + ) + ; + assert_eq!( + res, + json!({ + "title": "Add all missing 'async' modifiers", + "kind": "quickfix", + "diagnostics": [ + { + "range": { + "start": { + "line": 1, + "character": 2 + }, + "end": { + "line": 1, + "character": 7 + } + }, + "severity": 1, + "code": 1308, + "source": "deno-ts", + "message": "'await' expressions are only allowed within async functions and at the top levels of modules.", + "relatedInformation": [] + } + ], + "edit": { + "documentChanges": [{ + "textDocument": { + "uri": "file:///a/file.ts", + "version": 1 + }, + "edits": [{ + "range": { + "start": { "line": 0, "character": 7 }, + "end": { "line": 0, "character": 7 } + }, + "newText": "async " + }, { + "range": { + "start": { "line": 0, "character": 21 }, + "end": { "line": 0, "character": 25 } + }, + "newText": "Promise" + }, { + "range": { + "start": { "line": 4, "character": 7 }, + "end": { "line": 4, "character": 7 } + }, + "newText": "async " + }, { + "range": { + "start": { "line": 4, "character": 21 }, + "end": { "line": 4, "character": 25 } + }, + "newText": "Promise" + }] + }] + }, + "data": { + "specifier": "file:///a/file.ts", + "fixId": "fixAwaitInSyncFunction" + } + }) + ); + client.shutdown(); +} + +#[test] +fn test_lsp_code_actions_ordering() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": r#" + import "https://deno.land/x/a/mod.ts"; + let a = "a"; + console.log(a); + export function b(): void { + await Promise.resolve("b"); + } + "# + } + })); + let res = client.write_request( + "textDocument/codeAction", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "range": { + "start": { "line": 1, "character": 11 }, + "end": { "line": 6, "character": 12 } + }, + "context": { + "diagnostics": diagnostics.all(), + "only": ["quickfix"] + } + }), + ); + + // Simplify the serialization to `{ title, source }` for this test. + let mut actions: Vec = serde_json::from_value(res).unwrap(); + for action in &mut actions { + let action = action.as_object_mut().unwrap(); + let title = action.get("title").unwrap().as_str().unwrap().to_string(); + let diagnostics = action.get("diagnostics").unwrap().as_array().unwrap(); + let diagnostic = diagnostics.first().unwrap().as_object().unwrap(); + let source = diagnostic.get("source").unwrap(); + let source = source.as_str().unwrap().to_string(); + action.clear(); + action.insert("title".to_string(), serde_json::to_value(title).unwrap()); + action.insert("source".to_string(), serde_json::to_value(source).unwrap()); + } + let res = serde_json::to_value(actions).unwrap(); + + // Ensure ordering is "deno-ts" -> "deno" -> "deno-lint". + assert_eq!( + res, + json!([ + { + "title": "Add async modifier to containing function", + "source": "deno-ts", + }, + { + "title": "Cache \"https://deno.land/x/a/mod.ts\" and its dependencies.", + "source": "deno", + }, + { + "title": "Disable prefer-const for this line", + "source": "deno-lint", + }, + { + "title": "Disable prefer-const for the entire file", + "source": "deno-lint", + }, + { + "title": "Ignore lint errors for the entire file", + "source": "deno-lint", + }, + { + "title": "Disable no-await-in-sync-fn for this line", + "source": "deno-lint", + }, + { + "title": "Disable no-await-in-sync-fn for the entire file", + "source": "deno-lint", + }, + { + "title": "Ignore lint errors for the entire file", + "source": "deno-lint", + }, + ]) + ); +} + +#[test] +fn lsp_status_file() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + + let res = client.write_request( + "deno/virtualTextDocument", + json!({ + "textDocument": { + "uri": "deno:/status.md" + } + }), + ); + let res = res.as_str().unwrap().to_string(); + assert!(res.starts_with("# Deno Language Server Status")); + + let res = client.write_request( + "deno/virtualTextDocument", + json!({ + "textDocument": { + "uri": "deno:/status.md?1" + } + }), + ); + let res = res.as_str().unwrap().to_string(); + assert!(res.starts_with("# Deno Language Server Status")); +} + +#[test] +fn lsp_code_actions_deno_cache() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "import * as a from \"https://deno.land/x/a/mod.ts\";\n\nconsole.log(a);\n" + } + })); + assert_eq!( + diagnostics.messages_with_source("deno"), + serde_json::from_value(json!({ + "uri": "file:///a/file.ts", + "diagnostics": [{ + "range": { + "start": { "line": 0, "character": 19 }, + "end": { "line": 0, "character": 49 } + }, + "severity": 1, + "code": "no-cache", + "source": "deno", + "message": "Uncached or missing remote URL: https://deno.land/x/a/mod.ts", + "data": { "specifier": "https://deno.land/x/a/mod.ts" } + }], + "version": 1 + })).unwrap() + ); + + let res = + client + .write_request( "textDocument/codeAction", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "range": { + "start": { "line": 0, "character": 19 }, + "end": { "line": 0, "character": 49 } + }, + "context": { + "diagnostics": [{ + "range": { + "start": { "line": 0, "character": 19 }, + "end": { "line": 0, "character": 49 } + }, + "severity": 1, + "code": "no-cache", + "source": "deno", + "message": "Unable to load the remote module: \"https://deno.land/x/a/mod.ts\".", + "data": { + "specifier": "https://deno.land/x/a/mod.ts" + } + }], + "only": ["quickfix"] + } + }), + ) + ; + assert_eq!( + res, + json!([{ + "title": "Cache \"https://deno.land/x/a/mod.ts\" and its dependencies.", + "kind": "quickfix", + "diagnostics": [{ + "range": { + "start": { "line": 0, "character": 19 }, + "end": { "line": 0, "character": 49 } + }, + "severity": 1, + "code": "no-cache", + "source": "deno", + "message": "Unable to load the remote module: \"https://deno.land/x/a/mod.ts\".", + "data": { + "specifier": "https://deno.land/x/a/mod.ts" + } + }], + "command": { + "title": "", + "command": "deno.cache", + "arguments": [["https://deno.land/x/a/mod.ts"], "file:///a/file.ts"] + } + }]) + ); + client.shutdown(); +} + +#[test] +fn lsp_jsr_uncached() { + let context = TestContextBuilder::new() + .use_http_server() + .use_temp_cwd() + .build(); + let temp_dir = context.temp_dir(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": temp_dir.uri().join("file.ts").unwrap(), + "languageId": "typescript", + "version": 1, + "text": r#"import "jsr:@foo/bar";"#, + }, + })); + // TODO(nayeemrmn): This should check if the jsr dep is cached and give a + // diagnostic. + assert_eq!(json!(diagnostics.all()), json!([])); + client.shutdown(); +} + +#[test] +fn lsp_code_actions_deno_cache_npm() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "import chalk from \"npm:chalk\";\n\nconsole.log(chalk.green);\n" + } + })); + assert_eq!( + diagnostics.messages_with_source("deno"), + serde_json::from_value(json!({ + "uri": "file:///a/file.ts", + "diagnostics": [{ + "range": { + "start": { "line": 0, "character": 18 }, + "end": { "line": 0, "character": 29 } + }, + "severity": 1, + "code": "no-cache-npm", + "source": "deno", + "message": "Uncached or missing npm package: chalk", + "data": { "specifier": "npm:chalk" } + }], + "version": 1 + })) + .unwrap() + ); + + let res = client.write_request( + "textDocument/codeAction", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "range": { + "start": { "line": 0, "character": 18 }, + "end": { "line": 0, "character": 29 } + }, + "context": { + "diagnostics": [{ + "range": { + "start": { "line": 0, "character": 18 }, + "end": { "line": 0, "character": 29 } + }, + "severity": 1, + "code": "no-cache-npm", + "source": "deno", + "message": "Uncached or missing npm package: chalk", + "data": { "specifier": "npm:chalk" } + }], + "only": ["quickfix"] + } + }), + ); + assert_eq!( + res, + json!([{ + "title": "Cache \"npm:chalk\" and its dependencies.", + "kind": "quickfix", + "diagnostics": [{ + "range": { + "start": { "line": 0, "character": 18 }, + "end": { "line": 0, "character": 29 } + }, + "severity": 1, + "code": "no-cache-npm", + "source": "deno", + "message": "Uncached or missing npm package: chalk", + "data": { "specifier": "npm:chalk" } + }], + "command": { + "title": "", + "command": "deno.cache", + "arguments": [["npm:chalk"], "file:///a/file.ts"] + } + }]) + ); + client.shutdown(); +} + +#[test] +fn lsp_code_actions_deno_cache_all() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": r#" + import * as a from "https://deno.land/x/a/mod.ts"; + import chalk from "npm:chalk"; + console.log(a); + console.log(chalk); + "#, + } + })); + assert_eq!( + diagnostics.messages_with_source("deno"), + serde_json::from_value(json!({ + "uri": "file:///a/file.ts", + "diagnostics": [ + { + "range": { + "start": { "line": 1, "character": 27 }, + "end": { "line": 1, "character": 57 }, + }, + "severity": 1, + "code": "no-cache", + "source": "deno", + "message": "Uncached or missing remote URL: https://deno.land/x/a/mod.ts", + "data": { "specifier": "https://deno.land/x/a/mod.ts" }, + }, + { + "range": { + "start": { "line": 2, "character": 26 }, + "end": { "line": 2, "character": 37 }, + }, + "severity": 1, + "code": "no-cache-npm", + "source": "deno", + "message": "Uncached or missing npm package: chalk", + "data": { "specifier": "npm:chalk" }, + }, + ], + "version": 1, + })).unwrap() + ); + + let res = + client + .write_request( "textDocument/codeAction", + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + }, + "range": { + "start": { "line": 1, "character": 27 }, + "end": { "line": 1, "character": 57 }, + }, + "context": { + "diagnostics": [{ + "range": { + "start": { "line": 1, "character": 27 }, + "end": { "line": 1, "character": 57 }, + }, + "severity": 1, + "code": "no-cache", + "source": "deno", + "message": "Uncached or missing remote URL: https://deno.land/x/a/mod.ts", + "data": { + "specifier": "https://deno.land/x/a/mod.ts", + }, + }], + "only": ["quickfix"], + } + }), + ) + ; + assert_eq!( + res, + json!([ + { + "title": "Cache \"https://deno.land/x/a/mod.ts\" and its dependencies.", + "kind": "quickfix", + "diagnostics": [{ + "range": { + "start": { "line": 1, "character": 27 }, + "end": { "line": 1, "character": 57 }, + }, + "severity": 1, + "code": "no-cache", + "source": "deno", + "message": "Uncached or missing remote URL: https://deno.land/x/a/mod.ts", + "data": { + "specifier": "https://deno.land/x/a/mod.ts", + }, + }], + "command": { + "title": "", + "command": "deno.cache", + "arguments": [["https://deno.land/x/a/mod.ts"], "file:///a/file.ts"], + } + }, + { + "title": "Cache all dependencies of this module.", + "kind": "quickfix", + "diagnostics": [ + { + "range": { + "start": { "line": 1, "character": 27 }, + "end": { "line": 1, "character": 57 }, + }, + "severity": 1, + "code": "no-cache", + "source": "deno", + "message": "Uncached or missing remote URL: https://deno.land/x/a/mod.ts", + "data": { + "specifier": "https://deno.land/x/a/mod.ts", + }, + }, + { + "range": { + "start": { "line": 2, "character": 26 }, + "end": { "line": 2, "character": 37 }, + }, + "severity": 1, + "code": "no-cache-npm", + "source": "deno", + "message": "Uncached or missing npm package: chalk", + "data": { "specifier": "npm:chalk" }, + }, + ], + "command": { + "title": "", + "command": "deno.cache", + "arguments": [[], "file:///a/file.ts"], + } + }, + ]) + ); + client.shutdown(); +} + +#[test] +fn lsp_cache_on_save() { + let context = TestContextBuilder::new() + .use_http_server() + .use_temp_cwd() + .build(); + let temp_dir = context.temp_dir(); + temp_dir.write( + "file.ts", + r#" + import { printHello } from "http://localhost:4545/subdir/print_hello.ts"; + printHello(); + "#, + ); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.change_configuration(json!({ + "deno": { + "enable": true, + "cacheOnSave": true, + }, + })); + + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": temp_dir.uri().join("file.ts").unwrap(), + "languageId": "typescript", + "version": 1, + "text": temp_dir.read_to_string("file.ts"), + } + })); + assert_eq!( + diagnostics.messages_with_source("deno"), + serde_json::from_value(json!({ + "uri": temp_dir.uri().join("file.ts").unwrap(), + "diagnostics": [{ + "range": { + "start": { "line": 1, "character": 33 }, + "end": { "line": 1, "character": 78 } + }, + "severity": 1, + "code": "no-cache", + "source": "deno", + "message": "Uncached or missing remote URL: http://localhost:4545/subdir/print_hello.ts", + "data": { "specifier": "http://localhost:4545/subdir/print_hello.ts" } + }], + "version": 1 + })) + .unwrap() + ); + client.did_save(json!({ + "textDocument": { "uri": temp_dir.uri().join("file.ts").unwrap() }, + })); + assert_eq!(client.read_diagnostics().all(), vec![]); + + client.shutdown(); +} + +// Regression test for https://github.com/denoland/deno/issues/22122. +#[test] +fn lsp_cache_then_definition() { + let context = TestContextBuilder::new() + .use_http_server() + .use_temp_cwd() + .build(); + let temp_dir = context.temp_dir(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": temp_dir.uri().join("file.ts").unwrap(), + "languageId": "typescript", + "version": 1, + "text": r#"import "http://localhost:4545/run/002_hello.ts";"#, + }, + })); + // Prior to the fix, this would cause a faulty memoization that maps the + // URL "http://localhost:4545/run/002_hello.ts" to itself, preventing it from + // being reverse-mapped to "deno:/http/localhost%3A4545/run/002_hello.ts" on + // "textDocument/definition" request. + client.write_request( + "workspace/executeCommand", + json!({ + "command": "deno.cache", + "arguments": [ + ["http://localhost:4545/run/002_hello.ts"], + temp_dir.uri().join("file.ts").unwrap(), + ], + }), + ); + let res = client.write_request( + "textDocument/definition", + json!({ + "textDocument": { "uri": temp_dir.uri().join("file.ts").unwrap() }, + "position": { "line": 0, "character": 8 }, + }), + ); + assert_eq!( + res, + json!([{ + "targetUri": "deno:/http/localhost%3A4545/run/002_hello.ts", + "targetRange": { + "start": { + "line": 0, + "character": 0, + }, + "end": { + "line": 1, + "character": 0, + }, + }, + "targetSelectionRange": { + "start": { + "line": 0, + "character": 0, + }, + "end": { + "line": 1, + "character": 0, + }, + }, + }]), + ); +} + +#[test] +fn lsp_code_actions_imports() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file00.ts", + "languageId": "typescript", + "version": 1, + "text": r#"export interface MallardDuckConfigOptions extends DuckConfigOptions { + kind: "mallard"; +} + +export class MallardDuckConfig extends DuckConfig { + constructor(options: MallardDuckConfigOptions) { + super(options); + } +} +"# + } + })); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file01.ts", + "languageId": "typescript", + "version": 1, + "text": r#"import { DuckConfigOptions } from "./file02.ts"; + +export class DuckConfig { + readonly kind; + constructor(options: DuckConfigOptions) { + this.kind = options.kind; + } +} +"# + } + })); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file02.ts", + "languageId": "typescript", + "version": 1, + "text": r#"export interface DuckConfigOptions { + kind: string; + quacks: boolean; +} +"# + } + })); + + let res = client.write_request( + "textDocument/codeAction", + json!({ + "textDocument": { + "uri": "file:///a/file00.ts" + }, + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 6, "character": 0 } + }, + "context": { + "diagnostics": [{ + "range": { + "start": { "line": 0, "character": 50 }, + "end": { "line": 0, "character": 67 } + }, + "severity": 1, + "code": 2304, + "source": "deno-ts", + "message": "Cannot find name 'DuckConfigOptions'." + }, { + "range": { + "start": { "line": 4, "character": 39 }, + "end": { "line": 4, "character": 49 } + }, + "severity": 1, + "code": 2304, + "source": "deno-ts", + "message": "Cannot find name 'DuckConfig'." + }], + "only": ["quickfix"] + } + }), + ); + assert_eq!( + res, + json!([{ + "title": "Add import from \"./file02.ts\"", + "kind": "quickfix", + "diagnostics": [{ + "range": { + "start": { "line": 0, "character": 50 }, + "end": { "line": 0, "character": 67 } + }, + "severity": 1, + "code": 2304, + "source": "deno-ts", + "message": "Cannot find name 'DuckConfigOptions'." + }], + "edit": { + "documentChanges": [{ + "textDocument": { + "uri": "file:///a/file00.ts", + "version": 1 + }, + "edits": [{ + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 0, "character": 0 } + }, + "newText": "import { DuckConfigOptions } from \"./file02.ts\";\n\n" + }] + }] + } + }, { + "title": "Add import from \"./file01.ts\"", + "kind": "quickfix", + "diagnostics": [{ + "range": { + "start": { "line": 4, "character": 39 }, + "end": { "line": 4, "character": 49 } + }, + "severity": 1, + "code": 2304, + "source": "deno-ts", + "message": "Cannot find name 'DuckConfig'." + }], + "edit": { + "documentChanges": [{ + "textDocument": { + "uri": "file:///a/file00.ts", + "version": 1 + }, + "edits": [{ + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 0, "character": 0 } + }, + "newText": "import { DuckConfig } from \"./file01.ts\";\n\n" + }] + }] + } + }, { + "title": "Add all missing imports", + "kind": "quickfix", + "diagnostics": [{ + "range": { + "start": { "line": 0, "character": 50 }, + "end": { "line": 0, "character": 67 } + }, + "severity": 1, + "code": 2304, + "source": "deno-ts", + "message": "Cannot find name 'DuckConfigOptions'." + }], + "data": { + "specifier": "file:///a/file00.ts", + "fixId": "fixMissingImport" + } + }]) + ); + let res = client.write_request( + "codeAction/resolve", + json!({ + "title": "Add all missing imports", + "kind": "quickfix", + "diagnostics": [{ + "range": { + "start": { "line": 0, "character": 50 }, + "end": { "line": 0, "character": 67 } + }, + "severity": 1, + "code": 2304, + "source": "deno-ts", + "message": "Cannot find name 'DuckConfigOptions'." + }, { + "range": { + "start": { "line": 4, "character": 39 }, + "end": { "line": 4, "character": 49 } + }, + "severity": 1, + "code": 2304, + "source": "deno-ts", + "message": "Cannot find name 'DuckConfig'." + }], + "data": { + "specifier": "file:///a/file00.ts", + "fixId": "fixMissingImport" + } + }), + ); + assert_eq!( + res, + json!({ + "title": "Add all missing imports", + "kind": "quickfix", + "diagnostics": [{ + "range": { + "start": { "line": 0, "character": 50 }, + "end": { "line": 0, "character": 67 } + }, + "severity": 1, + "code": 2304, + "source": "deno-ts", + "message": "Cannot find name 'DuckConfigOptions'." + }, { + "range": { + "start": { "line": 4, "character": 39 }, + "end": { "line": 4, "character": 49 } + }, + "severity": 1, + "code": 2304, + "source": "deno-ts", + "message": "Cannot find name 'DuckConfig'." + }], + "edit": { + "documentChanges": [{ + "textDocument": { + "uri": "file:///a/file00.ts", + "version": 1 + }, + "edits": [{ + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 0, "character": 0 } + }, + "newText": "import { DuckConfig } from \"./file01.ts\";\nimport { DuckConfigOptions } from \"./file02.ts\";\n\n" + }] + }] + }, + "data": { + "specifier": "file:///a/file00.ts", + "fixId": "fixMissingImport" + } + }) + ); + + client.shutdown(); +} + +#[test] +fn lsp_code_actions_refactor() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "var x: { a?: number; b?: string } = {};\n" + } + })); + let res = client.write_request( + "textDocument/codeAction", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 1, "character": 0 } + }, + "context": { + "diagnostics": [], + "only": ["refactor"] + } + }), + ); + assert_eq!( + res, + json!([{ + "title": "Move to a new file", + "kind": "refactor.move.newFile", + "isPreferred": false, + "data": { + "specifier": "file:///a/file.ts", + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 1, "character": 0 } + }, + "refactorName": "Move to a new file", + "actionName": "Move to a new file" + } + }, { + "title": "Extract to function in module scope", + "kind": "refactor.extract.function", + "isPreferred": false, + "data": { + "specifier": "file:///a/file.ts", + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 1, "character": 0 } + }, + "refactorName": "Extract Symbol", + "actionName": "function_scope_0" + } + }, { + "title": "Extract to constant in enclosing scope", + "kind": "refactor.extract.constant", + "isPreferred": false, + "data": { + "specifier": "file:///a/file.ts", + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 1, "character": 0 } + }, + "refactorName": "Extract Symbol", + "actionName": "constant_scope_0" + } + }, { + "title": "Convert default export to named export", + "kind": "refactor.rewrite.export.named", + "isPreferred": false, + "disabled": { + "reason": "This file already has a default export" + }, + "data": { + "specifier": "file:///a/file.ts", + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 1, "character": 0 } + }, + "refactorName": "Convert export", + "actionName": "Convert default export to named export" + } + }, { + "title": "Convert named export to default export", + "kind": "refactor.rewrite.export.default", + "isPreferred": false, + "disabled": { + "reason": "This file already has a default export" + }, + "data": { + "specifier": "file:///a/file.ts", + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 1, "character": 0 } + }, + "refactorName": "Convert export", + "actionName": "Convert named export to default export" + } + }, { + "title": "Convert namespace import to named imports", + "kind": "refactor.rewrite.import.named", + "isPreferred": false, + "disabled": { + "reason": "Selection is not an import declaration." + }, + "data": { + "specifier": "file:///a/file.ts", + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 1, "character": 0 } + }, + "refactorName": "Convert import", + "actionName": "Convert namespace import to named imports" + } + }, { + "title": "Convert named imports to default import", + "kind": "refactor.rewrite.import.default", + "isPreferred": false, + "disabled": { + "reason": "Selection is not an import declaration." + }, + "data": { + "specifier": "file:///a/file.ts", + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 1, "character": 0 } + }, + "refactorName": "Convert import", + "actionName": "Convert named imports to default import" + } + }, { + "title": "Convert named imports to namespace import", + "kind": "refactor.rewrite.import.namespace", + "isPreferred": false, + "disabled": { + "reason": "Selection is not an import declaration." + }, + "data": { + "specifier": "file:///a/file.ts", + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 1, "character": 0 } + }, + "refactorName": "Convert import", + "actionName": "Convert named imports to namespace import" + } + }]) + ); + let res = client.write_request( + "codeAction/resolve", + json!({ + "title": "Extract to interface", + "kind": "refactor.extract.interface", + "isPreferred": true, + "data": { + "specifier": "file:///a/file.ts", + "range": { + "start": { "line": 0, "character": 7 }, + "end": { "line": 0, "character": 33 } + }, + "refactorName": "Extract type", + "actionName": "Extract to interface" + } + }), + ); + assert_eq!( + res, + json!({ + "title": "Extract to interface", + "kind": "refactor.extract.interface", + "edit": { + "documentChanges": [{ + "textDocument": { + "uri": "file:///a/file.ts", + "version": 1 + }, + "edits": [{ + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 0, "character": 0 } + }, + "newText": "interface NewType {\n a?: number;\n b?: string;\n}\n\n" + }, { + "range": { + "start": { "line": 0, "character": 7 }, + "end": { "line": 0, "character": 33 } + }, + "newText": "NewType" + }] + }] + }, + "isPreferred": true, + "data": { + "specifier": "file:///a/file.ts", + "range": { + "start": { "line": 0, "character": 7 }, + "end": { "line": 0, "character": 33 } + }, + "refactorName": "Extract type", + "actionName": "Extract to interface" + } + }) + ); + client.shutdown(); +} + +#[test] +fn lsp_code_actions_imports_respects_fmt_config() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + temp_dir.write( + "./deno.jsonc", + json!({ + "fmt": { + "semiColons": false, + "singleQuote": true, + } + }) + .to_string(), + ); + temp_dir.write( + "file00.ts", + r#" + export interface MallardDuckConfigOptions extends DuckConfigOptions { + kind: "mallard"; + } + "#, + ); + temp_dir.write( + "file01.ts", + r#" + export interface DuckConfigOptions { + kind: string; + quacks: boolean; + } + "#, + ); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": temp_dir.uri().join("file00.ts").unwrap(), + "languageId": "typescript", + "version": 1, + "text": temp_dir.read_to_string("file00.ts"), + } + })); + client.did_open(json!({ + "textDocument": { + "uri": temp_dir.uri().join("file01.ts").unwrap(), + "languageId": "typescript", + "version": 1, + "text": temp_dir.read_to_string("file01.ts"), + } + })); + + let res = client.write_request( + "textDocument/codeAction", + json!({ + "textDocument": { + "uri": temp_dir.uri().join("file00.ts").unwrap() + }, + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 4, "character": 0 } + }, + "context": { + "diagnostics": [{ + "range": { + "start": { "line": 1, "character": 55 }, + "end": { "line": 1, "character": 64 } + }, + "severity": 1, + "code": 2304, + "source": "deno-ts", + "message": "Cannot find name 'DuckConfigOptions'." + }], + "only": ["quickfix"] + } + }), + ); + assert_eq!( + res, + json!([{ + "title": "Add import from \"./file01.ts\"", + "kind": "quickfix", + "diagnostics": [{ + "range": { + "start": { "line": 1, "character": 55 }, + "end": { "line": 1, "character": 64 } + }, + "severity": 1, + "code": 2304, + "source": "deno-ts", + "message": "Cannot find name 'DuckConfigOptions'." + }], + "edit": { + "documentChanges": [{ + "textDocument": { + "uri": temp_dir.uri().join("file00.ts").unwrap(), + "version": 1 + }, + "edits": [{ + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 0, "character": 0 } + }, + "newText": "import { DuckConfigOptions } from './file01.ts'\n" + }] + }] + } + }]) + ); + let res = client.write_request( + "codeAction/resolve", + json!({ + "title": "Add all missing imports", + "kind": "quickfix", + "diagnostics": [{ + "range": { + "start": { "line": 1, "character": 55 }, + "end": { "line": 1, "character": 64 } + }, + "severity": 1, + "code": 2304, + "source": "deno-ts", + "message": "Cannot find name 'DuckConfigOptions'." + }], + "data": { + "specifier": temp_dir.uri().join("file00.ts").unwrap(), + "fixId": "fixMissingImport" + } + }), + ); + assert_eq!( + res, + json!({ + "title": "Add all missing imports", + "kind": "quickfix", + "diagnostics": [{ + "range": { + "start": { "line": 1, "character": 55 }, + "end": { "line": 1, "character": 64 } + }, + "severity": 1, + "code": 2304, + "source": "deno-ts", + "message": "Cannot find name 'DuckConfigOptions'." + }], + "edit": { + "documentChanges": [{ + "textDocument": { + "uri": temp_dir.uri().join("file00.ts").unwrap(), + "version": 1 + }, + "edits": [{ + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 0, "character": 0 } + }, + "newText": "import { DuckConfigOptions } from './file01.ts'\n" + }] + }] + }, + "data": { + "specifier": temp_dir.uri().join("file00.ts").unwrap(), + "fixId": "fixMissingImport" + } + }) + ); + + client.shutdown(); +} + +#[test] +fn lsp_quote_style_from_workspace_settings() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + temp_dir.write( + "file00.ts", + r#" + export interface MallardDuckConfigOptions extends DuckConfigOptions { + kind: "mallard"; + } + "#, + ); + temp_dir.write( + "file01.ts", + r#" + export interface DuckConfigOptions { + kind: string; + quacks: boolean; + } + "#, + ); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.change_configuration(json!({ + "deno": { + "enable": true, + }, + "typescript": { + "preferences": { + "quoteStyle": "single", + }, + }, + })); + + let code_action_params = json!({ + "textDocument": { + "uri": temp_dir.uri().join("file00.ts").unwrap(), + }, + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 4, "character": 0 }, + }, + "context": { + "diagnostics": [{ + "range": { + "start": { "line": 1, "character": 56 }, + "end": { "line": 1, "character": 73 }, + }, + "severity": 1, + "code": 2304, + "source": "deno-ts", + "message": "Cannot find name 'DuckConfigOptions'.", + }], + "only": ["quickfix"], + }, + }); + + let res = + client.write_request("textDocument/codeAction", code_action_params.clone()); + // Expect single quotes in the auto-import. + assert_eq!( + res, + json!([{ + "title": "Add import from \"./file01.ts\"", + "kind": "quickfix", + "diagnostics": [{ + "range": { + "start": { "line": 1, "character": 56 }, + "end": { "line": 1, "character": 73 }, + }, + "severity": 1, + "code": 2304, + "source": "deno-ts", + "message": "Cannot find name 'DuckConfigOptions'.", + }], + "edit": { + "documentChanges": [{ + "textDocument": { + "uri": temp_dir.uri().join("file00.ts").unwrap(), + "version": null, + }, + "edits": [{ + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 0, "character": 0 }, + }, + "newText": "import { DuckConfigOptions } from './file01.ts';\n", + }], + }], + }, + }]), + ); + + // It should ignore the workspace setting if a `deno.json` is present. + temp_dir.write("./deno.json", json!({}).to_string()); + client.did_change_watched_files(json!({ + "changes": [{ + "uri": temp_dir.uri().join("deno.json").unwrap(), + "type": 1, + }], + })); + + let res = client.write_request("textDocument/codeAction", code_action_params); + // Expect double quotes in the auto-import. + assert_eq!( + res, + json!([{ + "title": "Add import from \"./file01.ts\"", + "kind": "quickfix", + "diagnostics": [{ + "range": { + "start": { "line": 1, "character": 56 }, + "end": { "line": 1, "character": 73 }, + }, + "severity": 1, + "code": 2304, + "source": "deno-ts", + "message": "Cannot find name 'DuckConfigOptions'.", + }], + "edit": { + "documentChanges": [{ + "textDocument": { + "uri": temp_dir.uri().join("file00.ts").unwrap(), + "version": null, + }, + "edits": [{ + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 0, "character": 0 }, + }, + "newText": "import { DuckConfigOptions } from \"./file01.ts\";\n", + }], + }], + }, + }]), + ); +} + +#[test] +fn lsp_code_actions_refactor_no_disabled_support() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize(|builder| { + builder.with_capabilities(|c| { + let doc = c.text_document.as_mut().unwrap(); + let code_action = doc.code_action.as_mut().unwrap(); + code_action.disabled_support = Some(false); + }); + }); + client.did_open( + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "interface A {\n a: string;\n}\n\ninterface B {\n b: string;\n}\n\nclass AB implements A, B {\n a = \"a\";\n b = \"b\";\n}\n\nnew AB().a;\n" + } + }), + ); + let res = client.write_request( + "textDocument/codeAction", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 14, "character": 0 } + }, + "context": { + "diagnostics": [], + "only": ["refactor"] + } + }), + ); + assert_eq!( + res, + json!([{ + "title": "Move to a new file", + "kind": "refactor.move.newFile", + "isPreferred": false, + "data": { + "specifier": "file:///a/file.ts", + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 14, "character": 0 } + }, + "refactorName": "Move to a new file", + "actionName": "Move to a new file" + } + }, { + "title": "Extract to function in module scope", + "kind": "refactor.extract.function", + "isPreferred": false, + "data": { + "specifier": "file:///a/file.ts", + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 14, "character": 0 } + }, + "refactorName": "Extract Symbol", + "actionName": "function_scope_0" + } + }]) + ); + client.shutdown(); +} + +#[test] +fn lsp_code_actions_deadlock() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + let large_file_text = + fs::read_to_string(testdata_path().join("lsp").join("large_file.txt")) + .unwrap(); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "javascript", + "version": 1, + "text": large_file_text, + } + })); + client.write_request( + "textDocument/semanticTokens/full", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + } + }), + ); + client.write_notification( + "textDocument/didChange", + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "version": 2 + }, + "contentChanges": [ + { + "range": { + "start": { "line": 444, "character": 11 }, + "end": { "line": 444, "character": 14 } + }, + "text": "+++" + } + ] + }), + ); + client.write_notification( + "textDocument/didChange", + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "version": 2 + }, + "contentChanges": [ + { + "range": { + "start": { "line": 445, "character": 4 }, + "end": { "line": 445, "character": 4 } + }, + "text": "// " + } + ] + }), + ); + client.write_notification( + "textDocument/didChange", + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "version": 2 + }, + "contentChanges": [ + { + "range": { + "start": { "line": 477, "character": 4 }, + "end": { "line": 477, "character": 9 } + }, + "text": "error" + } + ] + }), + ); + // diagnostics only trigger after changes have elapsed in a separate thread, + // so we need to delay the next messages a little bit to attempt to create a + // potential for a deadlock with the codeAction + std::thread::sleep(std::time::Duration::from_millis(50)); + client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + }, + "position": { "line": 609, "character": 33, } + }), + ); + client.write_request( + "textDocument/codeAction", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "range": { + "start": { "line": 441, "character": 33 }, + "end": { "line": 441, "character": 42 } + }, + "context": { + "diagnostics": [{ + "range": { + "start": { "line": 441, "character": 33 }, + "end": { "line": 441, "character": 42 } + }, + "severity": 1, + "code": 7031, + "source": "deno-ts", + "message": "Binding element 'debugFlag' implicitly has an 'any' type." + }], + "only": [ "quickfix" ] + } + }), + ); + + client.read_diagnostics(); + + client.shutdown(); +} + +#[test] +fn lsp_completions() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "Deno." + } + })); + + let list = client.get_completion_list( + "file:///a/file.ts", + (0, 5), + json!({ + "triggerKind": 2, + "triggerCharacter": "." + }), + ); + assert!(!list.is_incomplete); + assert!(list.items.len() > 90); + + let res = client.write_request( + "completionItem/resolve", + json!({ + "label": "build", + "kind": 6, + "sortText": "1", + "insertTextFormat": 1, + "data": { + "tsc": { + "specifier": "file:///a/file.ts", + "position": 5, + "name": "build", + "useCodeSnippet": false + } + } + }), + ); + assert_eq!( + res, + json!({ + "label": "build", + "kind": 6, + "detail": "const Deno.build: {\n target: string;\n arch: \"x86_64\" | \"aarch64\";\n os: \"darwin\" | \"linux\" | \"android\" | \"windows\" | \"freebsd\" | \"netbsd\" | \"aix\" | \"solaris\" | \"illumos\";\n vendor: string;\n env?: string | undefined;\n}", + "documentation": { + "kind": "markdown", + "value": "Information related to the build of the current Deno runtime.\n\nUsers are discouraged from code branching based on this information, as\nassumptions about what is available in what build environment might change\nover time. Developers should specifically sniff out the features they\nintend to use.\n\nThe intended use for the information is for logging and debugging purposes.\n\n*@category* - Runtime Environment" + }, + "sortText": "1", + "insertTextFormat": 1 + }) + ); + client.shutdown(); +} + +#[test] +fn lsp_completions_private_fields() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": r#"class Foo { #myProperty = "value"; constructor() { this.# } }"# + } + })); + let list = client.get_completion_list( + "file:///a/file.ts", + (0, 57), + json!({ "triggerKind": 1 }), + ); + assert_eq!(list.items.len(), 1); + let item = &list.items[0]; + assert_eq!(item.label, "#myProperty"); + assert!(!list.is_incomplete); + client.shutdown(); +} + +#[test] +fn lsp_completions_optional() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open( + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "interface A {\n b?: string;\n}\n\nconst o: A = {};\n\nfunction c(s: string) {}\n\nc(o.)" + } + }), + ); + let res = client.get_completion( + "file:///a/file.ts", + (8, 4), + json!({ + "triggerKind": 2, + "triggerCharacter": "." + }), + ); + assert_eq!( + json!(res), + json!({ + "isIncomplete": false, + "items": [ + { + "label": "b?", + "kind": 5, + "sortText": "11", + "filterText": "b", + "insertText": "b", + "commitCharacters": [".", ",", ";", "("], + "data": { + "tsc": { + "specifier": "file:///a/file.ts", + "position": 79, + "name": "b", + "useCodeSnippet": false + } + } + } + ] + }) + ); + let res = client.write_request( + "completionItem/resolve", + json!({ + "label": "b?", + "kind": 5, + "sortText": "1", + "filterText": "b", + "insertText": "b", + "data": { + "tsc": { + "specifier": "file:///a/file.ts", + "position": 79, + "name": "b", + "useCodeSnippet": false + } + } + }), + ); + assert_eq!( + res, + json!({ + "label": "b?", + "kind": 5, + "detail": "(property) A.b?: string | undefined", + "documentation": { + "kind": "markdown", + "value": "" + }, + "sortText": "1", + "filterText": "b", + "insertText": "b" + }) + ); + client.shutdown(); +} + +#[test] +fn lsp_completions_auto_import() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/b.ts", + "languageId": "typescript", + "version": 1, + "text": "export const foo = \"foo\";\n", + } + })); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "export {};\n\n", + } + })); + let list = client.get_completion_list( + "file:///a/file.ts", + (2, 0), + json!({ "triggerKind": 1 }), + ); + assert!(!list.is_incomplete); + let item = list.items.iter().find(|item| item.label == "foo"); + let Some(item) = item else { + panic!("completions items missing 'foo' symbol"); + }; + let mut item_value = serde_json::to_value(item).unwrap(); + item_value["data"]["tsc"]["data"]["exportMapKey"] = + serde_json::Value::String("".to_string()); + + let req = json!({ + "label": "foo", + "labelDetails": { + "description": "./b.ts", + }, + "kind": 6, + "sortText": "￿16_0", + "commitCharacters": [ + ".", + ",", + ";", + "(" + ], + "data": { + "tsc": { + "specifier": "file:///a/file.ts", + "position": 12, + "name": "foo", + "source": "./b.ts", + "data": { + "exportName": "foo", + "exportMapKey": "", + "moduleSpecifier": "./b.ts", + "fileName": "file:///a/b.ts" + }, + "useCodeSnippet": false + } + } + }); + assert_eq!(item_value, req); + + let res = client.write_request("completionItem/resolve", req); + assert_eq!( + res, + json!({ + "label": "foo", + "labelDetails": { + "description": "./b.ts", + }, + "kind": 6, + "detail": "const foo: \"foo\"", + "documentation": { + "kind": "markdown", + "value": "" + }, + "sortText": "￿16_0", + "additionalTextEdits": [ + { + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 0, "character": 0 } + }, + "newText": "import { foo } from \"./b.ts\";\n\n" + } + ] + }) + ); +} + +#[test] +fn lsp_npm_completions_auto_import_and_quick_fix_no_import_map() { + let context = TestContextBuilder::new() + .use_http_server() + .use_temp_cwd() + .build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open( + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "import {getClient} from 'npm:@denotest/types-exports-subpaths@1/client';import chalk from 'npm:chalk@5.0';\n\n", + } + }), + ); + client.write_request( + "workspace/executeCommand", + json!({ + "command": "deno.cache", + "arguments": [ + ["npm:@denotest/types-exports-subpaths@1/client", "npm:chalk@5.0"], + "file:///a/file.ts", + ], + }), + ); + + // try auto-import with path + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/a.ts", + "languageId": "typescript", + "version": 1, + "text": "getClie", + } + })); + let list = client.get_completion_list( + "file:///a/a.ts", + (0, 7), + json!({ "triggerKind": 1 }), + ); + assert!(!list.is_incomplete); + let item = list + .items + .iter() + .find(|item| item.label == "getClient") + .unwrap(); + + let res = client.write_request("completionItem/resolve", item); + assert_eq!( + res, + json!({ + "label": "getClient", + "labelDetails": { + "description": "npm:@denotest/types-exports-subpaths@1/client", + }, + "kind": 3, + "detail": "function getClient(): 5", + "documentation": { + "kind": "markdown", + "value": "" + }, + "sortText": "￿16_1", + "additionalTextEdits": [ + { + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 0, "character": 0 } + }, + "newText": "import { getClient } from \"npm:@denotest/types-exports-subpaths@1/client\";\n\n" + } + ] + }) + ); + + // try quick fix with path + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": "file:///a/b.ts", + "languageId": "typescript", + "version": 1, + "text": "getClient", + } + })); + let diagnostics = diagnostics + .messages_with_file_and_source("file:///a/b.ts", "deno-ts") + .diagnostics; + let res = client.write_request( + "textDocument/codeAction", + json!(json!({ + "textDocument": { + "uri": "file:///a/b.ts" + }, + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 0, "character": 9 } + }, + "context": { + "diagnostics": diagnostics, + "only": ["quickfix"] + } + })), + ); + assert_eq!( + res, + json!([{ + "title": "Add import from \"npm:@denotest/types-exports-subpaths@1/client\"", + "kind": "quickfix", + "diagnostics": [ + { + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 0, "character": 9 } + }, + "severity": 1, + "code": 2304, + "source": "deno-ts", + "message": "Cannot find name 'getClient'.", + } + ], + "edit": { + "documentChanges": [{ + "textDocument": { + "uri": "file:///a/b.ts", + "version": 1, + }, + "edits": [{ + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 0, "character": 0 } + }, + "newText": "import { getClient } from \"npm:@denotest/types-exports-subpaths@1/client\";\n\n" + }] + }] + } + }]) + ); + + // try auto-import without path + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/c.ts", + "languageId": "typescript", + "version": 1, + "text": "chal", + } + })); + + let list = client.get_completion_list( + "file:///a/c.ts", + (0, 4), + json!({ "triggerKind": 1 }), + ); + assert!(!list.is_incomplete); + let item = list + .items + .iter() + .find(|item| item.label == "chalk") + .unwrap(); + + let mut res = client.write_request("completionItem/resolve", item); + let obj = res.as_object_mut().unwrap(); + obj.remove("detail"); // not worth testing these + obj.remove("documentation"); + assert_eq!( + res, + json!({ + "label": "chalk", + "labelDetails": { + "description": "npm:chalk@5.0", + }, + "kind": 6, + "sortText": "￿16_1", + "additionalTextEdits": [ + { + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 0, "character": 0 } + }, + "newText": "import chalk from \"npm:chalk@5.0\";\n\n" + } + ] + }) + ); + + // try quick fix without path + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": "file:///a/d.ts", + "languageId": "typescript", + "version": 1, + "text": "chalk", + } + })); + let diagnostics = diagnostics + .messages_with_file_and_source("file:///a/d.ts", "deno-ts") + .diagnostics; + let res = client.write_request( + "textDocument/codeAction", + json!(json!({ + "textDocument": { + "uri": "file:///a/d.ts" + }, + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 0, "character": 5 } + }, + "context": { + "diagnostics": diagnostics, + "only": ["quickfix"] + } + })), + ); + assert_eq!( + res, + json!([{ + "title": "Add import from \"npm:chalk@5.0\"", + "kind": "quickfix", + "diagnostics": [ + { + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 0, "character": 5 } + }, + "severity": 1, + "code": 2304, + "source": "deno-ts", + "message": "Cannot find name 'chalk'.", + } + ], + "edit": { + "documentChanges": [{ + "textDocument": { + "uri": "file:///a/d.ts", + "version": 1, + }, + "edits": [{ + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 0, "character": 0 } + }, + "newText": "import chalk from \"npm:chalk@5.0\";\n\n" + }] + }] + } + }]) + ); +} + +#[test] +fn lsp_semantic_tokens_for_disabled_module() { + let context = TestContextBuilder::new() + .use_http_server() + .use_temp_cwd() + .build(); + let mut client = context.new_lsp_command().build(); + client.initialize_with_config( + |builder| { + builder.set_deno_enable(false); + }, + json!({ "deno": { + "enable": false + } }), + ); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "const someConst = 1; someConst" + } + })); + let res = client.write_request( + "textDocument/semanticTokens/full", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + } + }), + ); + assert_eq!( + res, + json!({ + "data": [0, 6, 9, 7, 9, 0, 15, 9, 7, 8], + }) + ); +} + +#[test] +fn lsp_completions_auto_import_and_quick_fix_with_import_map() { + let context = TestContextBuilder::new() + .use_http_server() + .use_temp_cwd() + .build(); + let temp_dir = context.temp_dir(); + let import_map = r#"{ + "imports": { + "print_hello": "http://localhost:4545/subdir/print_hello.ts", + "chalk": "npm:chalk@~5", + "nested/": "npm:/@denotest/types-exports-subpaths@1/nested/", + "types-exports-subpaths/": "npm:/@denotest/types-exports-subpaths@1/" + } + }"#; + temp_dir.write("import_map.json", import_map); + + let mut client = context.new_lsp_command().build(); + client.initialize(|builder| { + builder.set_import_map("import_map.json"); + }); + client.did_open( + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": concat!( + "import {getClient} from 'npm:@denotest/types-exports-subpaths@1/client';\n", + "import _test1 from 'npm:chalk@^5.0';\n", + "import chalk from 'npm:chalk@~5';\n", + "import chalk from 'npm:chalk@~5';\n", + "import {entryB} from 'npm:@denotest/types-exports-subpaths@1/nested/entry-b';\n", + "import {printHello} from 'print_hello';\n", + "\n", + ), + } + }), + ); + client.write_request( + "workspace/executeCommand", + json!({ + "command": "deno.cache", + "arguments": [ + [ + "npm:@denotest/types-exports-subpaths@1/client", + "npm:@denotest/types-exports-subpaths@1/nested/entry-b", + "npm:chalk@^5.0", + "npm:chalk@~5", + "http://localhost:4545/subdir/print_hello.ts", + ], + "file:///a/file.ts", + ], + }), + ); + + // try auto-import with path + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/a.ts", + "languageId": "typescript", + "version": 1, + "text": "getClie", + } + })); + let list = client.get_completion_list( + "file:///a/a.ts", + (0, 7), + json!({ "triggerKind": 1 }), + ); + assert!(!list.is_incomplete); + let item = list + .items + .iter() + .find(|item| item.label == "getClient") + .unwrap(); + + let res = client.write_request("completionItem/resolve", item); + assert_eq!( + res, + json!({ + "label": "getClient", + "labelDetails": { + "description": "types-exports-subpaths/client", + }, + "kind": 3, + "detail": "function getClient(): 5", + "documentation": { + "kind": "markdown", + "value": "" + }, + "sortText": "￿16_0", + "additionalTextEdits": [ + { + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 0, "character": 0 } + }, + "newText": "import { getClient } from \"types-exports-subpaths/client\";\n\n" + } + ] + }) + ); + + // try quick fix with path + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": "file:///a/b.ts", + "languageId": "typescript", + "version": 1, + "text": "getClient", + } + })); + let diagnostics = diagnostics + .messages_with_file_and_source("file:///a/b.ts", "deno-ts") + .diagnostics; + let res = client.write_request( + "textDocument/codeAction", + json!(json!({ + "textDocument": { + "uri": "file:///a/b.ts" + }, + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 0, "character": 9 } + }, + "context": { + "diagnostics": diagnostics, + "only": ["quickfix"] + } + })), + ); + assert_eq!( + res, + json!([{ + "title": "Add import from \"types-exports-subpaths/client\"", + "kind": "quickfix", + "diagnostics": [ + { + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 0, "character": 9 } + }, + "severity": 1, + "code": 2304, + "source": "deno-ts", + "message": "Cannot find name 'getClient'.", + } + ], + "edit": { + "documentChanges": [{ + "textDocument": { + "uri": "file:///a/b.ts", + "version": 1, + }, + "edits": [{ + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 0, "character": 0 } + }, + "newText": "import { getClient } from \"types-exports-subpaths/client\";\n\n" + }] + }] + } + }]) + ); + + // try auto-import without path + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/c.ts", + "languageId": "typescript", + "version": 1, + "text": "chal", + } + })); + + let list = client.get_completion_list( + "file:///a/c.ts", + (0, 4), + json!({ "triggerKind": 1 }), + ); + assert!(!list.is_incomplete); + let item = list + .items + .iter() + .find(|item| item.label == "chalk") + .unwrap(); + + let mut res = client.write_request("completionItem/resolve", item); + let obj = res.as_object_mut().unwrap(); + obj.remove("detail"); // not worth testing these + obj.remove("documentation"); + assert_eq!( + res, + json!({ + "label": "chalk", + "labelDetails": { + "description": "chalk", + }, + "kind": 6, + "sortText": "￿16_0", + "additionalTextEdits": [ + { + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 0, "character": 0 } + }, + "newText": "import chalk from \"chalk\";\n\n" + } + ] + }) + ); + + // try quick fix without path + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": "file:///a/d.ts", + "languageId": "typescript", + "version": 1, + "text": "chalk", + } + })); + let diagnostics = diagnostics + .messages_with_file_and_source("file:///a/d.ts", "deno-ts") + .diagnostics; + let res = client.write_request( + "textDocument/codeAction", + json!(json!({ + "textDocument": { + "uri": "file:///a/d.ts" + }, + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 0, "character": 5 } + }, + "context": { + "diagnostics": diagnostics, + "only": ["quickfix"] + } + })), + ); + assert_eq!( + res, + json!([{ + "title": "Add import from \"chalk\"", + "kind": "quickfix", + "diagnostics": [ + { + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 0, "character": 5 } + }, + "severity": 1, + "code": 2304, + "source": "deno-ts", + "message": "Cannot find name 'chalk'.", + } + ], + "edit": { + "documentChanges": [{ + "textDocument": { + "uri": "file:///a/d.ts", + "version": 1, + }, + "edits": [{ + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 0, "character": 0 } + }, + "newText": "import chalk from \"chalk\";\n\n" + }] + }] + } + }]) + ); + + // try auto-import with http import map + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/e.ts", + "languageId": "typescript", + "version": 1, + "text": "printH", + } + })); + + let list = client.get_completion_list( + "file:///a/e.ts", + (0, 6), + json!({ "triggerKind": 1 }), + ); + assert!(!list.is_incomplete); + let item = list + .items + .iter() + .find(|item| item.label == "printHello") + .unwrap(); + + let mut res = client.write_request("completionItem/resolve", item); + let obj = res.as_object_mut().unwrap(); + obj.remove("detail"); // not worth testing these + obj.remove("documentation"); + assert_eq!( + res, + json!({ + "label": "printHello", + "labelDetails": { + "description": "print_hello", + }, + "kind": 3, + "sortText": "￿16_0", + "additionalTextEdits": [ + { + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 0, "character": 0 } + }, + "newText": "import { printHello } from \"print_hello\";\n\n" + } + ] + }) + ); + + // try quick fix with http import + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": "file:///a/f.ts", + "languageId": "typescript", + "version": 1, + "text": "printHello", + } + })); + let diagnostics = diagnostics + .messages_with_file_and_source("file:///a/f.ts", "deno-ts") + .diagnostics; + let res = client.write_request( + "textDocument/codeAction", + json!(json!({ + "textDocument": { + "uri": "file:///a/f.ts" + }, + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 0, "character": 10 } + }, + "context": { + "diagnostics": diagnostics, + "only": ["quickfix"] + } + })), + ); + assert_eq!( + res, + json!([{ + "title": "Add import from \"print_hello\"", + "kind": "quickfix", + "diagnostics": [ + { + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 0, "character": 10 } + }, + "severity": 1, + "code": 2304, + "source": "deno-ts", + "message": "Cannot find name 'printHello'.", + } + ], + "edit": { + "documentChanges": [{ + "textDocument": { + "uri": "file:///a/f.ts", + "version": 1, + }, + "edits": [{ + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 0, "character": 0 } + }, + "newText": "import { printHello } from \"print_hello\";\n\n" + }] + }] + } + }]) + ); + + // try auto-import with npm package with sub-path on value side of import map + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/nested_path.ts", + "languageId": "typescript", + "version": 1, + "text": "entry", + } + })); + let list = client.get_completion_list( + "file:///a/nested_path.ts", + (0, 5), + json!({ "triggerKind": 1 }), + ); + assert!(!list.is_incomplete); + let item = list + .items + .iter() + .find(|item| item.label == "entryB") + .unwrap(); + + let res = client.write_request("completionItem/resolve", item); + assert_eq!( + res, + json!({ + "label": "entryB", + "labelDetails": { + "description": "nested/entry-b", + }, + "kind": 3, + "detail": "function entryB(): \"b\"", + "documentation": { + "kind": "markdown", + "value": "" + }, + "sortText": "￿16_0", + "additionalTextEdits": [ + { + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 0, "character": 0 } + }, + "newText": "import { entryB } from \"nested/entry-b\";\n\n" + } + ] + }) + ); +} + +#[test] +fn lsp_completions_snippet() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open( + json!({ + "textDocument": { + "uri": "file:///a/a.tsx", + "languageId": "typescriptreact", + "version": 1, + "text": "function A({ type }: { type: string }) {\n return type;\n}\n\nfunction B() {\n return >(); + assert_eq!( + json!(non_existent_diagnostics), + json!([ + { + "range": { + "start": { "line": 0, "character": 15 }, + "end": { "line": 0, "character": 34 }, + }, + "severity": 1, + "code": "resolver-error", + "source": "deno", + "message": "Unknown Node built-in module: non-existent" + } + ]) + ); + + // update to have fs import + client.write_notification( + "textDocument/didChange", + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "version": 2 + }, + "contentChanges": [ + { + "range": { + "start": { "line": 0, "character": 16 }, + "end": { "line": 0, "character": 33 }, + }, + "text": "fs" + } + ] + }), + ); + let diagnostics = client.read_diagnostics(); + let diagnostics = diagnostics + .messages_with_file_and_source("file:///a/file.ts", "deno") + .diagnostics + .into_iter() + .filter(|d| { + d.code + == Some(lsp::NumberOrString::String( + "import-node-prefix-missing".to_string(), + )) + }) + .collect::>(); + + // get the quick fixes + let res = client.write_request( + "textDocument/codeAction", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "range": { + "start": { "line": 0, "character": 16 }, + "end": { "line": 0, "character": 18 }, + }, + "context": { + "diagnostics": json!(diagnostics), + "only": ["quickfix"] + } + }), + ); + assert_eq!( + res, + json!([{ + "title": "Update specifier to node:fs", + "kind": "quickfix", + "diagnostics": [ + { + "range": { + "start": { "line": 0, "character": 15 }, + "end": { "line": 0, "character": 19 } + }, + "severity": 1, + "code": "import-node-prefix-missing", + "source": "deno", + "message": "Relative import path \"fs\" not prefixed with / or ./ or ../\nIf you want to use a built-in Node module, add a \"node:\" prefix (ex. \"node:fs\").", + "data": { + "specifier": "fs" + }, + } + ], + "edit": { + "changes": { + "file:///a/file.ts": [ + { + "range": { + "start": { "line": 0, "character": 15 }, + "end": { "line": 0, "character": 19 } + }, + "newText": "\"node:fs\"" + } + ] + } + } + }]) + ); + + // update to have node:fs import + client.write_notification( + "textDocument/didChange", + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "version": 3, + }, + "contentChanges": [ + { + "range": { + "start": { "line": 0, "character": 15 }, + "end": { "line": 0, "character": 19 }, + }, + "text": "\"node:fs\"", + } + ] + }), + ); + + let diagnostics = client.read_diagnostics(); + let cache_diagnostics = diagnostics + .messages_with_file_and_source("file:///a/file.ts", "deno") + .diagnostics + .into_iter() + .filter(|d| { + d.code == Some(lsp::NumberOrString::String("no-cache-npm".to_string())) + }) + .collect::>(); + + assert_eq!( + json!(cache_diagnostics), + json!([ + { + "range": { + "start": { "line": 0, "character": 15 }, + "end": { "line": 0, "character": 24 } + }, + "data": { + "specifier": "npm:@types/node", + }, + "severity": 1, + "code": "no-cache-npm", + "source": "deno", + "message": "Uncached or missing npm package: @types/node" + } + ]) + ); + + client.write_request( + "workspace/executeCommand", + json!({ + "command": "deno.cache", + "arguments": [["npm:@types/node"], "file:///a/file.ts"], + }), + ); + + client.write_notification( + "textDocument/didChange", + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "version": 4 + }, + "contentChanges": [ + { + "range": { + "start": { "line": 2, "character": 0 }, + "end": { "line": 2, "character": 0 } + }, + "text": "fs." + } + ] + }), + ); + client.read_diagnostics(); + + let list = client.get_completion_list( + "file:///a/file.ts", + (2, 3), + json!({ + "triggerKind": 2, + "triggerCharacter": "." + }), + ); + assert!(!list.is_incomplete); + assert!(list.items.iter().any(|i| i.label == "writeFile")); + assert!(list.items.iter().any(|i| i.label == "writeFileSync")); + + client.shutdown(); +} + +#[test] +fn lsp_completions_registry() { + let context = TestContextBuilder::new() + .use_http_server() + .use_temp_cwd() + .build(); + let mut client = context.new_lsp_command().build(); + client.initialize(|builder| { + builder.add_test_server_suggestions(); + }); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "import * as a from \"http://localhost:4545/x/a@\"" + } + })); + let list = client.get_completion_list( + "file:///a/file.ts", + (0, 46), + json!({ + "triggerKind": 2, + "triggerCharacter": "@" + }), + ); + assert!(!list.is_incomplete); + assert_eq!(list.items.len(), 3); + + let res = client.write_request( + "completionItem/resolve", + json!({ + "label": "v2.0.0", + "kind": 19, + "detail": "(version)", + "sortText": "0000000003", + "filterText": "http://localhost:4545/x/a@v2.0.0", + "textEdit": { + "range": { + "start": { "line": 0, "character": 20 }, + "end": { "line": 0, "character": 46 } + }, + "newText": "http://localhost:4545/x/a@v2.0.0" + } + }), + ); + assert_eq!( + res, + json!({ + "label": "v2.0.0", + "kind": 19, + "detail": "(version)", + "sortText": "0000000003", + "filterText": "http://localhost:4545/x/a@v2.0.0", + "textEdit": { + "range": { + "start": { "line": 0, "character": 20 }, + "end": { "line": 0, "character": 46 } + }, + "newText": "http://localhost:4545/x/a@v2.0.0" + } + }) + ); + client.shutdown(); +} + +#[test] +fn lsp_completions_registry_empty() { + let context = TestContextBuilder::new() + .use_http_server() + .use_temp_cwd() + .build(); + let mut client = context.new_lsp_command().build(); + client.initialize(|builder| { + builder.add_test_server_suggestions(); + }); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "import * as a from \"\"" + } + })); + let res = client.get_completion( + "file:///a/file.ts", + (0, 20), + json!({ + "triggerKind": 2, + "triggerCharacter": "\"" + }), + ); + assert_eq!( + json!(res), + json!({ + "isIncomplete": false, + "items": [{ + "label": ".", + "kind": 19, + "detail": "(local)", + "sortText": "1", + "insertText": ".", + "commitCharacters": ["\"", "'"] + }, { + "label": "..", + "kind": 19, + "detail": "(local)", + "sortText": "1", + "insertText": "..", + "commitCharacters": ["\"", "'" ] + }, { + "label": "http://localhost:4545", + "kind": 19, + "detail": "(registry)", + "sortText": "2", + "textEdit": { + "range": { + "start": { "line": 0, "character": 20 }, + "end": { "line": 0, "character": 20 } + }, + "newText": "http://localhost:4545" + }, + "commitCharacters": ["\"", "'"] + }] + }) + ); + client.shutdown(); +} + +#[test] +fn lsp_auto_discover_registry() { + let context = TestContextBuilder::new() + .use_http_server() + .use_temp_cwd() + .build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "import * as a from \"http://localhost:4545/x/a@\"" + } + })); + client.get_completion( + "file:///a/file.ts", + (0, 46), + json!({ + "triggerKind": 2, + "triggerCharacter": "@" + }), + ); + let (method, res) = client.read_notification(); + assert_eq!(method, "deno/registryState"); + assert_eq!( + res, + Some(json!({ + "origin": "http://localhost:4545", + "suggestions": true, + })) + ); + client.shutdown(); +} + +#[test] +fn lsp_cache_location() { + let context = TestContextBuilder::new() + .use_http_server() + .use_temp_cwd() + .build(); + let temp_dir = context.temp_dir(); + let mut client = context.new_lsp_command().build(); + client.initialize(|builder| { + builder.set_cache(".cache").add_test_server_suggestions(); + }); + + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file_01.ts", + "languageId": "typescript", + "version": 1, + "text": "export const a = \"a\";\n", + } + })); + let diagnostics = + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "import * as a from \"http://127.0.0.1:4545/xTypeScriptTypes.js\";\n// @deno-types=\"http://127.0.0.1:4545/type_definitions/foo.d.ts\"\nimport * as b from \"http://127.0.0.1:4545/type_definitions/foo.js\";\nimport * as c from \"http://127.0.0.1:4545/subdir/type_reference.js\";\nimport * as d from \"http://127.0.0.1:4545/subdir/mod1.ts\";\nimport * as e from \"data:application/typescript;base64,ZXhwb3J0IGNvbnN0IGEgPSAiYSI7CgpleHBvcnQgZW51bSBBIHsKICBBLAogIEIsCiAgQywKfQo=\";\nimport * as f from \"./file_01.ts\";\nimport * as g from \"http://localhost:4545/x/a/mod.ts\";\n\nconsole.log(a, b, c, d, e, f, g);\n" + } + })); + assert_eq!(diagnostics.all().len(), 6); + client.write_request( + "workspace/executeCommand", + json!({ + "command": "deno.cache", + "arguments": [[], "file:///a/file.ts"], + }), + ); + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + }, + "position": { "line": 0, "character": 28 } + }), + ); + assert_eq!( + res, + json!({ + "contents": { + "kind": "markdown", + "value": "**Resolved Dependency**\n\n**Code**: http​://127.0.0.1:4545/xTypeScriptTypes.js\n\n**Types**: http​://127.0.0.1:4545/xTypeScriptTypes.d.ts\n" + }, + "range": { + "start": { "line": 0, "character": 19 }, + "end": { "line": 0, "character": 62 } + } + }) + ); + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + }, + "position": { "line": 7, "character": 28 } + }), + ); + assert_eq!( + res, + json!({ + "contents": { + "kind": "markdown", + "value": "**Resolved Dependency**\n\n**Code**: http​://localhost:4545/x/a/mod.ts\n\n\n---\n\n**a**\n\nmod.ts" + }, + "range": { + "start": { "line": 7, "character": 19 }, + "end": { "line": 7, "character": 53 } + } + }) + ); + let cache_path = temp_dir.path().join(".cache"); + assert!(cache_path.is_dir()); + assert!(!cache_path.join("gen").is_dir()); // not created because no emitting has occurred + client.shutdown(); +} + +/// Sets the TLS root certificate on startup, which allows the LSP to connect to +/// the custom signed test server and be able to retrieve the registry config +/// and cache files. +#[test] +fn lsp_tls_cert() { + let context = TestContextBuilder::new() + .use_http_server() + .use_temp_cwd() + .build(); + let mut client = context.new_lsp_command().build(); + client.initialize(|builder| { + builder + .set_suggest_imports_hosts(vec![ + ("http://localhost:4545/".to_string(), true), + ("https://localhost:5545/".to_string(), true), + ]) + .set_tls_certificate(""); + }); + + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file_01.ts", + "languageId": "typescript", + "version": 1, + "text": "export const a = \"a\";\n", + } + })); + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "import * as a from \"https://localhost:5545/xTypeScriptTypes.js\";\n// @deno-types=\"https://localhost:5545/type_definitions/foo.d.ts\"\nimport * as b from \"https://localhost:5545/type_definitions/foo.js\";\nimport * as c from \"https://localhost:5545/subdir/type_reference.js\";\nimport * as d from \"https://localhost:5545/subdir/mod1.ts\";\nimport * as e from \"data:application/typescript;base64,ZXhwb3J0IGNvbnN0IGEgPSAiYSI7CgpleHBvcnQgZW51bSBBIHsKICBBLAogIEIsCiAgQywKfQo=\";\nimport * as f from \"./file_01.ts\";\nimport * as g from \"http://localhost:4545/x/a/mod.ts\";\n\nconsole.log(a, b, c, d, e, f, g);\n" + } + })); + let diagnostics = diagnostics.all(); + assert_eq!(diagnostics.len(), 6); + client.write_request( + "workspace/executeCommand", + json!({ + "command": "deno.cache", + "arguments": [[], "file:///a/file.ts"], + }), + ); + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + }, + "position": { "line": 0, "character": 28 } + }), + ); + assert_eq!( + res, + json!({ + "contents": { + "kind": "markdown", + "value": "**Resolved Dependency**\n\n**Code**: https​://localhost:5545/xTypeScriptTypes.js\n" + }, + "range": { + "start": { "line": 0, "character": 19 }, + "end": { "line": 0, "character": 63 } + } + }) + ); + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + }, + "position": { "line": 7, "character": 28 } + }), + ); + assert_eq!( + res, + json!({ + "contents": { + "kind": "markdown", + "value": "**Resolved Dependency**\n\n**Code**: http​://localhost:4545/x/a/mod.ts\n\n\n---\n\n**a**\n\nmod.ts" + }, + "range": { + "start": { "line": 7, "character": 19 }, + "end": { "line": 7, "character": 53 } + } + }) + ); + client.shutdown(); +} + +#[test] +fn lsp_diagnostics_warn_redirect() { + let context = TestContextBuilder::new() + .use_http_server() + .use_temp_cwd() + .build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open( + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "import * as a from \"http://127.0.0.1:4545/x_deno_warning.js\";\n\nconsole.log(a)\n", + }, + }), + ); + client.write_request( + "workspace/executeCommand", + json!({ + "command": "deno.cache", + "arguments": [ + ["http://127.0.0.1:4545/x_deno_warning.js"], + "file:///a/file.ts", + ], + }), + ); + let diagnostics = client.read_diagnostics(); + assert_eq!( + diagnostics.messages_with_source("deno"), + lsp::PublishDiagnosticsParams { + uri: Url::parse("file:///a/file.ts").unwrap(), + diagnostics: vec![ + lsp::Diagnostic { + range: lsp::Range { + start: lsp::Position { + line: 0, + character: 19 + }, + end: lsp::Position { + line: 0, + character: 60 + } + }, + severity: Some(lsp::DiagnosticSeverity::WARNING), + code: Some(lsp::NumberOrString::String("deno-warn".to_string())), + source: Some("deno".to_string()), + message: "foobar".to_string(), + ..Default::default() + }, + lsp::Diagnostic { + range: lsp::Range { + start: lsp::Position { + line: 0, + character: 19 + }, + end: lsp::Position { + line: 0, + character: 60 + } + }, + severity: Some(lsp::DiagnosticSeverity::INFORMATION), + code: Some(lsp::NumberOrString::String("redirect".to_string())), + source: Some("deno".to_string()), + message: "The import of \"http://127.0.0.1:4545/x_deno_warning.js\" was redirected to \"http://127.0.0.1:4545/lsp/x_deno_warning_redirect.js\".".to_string(), + data: Some(json!({"specifier": "http://127.0.0.1:4545/x_deno_warning.js", "redirect": "http://127.0.0.1:4545/lsp/x_deno_warning_redirect.js"})), + ..Default::default() + } + ], + version: Some(1), + } + ); + client.shutdown(); +} + +#[test] +fn lsp_redirect_quick_fix() { + let context = TestContextBuilder::new() + .use_http_server() + .use_temp_cwd() + .build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open( + json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "import * as a from \"http://127.0.0.1:4545/x_deno_warning.js\";\n\nconsole.log(a)\n", + }, + }), + ); + client.write_request( + "workspace/executeCommand", + json!({ + "command": "deno.cache", + "arguments": [ + ["http://127.0.0.1:4545/x_deno_warning.js"], + "file:///a/file.ts", + ], + }), + ); + let diagnostics = client + .read_diagnostics() + .messages_with_source("deno") + .diagnostics; + let res = client.write_request( + "textDocument/codeAction", + json!(json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "range": { + "start": { "line": 0, "character": 19 }, + "end": { "line": 0, "character": 60 } + }, + "context": { + "diagnostics": diagnostics, + "only": ["quickfix"] + } + })), + ); + assert_eq!( + res, + json!([{ + "title": "Update specifier to its redirected specifier.", + "kind": "quickfix", + "diagnostics": [ + { + "range": { + "start": { "line": 0, "character": 19 }, + "end": { "line": 0, "character": 60 } + }, + "severity": 3, + "code": "redirect", + "source": "deno", + "message": "The import of \"http://127.0.0.1:4545/x_deno_warning.js\" was redirected to \"http://127.0.0.1:4545/lsp/x_deno_warning_redirect.js\".", + "data": { + "specifier": "http://127.0.0.1:4545/x_deno_warning.js", + "redirect": "http://127.0.0.1:4545/lsp/x_deno_warning_redirect.js" + } + } + ], + "edit": { + "changes": { + "file:///a/file.ts": [ + { + "range": { + "start": { "line": 0, "character": 19 }, + "end": { "line": 0, "character": 60 } + }, + "newText": "\"http://127.0.0.1:4545/lsp/x_deno_warning_redirect.js\"" + } + ] + } + } + }]) + ); + client.shutdown(); +} + +#[test] +fn lsp_diagnostics_deprecated() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "/** @deprecated */\nexport const a = \"a\";\n\na;\n", + }, + })); + assert_eq!( + json!(diagnostics.all_messages()), + json!([{ + "uri": "file:///a/file.ts", + "diagnostics": [ + { + "range": { + "start": { "line": 3, "character": 0 }, + "end": { "line": 3, "character": 1 } + }, + "severity": 4, + "code": 6385, + "source": "deno-ts", + "message": "'a' is deprecated.", + "relatedInformation": [ + { + "location": { + "uri": "file:///a/file.ts", + "range": { + "start": { + "line": 0, + "character": 4, + }, + "end": { + "line": 0, + "character": 16, + }, + }, + }, + "message": "The declaration was marked as deprecated here.", + }, + ], + "tags": [2] + } + ], + "version": 1 + }]) + ); + client.shutdown(); +} + +#[test] +fn lsp_diagnostics_deno_types() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + let diagnostics = client + .did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "/// \n/// , +} + +#[test] +fn lsp_performance() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "console.log(Deno.args);\n" + } + })); + client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "position": { "line": 0, "character": 19 } + }), + ); + let res = client.write_request_with_res_as::( + "deno/performance", + json!(null), + ); + let mut averages = res + .averages + .iter() + .map(|a| a.name.as_str()) + .collect::>(); + averages.sort(); + assert_eq!( + averages, + vec![ + "lsp.did_open", + "lsp.hover", + "lsp.initialize", + "lsp.testing_update", + "lsp.update_cache", + "lsp.update_diagnostics_deps", + "lsp.update_diagnostics_lint", + "lsp.update_diagnostics_ts", + "lsp.update_import_map", + "lsp.update_registries", + "lsp.update_tsconfig", + "tsc.host.$configure", + "tsc.host.$getAssets", + "tsc.host.$getDiagnostics", + "tsc.host.$getSupportedCodeFixes", + "tsc.host.getQuickInfoAtPosition", + "tsc.op.op_is_node_file", + "tsc.op.op_load", + "tsc.op.op_project_version", + "tsc.op.op_script_names", + "tsc.op.op_script_version", + "tsc.request.$configure", + "tsc.request.$getAssets", + "tsc.request.$getSupportedCodeFixes", + "tsc.request.getQuickInfoAtPosition", + ] + ); + client.shutdown(); +} + +#[test] +fn lsp_format_no_changes() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "console;\n" + } + })); + let res = client.write_request( + "textDocument/formatting", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "options": { + "tabSize": 2, + "insertSpaces": true + } + }), + ); + assert_eq!(res, json!(null)); + client.assert_no_notification("window/showMessage"); + client.shutdown(); +} + +#[test] +fn lsp_format_error() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "console test test\n" + } + })); + let res = client.write_request( + "textDocument/formatting", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "options": { + "tabSize": 2, + "insertSpaces": true + } + }), + ); + assert_eq!(res, json!(null)); + client.shutdown(); +} + +#[test] +fn lsp_format_mbc() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "const bar = '👍🇺🇸😃'\nconsole.log('hello deno')\n" + } + })); + let res = client.write_request( + "textDocument/formatting", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "options": { + "tabSize": 2, + "insertSpaces": true + } + }), + ); + assert_eq!( + res, + json!([{ + "range": { + "start": { "line": 0, "character": 12 }, + "end": { "line": 0, "character": 13 } + }, + "newText": "\"" + }, { + "range": { + "start": { "line": 0, "character": 21 }, + "end": { "line": 0, "character": 22 } + }, + "newText": "\";" + }, { + "range": { + "start": { "line": 1, "character": 12 }, + "end": { "line": 1, "character": 13 } + }, + "newText": "\"" + }, { + "range": { + "start": { "line": 1, "character": 23 }, + "end": { "line": 1, "character": 25 } + }, + "newText": "\");" + }]) + ); + client.shutdown(); +} + +#[test] +fn lsp_format_exclude_with_config() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + + temp_dir.write( + "deno.fmt.jsonc", + r#"{ + "fmt": { + "files": { + "exclude": ["ignored.ts"] + }, + "options": { + "useTabs": true, + "lineWidth": 40, + "indentWidth": 8, + "singleQuote": true, + "proseWrap": "always" + } + } + }"#, + ); + + let mut client = context.new_lsp_command().build(); + client.initialize(|builder| { + builder.set_config("./deno.fmt.jsonc"); + }); + + let file_uri = temp_dir.uri().join("ignored.ts").unwrap(); + client.did_open(json!({ + "textDocument": { + "uri": file_uri, + "languageId": "typescript", + "version": 1, + "text": "function myFunc(){}" + } + })); + let res = client.write_request( + "textDocument/formatting", + json!({ + "textDocument": { + "uri": file_uri + }, + "options": { + "tabSize": 2, + "insertSpaces": true + } + }), + ); + assert_eq!(res, json!(null)); + client.shutdown(); +} + +#[test] +fn lsp_format_exclude_default_config() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + + temp_dir.write( + "deno.fmt.jsonc", + r#"{ + "fmt": { + "files": { + "exclude": ["ignored.ts"] + }, + "options": { + "useTabs": true, + "lineWidth": 40, + "indentWidth": 8, + "singleQuote": true, + "proseWrap": "always" + } + } + }"#, + ); + + let mut client = context.new_lsp_command().build(); + client.initialize(|builder| { + builder.set_config("./deno.fmt.jsonc"); + }); + + let file_uri = temp_dir.uri().join("ignored.ts").unwrap(); + client.did_open(json!({ + "textDocument": { + "uri": file_uri, + "languageId": "typescript", + "version": 1, + "text": "function myFunc(){}" + } + })); + let res = client.write_request( + "textDocument/formatting", + json!({ + "textDocument": { + "uri": file_uri + }, + "options": { + "tabSize": 2, + "insertSpaces": true + } + }), + ); + assert_eq!(res, json!(null)); + client.shutdown(); +} + +#[test] +fn lsp_format_json() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir_path = context.temp_dir().path(); + // Also test out using a non-json file extension here. + // What should matter is the language identifier. + let lock_file_path = temp_dir_path.join("file.lock"); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": lock_file_path.uri_file(), + "languageId": "json", + "version": 1, + "text": "{\"key\":\"value\"}" + } + })); + + let res = client.write_request( + "textDocument/formatting", + json!({ + "textDocument": { + "uri": lock_file_path.uri_file(), + }, + "options": { + "tabSize": 2, + "insertSpaces": true + } + }), + ); + + assert_eq!( + res, + json!([ + { + "range": { + "start": { "line": 0, "character": 1 }, + "end": { "line": 0, "character": 1 } + }, + "newText": " " + }, { + "range": { + "start": { "line": 0, "character": 7 }, + "end": { "line": 0, "character": 7 } + }, + "newText": " " + }, { + "range": { + "start": { "line": 0, "character": 14 }, + "end": { "line": 0, "character": 15 } + }, + "newText": " }\n" + } + ]) + ); + client.shutdown(); +} + +#[test] +fn lsp_json_no_diagnostics() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.json", + "languageId": "json", + "version": 1, + "text": "{\"key\":\"value\"}" + } + })); + + let res = client.write_request( + "textDocument/semanticTokens/full", + json!({ + "textDocument": { + "uri": "file:///a/file.json" + } + }), + ); + assert_eq!(res, json!(null)); + + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": "file:///a/file.json" + }, + "position": { "line": 0, "character": 3 } + }), + ); + assert_eq!(res, json!(null)); + + client.shutdown(); +} + +#[test] +fn lsp_json_import_with_query_string() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + temp_dir.write("data.json", r#"{"k": "v"}"#); + temp_dir.write( + "main.ts", + r#" + import data from "./data.json?1" with { type: "json" }; + console.log(data); + "#, + ); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": temp_dir.uri().join("data.json").unwrap(), + "languageId": "json", + "version": 1, + "text": temp_dir.read_to_string("data.json"), + } + })); + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": temp_dir.uri().join("main.ts").unwrap(), + "languageId": "typescript", + "version": 1, + "text": temp_dir.read_to_string("main.ts"), + } + })); + assert_eq!(diagnostics.all(), vec![]); + client.shutdown(); +} + +#[test] +fn lsp_format_markdown() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let markdown_file = context.temp_dir().path().join("file.md"); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": markdown_file.uri_file(), + "languageId": "markdown", + "version": 1, + "text": "# Hello World" + } + })); + + let res = client.write_request( + "textDocument/formatting", + json!({ + "textDocument": { + "uri": markdown_file.uri_file() + }, + "options": { + "tabSize": 2, + "insertSpaces": true + } + }), + ); + + assert_eq!( + res, + json!([ + { + "range": { + "start": { "line": 0, "character": 1 }, + "end": { "line": 0, "character": 3 } + }, + "newText": "" + }, { + "range": { + "start": { "line": 0, "character": 15 }, + "end": { "line": 0, "character": 15 } + }, + "newText": "\n" + } + ]) + ); + client.shutdown(); +} + +#[test] +fn lsp_format_with_config() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + temp_dir.write( + "deno.fmt.jsonc", + r#"{ + "fmt": { + "options": { + "useTabs": true, + "lineWidth": 40, + "indentWidth": 8, + "singleQuote": true, + "proseWrap": "always" + } + } + } + "#, + ); + + let mut client = context.new_lsp_command().build(); + client.initialize(|builder| { + builder.set_config("./deno.fmt.jsonc"); + }); + + let ts_file = temp_dir.path().join("file.ts"); + client + .did_open( + json!({ + "textDocument": { + "uri": ts_file.uri_file(), + "languageId": "typescript", + "version": 1, + "text": "export async function someVeryLongFunctionName() {\nconst response = fetch(\"http://localhost:4545/some/non/existent/path.json\");\nconsole.log(response.text());\nconsole.log(\"finished!\")\n}" + } + }), + ); + + // The options below should be ignored in favor of configuration from config file. + let res = client.write_request( + "textDocument/formatting", + json!({ + "textDocument": { + "uri": ts_file.uri_file() + }, + "options": { + "tabSize": 2, + "insertSpaces": true + } + }), + ); + + assert_eq!( + res, + json!([{ + "range": { + "start": { "line": 1, "character": 0 }, + "end": { "line": 1, "character": 0 } + }, + "newText": "\t" + }, { + "range": { + "start": { "line": 1, "character": 23 }, + "end": { "line": 1, "character": 24 } + }, + "newText": "\n\t\t'" + }, { + "range": { + "start": { "line": 1, "character": 73 }, + "end": { "line": 1, "character": 74 } + }, + "newText": "',\n\t" + }, { + "range": { + "start": { "line": 2, "character": 0 }, + "end": { "line": 2, "character": 0 } + }, + "newText": "\t" + }, { + "range": { + "start": { "line": 3, "character": 0 }, + "end": { "line": 3, "character": 0 } + }, + "newText": "\t" + }, { + "range": { + "start": { "line": 3, "character": 12 }, + "end": { "line": 3, "character": 13 } + }, + "newText": "'" + }, { + "range": { + "start": { "line": 3, "character": 22 }, + "end": { "line": 3, "character": 24 } + }, + "newText": "');" + }, { + "range": { + "start": { "line": 4, "character": 1 }, + "end": { "line": 4, "character": 1 } + }, + "newText": "\n" + }] + ) + ); + client.shutdown(); +} + +#[test] +fn lsp_markdown_no_diagnostics() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.md", + "languageId": "markdown", + "version": 1, + "text": "# Hello World" + } + })); + + let res = client.write_request( + "textDocument/semanticTokens/full", + json!({ + "textDocument": { + "uri": "file:///a/file.md" + } + }), + ); + assert_eq!(res, json!(null)); + + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": "file:///a/file.md" + }, + "position": { "line": 0, "character": 3 } + }), + ); + assert_eq!(res, json!(null)); + + client.shutdown(); +} + +#[test] +fn lsp_configuration_did_change() { + let context = TestContextBuilder::new() + .use_http_server() + .use_temp_cwd() + .build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "import * as a from \"http://localhost:4545/x/a@\"" + } + })); + client.change_configuration(json!({ "deno": { + "enable": true, + "codeLens": { + "implementations": true, + "references": true, + }, + "importMap": null, + "lint": true, + "suggest": { + "autoImports": true, + "completeFunctionCalls": false, + "names": true, + "paths": true, + "imports": { + "hosts": { + "http://localhost:4545/": true, + }, + }, + }, + "unstable": false, + } })); + + let list = client.get_completion_list( + "file:///a/file.ts", + (0, 46), + json!({ + "triggerKind": 2, + "triggerCharacter": "@" + }), + ); + assert!(!list.is_incomplete); + assert_eq!(list.items.len(), 3); + + let res = client.write_request( + "completionItem/resolve", + json!({ + "label": "v2.0.0", + "kind": 19, + "detail": "(version)", + "sortText": "0000000003", + "filterText": "http://localhost:4545/x/a@v2.0.0", + "textEdit": { + "range": { + "start": { "line": 0, "character": 20 }, + "end": { "line": 0, "character": 46 } + }, + "newText": "http://localhost:4545/x/a@v2.0.0" + } + }), + ); + assert_eq!( + res, + json!({ + "label": "v2.0.0", + "kind": 19, + "detail": "(version)", + "sortText": "0000000003", + "filterText": "http://localhost:4545/x/a@v2.0.0", + "textEdit": { + "range": { + "start": { "line": 0, "character": 20 }, + "end": { "line": 0, "character": 46 } + }, + "newText": "http://localhost:4545/x/a@v2.0.0" + } + }) + ); + client.shutdown(); +} + +#[test] +fn lsp_completions_complete_function_calls() { + let context = TestContextBuilder::new() + .use_http_server() + .use_temp_cwd() + .build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "[]." + } + })); + client.change_configuration(json!({ + "deno": { + "enable": true, + }, + "typescript": { + "suggest": { + "completeFunctionCalls": true, + }, + }, + })); + + let list = client.get_completion_list( + "file:///a/file.ts", + (0, 3), + json!({ + "triggerKind": 2, + "triggerCharacter": ".", + }), + ); + assert!(!list.is_incomplete); + + let res = client.write_request( + "completionItem/resolve", + json!({ + "label": "map", + "kind": 2, + "sortText": "1", + "insertTextFormat": 1, + "data": { + "tsc": { + "specifier": "file:///a/file.ts", + "position": 3, + "name": "map", + "useCodeSnippet": true + } + } + }), + ); + assert_eq!( + res, + json!({ + "label": "map", + "kind": 2, + "detail": "(method) Array.map(callbackfn: (value: never, index: number, array: never[]) => U, thisArg?: any): U[]", + "documentation": { + "kind": "markdown", + "value": "Calls a defined callback function on each element of an array, and returns an array that contains the results.\n\n*@param* - callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.*@param* - thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value." + }, + "sortText": "1", + "insertText": "map(${1:callbackfn})", + "insertTextFormat": 2, + }) + ); + client.shutdown(); +} + +#[test] +fn lsp_workspace_symbol() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "export class A {\n fieldA: string;\n fieldB: string;\n}\n", + } + })); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file_01.ts", + "languageId": "typescript", + "version": 1, + "text": "export class B {\n fieldC: string;\n fieldD: string;\n}\n", + } + })); + let mut res = client.write_request( + "workspace/symbol", + json!({ + "query": "field" + }), + ); + + // Replace `range` fields with `null` values. These are not important + // for assertion and require to be updated if we change unstable APIs. + for obj in res.as_array_mut().unwrap().iter_mut() { + *obj + .as_object_mut() + .unwrap() + .get_mut("location") + .unwrap() + .as_object_mut() + .unwrap() + .get_mut("range") + .unwrap() = Value::Null; + } + + assert_eq!( + res, + json!([ + { + "name": "fieldA", + "kind": 8, + "location": { + "uri": "file:///a/file.ts", + "range": null, + }, + "containerName": "A" + }, + { + "name": "fieldB", + "kind": 8, + "location": { + "uri": "file:///a/file.ts", + "range": null, + }, + "containerName": "A" + }, + { + "name": "fieldC", + "kind": 8, + "location": { + "uri": "file:///a/file_01.ts", + "range": null, + }, + "containerName": "B" + }, + { + "name": "fieldD", + "kind": 8, + "location": { + "uri": "file:///a/file_01.ts", + "range": null, + }, + "containerName": "B" + }, + { + "name": "fields", + "kind": 6, + "location": { + "uri": "deno:/asset/lib.deno.unstable.d.ts", + "range": null, + }, + "containerName": "CalendarProtocol" + }, + { + "name": "fields", + "kind": 6, + "location": { + "uri": "deno:/asset/lib.deno.unstable.d.ts", + "range": null, + }, + "containerName": "Calendar" + }, + { + "name": "ClassFieldDecoratorContext", + "kind": 11, + "location": { + "uri": "deno:/asset/lib.decorators.d.ts", + "range": null, + }, + "containerName": "" + }, + { + "name": "dateFromFields", + "kind": 6, + "location": { + "uri": "deno:/asset/lib.deno.unstable.d.ts", + "range": null, + }, + "containerName": "CalendarProtocol" + }, + { + "name": "dateFromFields", + "kind": 6, + "location": { + "uri": "deno:/asset/lib.deno.unstable.d.ts", + "range": null, + }, + "containerName": "Calendar" + }, + { + "name": "getISOFields", + "kind": 6, + "location": { + "uri": "deno:/asset/lib.deno.unstable.d.ts", + "range": null, + }, + "containerName": "PlainDate" + }, + { + "name": "getISOFields", + "kind": 6, + "location": { + "uri": "deno:/asset/lib.deno.unstable.d.ts", + "range": null, + }, + "containerName": "PlainDateTime" + }, + { + "name": "getISOFields", + "kind": 6, + "location": { + "uri": "deno:/asset/lib.deno.unstable.d.ts", + "range": null, + }, + "containerName": "PlainMonthDay" + }, + { + "name": "getISOFields", + "kind": 6, + "location": { + "uri": "deno:/asset/lib.deno.unstable.d.ts", + "range": null, + }, + "containerName": "PlainTime" + }, + { + "name": "getISOFields", + "kind": 6, + "location": { + "uri": "deno:/asset/lib.deno.unstable.d.ts", + "range": null, + }, + "containerName": "PlainYearMonth" + }, + { + "name": "getISOFields", + "kind": 6, + "location": { + "uri": "deno:/asset/lib.deno.unstable.d.ts", + "range": null, + }, + "containerName": "ZonedDateTime" + }, + { + "name": "mergeFields", + "kind": 6, + "location": { + "uri": "deno:/asset/lib.deno.unstable.d.ts", + "range": null, + }, + "containerName": "CalendarProtocol" + }, + { + "name": "mergeFields", + "kind": 6, + "location": { + "uri": "deno:/asset/lib.deno.unstable.d.ts", + "range": null, + }, + "containerName": "Calendar" + }, + { + "name": "monthDayFromFields", + "kind": 6, + "location": { + "uri": "deno:/asset/lib.deno.unstable.d.ts", + "range": null, + }, + "containerName": "CalendarProtocol" + }, + { + "name": "monthDayFromFields", + "kind": 6, + "location": { + "uri": "deno:/asset/lib.deno.unstable.d.ts", + "range": null, + }, + "containerName": "Calendar" + }, + { + "name": "PlainDateISOFields", + "kind": 5, + "location": { + "uri": "deno:/asset/lib.deno.unstable.d.ts", + "range": null, + }, + "containerName": "Temporal" + }, + { + "name": "PlainDateTimeISOFields", + "kind": 5, + "location": { + "uri": "deno:/asset/lib.deno.unstable.d.ts", + "range": null, + }, + "containerName": "Temporal" + }, + { + "name": "PlainTimeISOFields", + "kind": 5, + "location": { + "uri": "deno:/asset/lib.deno.unstable.d.ts", + "range": null, + }, + "containerName": "Temporal" + }, + { + "name": "yearMonthFromFields", + "kind": 6, + "location": { + "uri": "deno:/asset/lib.deno.unstable.d.ts", + "range": null, + }, + "containerName": "CalendarProtocol" + }, + { + "name": "yearMonthFromFields", + "kind": 6, + "location": { + "uri": "deno:/asset/lib.deno.unstable.d.ts", + "range": null, + }, + "containerName": "Calendar" + }, + { + "name": "ZonedDateTimeISOFields", + "kind": 5, + "location": { + "uri": "deno:/asset/lib.deno.unstable.d.ts", + "range": null, + }, + "containerName": "Temporal" + } + ]) + ); + client.shutdown(); +} + +#[test] +fn lsp_code_actions_ignore_lint() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "let message = 'Hello, Deno!';\nconsole.log(message);\n" + } + })); + let res = client.write_request( + "textDocument/codeAction", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "range": { + "start": { "line": 1, "character": 5 }, + "end": { "line": 1, "character": 12 } + }, + "context": { + "diagnostics": [ + { + "range": { + "start": { "line": 1, "character": 5 }, + "end": { "line": 1, "character": 12 } + }, + "severity": 1, + "code": "prefer-const", + "source": "deno-lint", + "message": "'message' is never reassigned\nUse 'const' instead", + "relatedInformation": [] + } + ], + "only": ["quickfix"] + } + }), + ); + assert_eq!( + res, + json!([{ + "title": "Disable prefer-const for this line", + "kind": "quickfix", + "diagnostics": [{ + "range": { + "start": { "line": 1, "character": 5 }, + "end": { "line": 1, "character": 12 } + }, + "severity": 1, + "code": "prefer-const", + "source": "deno-lint", + "message": "'message' is never reassigned\nUse 'const' instead", + "relatedInformation": [] + }], + "edit": { + "changes": { + "file:///a/file.ts": [{ + "range": { + "start": { "line": 1, "character": 0 }, + "end": { "line": 1, "character": 0 } + }, + "newText": "// deno-lint-ignore prefer-const\n" + }] + } + } + }, { + "title": "Disable prefer-const for the entire file", + "kind": "quickfix", + "diagnostics": [{ + "range": { + "start": { "line": 1, "character": 5 }, + "end": { "line": 1, "character": 12 } + }, + "severity": 1, + "code": "prefer-const", + "source": "deno-lint", + "message": "'message' is never reassigned\nUse 'const' instead", + "relatedInformation": [] + }], + "edit": { + "changes": { + "file:///a/file.ts": [{ + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 0, "character": 0 } + }, + "newText": "// deno-lint-ignore-file prefer-const\n" + }] + } + } + }, { + "title": "Ignore lint errors for the entire file", + "kind": "quickfix", + "diagnostics": [{ + "range": { + "start": { "line": 1, "character": 5 }, + "end": { "line": 1, "character": 12 } + }, + "severity": 1, + "code": "prefer-const", + "source": "deno-lint", + "message": "'message' is never reassigned\nUse 'const' instead", + "relatedInformation": [] + }], + "edit": { + "changes": { + "file:///a/file.ts": [{ + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 0, "character": 0 } + }, + "newText": "// deno-lint-ignore-file\n" + }] + } + } + }]) + ); + client.shutdown(); +} + +/// This test exercises updating an existing deno-lint-ignore-file comment. +#[test] +fn lsp_code_actions_update_ignore_lint() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": +"#!/usr/bin/env -S deno run +// deno-lint-ignore-file camelcase +let snake_case = 'Hello, Deno!'; +console.log(snake_case); +", + } + })); + let res = client.write_request( + "textDocument/codeAction", + json!({ + "textDocument": { + "uri": "file:///a/file.ts" + }, + "range": { + "start": { "line": 3, "character": 5 }, + "end": { "line": 3, "character": 15 } + }, + "context": { + "diagnostics": [{ + "range": { + "start": { "line": 3, "character": 5 }, + "end": { "line": 3, "character": 15 } + }, + "severity": 1, + "code": "prefer-const", + "source": "deno-lint", + "message": "'snake_case' is never reassigned\nUse 'const' instead", + "relatedInformation": [] + }], + "only": ["quickfix"] + } + }), + ); + assert_eq!( + res, + json!([{ + "title": "Disable prefer-const for this line", + "kind": "quickfix", + "diagnostics": [{ + "range": { + "start": { "line": 3, "character": 5 }, + "end": { "line": 3, "character": 15 } + }, + "severity": 1, + "code": "prefer-const", + "source": "deno-lint", + "message": "'snake_case' is never reassigned\nUse 'const' instead", + "relatedInformation": [] + }], + "edit": { + "changes": { + "file:///a/file.ts": [{ + "range": { + "start": { "line": 3, "character": 0 }, + "end": { "line": 3, "character": 0 } + }, + "newText": "// deno-lint-ignore prefer-const\n" + }] + } + } + }, { + "title": "Disable prefer-const for the entire file", + "kind": "quickfix", + "diagnostics": [{ + "range": { + "start": { "line": 3, "character": 5 }, + "end": { "line": 3, "character": 15 } + }, + "severity": 1, + "code": "prefer-const", + "source": "deno-lint", + "message": "'snake_case' is never reassigned\nUse 'const' instead", + "relatedInformation": [] + }], + "edit": { + "changes": { + "file:///a/file.ts": [{ + "range": { + "start": { "line": 1, "character": 34 }, + "end": { "line": 1, "character": 34 } + }, + "newText": " prefer-const" + }] + } + } + }, { + "title": "Ignore lint errors for the entire file", + "kind": "quickfix", + "diagnostics": [{ + "range": { + "start": { "line": 3, "character": 5 }, + "end": { "line": 3, "character": 15 } + }, + "severity": 1, + "code": "prefer-const", + "source": "deno-lint", + "message": "'snake_case' is never reassigned\nUse 'const' instead", + "relatedInformation": [] + }], + "edit": { + "changes": { + "file:///a/file.ts": [{ + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 0, "character": 0 } + }, + "newText": "// deno-lint-ignore-file\n" + }] + } + } + }]) + ); + client.shutdown(); +} + +#[test] +fn lsp_lint_with_config() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + + temp_dir.write( + "deno.lint.jsonc", + r#"{ + "lint": { + "rules": { + "exclude": ["camelcase"], + "include": ["ban-untagged-todo"], + "tags": [] + } + } + } + "#, + ); + + let mut client = context.new_lsp_command().build(); + client.initialize(|builder| { + builder.set_config("./deno.lint.jsonc"); + }); + + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.ts", + "languageId": "typescript", + "version": 1, + "text": "// TODO: fixme\nexport async function non_camel_case() {\nconsole.log(\"finished!\")\n}" + } + })); + let diagnostics = diagnostics.all(); + assert_eq!(diagnostics.len(), 1); + assert_eq!( + diagnostics[0].code, + Some(lsp::NumberOrString::String("ban-untagged-todo".to_string())) + ); + client.shutdown(); +} + +#[test] +fn lsp_lint_exclude_with_config() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + + temp_dir.write( + "deno.lint.jsonc", + r#"{ + "lint": { + "files": { + "exclude": ["ignored.ts"] + }, + "rules": { + "exclude": ["camelcase"], + "include": ["ban-untagged-todo"], + "tags": [] + } + } + }"#, + ); + + let mut client = context.new_lsp_command().build(); + client.initialize(|builder| { + builder.set_config("./deno.lint.jsonc"); + }); + + let diagnostics = client.did_open( + json!({ + "textDocument": { + "uri": ModuleSpecifier::from_file_path(temp_dir.path().join("ignored.ts")).unwrap().to_string(), + "languageId": "typescript", + "version": 1, + "text": "// TODO: fixme\nexport async function non_camel_case() {\nconsole.log(\"finished!\")\n}" + } + }), + ); + let diagnostics = diagnostics.all(); + assert_eq!(diagnostics, Vec::new()); + client.shutdown(); +} + +#[test] +fn lsp_jsx_import_source_pragma() { + let context = TestContextBuilder::new() + .use_http_server() + .use_temp_cwd() + .build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": "file:///a/file.tsx", + "languageId": "typescriptreact", + "version": 1, + "text": +"/** @jsxImportSource http://localhost:4545/jsx */ + +function A() { + return \"hello\"; +} + +export function B() { + return ; +} +", + } + })); + client.write_request( + "workspace/executeCommand", + json!({ + "command": "deno.cache", + "arguments": [ + ["http://127.0.0.1:4545/jsx/jsx-runtime"], + "file:///a/file.tsx", + ], + }), + ); + let res = client.write_request( + "textDocument/hover", + json!({ + "textDocument": { + "uri": "file:///a/file.tsx" + }, + "position": { "line": 0, "character": 25 } + }), + ); + assert_eq!( + res, + json!({ + "contents": { + "kind": "markdown", + "value": "**Resolved Dependency**\n\n**Code**: http​://localhost:4545/jsx/jsx-runtime\n", + }, + "range": { + "start": { "line": 0, "character": 21 }, + "end": { "line": 0, "character": 46 } + } + }) + ); + client.shutdown(); +} + +#[ignore = "https://github.com/denoland/deno/issues/21770"] +#[test] +fn lsp_jsx_import_source_config_file_automatic_cache() { + let context = TestContextBuilder::new() + .use_http_server() + .use_temp_cwd() + .build(); + let temp_dir = context.temp_dir(); + temp_dir.write( + "deno.json", + json!({ + "compilerOptions": { + "jsx": "react-jsx", + "jsxImportSource": "http://localhost:4545/jsx", + }, + }) + .to_string(), + ); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + let mut diagnostics = client.did_open(json!({ + "textDocument": { + "uri": temp_dir.uri().join("file.tsx").unwrap(), + "languageId": "typescriptreact", + "version": 1, + "text": " + export function Foo() { + return
; + } + ", + }, + })); + // The caching is done on an asynchronous task spawned after init, so there's + // a chance it wasn't done in time and we need to wait for another batch of + // diagnostics. + while !diagnostics.all().is_empty() { + std::thread::sleep(std::time::Duration::from_millis(50)); + // The post-cache diagnostics update triggers inconsistently on CI for some + // reason. Force it with this notification. + diagnostics = client.did_open(json!({ + "textDocument": { + "uri": temp_dir.uri().join("file.tsx").unwrap(), + "languageId": "typescriptreact", + "version": 1, + "text": " + export function Foo() { + return
; + } + ", + }, + })); + } + assert_eq!(diagnostics.all(), vec![]); + client.shutdown(); +} + +#[derive(Debug, Clone, Deserialize, PartialEq)] +#[serde(rename_all = "camelCase")] +struct TestData { + id: String, + label: String, + steps: Option>, + range: Option, +} + +#[derive(Debug, Deserialize, PartialEq)] +#[serde(rename_all = "camelCase")] +enum TestModuleNotificationKind { + Insert, + Replace, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +struct TestModuleNotificationParams { + text_document: lsp::TextDocumentIdentifier, + kind: TestModuleNotificationKind, + label: String, + tests: Vec, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +struct EnqueuedTestModule { + text_document: lsp::TextDocumentIdentifier, + ids: Vec, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +struct TestRunResponseParams { + enqueued: Vec, +} + +#[test] +fn lsp_testing_api() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + + let contents = r#" +Deno.test({ + name: "test a", + async fn(t) { + console.log("test a"); + await t.step("step of test a", () => {}); + } +}); +"#; + temp_dir.write("./test.ts", contents); + temp_dir.write("./deno.jsonc", "{}"); + let specifier = temp_dir.uri().join("test.ts").unwrap(); + + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + + client.did_open(json!({ + "textDocument": { + "uri": specifier, + "languageId": "typescript", + "version": 1, + "text": contents, + } + })); + + let notification = + client.read_notification_with_method::("deno/testModule"); + let params: TestModuleNotificationParams = + serde_json::from_value(notification.unwrap()).unwrap(); + assert_eq!(params.text_document.uri, specifier); + assert_eq!(params.kind, TestModuleNotificationKind::Replace); + assert_eq!(params.label, "test.ts"); + assert_eq!(params.tests.len(), 1); + let test = ¶ms.tests[0]; + assert_eq!(test.label, "test a"); + assert_eq!( + test.range, + Some(lsp::Range { + start: lsp::Position { + line: 1, + character: 5, + }, + end: lsp::Position { + line: 1, + character: 9, + } + }) + ); + let steps = test.steps.as_ref().unwrap(); + assert_eq!(steps.len(), 1); + let step = &steps[0]; + assert_eq!(step.label, "step of test a"); + assert_eq!( + step.range, + Some(lsp::Range { + start: lsp::Position { + line: 5, + character: 12, + }, + end: lsp::Position { + line: 5, + character: 16, + } + }) + ); + + let res = client.write_request_with_res_as::( + "deno/testRun", + json!({ + "id": 1, + "kind": "run", + }), + ); + assert_eq!(res.enqueued.len(), 1); + assert_eq!(res.enqueued[0].text_document.uri, specifier); + assert_eq!(res.enqueued[0].ids.len(), 1); + let id = res.enqueued[0].ids[0].clone(); + let notification = + client.read_notification_with_method::("deno/testRunProgress"); + assert_eq!( + notification, + Some(json!({ + "id": 1, + "message": { + "type": "started", + "test": { + "textDocument": { + "uri": specifier, + }, + "id": id, + }, + } + })) + ); + + let notification = + client.read_notification_with_method::("deno/testRunProgress"); + let notification_value = notification + .as_ref() + .unwrap() + .as_object() + .unwrap() + .get("message") + .unwrap() + .as_object() + .unwrap() + .get("value") + .unwrap() + .as_str() + .unwrap(); + // deno test's output capturing flushes with a zero-width space in order to + // synchronize the output pipes. Occasionally this zero width space + // might end up in the output so strip it from the output comparison here. + assert_eq!(notification_value.replace('\u{200B}', ""), "test a\r\n"); + assert_eq!( + notification, + Some(json!({ + "id": 1, + "message": { + "type": "output", + "value": notification_value, + "test": { + "textDocument": { + "uri": specifier, + }, + "id": id, + }, + } + })) + ); + + let notification = + client.read_notification_with_method::("deno/testRunProgress"); + assert_eq!( + notification, + Some(json!({ + "id": 1, + "message": { + "type": "started", + "test": { + "textDocument": { + "uri": specifier, + }, + "id": id, + "stepId": step.id, + }, + } + })) + ); + + let notification = + client.read_notification_with_method::("deno/testRunProgress"); + let mut notification = notification.unwrap(); + let duration = notification + .as_object_mut() + .unwrap() + .get_mut("message") + .unwrap() + .as_object_mut() + .unwrap() + .remove("duration"); + assert!(duration.is_some()); + assert_eq!( + notification, + json!({ + "id": 1, + "message": { + "type": "passed", + "test": { + "textDocument": { + "uri": specifier, + }, + "id": id, + "stepId": step.id, + }, + } + }) + ); + + let notification = + client.read_notification_with_method::("deno/testRunProgress"); + let notification = notification.unwrap(); + let obj = notification.as_object().unwrap(); + assert_eq!(obj.get("id"), Some(&json!(1))); + let message = obj.get("message").unwrap().as_object().unwrap(); + match message.get("type").and_then(|v| v.as_str()) { + Some("passed") => { + assert_eq!( + message.get("test"), + Some(&json!({ + "textDocument": { + "uri": specifier + }, + "id": id, + })) + ); + assert!(message.contains_key("duration")); + + let notification = + client.read_notification_with_method::("deno/testRunProgress"); + assert_eq!( + notification, + Some(json!({ + "id": 1, + "message": { + "type": "end", + } + })) + ); + } + // sometimes on windows, the messages come out of order, but it actually is + // working, so if we do get the end before the passed, we will simply let + // the test pass + Some("end") => (), + _ => panic!("unexpected message {}", json!(notification)), + } + + // Regression test for https://github.com/denoland/vscode_deno/issues/899. + temp_dir.write("./test.ts", ""); + client.write_notification( + "textDocument/didChange", + json!({ + "textDocument": { + "uri": temp_dir.uri().join("test.ts").unwrap(), + "version": 2 + }, + "contentChanges": [{ "text": "" }], + }), + ); + + assert_eq!(client.read_diagnostics().all().len(), 0); + + let notification = + client.read_notification_with_method::("deno/testModuleDelete"); + assert_eq!( + notification, + Some(json!({ + "textDocument": { + "uri": temp_dir.uri().join("test.ts").unwrap() + } + })) + ); + + client.shutdown(); +} + +#[test] +fn lsp_closed_file_find_references() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + temp_dir.write("./mod.ts", "export const a = 5;"); + temp_dir.write( + "./mod.test.ts", + "import { a } from './mod.ts'; console.log(a);", + ); + let temp_dir_url = temp_dir.uri(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": temp_dir_url.join("mod.ts").unwrap(), + "languageId": "typescript", + "version": 1, + "text": r#"export const a = 5;"# + } + })); + let res = client.write_request( + "textDocument/references", + json!({ + "textDocument": { + "uri": temp_dir_url.join("mod.ts").unwrap(), + }, + "position": { "line": 0, "character": 13 }, + "context": { + "includeDeclaration": false + } + }), + ); + + assert_eq!( + res, + json!([{ + "uri": temp_dir_url.join("mod.test.ts").unwrap(), + "range": { + "start": { "line": 0, "character": 9 }, + "end": { "line": 0, "character": 10 } + } + }, { + "uri": temp_dir_url.join("mod.test.ts").unwrap(), + "range": { + "start": { "line": 0, "character": 42 }, + "end": { "line": 0, "character": 43 } + } + }]) + ); + + client.shutdown(); +} + +#[test] +fn lsp_closed_file_find_references_low_document_pre_load() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + temp_dir.create_dir_all("sub_dir"); + temp_dir.write("./other_file.ts", "export const b = 5;"); + temp_dir.write("./sub_dir/mod.ts", "export const a = 5;"); + temp_dir.write( + "./sub_dir/mod.test.ts", + "import { a } from './mod.ts'; console.log(a);", + ); + let temp_dir_url = temp_dir.uri(); + let mut client = context.new_lsp_command().build(); + client.initialize(|builder| { + builder.set_preload_limit(1); + }); + client.did_open(json!({ + "textDocument": { + "uri": temp_dir_url.join("sub_dir/mod.ts").unwrap(), + "languageId": "typescript", + "version": 1, + "text": r#"export const a = 5;"# + } + })); + let res = client.write_request( + "textDocument/references", + json!({ + "textDocument": { + "uri": temp_dir_url.join("sub_dir/mod.ts").unwrap(), + }, + "position": { "line": 0, "character": 13 }, + "context": { + "includeDeclaration": false + } + }), + ); + + // won't have results because the document won't be pre-loaded + assert_eq!(res, json!([])); + + client.shutdown(); +} + +#[test] +fn lsp_closed_file_find_references_excluded_path() { + // we exclude any files or folders in the "exclude" part of + // the config file from being pre-loaded + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + temp_dir.create_dir_all("sub_dir"); + temp_dir.create_dir_all("other_dir/sub_dir"); + temp_dir.write("./sub_dir/mod.ts", "export const a = 5;"); + temp_dir.write( + "./sub_dir/mod.test.ts", + "import { a } from './mod.ts'; console.log(a);", + ); + temp_dir.write( + "./other_dir/sub_dir/mod.test.ts", + "import { a } from '../../sub_dir/mod.ts'; console.log(a);", + ); + temp_dir.write( + "deno.json", + r#"{ + "exclude": [ + "./sub_dir/mod.test.ts", + "./other_dir/sub_dir", + ] +}"#, + ); + let temp_dir_url = temp_dir.uri(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": temp_dir_url.join("sub_dir/mod.ts").unwrap(), + "languageId": "typescript", + "version": 1, + "text": r#"export const a = 5;"# + } + })); + let res = client.write_request( + "textDocument/references", + json!({ + "textDocument": { + "uri": temp_dir_url.join("sub_dir/mod.ts").unwrap(), + }, + "position": { "line": 0, "character": 13 }, + "context": { + "includeDeclaration": false + } + }), + ); + + // won't have results because the documents won't be pre-loaded + assert_eq!(res, json!([])); + + client.shutdown(); +} + +#[test] +fn lsp_data_urls_with_jsx_compiler_option() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + temp_dir.write( + "deno.json", + r#"{ "compilerOptions": { "jsx": "react-jsx" } }"#, + ); + + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + + let uri = Url::from_file_path(temp_dir.path().join("main.ts")).unwrap(); + + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": uri, + "languageId": "typescript", + "version": 1, + "text": "import a from \"data:application/typescript,export default 5;\";\na;" + } + })).all(); + + assert_eq!(diagnostics.len(), 0); + + let res: Value = client.write_request( + "textDocument/references", + json!({ + "textDocument": { + "uri": uri + }, + "position": { "line": 1, "character": 1 }, + "context": { + "includeDeclaration": false + } + }), + ); + + assert_eq!( + res, + json!([{ + "uri": uri, + "range": { + "start": { "line": 0, "character": 7 }, + "end": { "line": 0, "character": 8 } + } + }, { + "uri": uri, + "range": { + "start": { "line": 1, "character": 0 }, + "end": { "line": 1, "character": 1 } + } + }, { + "uri": "deno:/ed0224c51f7e2a845dfc0941ed6959675e5e3e3d2a39b127f0ff569c1ffda8d8/data_url.ts", + "range": { + "start": { "line": 0, "character": 7 }, + "end": {"line": 0, "character": 14 }, + }, + }]) + ); + + client.shutdown(); +} + +#[test] +fn lsp_node_modules_dir() { + let context = TestContextBuilder::new() + .use_http_server() + .use_temp_cwd() + .build(); + let temp_dir = context.temp_dir(); + + // having a package.json should have no effect on whether + // a node_modules dir is created + temp_dir.write("package.json", "{}"); + + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + let file_uri = temp_dir.uri().join("file.ts").unwrap(); + client.did_open(json!({ + "textDocument": { + "uri": file_uri, + "languageId": "typescript", + "version": 1, + "text": "import chalk from 'npm:chalk';\nimport path from 'node:path';\n\nconsole.log(chalk.green(path.join('a', 'b')));", + } + })); + let cache = |client: &mut LspClient| { + client.write_request( + "workspace/executeCommand", + json!({ + "command": "deno.cache", + "arguments": [["npm:chalk", "npm:@types/node"], file_uri], + }), + ); + }; + + cache(&mut client); + + assert!(!temp_dir.path().join("node_modules").exists()); + + temp_dir.write( + temp_dir.path().join("deno.json"), + "{ \"nodeModulesDir\": true, \"lock\": false }\n", + ); + let refresh_config = |client: &mut LspClient| { + client.change_configuration(json!({ "deno": { + "enable": true, + "config": "./deno.json", + "codeLens": { + "implementations": true, + "references": true, + }, + "importMap": null, + "lint": false, + "suggest": { + "autoImports": true, + "completeFunctionCalls": false, + "names": true, + "paths": true, + "imports": {}, + }, + "unstable": false, + } })); + }; + refresh_config(&mut client); + + let diagnostics = client.read_diagnostics(); + assert_eq!(diagnostics.all().len(), 2, "{:#?}", diagnostics); // not cached + + cache(&mut client); + + assert!(temp_dir.path().join("node_modules/chalk").exists()); + assert!(temp_dir.path().join("node_modules/@types/node").exists()); + assert!(!temp_dir.path().join("deno.lock").exists()); + + // now add a lockfile and cache + temp_dir.write( + temp_dir.path().join("deno.json"), + "{ \"nodeModulesDir\": true }\n", + ); + refresh_config(&mut client); + cache(&mut client); + + let diagnostics = client.read_diagnostics(); + assert_eq!(diagnostics.all().len(), 0, "{:#?}", diagnostics); + + assert!(temp_dir.path().join("deno.lock").exists()); + + // the declaration should be found in the node_modules directory + let res = client.write_request( + "textDocument/references", + json!({ + "textDocument": { + "uri": file_uri, + }, + "position": { "line": 0, "character": 7 }, // chalk + "context": { + "includeDeclaration": false + } + }), + ); + + // ensure that it's using the node_modules directory + let references = res.as_array().unwrap(); + assert_eq!(references.len(), 2, "references: {:#?}", references); + let uri = references[1] + .as_object() + .unwrap() + .get("uri") + .unwrap() + .as_str() + .unwrap(); + // canonicalize for mac + let path = temp_dir.path().join("node_modules").canonicalize(); + assert_starts_with!( + uri, + ModuleSpecifier::from_file_path(&path).unwrap().as_str() + ); + + client.shutdown(); +} + +#[test] +fn lsp_vendor_dir() { + let context = TestContextBuilder::new() + .use_http_server() + .use_temp_cwd() + .build(); + let temp_dir = context.temp_dir(); + + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + let local_file_uri = temp_dir.uri().join("file.ts").unwrap(); + client.did_open(json!({ + "textDocument": { + "uri": local_file_uri, + "languageId": "typescript", + "version": 1, + "text": "import { returnsHi } from 'http://localhost:4545/subdir/mod1.ts';\nconst test: string = returnsHi();\nconsole.log(test);", + } + })); + let cache = |client: &mut LspClient| { + client.write_request( + "workspace/executeCommand", + json!({ + "command": "deno.cache", + "arguments": [["http://localhost:4545/subdir/mod1.ts"], local_file_uri], + }), + ); + }; + + cache(&mut client); + + assert!(!temp_dir.path().join("vendor").exists()); + + temp_dir.write( + temp_dir.path().join("deno.json"), + "{ \"vendor\": true, \"lock\": false }\n", + ); + let refresh_config = |client: &mut LspClient| { + client.change_configuration(json!({ "deno": { + "enable": true, + "config": "./deno.json", + "codeLens": { + "implementations": true, + "references": true, + }, + "importMap": null, + "lint": false, + "suggest": { + "autoImports": true, + "completeFunctionCalls": false, + "names": true, + "paths": true, + "imports": {}, + }, + "unstable": false, + } })); + }; + refresh_config(&mut client); + + let diagnostics = client.read_diagnostics(); + assert_eq!(diagnostics.all().len(), 0, "{:#?}", diagnostics); // cached + + // no caching necessary because it was already cached. It should exist now + assert!(temp_dir + .path() + .join("vendor/http_localhost_4545/subdir/mod1.ts") + .exists()); + + // the declaration should be found in the vendor directory + let res = client.write_request( + "textDocument/references", + json!({ + "textDocument": { + "uri": local_file_uri, + }, + "position": { "line": 0, "character": 9 }, // returnsHi + "context": { + "includeDeclaration": false + } + }), + ); + + // ensure that it's using the vendor directory + let references = res.as_array().unwrap(); + assert_eq!(references.len(), 2, "references: {:#?}", references); + let uri = references[1] + .as_object() + .unwrap() + .get("uri") + .unwrap() + .as_str() + .unwrap(); + let file_path = temp_dir + .path() + .join("vendor/http_localhost_4545/subdir/mod1.ts"); + let remote_file_uri = file_path.uri_file(); + assert_eq!(uri, remote_file_uri.as_str()); + + let file_text = file_path.read_to_string(); + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": remote_file_uri, + "languageId": "typescript", + "version": 1, + "text": file_text, + } + })); + assert_eq!(diagnostics.all(), Vec::new()); + + client.write_notification( + "textDocument/didChange", + json!({ + "textDocument": { + "uri": remote_file_uri, + "version": 2 + }, + "contentChanges": [ + { + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 17, "character": 0 }, + }, + "text": "export function returnsHi(): number { return new Date(); }" + } + ] + }), + ); + + let diagnostics = client.read_diagnostics(); + + assert_eq!( + json!( + diagnostics + .messages_with_file_and_source(remote_file_uri.as_str(), "deno-ts") + .diagnostics + ), + json!([ + { + "range": { + "start": { "line": 0, "character": 38 }, + "end": { "line": 0, "character": 44 } + }, + "severity": 1, + "code": 2322, + "source": "deno-ts", + "message": "Type 'Date' is not assignable to type 'number'." + } + ]), + ); + + assert_eq!( + json!( + diagnostics + .messages_with_file_and_source(local_file_uri.as_str(), "deno-ts") + .diagnostics + ), + json!([ + { + "range": { + "start": { "line": 1, "character": 6 }, + "end": { "line": 1, "character": 10 } + }, + "severity": 1, + "code": 2322, + "source": "deno-ts", + "message": "Type 'number' is not assignable to type 'string'." + } + ]), + ); + assert_eq!(diagnostics.all().len(), 2); + + // now try doing a relative import into the vendor directory + client.write_notification( + "textDocument/didChange", + json!({ + "textDocument": { + "uri": local_file_uri, + "version": 2 + }, + "contentChanges": [ + { + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 2, "character": 0 }, + }, + "text": "import { returnsHi } from './vendor/subdir/mod1.ts';\nconst test: string = returnsHi();\nconsole.log(test);" + } + ] + }), + ); + + let diagnostics = client.read_diagnostics(); + + assert_eq!( + json!( + diagnostics + .messages_with_file_and_source(local_file_uri.as_str(), "deno") + .diagnostics + ), + json!([ + { + "range": { + "start": { "line": 0, "character": 26 }, + "end": { "line": 0, "character": 51 } + }, + "severity": 1, + "code": "resolver-error", + "source": "deno", + "message": "Importing from the vendor directory is not permitted. Use a remote specifier instead or disable vendoring." + } + ]), + ); + + client.shutdown(); +} + +#[test] +fn lsp_import_unstable_bare_node_builtins_auto_discovered() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + + let contents = r#"import path from "path";"#; + temp_dir.write("main.ts", contents); + temp_dir.write("deno.json", r#"{ "unstable": ["bare-node-builtins"] }"#); + let main_script = temp_dir.uri().join("main.ts").unwrap(); + + let mut client = context.new_lsp_command().capture_stderr().build(); + client.initialize_default(); + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": main_script, + "languageId": "typescript", + "version": 1, + "text": contents, + } + })); + + let diagnostics = diagnostics + .messages_with_file_and_source(main_script.as_ref(), "deno") + .diagnostics + .into_iter() + .filter(|d| { + d.code + == Some(lsp::NumberOrString::String( + "import-node-prefix-missing".to_string(), + )) + }) + .collect::>(); + + // get the quick fixes + let res = client.write_request( + "textDocument/codeAction", + json!({ + "textDocument": { + "uri": main_script + }, + "range": { + "start": { "line": 0, "character": 16 }, + "end": { "line": 0, "character": 18 }, + }, + "context": { + "diagnostics": json!(diagnostics), + "only": ["quickfix"] + } + }), + ); + assert_eq!( + res, + json!([{ + "title": "Update specifier to node:path", + "kind": "quickfix", + "diagnostics": [ + { + "range": { + "start": { "line": 0, "character": 17 }, + "end": { "line": 0, "character": 23 } + }, + "severity": 2, + "code": "import-node-prefix-missing", + "source": "deno", + "message": "\"path\" is resolved to \"node:path\". If you want to use a built-in Node module, add a \"node:\" prefix.", + "data": { + "specifier": "path" + }, + } + ], + "edit": { + "changes": { + main_script: [ + { + "range": { + "start": { "line": 0, "character": 17 }, + "end": { "line": 0, "character": 23 } + }, + "newText": "\"node:path\"" + } + ] + } + } + }]) + ); + + client.shutdown(); +} + +#[test] +fn lsp_jupyter_byonm_diagnostics() { + let context = TestContextBuilder::for_npm().use_temp_cwd().build(); + let temp_dir = context.temp_dir().path(); + temp_dir.join("package.json").write_json(&json!({ + "dependencies": { + "@denotest/esm-basic": "*" + } + })); + temp_dir.join("deno.json").write_json(&json!({ + "unstable": ["byonm"] + })); + context.run_npm("install"); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + let notebook_specifier = temp_dir.join("notebook.ipynb").uri_file(); + let notebook_specifier = format!( + "{}#abc", + notebook_specifier + .to_string() + .replace("file://", "deno-notebook-cell:") + ); + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": notebook_specifier, + "languageId": "typescript", + "version": 1, + "text": "import { getValue, nonExistent } from '@denotest/esm-basic';\n console.log(getValue, nonExistent);", + }, + })); + assert_eq!( + json!(diagnostics.all_messages()), + json!([ + { + "uri": notebook_specifier, + "diagnostics": [ + { + "range": { + "start": { + "line": 0, + "character": 19, + }, + "end": { + "line": 0, + "character": 30, + }, + }, + "severity": 1, + "code": 2305, + "source": "deno-ts", + "message": "Module '\"@denotest/esm-basic\"' has no exported member 'nonExistent'.", + }, + ], + "version": 1, + }, + ]) + ); + client.shutdown(); +} + +#[test] +fn lsp_sloppy_imports_warn() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + let temp_dir = temp_dir.path(); + temp_dir + .join("deno.json") + .write(r#"{ "unstable": ["sloppy-imports"] }"#); + // should work when exists on the fs and when doesn't + temp_dir.join("a.ts").write("export class A {}"); + let mut client = context.new_lsp_command().build(); + client.initialize(|builder| { + builder.set_root_uri(temp_dir.uri_dir()); + }); + client.did_open(json!({ + "textDocument": { + "uri": temp_dir.join("b.ts").uri_file(), + "languageId": "typescript", + "version": 1, + "text": "export class B {}", + }, + })); + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": temp_dir.join("file.ts").uri_file(), + "languageId": "typescript", + "version": 1, + "text": "import * as a from './a';\nimport * as b from './b.js';\nconsole.log(a)\nconsole.log(b);\n", + }, + })); + assert_eq!( + diagnostics.messages_with_source("deno"), + lsp::PublishDiagnosticsParams { + uri: temp_dir.join("file.ts").uri_file(), + diagnostics: vec![ + lsp::Diagnostic { + range: lsp::Range { + start: lsp::Position { + line: 0, + character: 19 + }, + end: lsp::Position { + line: 0, + character: 24 + } + }, + severity: Some(lsp::DiagnosticSeverity::INFORMATION), + code: Some(lsp::NumberOrString::String("redirect".to_string())), + source: Some("deno".to_string()), + message: format!( + "The import of \"{}\" was redirected to \"{}\".", + temp_dir.join("a").uri_file(), + temp_dir.join("a.ts").uri_file() + ), + data: Some(json!({ + "specifier": temp_dir.join("a").uri_file(), + "redirect": temp_dir.join("a.ts").uri_file() + })), + ..Default::default() + }, + lsp::Diagnostic { + range: lsp::Range { + start: lsp::Position { + line: 1, + character: 19 + }, + end: lsp::Position { + line: 1, + character: 27 + } + }, + severity: Some(lsp::DiagnosticSeverity::INFORMATION), + code: Some(lsp::NumberOrString::String("redirect".to_string())), + source: Some("deno".to_string()), + message: format!( + "The import of \"{}\" was redirected to \"{}\".", + temp_dir.join("b.js").uri_file(), + temp_dir.join("b.ts").uri_file() + ), + data: Some(json!({ + "specifier": temp_dir.join("b.js").uri_file(), + "redirect": temp_dir.join("b.ts").uri_file() + })), + ..Default::default() + } + ], + version: Some(1), + } + ); + + let res = client.write_request( + "textDocument/codeAction", + json!({ + "textDocument": { + "uri": temp_dir.join("file.ts").uri_file() + }, + "range": { + "start": { "line": 0, "character": 19 }, + "end": { "line": 0, "character": 24 } + }, + "context": { + "diagnostics": [{ + "range": { + "start": { "line": 0, "character": 19 }, + "end": { "line": 0, "character": 24 } + }, + "severity": 3, + "code": "redirect", + "source": "deno", + "message": format!( + "The import of \"{}\" was redirected to \"{}\".", + temp_dir.join("a").uri_file(), + temp_dir.join("a.ts").uri_file() + ), + "data": { + "specifier": temp_dir.join("a").uri_file(), + "redirect": temp_dir.join("a.ts").uri_file(), + }, + }], + "only": ["quickfix"] + } + }), + ); + assert_eq!( + res, + json!([{ + "title": "Update specifier to its redirected specifier.", + "kind": "quickfix", + "diagnostics": [{ + "range": { + "start": { "line": 0, "character": 19 }, + "end": { "line": 0, "character": 24 } + }, + "severity": 3, + "code": "redirect", + "source": "deno", + "message": format!( + "The import of \"{}\" was redirected to \"{}\".", + temp_dir.join("a").uri_file(), + temp_dir.join("a.ts").uri_file() + ), + "data": { + "specifier": temp_dir.join("a").uri_file(), + "redirect": temp_dir.join("a.ts").uri_file() + }, + }], + "edit": { + "changes": { + temp_dir.join("file.ts").uri_file(): [{ + "range": { + "start": { "line": 0, "character": 19 }, + "end": { "line": 0, "character": 24 } + }, + "newText": "\"./a.ts\"" + }] + } + } + }]) + ); + + client.shutdown(); +} + +#[test] +fn sloppy_imports_not_enabled() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + let temp_dir = temp_dir.path(); + temp_dir.join("deno.json").write(r#"{}"#); + // The enhanced, more helpful error message is only available + // when the file exists on the file system at the moment because + // it's a little more complicated to hook it up otherwise. + temp_dir.join("a.ts").write("export class A {}"); + let mut client = context.new_lsp_command().build(); + client.initialize(|builder| { + builder.set_root_uri(temp_dir.uri_dir()); + }); + let diagnostics = client.did_open(json!({ + "textDocument": { + "uri": temp_dir.join("file.ts").uri_file(), + "languageId": "typescript", + "version": 1, + "text": "import * as a from './a';\nconsole.log(a)\n", + }, + })); + assert_eq!( + diagnostics.messages_with_source("deno"), + lsp::PublishDiagnosticsParams { + uri: temp_dir.join("file.ts").uri_file(), + diagnostics: vec![lsp::Diagnostic { + range: lsp::Range { + start: lsp::Position { + line: 0, + character: 19 + }, + end: lsp::Position { + line: 0, + character: 24 + } + }, + severity: Some(lsp::DiagnosticSeverity::ERROR), + code: Some(lsp::NumberOrString::String("no-local".to_string())), + source: Some("deno".to_string()), + message: format!( + "Unable to load a local module: {}\nMaybe add a '.ts' extension.", + temp_dir.join("a").uri_file(), + ), + data: Some(json!({ + "specifier": temp_dir.join("a").uri_file(), + "to": temp_dir.join("a.ts").uri_file(), + "message": "Add a '.ts' extension.", + })), + ..Default::default() + }], + version: Some(1), + } + ); + let res = client.write_request( + "textDocument/codeAction", + json!({ + "textDocument": { + "uri": temp_dir.join("file.ts").uri_file() + }, + "range": { + "start": { "line": 0, "character": 19 }, + "end": { "line": 0, "character": 24 } + }, + "context": { + "diagnostics": [{ + "range": { + "start": { "line": 0, "character": 19 }, + "end": { "line": 0, "character": 24 } + }, + "severity": 3, + "code": "no-local", + "source": "deno", + "message": format!( + "Unable to load a local module: {}\nMaybe add a '.ts' extension.", + temp_dir.join("a").uri_file(), + ), + "data": { + "specifier": temp_dir.join("a").uri_file(), + "to": temp_dir.join("a.ts").uri_file(), + "message": "Add a '.ts' extension.", + }, + }], + "only": ["quickfix"] + } + }), + ); + assert_eq!( + res, + json!([{ + "title": "Add a '.ts' extension.", + "kind": "quickfix", + "diagnostics": [{ + "range": { + "start": { "line": 0, "character": 19 }, + "end": { "line": 0, "character": 24 } + }, + "severity": 3, + "code": "no-local", + "source": "deno", + "message": format!( + "Unable to load a local module: {}\nMaybe add a '.ts' extension.", + temp_dir.join("a").uri_file(), + ), + "data": { + "specifier": temp_dir.join("a").uri_file(), + "to": temp_dir.join("a.ts").uri_file(), + "message": "Add a '.ts' extension.", + }, + }], + "edit": { + "changes": { + temp_dir.join("file.ts").uri_file(): [{ + "range": { + "start": { "line": 0, "character": 19 }, + "end": { "line": 0, "character": 24 } + }, + "newText": "\"./a.ts\"" + }] + } + } + }]) + ); + client.shutdown(); +} + +#[test] +fn decorators_tc39() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + temp_dir.write("deno.json", r#"{}"#); + + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + + let uri = Url::from_file_path(temp_dir.path().join("main.ts")).unwrap(); + + let diagnostics = client + .did_open(json!({ + "textDocument": { + "uri": uri, + "languageId": "typescript", + "version": 1, + "text": r#"// deno-lint-ignore no-explicit-any +function logged(value: any, { kind, name }: { kind: string; name: string }) { + if (kind === "method") { + return function (...args: unknown[]) { + console.log(`starting ${name} with arguments ${args.join(", ")}`); + // @ts-ignore this has implicit any type + const ret = value.call(this, ...args); + console.log(`ending ${name}`); + return ret; + }; + } +} + +class C { + @logged + m(arg: number) { + console.log("C.m", arg); + } +} + +new C().m(1); +"# + } + })) + .all(); + + assert_eq!(diagnostics.len(), 0); + + client.shutdown(); +} + +#[test] +fn decorators_ts() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + temp_dir.write( + "deno.json", + r#"{ "compilerOptions": { "experimentalDecorators": true } }"#, + ); + + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + + let uri = Url::from_file_path(temp_dir.path().join("main.ts")).unwrap(); + + let diagnostics = client + .did_open(json!({ + "textDocument": { + "uri": uri, + "languageId": "typescript", + "version": 1, + "text": r#"// deno-lint-ignore-file +function a() { + console.log("@A evaluated"); + return function ( + _target: any, + _propertyKey: string, + descriptor: PropertyDescriptor, + ) { + console.log("@A called"); + const fn = descriptor.value; + descriptor.value = function () { + console.log("fn() called from @A"); + fn(); + }; + }; +} + +class C { + @a() + static test() { + console.log("C.test() called"); + } +} + +C.test(); +"# + } + })) + .all(); + + assert_eq!(diagnostics.len(), 0); + + client.shutdown(); +} diff --git a/tests/integration/mod.rs b/tests/integration/mod.rs new file mode 100644 index 000000000..19796f245 --- /dev/null +++ b/tests/integration/mod.rs @@ -0,0 +1,158 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +#[macro_export] +macro_rules! itest( +($name:ident {$( $key:ident: $value:expr,)*}) => { + #[test] + fn $name() { + let test = test_util::CheckOutputIntegrationTest { + $( + $key: $value, + )* + .. Default::default() + }; + let output = test.output(); + output.assert_exit_code(test.exit_code); + if !test.output.is_empty() { + assert!(test.output_str.is_none()); + output.assert_matches_file(test.output); + } else { + output.assert_matches_text(test.output_str.unwrap_or("")); + } + } +} +); + +#[macro_export] +macro_rules! itest_flaky( +($name:ident {$( $key:ident: $value:expr,)*}) => { + #[flaky_test::flaky_test] + fn $name() { + let test = test_util::CheckOutputIntegrationTest { + $( + $key: $value, + )* + .. Default::default() + }; + let output = test.output(); + output.assert_exit_code(test.exit_code); + if !test.output.is_empty() { + assert!(test.output_str.is_none()); + output.assert_matches_file(test.output); + } else { + output.assert_matches_text(test.output_str.unwrap_or("")); + } + } +} +); + +#[macro_export] +macro_rules! context( +({$( $key:ident: $value:expr,)*}) => { + test_util::TestContext::create(test_util::TestContextOptions { + $( + $key: $value, + )* + .. Default::default() + }) +} +); + +#[macro_export] +macro_rules! itest_steps( +($name:ident {$( $key:ident: $value:expr,)*}) => { + #[test] + fn $name() { + (test_util::CheckOutputIntegrationTestSteps { + $( + $key: $value, + )* + .. Default::default() + }).run() + } +} +); + +#[macro_export] +macro_rules! command_step( +({$( $key:ident: $value:expr,)*}) => { + test_util::CheckOutputIntegrationTestCommandStep { + $( + $key: $value, + )* + .. Default::default() + } +} +); + +// These files have `_tests.rs` suffix to make it easier to tell which file is +// the test (ex. `lint_tests.rs`) and which is the implementation (ex. `lint.rs`) +// when both are open, especially for two tabs in VS Code + +#[path = "bench_tests.rs"] +mod bench; +#[path = "bundle_tests.rs"] +mod bundle; +#[path = "cache_tests.rs"] +mod cache; +#[path = "cert_tests.rs"] +mod cert; +#[path = "check_tests.rs"] +mod check; +#[path = "compile_tests.rs"] +mod compile; +#[path = "coverage_tests.rs"] +mod coverage; +#[path = "doc_tests.rs"] +mod doc; +#[path = "eval_tests.rs"] +mod eval; +#[path = "flags_tests.rs"] +mod flags; +#[path = "fmt_tests.rs"] +mod fmt; +#[path = "info_tests.rs"] +mod info; +#[path = "init_tests.rs"] +mod init; +#[path = "inspector_tests.rs"] +mod inspector; +#[path = "install_tests.rs"] +mod install; +#[path = "js_unit_tests.rs"] +mod js_unit_tests; +#[path = "jsr_tests.rs"] +mod jsr; +#[path = "jupyter_tests.rs"] +mod jupyter; +#[path = "lint_tests.rs"] +mod lint; +#[path = "lsp_tests.rs"] +mod lsp; +#[path = "node_compat_tests.rs"] +mod node_compat_tests; +#[path = "node_unit_tests.rs"] +mod node_unit_tests; +#[path = "npm_tests.rs"] +mod npm; +#[path = "publish_tests.rs"] +mod publish; + +#[path = "repl_tests.rs"] +mod repl; +#[path = "run_tests.rs"] +mod run; +#[path = "shared_library_tests.rs"] +mod shared_library_tests; +#[path = "task_tests.rs"] +mod task; +#[path = "test_tests.rs"] +mod test; +#[path = "upgrade_tests.rs"] +mod upgrade; +#[path = "vendor_tests.rs"] +mod vendor; +#[path = "watcher_tests.rs"] +mod watcher; +#[path = "worker_tests.rs"] +mod worker; diff --git a/tests/integration/node_compat_tests.rs b/tests/integration/node_compat_tests.rs new file mode 100644 index 000000000..d592c75a5 --- /dev/null +++ b/tests/integration/node_compat_tests.rs @@ -0,0 +1,31 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +use test_util as util; +use util::env_vars_for_npm_tests; + +#[test] +fn node_compat_tests() { + let mut deno = util::deno_cmd() + .current_dir(util::root_path()) + .arg("test") + .arg("--config") + .arg("tests/config/deno.json") + .arg("--no-lock") + .arg("--unstable") + .arg("-A") + .arg(util::tests_path().join("node_compat")) + .spawn() + .expect("failed to spawn script"); + + let status = deno.wait().expect("failed to wait for the child process"); + assert_eq!(Some(0), status.code()); + assert!(status.success()); +} + +itest!(node_test_module { + args: "test node/test.js", + output: "node/test.out", + envs: env_vars_for_npm_tests(), + exit_code: 1, + http_server: true, +}); diff --git a/tests/integration/node_unit_tests.rs b/tests/integration/node_unit_tests.rs new file mode 100644 index 000000000..c99586fa1 --- /dev/null +++ b/tests/integration/node_unit_tests.rs @@ -0,0 +1,207 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +use std::io::BufRead; +use std::io::BufReader; +use std::time::Duration; +use std::time::Instant; +use test_util as util; +use util::env_vars_for_npm_tests; + +util::unit_test_factory!( + node_unit_test, + "../tests/unit_node", + "**/*_test.ts", + [ + _fs_access_test = _fs / _fs_access_test, + _fs_appendFile_test = _fs / _fs_appendFile_test, + _fs_chmod_test = _fs / _fs_chmod_test, + _fs_chown_test = _fs / _fs_chown_test, + _fs_close_test = _fs / _fs_close_test, + _fs_copy_test = _fs / _fs_copy_test, + _fs_dir_test = _fs / _fs_dir_test, + _fs_dirent_test = _fs / _fs_dirent_test, + _fs_open_test = _fs / _fs_open_test, + _fs_read_test = _fs / _fs_read_test, + _fs_exists_test = _fs / _fs_exists_test, + _fs_fdatasync_test = _fs / _fs_fdatasync_test, + _fs_fstat_test = _fs / _fs_fstat_test, + _fs_fsync_test = _fs / _fs_fsync_test, + _fs_ftruncate_test = _fs / _fs_ftruncate_test, + _fs_futimes_test = _fs / _fs_futimes_test, + _fs_handle_test = _fs / _fs_handle_test, + _fs_link_test = _fs / _fs_link_test, + _fs_lstat_test = _fs / _fs_lstat_test, + _fs_mkdir_test = _fs / _fs_mkdir_test, + _fs_mkdtemp_test = _fs / _fs_mkdtemp_test, + _fs_opendir_test = _fs / _fs_opendir_test, + _fs_readFile_test = _fs / _fs_readFile_test, + _fs_readdir_test = _fs / _fs_readdir_test, + _fs_readlink_test = _fs / _fs_readlink_test, + _fs_realpath_test = _fs / _fs_realpath_test, + _fs_rename_test = _fs / _fs_rename_test, + _fs_rm_test = _fs / _fs_rm_test, + _fs_rmdir_test = _fs / _fs_rmdir_test, + _fs_stat_test = _fs / _fs_stat_test, + _fs_symlink_test = _fs / _fs_symlink_test, + _fs_truncate_test = _fs / _fs_truncate_test, + _fs_unlink_test = _fs / _fs_unlink_test, + _fs_utimes_test = _fs / _fs_utimes_test, + _fs_watch_test = _fs / _fs_watch_test, + _fs_writeFile_test = _fs / _fs_writeFile_test, + _fs_write_test = _fs / _fs_write_test, + async_hooks_test, + assertion_error_test, + buffer_test, + child_process_test, + console_test, + crypto_cipher_test = crypto / crypto_cipher_test, + crypto_cipher_gcm_test = crypto / crypto_cipher_gcm_test, + crypto_hash_test = crypto / crypto_hash_test, + crypto_key_test = crypto / crypto_key_test, + crypto_sign_test = crypto / crypto_sign_test, + events_test, + dgram_test, + fs_test, + http_test, + http2_test, + _randomBytes_test = internal / _randomBytes_test, + _randomFill_test = internal / _randomFill_test, + _randomInt_test = internal / _randomInt_test, + pbkdf2_test = internal / pbkdf2_test, + scrypt_test = internal / scrypt_test, + module_test, + net_test, + os_test, + path_test, + perf_hooks_test, + process_test, + querystring_test, + readline_test, + repl_test, + stream_test, + string_decoder_test, + timers_test, + tls_test, + tty_test, + util_test, + v8_test, + vm_test, + worker_threads_test, + zlib_test + ] +); + +fn node_unit_test(test: String) { + let _g = util::http_server(); + + let mut deno = util::deno_cmd() + .current_dir(util::root_path()) + .arg("test") + .arg("--config") + .arg("tests/config/deno.json") + .arg("--no-lock") + .arg("--unstable") + // TODO(kt3k): This option is required to pass tls_test.ts, + // but this shouldn't be necessary. tls.connect currently doesn't + // pass hostname option correctly and it causes cert errors. + .arg("--unsafely-ignore-certificate-errors") + .arg("-A"); + // Parallel tests for crypto + if test.starts_with("crypto/") { + deno = deno.arg("--parallel"); + } + let mut deno = deno + .arg( + util::tests_path() + .join("unit_node") + .join(format!("{test}.ts")), + ) + .envs(env_vars_for_npm_tests()) + .piped_output() + .spawn() + .expect("failed to spawn script"); + + let now = Instant::now(); + let stdout = deno.stdout.take().unwrap(); + let test_name = test.clone(); + let stdout = std::thread::spawn(move || { + let reader = BufReader::new(stdout); + for line in reader.lines() { + if let Ok(line) = line { + println!("[{test_name} {:0>6.2}] {line}", now.elapsed().as_secs_f32()); + } else { + break; + } + } + }); + + let now = Instant::now(); + let stderr = deno.stderr.take().unwrap(); + let test_name = test.clone(); + let stderr = std::thread::spawn(move || { + let reader = BufReader::new(stderr); + for line in reader.lines() { + if let Ok(line) = line { + eprintln!("[{test_name} {:0>6.2}] {line}", now.elapsed().as_secs_f32()); + } else { + break; + } + } + }); + + const PER_TEST_TIMEOUT: Duration = Duration::from_secs(5 * 60); + + let now = Instant::now(); + let status = loop { + if now.elapsed() > PER_TEST_TIMEOUT { + // Last-ditch kill + _ = deno.kill(); + panic!("Test {test} failed to complete in time"); + } + if let Some(status) = deno + .try_wait() + .expect("failed to wait for the child process") + { + break status; + } + std::thread::sleep(Duration::from_millis(100)); + }; + + #[cfg(unix)] + assert_eq!( + std::os::unix::process::ExitStatusExt::signal(&status), + None, + "Deno should not have died with a signal" + ); + assert_eq!(Some(0), status.code(), "Deno should have exited cleanly"); + + stdout.join().unwrap(); + stderr.join().unwrap(); + + assert!(status.success()); +} + +// Regression test for https://github.com/denoland/deno/issues/16928 +itest!(unhandled_rejection_web { + args: "run -A node/unhandled_rejection_web.ts", + output: "node/unhandled_rejection_web.ts.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +// Ensure that Web `onunhandledrejection` is fired before +// Node's `process.on('unhandledRejection')`. +itest!(unhandled_rejection_web_process { + args: "run -A node/unhandled_rejection_web_process.ts", + output: "node/unhandled_rejection_web_process.ts.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +// Ensure that Web `onrejectionhandled` is fired before +// Node's `process.on('rejectionHandled')`. +itest!(rejection_handled_web_process { + args: "run -A --quiet node/rejection_handled_web_process.ts", + output: "node/rejection_handled_web_process.ts.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); diff --git a/tests/integration/npm_tests.rs b/tests/integration/npm_tests.rs new file mode 100644 index 000000000..a63253260 --- /dev/null +++ b/tests/integration/npm_tests.rs @@ -0,0 +1,2750 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +use deno_core::serde_json; +use deno_core::serde_json::json; +use deno_core::serde_json::Value; +use pretty_assertions::assert_eq; +use test_util as util; +use util::assert_contains; +use util::env_vars_for_npm_tests; +use util::http_server; +use util::TestContextBuilder; + +// NOTE: See how to make test npm packages at ./testdata/npm/README.md + +itest!(es_module { + args: "run --allow-read --allow-env npm/esm/main.js", + output: "npm/esm/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(es_module_eval { + args_vec: vec![ + "eval", + "import chalk from 'npm:chalk@5'; console.log(chalk.green('chalk esm loads'));", + ], + output: "npm/esm/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(es_module_deno_test { + args: "test --allow-read --allow-env npm/esm/test.js", + output: "npm/esm/test.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(esm_import_cjs_default { + args: "run --allow-read --allow-env --quiet --check=all npm/esm_import_cjs_default/main.ts", + output: "npm/esm_import_cjs_default/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(cjs_with_deps { + args: "run --allow-read --allow-env npm/cjs_with_deps/main.js", + output: "npm/cjs_with_deps/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(cjs_sub_path { + args: "run --allow-read npm/cjs_sub_path/main.js", + output: "npm/cjs_sub_path/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(cjs_local_global_decls { + args: "run --allow-read npm/cjs_local_global_decls/main.ts", + output: "npm/cjs_local_global_decls/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(cjs_reexport_collision { + args: "run -A --quiet npm/cjs_reexport_collision/main.ts", + output: "npm/cjs_reexport_collision/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(cjs_this_in_exports { + args: "run --allow-read --quiet npm/cjs_this_in_exports/main.js", + output: "npm/cjs_this_in_exports/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, + exit_code: 1, +}); + +itest!(cjs_invalid_name_exports { + args: "run --allow-read --quiet npm/cjs-invalid-name-exports/main.ts", + output: "npm/cjs-invalid-name-exports/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(cjs_require_esm_error { + args: "run --allow-read --quiet npm/cjs_require_esm_error/main.ts", + output: "npm/cjs_require_esm_error/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, + exit_code: 1, +}); + +itest!(cjs_require_esm_mjs_error { + args: "run --allow-read --quiet npm/cjs_require_esm_mjs_error/main.ts", + output: "npm/cjs_require_esm_mjs_error/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, + exit_code: 1, +}); + +itest!(require_esm_error { + args: "run --allow-read --quiet node/require_esm_error/main.ts", + output: "node/require_esm_error/main.out", + exit_code: 1, +}); + +itest!(dynamic_import_deno_ts_from_npm { + args: "run --allow-read --quiet npm/dynamic_import_deno_ts_from_npm/main.ts", + output: "npm/dynamic_import_deno_ts_from_npm/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(translate_cjs_to_esm { + args: "run -A --quiet npm/translate_cjs_to_esm/main.js", + output: "npm/translate_cjs_to_esm/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(compare_globals { + args: "run --allow-read --check=all npm/compare_globals/main.ts", + output: "npm/compare_globals/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(conditional_exports { + args: "run --allow-read npm/conditional_exports/main.js", + output: "npm/conditional_exports/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(conditional_exports_node_modules_dir { + args: + "run --allow-read --node-modules-dir $TESTDATA/npm/conditional_exports/main.js", + output: "npm/conditional_exports/main_node_modules.out", + envs: env_vars_for_npm_tests(), + http_server: true, + temp_cwd: true, +}); + +itest!(dual_cjs_esm { + args: "run -A --quiet npm/dual_cjs_esm/main.ts", + output: "npm/dual_cjs_esm/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(child_process_fork_test { + args: "run -A --quiet npm/child_process_fork_test/main.ts", + output: "npm/child_process_fork_test/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(cjs_module_export_assignment { + args: "run -A --quiet --check=all npm/cjs_module_export_assignment/main.ts", + output: "npm/cjs_module_export_assignment/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(cjs_module_export_assignment_number { + args: + "run -A --quiet --check=all npm/cjs_module_export_assignment_number/main.ts", + output: "npm/cjs_module_export_assignment_number/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(mixed_case_package_name_global_dir { + args: "run npm/mixed_case_package_name/global.ts", + output: "npm/mixed_case_package_name/global.out", + exit_code: 0, + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(mixed_case_package_name_local_dir { + args: + "run --node-modules-dir -A $TESTDATA/npm/mixed_case_package_name/local.ts", + output: "npm/mixed_case_package_name/local.out", + exit_code: 0, + envs: env_vars_for_npm_tests(), + http_server: true, + temp_cwd: true, +}); + +itest!(local_dir_resolves_symlinks { + args: "run -A index.js", + output: "npm/local_dir_resolves_symlinks/index.out", + exit_code: 0, + envs: env_vars_for_npm_tests(), + cwd: Some("npm/local_dir_resolves_symlinks/"), + copy_temp_dir: Some("npm/local_dir_resolves_symlinks/"), + http_server: true, +}); + +// FIXME(bartlomieju): npm: specifiers are not handled in dynamic imports +// at the moment +// itest!(dynamic_import { +// args: "run --allow-read --allow-env npm/dynamic_import/main.ts", +// output: "npm/dynamic_import/main.out", +// envs: env_vars_for_npm_tests(), +// http_server: true, +// }); + +itest!(dynamic_import_reload_same_package { + args: "run -A --reload npm/dynamic_import_reload_same_package/main.ts", + output: "npm/dynamic_import_reload_same_package/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(dynamic_import_invalid_package_name { + args: "run -A --reload npm/dynamic_import_invalid_package_name/main.ts", + output: "npm/dynamic_import_invalid_package_name/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(env_var_re_export_dev { + args: "run --allow-read --allow-env --quiet npm/env_var_re_export/main.js", + output_str: Some("dev\n"), + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(env_var_re_export_prod { + args: "run --allow-read --allow-env --quiet npm/env_var_re_export/main.js", + output_str: Some("prod\n"), + envs: { + let mut vars = env_vars_for_npm_tests(); + vars.push(("NODE_ENV".to_string(), "production".to_string())); + vars + }, + http_server: true, +}); + +itest!(cached_only { + args: "run --cached-only npm/cached_only/main.ts", + output: "npm/cached_only/main.out", + envs: env_vars_for_npm_tests(), + exit_code: 1, +}); + +itest!(import_map { + args: "run --allow-read --allow-env --import-map npm/import_map/import_map.json npm/import_map/main.js", + output: "npm/import_map/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, + }); + +itest!(lock_file_integrity_failure { + args: "run --allow-read --allow-env --lock npm/lock_file/lock.json npm/lock_file/main.js", + output: "npm/lock_file/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, + exit_code: 10, + }); + +itest!(sub_paths { + args: "run -A --quiet npm/sub_paths/main.jsx", + output: "npm/sub_paths/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(remote_npm_specifier { + args: "run --quiet -A npm/remote_npm_specifier/main.ts", + output: "npm/remote_npm_specifier/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, + exit_code: 0, +}); + +itest!(tarball_with_global_header { + args: "run -A --quiet npm/tarball_with_global_header/main.js", + output: "npm/tarball_with_global_header/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(node_modules_deno_node_modules { + args: "run --quiet npm/node_modules_deno_node_modules/main.ts", + output: "npm/node_modules_deno_node_modules/main.out", + copy_temp_dir: Some("npm/node_modules_deno_node_modules/"), + exit_code: 0, + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(node_modules_deno_node_modules_local { + args: + "run --quiet --node-modules-dir npm/node_modules_deno_node_modules/main.ts", + output: "npm/node_modules_deno_node_modules/main.out", + copy_temp_dir: Some("npm/node_modules_deno_node_modules/"), + exit_code: 0, + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(nonexistent_file { + args: "run -A --quiet npm/nonexistent_file/main.js", + output: "npm/nonexistent_file/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, + exit_code: 1, +}); + +itest!(nonexistent_file_node_modules_dir { + // there was a bug where the message was different when using a node_modules dir + args: "run -A --quiet --node-modules-dir npm/nonexistent_file/main.js", + output: "npm/nonexistent_file/main.out", + copy_temp_dir: Some("npm/nonexistent_file/"), + envs: env_vars_for_npm_tests(), + http_server: true, + exit_code: 1, +}); + +itest!(invalid_package_name { + args: "run -A --quiet npm/invalid_package_name/main.js", + output: "npm/invalid_package_name/main.out", + envs: env_vars_for_npm_tests(), + exit_code: 1, +}); + +itest!(require_json { + args: "run -A --quiet npm/require_json/main.js", + output: "npm/require_json/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(error_version_after_subpath { + args: "run -A --quiet npm/error_version_after_subpath/main.js", + output: "npm/error_version_after_subpath/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, + exit_code: 1, +}); + +itest!(deno_cache { + args: "cache --reload npm:chalk npm:mkdirp", + output: "npm/deno_cache.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(check_all { + args: "check --all npm/check_errors/main.ts", + output: "npm/check_errors/main_all.out", + envs: env_vars_for_npm_tests(), + http_server: true, + exit_code: 1, +}); + +itest!(check_local { + args: "check npm/check_errors/main.ts", + output: "npm/check_errors/main_local.out", + envs: env_vars_for_npm_tests(), + http_server: true, + exit_code: 1, +}); + +itest!(types_general { + args: "check --quiet npm/types/main.ts", + output: "npm/types/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, + exit_code: 1, +}); + +itest!(types_ambient_module { + args: "check --quiet npm/types_ambient_module/main.ts", + output: "npm/types_ambient_module/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, + exit_code: 1, +}); + +itest!(types_ambient_module_import_map { + args: "check --quiet --import-map=npm/types_ambient_module/import_map.json npm/types_ambient_module/main_import_map.ts", + output: "npm/types_ambient_module/main_import_map.out", + envs: env_vars_for_npm_tests(), + http_server: true, + exit_code: 1, + }); + +itest!(no_types_cjs { + args: "check --quiet npm/no_types_cjs/main.ts", + output_str: Some(""), + exit_code: 0, + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(no_types_in_conditional_exports { + args: "run --check npm/no_types_in_conditional_exports/main.ts", + output: "npm/no_types_in_conditional_exports/main.out", + exit_code: 0, + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(types_entry_value_not_exists { + args: "check --all npm/types_entry_value_not_exists/main.ts", + output: "npm/types_entry_value_not_exists/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, + exit_code: 1, +}); + +itest!(types_exports_import_types { + args: "check --all npm/types_exports_import_types/main.ts", + output: "npm/types_exports_import_types/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, + exit_code: 1, +}); + +itest!(types_no_types_entry { + args: "check --all npm/types_no_types_entry/main.ts", + output: "npm/types_no_types_entry/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, + exit_code: 1, +}); + +itest!(types_d_ext { + args: "check --all npm/d_ext/main.ts", + output: "npm/d_ext/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(typescript_file_in_package { + args: "run npm/typescript_file_in_package/main.ts", + output: "npm/typescript_file_in_package/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, + exit_code: 1, +}); + +itest!(permissions_outside_package { + args: "run --allow-read npm/permissions_outside_package/main.ts", + output: "npm/permissions_outside_package/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(run_existing_npm_package { + args: "run --allow-read --node-modules-dir npm:@denotest/bin", + output: "npm/run_existing_npm_package/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, + temp_cwd: true, + cwd: Some("npm/run_existing_npm_package/"), + copy_temp_dir: Some("npm/run_existing_npm_package/"), +}); + +itest!(run_existing_npm_package_with_subpath { + args: + "run --allow-read --node-modules-dir npm:@denotest/bin/cli-esm dev --help", + output: "npm/run_existing_npm_package_with_subpath/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, + temp_cwd: true, + cwd: Some("npm/run_existing_npm_package_with_subpath/"), + copy_temp_dir: Some("npm/run_existing_npm_package_with_subpath/"), +}); + +#[test] +fn parallel_downloading() { + let (out, _err) = util::run_and_collect_output_with_args( + true, + vec![ + "run", + "--allow-read", + "--allow-env", + "npm/cjs_with_deps/main.js", + ], + None, + // don't use the sync env var + Some(env_vars_for_npm_tests()), + true, + ); + assert!(out.contains("chalk cjs loads")); +} + +#[test] +fn cached_only_after_first_run() { + let _server = http_server(); + + let deno_dir = util::new_deno_dir(); + + let deno = util::deno_cmd_with_deno_dir(&deno_dir) + .current_dir(util::testdata_path()) + .arg("run") + .arg("--allow-read") + .arg("--allow-env") + .arg("npm/cached_only_after_first_run/main1.ts") + .env("NO_COLOR", "1") + .envs(env_vars_for_npm_tests()) + .piped_output() + .spawn() + .unwrap(); + let output = deno.wait_with_output().unwrap(); + let stderr = String::from_utf8_lossy(&output.stderr); + let stdout = String::from_utf8_lossy(&output.stdout); + assert_contains!(stderr, "Download"); + assert_contains!(stdout, "[Function: chalk] createChalk"); + assert!(output.status.success()); + + let deno = util::deno_cmd_with_deno_dir(&deno_dir) + .current_dir(util::testdata_path()) + .arg("run") + .arg("--allow-read") + .arg("--allow-env") + .arg("--cached-only") + .arg("npm/cached_only_after_first_run/main2.ts") + .env("NO_COLOR", "1") + .envs(env_vars_for_npm_tests()) + .piped_output() + .spawn() + .unwrap(); + let output = deno.wait_with_output().unwrap(); + let stderr = String::from_utf8_lossy(&output.stderr); + let stdout = String::from_utf8_lossy(&output.stdout); + assert_contains!( + stderr, + "An npm specifier not found in cache: \"ansi-styles\", --cached-only is specified." + ); + assert!(stdout.is_empty()); + assert!(!output.status.success()); + + let deno = util::deno_cmd_with_deno_dir(&deno_dir) + .current_dir(util::testdata_path()) + .arg("run") + .arg("--allow-read") + .arg("--allow-env") + .arg("--cached-only") + .arg("npm/cached_only_after_first_run/main1.ts") + .env("NO_COLOR", "1") + .envs(env_vars_for_npm_tests()) + .piped_output() + .spawn() + .unwrap(); + + let output = deno.wait_with_output().unwrap(); + let stderr = String::from_utf8_lossy(&output.stderr); + let stdout = String::from_utf8_lossy(&output.stdout); + assert!(output.status.success()); + assert!(stderr.is_empty()); + assert_contains!(stdout, "[Function: chalk] createChalk"); +} + +#[test] +fn reload_flag() { + let _server = http_server(); + + let deno_dir = util::new_deno_dir(); + + let deno = util::deno_cmd_with_deno_dir(&deno_dir) + .current_dir(util::testdata_path()) + .arg("run") + .arg("--allow-read") + .arg("--allow-env") + .arg("npm/reload/main.ts") + .env("NO_COLOR", "1") + .envs(env_vars_for_npm_tests()) + .piped_output() + .spawn() + .unwrap(); + let output = deno.wait_with_output().unwrap(); + let stderr = String::from_utf8_lossy(&output.stderr); + let stdout = String::from_utf8_lossy(&output.stdout); + assert_contains!(stderr, "Download"); + assert_contains!(stdout, "[Function: chalk] createChalk"); + assert!(output.status.success()); + + let deno = util::deno_cmd_with_deno_dir(&deno_dir) + .current_dir(util::testdata_path()) + .arg("run") + .arg("--allow-read") + .arg("--allow-env") + .arg("--reload") + .arg("npm/reload/main.ts") + .env("NO_COLOR", "1") + .envs(env_vars_for_npm_tests()) + .piped_output() + .spawn() + .unwrap(); + let output = deno.wait_with_output().unwrap(); + let stderr = String::from_utf8_lossy(&output.stderr); + let stdout = String::from_utf8_lossy(&output.stdout); + assert_contains!(stderr, "Download"); + assert_contains!(stdout, "[Function: chalk] createChalk"); + assert!(output.status.success()); + + let deno = util::deno_cmd_with_deno_dir(&deno_dir) + .current_dir(util::testdata_path()) + .arg("run") + .arg("--allow-read") + .arg("--allow-env") + .arg("--reload=npm:") + .arg("npm/reload/main.ts") + .env("NO_COLOR", "1") + .envs(env_vars_for_npm_tests()) + .piped_output() + .spawn() + .unwrap(); + let output = deno.wait_with_output().unwrap(); + let stderr = String::from_utf8_lossy(&output.stderr); + let stdout = String::from_utf8_lossy(&output.stdout); + assert_contains!(stderr, "Download"); + assert_contains!(stdout, "[Function: chalk] createChalk"); + assert!(output.status.success()); + + let deno = util::deno_cmd_with_deno_dir(&deno_dir) + .current_dir(util::testdata_path()) + .arg("run") + .arg("--allow-read") + .arg("--allow-env") + .arg("--reload=npm:chalk") + .arg("npm/reload/main.ts") + .env("NO_COLOR", "1") + .envs(env_vars_for_npm_tests()) + .piped_output() + .spawn() + .unwrap(); + let output = deno.wait_with_output().unwrap(); + let stderr = String::from_utf8_lossy(&output.stderr); + let stdout = String::from_utf8_lossy(&output.stdout); + assert_contains!(stderr, "Download"); + assert_contains!(stdout, "[Function: chalk] createChalk"); + assert!(output.status.success()); + + let deno = util::deno_cmd_with_deno_dir(&deno_dir) + .current_dir(util::testdata_path()) + .arg("run") + .arg("--allow-read") + .arg("--allow-env") + .arg("--reload=npm:foobar") + .arg("npm/reload/main.ts") + .env("NO_COLOR", "1") + .envs(env_vars_for_npm_tests()) + .piped_output() + .spawn() + .unwrap(); + let output = deno.wait_with_output().unwrap(); + let stderr = String::from_utf8_lossy(&output.stderr); + let stdout = String::from_utf8_lossy(&output.stdout); + assert!(stderr.is_empty()); + assert_contains!(stdout, "[Function: chalk] createChalk"); + assert!(output.status.success()); +} + +#[test] +fn no_npm_after_first_run() { + let _server = http_server(); + + let deno_dir = util::new_deno_dir(); + + let deno = util::deno_cmd_with_deno_dir(&deno_dir) + .current_dir(util::testdata_path()) + .arg("run") + .arg("--allow-read") + .arg("--allow-env") + .arg("--no-npm") + .arg("npm/no_npm_after_first_run/main1.ts") + .env("NO_COLOR", "1") + .envs(env_vars_for_npm_tests()) + .piped_output() + .spawn() + .unwrap(); + let output = deno.wait_with_output().unwrap(); + let stderr = String::from_utf8_lossy(&output.stderr); + let stdout = String::from_utf8_lossy(&output.stdout); + assert_contains!( + stderr, + "error: npm specifiers were requested; but --no-npm is specified\n at file:///" + ); + assert!(stdout.is_empty()); + assert!(!output.status.success()); + + let deno = util::deno_cmd_with_deno_dir(&deno_dir) + .current_dir(util::testdata_path()) + .arg("run") + .arg("--allow-read") + .arg("--allow-env") + .arg("npm/no_npm_after_first_run/main1.ts") + .env("NO_COLOR", "1") + .envs(env_vars_for_npm_tests()) + .piped_output() + .spawn() + .unwrap(); + let output = deno.wait_with_output().unwrap(); + let stderr = String::from_utf8_lossy(&output.stderr); + let stdout = String::from_utf8_lossy(&output.stdout); + assert_contains!(stderr, "Download"); + assert_contains!(stdout, "[Function: chalk] createChalk"); + assert!(output.status.success()); + + let deno = util::deno_cmd_with_deno_dir(&deno_dir) + .current_dir(util::testdata_path()) + .arg("run") + .arg("--allow-read") + .arg("--allow-env") + .arg("--no-npm") + .arg("npm/no_npm_after_first_run/main1.ts") + .env("NO_COLOR", "1") + .envs(env_vars_for_npm_tests()) + .piped_output() + .spawn() + .unwrap(); + let output = deno.wait_with_output().unwrap(); + let stderr = String::from_utf8_lossy(&output.stderr); + let stdout = String::from_utf8_lossy(&output.stdout); + assert_contains!( + stderr, + "error: npm specifiers were requested; but --no-npm is specified\n at file:///" + ); + assert!(stdout.is_empty()); + assert!(!output.status.success()); +} + +#[test] +fn deno_run_cjs_module() { + let _server = http_server(); + + let deno_dir = util::new_deno_dir(); + + let deno = util::deno_cmd_with_deno_dir(&deno_dir) + .current_dir(deno_dir.path()) + .arg("run") + .arg("--allow-read") + .arg("--allow-env") + .arg("--allow-write") + .arg("npm:mkdirp@1.0.4") + .arg("test_dir") + .env("NO_COLOR", "1") + .envs(env_vars_for_npm_tests()) + .spawn() + .unwrap(); + let output = deno.wait_with_output().unwrap(); + assert!(output.status.success()); + + assert!(deno_dir.path().join("test_dir").exists()); +} + +itest!(deno_run_cowsay { + args: "run -A --quiet npm:cowsay@1.5.0 Hello", + output: "npm/deno_run_cowsay.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(deno_run_cowsay_with_node_modules_dir { + args: "run -A --quiet --node-modules-dir npm:cowsay@1.5.0 Hello", + temp_cwd: true, + output: "npm/deno_run_cowsay.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(deno_run_cowsay_explicit { + args: "run -A --quiet npm:cowsay@1.5.0/cowsay Hello", + output: "npm/deno_run_cowsay.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(deno_run_cowthink { + args: "run -A --quiet npm:cowsay@1.5.0/cowthink Hello", + output: "npm/deno_run_cowthink.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(deno_run_bin_esm { + args: "run -A --quiet npm:@denotest/bin/cli-esm this is a test", + output: "npm/deno_run_esm.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(deno_run_bin_esm_no_bin_entrypoint { + args: "run -A --quiet npm:@denotest/bin@0.6.0/cli.mjs this is a test", + output: "npm/deno_run_esm.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(deno_run_bin_cjs_no_bin_entrypoint { + args: "run -A --quiet npm:@denotest/bin@0.6.0/cli-cjs.js this is a test", + output: "npm/deno_run_cjs.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(deno_run_bin_special_chars { + args: "run -A --quiet npm:@denotest/special-chars-in-bin-name/\\foo\" this is a test", + output: "npm/deno_run_special_chars_in_bin_name.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(deno_run_bin_no_ext { + args: "run -A --quiet npm:@denotest/bin/cli-no-ext this is a test", + output: "npm/deno_run_no_ext.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(deno_run_bin_cjs { + args: "run -A --quiet npm:@denotest/bin/cli-cjs this is a test", + output: "npm/deno_run_cjs.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +#[test] +fn deno_run_bin_lockfile() { + let context = TestContextBuilder::for_npm().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + temp_dir.write("deno.json", "{}"); + let output = context + .new_command() + .args("run -A --quiet npm:@denotest/bin/cli-esm this is a test") + .run(); + output.assert_matches_file("npm/deno_run_esm.out"); + assert!(temp_dir.path().join("deno.lock").exists()); +} + +itest!(deno_run_non_existent { + args: "run npm:mkdirp@0.5.125", + output: "npm/deno_run_non_existent.out", + envs: env_vars_for_npm_tests(), + http_server: true, + exit_code: 1, +}); + +itest!(deno_run_no_bin_entrypoint { + args: "run -A --quiet npm:@denotest/esm-basic", + output: "npm/deno_run_no_bin_entrypoint.out", + envs: env_vars_for_npm_tests(), + http_server: true, + exit_code: 1, +}); + +itest!(deno_run_no_bin_entrypoint_non_existent_subpath { + args: "run -A --quiet npm:@denotest/esm-basic/non-existent.js", + output: "npm/deno_run_no_bin_entrypoint_non_existent_subpath.out", + envs: env_vars_for_npm_tests(), + http_server: true, + exit_code: 1, +}); + +itest!(directory_import_folder_index_js { + args: "run npm/directory_import/folder_index_js.ts", + output: "npm/directory_import/folder_index_js.out", + envs: env_vars_for_npm_tests(), + http_server: true, + exit_code: 1, +}); + +itest!(directory_import_folder_no_index { + args: "run npm/directory_import/folder_no_index.ts", + output: "npm/directory_import/folder_no_index.out", + envs: env_vars_for_npm_tests(), + http_server: true, + exit_code: 1, +}); + +itest!(builtin_module_module { + args: "run --allow-read --quiet npm/builtin_module_module/main.js", + output: "npm/builtin_module_module/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(node_modules_dir_require_added_node_modules_folder { + args: + "run --node-modules-dir -A --quiet $TESTDATA/npm/require_added_nm_folder/main.js", + output: "npm/require_added_nm_folder/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, + exit_code: 0, + temp_cwd: true, +}); + +itest!(node_modules_dir_require_main_entry { + args: "run --node-modules-dir -A --quiet $TESTDATA/npm/require_main/main.js", + output: "npm/require_main/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, + exit_code: 0, + temp_cwd: true, +}); + +itest!(node_modules_dir_with_deps { + args: "run --allow-read --allow-env --node-modules-dir $TESTDATA/npm/cjs_with_deps/main.js", + output: "npm/cjs_with_deps/main_node_modules.out", + envs: env_vars_for_npm_tests(), + http_server: true, + temp_cwd: true, +}); + +itest!(node_modules_dir_yargs { + args: "run --allow-read --allow-env --node-modules-dir $TESTDATA/npm/cjs_yargs/main.js", + output: "npm/cjs_yargs/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, + temp_cwd: true, +}); + +#[test] +fn node_modules_dir_cache() { + let _server = http_server(); + + let deno_dir = util::new_deno_dir(); + + let deno = util::deno_cmd_with_deno_dir(&deno_dir) + .current_dir(deno_dir.path()) + .arg("cache") + .arg("--node-modules-dir") + .arg("--quiet") + .arg(util::testdata_path().join("npm/dual_cjs_esm/main.ts")) + .envs(env_vars_for_npm_tests()) + .spawn() + .unwrap(); + let output = deno.wait_with_output().unwrap(); + assert!(output.status.success()); + + let node_modules = deno_dir.path().join("node_modules"); + assert!(node_modules + .join( + ".deno/@denotest+dual-cjs-esm@1.0.0/node_modules/@denotest/dual-cjs-esm" + ) + .exists()); + assert!(node_modules.join("@denotest/dual-cjs-esm").exists()); + + // now try deleting the folder with the package source in the npm cache dir + let package_global_cache_dir = deno_dir + .path() + .join("npm") + .join("localhost_4545") + .join("npm") + .join("registry") + .join("@denotest") + .join("dual-cjs-esm") + .join("1.0.0"); + assert!(package_global_cache_dir.exists()); + std::fs::remove_dir_all(&package_global_cache_dir).unwrap(); + + // run the output, and it shouldn't bother recreating the directory + // because it already has everything cached locally in the node_modules folder + let deno = util::deno_cmd_with_deno_dir(&deno_dir) + .current_dir(deno_dir.path()) + .arg("run") + .arg("--node-modules-dir") + .arg("--quiet") + .arg("-A") + .arg(util::testdata_path().join("npm/dual_cjs_esm/main.ts")) + .envs(env_vars_for_npm_tests()) + .spawn() + .unwrap(); + let output = deno.wait_with_output().unwrap(); + assert!(output.status.success()); + + // this won't exist, but actually the parent directory + // will because it still re-downloads the registry information + assert!(!package_global_cache_dir.exists()); +} + +#[test] +fn ensure_registry_files_local() { + // ensures the registry files all point at local tarballs + let registry_dir_path = util::testdata_path().join("npm").join("registry"); + for entry in std::fs::read_dir(®istry_dir_path).unwrap() { + let entry = entry.unwrap(); + if entry.metadata().unwrap().is_dir() { + let registry_json_path = registry_dir_path + .join(entry.file_name()) + .join("registry.json"); + if registry_json_path.exists() { + let file_text = std::fs::read_to_string(®istry_json_path).unwrap(); + if file_text.contains("https://registry.npmjs.org/") { + panic!( + "file {} contained a reference to the npm registry", + registry_json_path + ); + } + } + } + } +} + +itest!(bundle_errors { + args: "bundle --quiet npm/esm/main.js", + output_str: Some("error: npm specifiers have not yet been implemented for this subcommand (https://github.com/denoland/deno/issues/15960). Found: npm:/chalk@5.0.1\n"), + exit_code: 1, + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(info_chalk_display { + args: "info --quiet npm/cjs_with_deps/main.js", + output: "npm/cjs_with_deps/main_info.out", + exit_code: 0, + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(info_chalk_display_node_modules_dir { + args: "info --quiet --node-modules-dir $TESTDATA/npm/cjs_with_deps/main.js", + output: "npm/cjs_with_deps/main_info.out", + exit_code: 0, + envs: env_vars_for_npm_tests(), + http_server: true, + temp_cwd: true, +}); + +itest!(info_chalk_json { + args: "info --quiet --json npm/cjs_with_deps/main.js", + output: "npm/cjs_with_deps/main_info_json.out", + exit_code: 0, + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(info_chalk_json_node_modules_dir { + args: + "info --quiet --node-modules-dir --json $TESTDATA/npm/cjs_with_deps/main.js", + output: "npm/cjs_with_deps/main_info_json.out", + exit_code: 0, + envs: env_vars_for_npm_tests(), + http_server: true, + temp_cwd: true, +}); + +itest!(info_cli_chalk_display { + args: "info --quiet npm:chalk@4", + output: "npm/info/chalk.out", + exit_code: 0, + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(info_cli_chalk_json { + args: "info --quiet --json npm:chalk@4", + output: "npm/info/chalk_json.out", + exit_code: 0, + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +#[test] +fn lock_file_missing_top_level_package() { + let _server = http_server(); + + let deno_dir = util::new_deno_dir(); + let temp_dir = util::TempDir::new(); + + // write empty config file + temp_dir.write("deno.json", "{}"); + + // Lock file that is automatically picked up has been intentionally broken, + // by removing "cowsay" package from it. This test ensures that npm resolver + // snapshot can be successfully hydrated in such situation + let lock_file_content = r#"{ + "version": "2", + "remote": {}, + "npm": { + "specifiers": { "cowsay": "cowsay@1.5.0" }, + "packages": { + "ansi-regex@3.0.1": { + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dependencies": {} + }, + "ansi-regex@5.0.1": { + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dependencies": {} + }, + "ansi-styles@4.3.0": { + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { "color-convert": "color-convert@2.0.1" } + }, + "camelcase@5.3.1": { + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dependencies": {} + }, + "cliui@6.0.0": { + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dependencies": { + "string-width": "string-width@4.2.3", + "strip-ansi": "strip-ansi@6.0.1", + "wrap-ansi": "wrap-ansi@6.2.0" + } + }, + "color-convert@2.0.1": { + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { "color-name": "color-name@1.1.4" } + }, + "color-name@1.1.4": { + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dependencies": {} + }, + "decamelize@1.2.0": { + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dependencies": {} + }, + "emoji-regex@8.0.0": { + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dependencies": {} + }, + "find-up@4.1.0": { + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dependencies": { + "locate-path": "locate-path@5.0.0", + "path-exists": "path-exists@4.0.0" + } + }, + "get-caller-file@2.0.5": { + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dependencies": {} + }, + "get-stdin@8.0.0": { + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "dependencies": {} + }, + "is-fullwidth-code-point@2.0.0": { + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dependencies": {} + }, + "is-fullwidth-code-point@3.0.0": { + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dependencies": {} + }, + "locate-path@5.0.0": { + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dependencies": { "p-locate": "p-locate@4.1.0" } + }, + "p-limit@2.3.0": { + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dependencies": { "p-try": "p-try@2.2.0" } + }, + "p-locate@4.1.0": { + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dependencies": { "p-limit": "p-limit@2.3.0" } + }, + "p-try@2.2.0": { + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dependencies": {} + }, + "path-exists@4.0.0": { + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dependencies": {} + }, + "require-directory@2.1.1": { + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dependencies": {} + }, + "require-main-filename@2.0.0": { + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dependencies": {} + }, + "set-blocking@2.0.0": { + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dependencies": {} + }, + "string-width@2.1.1": { + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dependencies": { + "is-fullwidth-code-point": "is-fullwidth-code-point@2.0.0", + "strip-ansi": "strip-ansi@4.0.0" + } + }, + "string-width@4.2.3": { + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "emoji-regex@8.0.0", + "is-fullwidth-code-point": "is-fullwidth-code-point@3.0.0", + "strip-ansi": "strip-ansi@6.0.1" + } + }, + "strip-ansi@4.0.0": { + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dependencies": { "ansi-regex": "ansi-regex@3.0.1" } + }, + "strip-ansi@6.0.1": { + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { "ansi-regex": "ansi-regex@5.0.1" } + }, + "strip-final-newline@2.0.0": { + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dependencies": {} + }, + "which-module@2.0.0": { + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", + "dependencies": {} + }, + "wrap-ansi@6.2.0": { + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dependencies": { + "ansi-styles": "ansi-styles@4.3.0", + "string-width": "string-width@4.2.3", + "strip-ansi": "strip-ansi@6.0.1" + } + }, + "y18n@4.0.3": { + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dependencies": {} + }, + "yargs-parser@18.1.3": { + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dependencies": { + "camelcase": "camelcase@5.3.1", + "decamelize": "decamelize@1.2.0" + } + }, + "yargs@15.4.1": { + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dependencies": { + "cliui": "cliui@6.0.0", + "decamelize": "decamelize@1.2.0", + "find-up": "find-up@4.1.0", + "get-caller-file": "get-caller-file@2.0.5", + "require-directory": "require-directory@2.1.1", + "require-main-filename": "require-main-filename@2.0.0", + "set-blocking": "set-blocking@2.0.0", + "string-width": "string-width@4.2.3", + "which-module": "which-module@2.0.0", + "y18n": "y18n@4.0.3", + "yargs-parser": "yargs-parser@18.1.3" + } + } + } + } + } + "#; + temp_dir.write("deno.lock", lock_file_content); + let main_contents = r#" + import cowsay from "npm:cowsay"; + console.log(cowsay); + "#; + temp_dir.write("main.ts", main_contents); + + let deno = util::deno_cmd_with_deno_dir(&deno_dir) + .current_dir(temp_dir.path()) + .arg("run") + .arg("--quiet") + .arg("--lock") + .arg("deno.lock") + .arg("-A") + .arg("main.ts") + .envs(env_vars_for_npm_tests()) + .piped_output() + .spawn() + .unwrap(); + let output = deno.wait_with_output().unwrap(); + assert!(!output.status.success()); + + let stderr = String::from_utf8(output.stderr).unwrap(); + assert_eq!( + stderr, + concat!( + "error: failed reading lockfile 'deno.lock'\n", + "\n", + "Caused by:\n", + " 0: The lockfile is corrupt. You can recreate it with --lock-write\n", + " 1: Could not find 'cowsay@1.5.0' in the list of packages.\n" + ) + ); +} + +#[test] +fn lock_file_lock_write() { + // https://github.com/denoland/deno/issues/16666 + // Ensure that --lock-write still adds npm packages to the lockfile + let _server = http_server(); + + let deno_dir = util::new_deno_dir(); + let temp_dir = util::TempDir::new(); + + // write empty config file + temp_dir.write("deno.json", "{}"); + + // write a lock file with borked integrity + let lock_file_content = r#"{ + "version": "3", + "packages": { + "specifiers": { + "npm:cowsay@1.5.0": "npm:cowsay@1.5.0" + }, + "npm": { + "ansi-regex@3.0.1": { + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dependencies": {} + }, + "ansi-regex@5.0.1": { + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dependencies": {} + }, + "ansi-styles@4.3.0": { + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "color-convert@2.0.1" + } + }, + "camelcase@5.3.1": { + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dependencies": {} + }, + "cliui@6.0.0": { + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dependencies": { + "string-width": "string-width@4.2.3", + "strip-ansi": "strip-ansi@6.0.1", + "wrap-ansi": "wrap-ansi@6.2.0" + } + }, + "color-convert@2.0.1": { + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "color-name@1.1.4" + } + }, + "color-name@1.1.4": { + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dependencies": {} + }, + "cowsay@1.5.0": { + "integrity": "sha512-8Ipzr54Z8zROr/62C8f0PdhQcDusS05gKTS87xxdji8VbWefWly0k8BwGK7+VqamOrkv3eGsCkPtvlHzrhWsCA==", + "dependencies": { + "get-stdin": "get-stdin@8.0.0", + "string-width": "string-width@2.1.1", + "strip-final-newline": "strip-final-newline@2.0.0", + "yargs": "yargs@15.4.1" + } + }, + "decamelize@1.2.0": { + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dependencies": {} + }, + "emoji-regex@8.0.0": { + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dependencies": {} + }, + "find-up@4.1.0": { + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dependencies": { + "locate-path": "locate-path@5.0.0", + "path-exists": "path-exists@4.0.0" + } + }, + "get-caller-file@2.0.5": { + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dependencies": {} + }, + "get-stdin@8.0.0": { + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "dependencies": {} + }, + "is-fullwidth-code-point@2.0.0": { + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dependencies": {} + }, + "is-fullwidth-code-point@3.0.0": { + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dependencies": {} + }, + "locate-path@5.0.0": { + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dependencies": { + "p-locate": "p-locate@4.1.0" + } + }, + "p-limit@2.3.0": { + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dependencies": { + "p-try": "p-try@2.2.0" + } + }, + "p-locate@4.1.0": { + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dependencies": { + "p-limit": "p-limit@2.3.0" + } + }, + "p-try@2.2.0": { + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dependencies": {} + }, + "path-exists@4.0.0": { + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dependencies": {} + }, + "require-directory@2.1.1": { + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dependencies": {} + }, + "require-main-filename@2.0.0": { + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dependencies": {} + }, + "set-blocking@2.0.0": { + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dependencies": {} + }, + "string-width@2.1.1": { + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dependencies": { + "is-fullwidth-code-point": "is-fullwidth-code-point@2.0.0", + "strip-ansi": "strip-ansi@4.0.0" + } + }, + "string-width@4.2.3": { + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "emoji-regex@8.0.0", + "is-fullwidth-code-point": "is-fullwidth-code-point@3.0.0", + "strip-ansi": "strip-ansi@6.0.1" + } + }, + "strip-ansi@4.0.0": { + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dependencies": { + "ansi-regex": "ansi-regex@3.0.1" + } + }, + "strip-ansi@6.0.1": { + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "ansi-regex@5.0.1" + } + }, + "strip-final-newline@2.0.0": { + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dependencies": {} + }, + "which-module@2.0.0": { + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", + "dependencies": {} + }, + "wrap-ansi@6.2.0": { + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dependencies": { + "ansi-styles": "ansi-styles@4.3.0", + "string-width": "string-width@4.2.3", + "strip-ansi": "strip-ansi@6.0.1" + } + }, + "y18n@4.0.3": { + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dependencies": {} + }, + "yargs-parser@18.1.3": { + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dependencies": { + "camelcase": "camelcase@5.3.1", + "decamelize": "decamelize@1.2.0" + } + }, + "yargs@15.4.1": { + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dependencies": { + "cliui": "cliui@6.0.0", + "decamelize": "decamelize@1.2.0", + "find-up": "find-up@4.1.0", + "get-caller-file": "get-caller-file@2.0.5", + "require-directory": "require-directory@2.1.1", + "require-main-filename": "require-main-filename@2.0.0", + "set-blocking": "set-blocking@2.0.0", + "string-width": "string-width@4.2.3", + "which-module": "which-module@2.0.0", + "y18n": "y18n@4.0.3", + "yargs-parser": "yargs-parser@18.1.3" + } + } + } + }, + "remote": {} +} +"#; + temp_dir.write("deno.lock", lock_file_content); + + let deno = util::deno_cmd_with_deno_dir(&deno_dir) + .current_dir(temp_dir.path()) + .arg("cache") + .arg("--lock-write") + .arg("--quiet") + .arg("npm:cowsay@1.5.0") + .envs(env_vars_for_npm_tests()) + .piped_output() + .spawn() + .unwrap(); + let output = deno.wait_with_output().unwrap(); + assert!(output.status.success()); + assert_eq!(output.status.code(), Some(0)); + + let stdout = String::from_utf8(output.stdout).unwrap(); + assert!(stdout.is_empty()); + let stderr = String::from_utf8(output.stderr).unwrap(); + assert!(stderr.is_empty()); + assert_eq!( + lock_file_content, + std::fs::read_to_string(temp_dir.path().join("deno.lock")).unwrap() + ); +} + +#[test] +fn auto_discover_lock_file() { + let context = TestContextBuilder::for_npm().use_temp_cwd().build(); + + let temp_dir = context.temp_dir(); + + // write empty config file + temp_dir.write("deno.json", "{}"); + + // write a lock file with borked integrity + let lock_file_content = r#"{ + "version": "3", + "packages": { + "specifiers": { "npm:@denotest/bin": "npm:@denotest/bin@1.0.0" }, + "npm": { + "@denotest/bin@1.0.0": { + "integrity": "sha512-foobar", + "dependencies": {} + } + } + }, + "remote": {} + }"#; + temp_dir.write("deno.lock", lock_file_content); + + let output = context + .new_command() + .args("run -A npm:@denotest/bin/cli-esm test") + .run(); + output + .assert_matches_text( +r#"Download http://localhost:4545/npm/registry/@denotest/bin +error: Integrity check failed for npm package: "@denotest/bin@1.0.0". Unable to verify that the package +is the same as when the lockfile was generated. + +Actual: sha512-[WILDCARD] +Expected: sha512-foobar + +This could be caused by: + * the lock file may be corrupt + * the source itself may be corrupt + +Use "--lock-write" flag to regenerate the lockfile at "[WILDCARD]deno.lock". +"#) + .assert_exit_code(10); +} + +#[test] +fn peer_deps_with_copied_folders_and_lockfile() { + let context = TestContextBuilder::for_npm() + .use_copy_temp_dir("npm/peer_deps_with_copied_folders") + .cwd("npm/peer_deps_with_copied_folders") + .build(); + + let deno_dir = context.deno_dir(); + let temp_dir = context.temp_dir(); + let temp_dir_sub_path = + temp_dir.path().join("npm/peer_deps_with_copied_folders"); + + // write empty config file + temp_dir.write("npm/peer_deps_with_copied_folders/deno.json", "{}"); + + let output = context.new_command().args("run -A main.ts").run(); + output.assert_exit_code(0); + output.assert_matches_file("npm/peer_deps_with_copied_folders/main.out"); + + assert!(temp_dir_sub_path.join("deno.lock").exists()); + let grandchild_path = deno_dir + .path() + .join("npm") + .join("localhost_4545") + .join("npm") + .join("registry") + .join("@denotest") + .join("peer-dep-test-grandchild"); + assert!(grandchild_path.join("1.0.0").exists()); + assert!(grandchild_path.join("1.0.0_1").exists()); // copy folder, which is hardlinked + + // run again + let output = context.new_command().args("run -A main.ts").run(); + output.assert_exit_code(0); + output.assert_matches_text("1\n2\n"); + + // run with reload + let output = context.new_command().args("run -A --reload main.ts").run(); + output.assert_exit_code(0); + output.assert_matches_file("npm/peer_deps_with_copied_folders/main.out"); + + // now run with local node modules + let output = context + .new_command() + .args("run -A --node-modules-dir main.ts") + .run(); + output.assert_exit_code(0); + output.assert_matches_file( + "npm/peer_deps_with_copied_folders/main_node_modules.out", + ); + + let deno_folder = temp_dir_sub_path.join("node_modules").join(".deno"); + assert!(deno_folder + .join("@denotest+peer-dep-test-grandchild@1.0.0") + .exists()); + assert!(deno_folder + .join("@denotest+peer-dep-test-grandchild@1.0.0_1") + .exists()); // copy folder + + // now again run with local node modules + let output = context + .new_command() + .args("run -A --node-modules-dir main.ts") + .run(); + output.assert_exit_code(0); + output.assert_matches_text("1\n2\n"); + + // now ensure it works with reloading + let output = context + .new_command() + .args("run -A --reload --node-modules-dir main.ts") + .run(); + output.assert_exit_code(0); + output.assert_matches_file( + "npm/peer_deps_with_copied_folders/main_node_modules_reload.out", + ); + + // now ensure it works with reloading and no lockfile + let output = context + .new_command() + .args("run -A --reload --node-modules-dir --no-lock main.ts") + .run(); + output.assert_exit_code(0); + output.assert_matches_file( + "npm/peer_deps_with_copied_folders/main_node_modules_reload.out", + ); +} + +itest!(info_peer_deps { + args: "info --quiet npm/peer_deps_with_copied_folders/main.ts", + output: "npm/peer_deps_with_copied_folders/main_info.out", + exit_code: 0, + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(info_peer_deps_json { + args: "info --quiet --json npm/peer_deps_with_copied_folders/main.ts", + output: "npm/peer_deps_with_copied_folders/main_info_json.out", + exit_code: 0, + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(create_require { + args: "run --reload --allow-read npm/create_require/main.ts", + output: "npm/create_require/main.out", + exit_code: 0, + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(node_modules_import_run { + args: "run --quiet main.ts", + output: "npm/node_modules_import/main.out", + http_server: true, + copy_temp_dir: Some("npm/node_modules_import/"), + cwd: Some("npm/node_modules_import/"), + envs: env_vars_for_npm_tests(), + exit_code: 0, +}); + +itest!(node_modules_import_check { + args: "check --quiet main.ts", + output: "npm/node_modules_import/main_check.out", + envs: env_vars_for_npm_tests(), + http_server: true, + cwd: Some("npm/node_modules_import/"), + copy_temp_dir: Some("npm/node_modules_import/"), + exit_code: 1, +}); + +itest!(non_existent_dep { + args: "cache npm:@denotest/non-existent-dep", + envs: env_vars_for_npm_tests(), + http_server: true, + exit_code: 1, + output_str: Some(concat!( + "[UNORDERED_START]\n", + "Download http://localhost:4545/npm/registry/@denotest/non-existent-dep\n", + "Download http://localhost:4545/npm/registry/@denotest/non-existent\n", + "[UNORDERED_END]\n", + "error: npm package '@denotest/non-existent' does not exist.\n" + )), +}); + +itest!(non_existent_dep_version { + args: "cache npm:@denotest/non-existent-dep-version", + envs: env_vars_for_npm_tests(), + http_server: true, + exit_code: 1, + output_str: Some(concat!( + "[UNORDERED_START]\n", + "Download http://localhost:4545/npm/registry/@denotest/non-existent-dep-version\n", + "Download http://localhost:4545/npm/registry/@denotest/esm-basic\n", + "[UNORDERED_END]\n", + // does two downloads because when failing once it max tries to + // get the latest version a second time + "[UNORDERED_START]\n", + "Download http://localhost:4545/npm/registry/@denotest/non-existent-dep-version\n", + "Download http://localhost:4545/npm/registry/@denotest/esm-basic\n", + "[UNORDERED_END]\n", + "error: Could not find npm package '@denotest/esm-basic' matching '=99.99.99'.\n" + )), +}); + +#[test] +fn reload_info_not_found_cache_but_exists_remote() { + fn remove_version(registry_json: &mut Value, version: &str) { + registry_json + .as_object_mut() + .unwrap() + .get_mut("versions") + .unwrap() + .as_object_mut() + .unwrap() + .remove(version); + } + + fn remove_version_for_package( + deno_dir: &util::TempDir, + package: &str, + version: &str, + ) { + let registry_json_path = + format!("npm/localhost_4545/npm/registry/{}/registry.json", package); + let mut registry_json: Value = + serde_json::from_str(&deno_dir.read_to_string(®istry_json_path)) + .unwrap(); + remove_version(&mut registry_json, version); + // for the purpose of this test, just remove the dist-tag as it might contain this version + registry_json + .as_object_mut() + .unwrap() + .get_mut("dist-tags") + .unwrap() + .as_object_mut() + .unwrap() + .remove("latest"); + deno_dir.write( + ®istry_json_path, + serde_json::to_string(®istry_json).unwrap(), + ); + } + + // This tests that when a local machine doesn't have a version + // specified in a dependency that exists in the npm registry + let test_context = TestContextBuilder::for_npm().use_temp_cwd().build(); + let deno_dir = test_context.deno_dir(); + let temp_dir = test_context.temp_dir(); + temp_dir.write( + "main.ts", + "import 'npm:@denotest/esm-import-cjs-default@1.0.0';", + ); + + // cache successfully to the deno_dir + let output = test_context + .new_command() + .args("cache main.ts npm:@denotest/esm-basic@1.0.0") + .run(); + output.assert_matches_text(concat!( + "[UNORDERED_START]\n", + "Download http://localhost:4545/npm/registry/@denotest/esm-basic\n", + "Download http://localhost:4545/npm/registry/@denotest/esm-import-cjs-default\n", + "Download http://localhost:4545/npm/registry/@denotest/cjs-default-export\n", + "Download http://localhost:4545/npm/registry/@denotest/cjs-default-export/1.0.0.tgz\n", + "Download http://localhost:4545/npm/registry/@denotest/esm-basic/1.0.0.tgz\n", + "Download http://localhost:4545/npm/registry/@denotest/esm-import-cjs-default/1.0.0.tgz\n", + "[UNORDERED_END]\n", + )); + + // test in dependency + { + // modify the package information in the cache to remove the latest version + remove_version_for_package( + deno_dir, + "@denotest/cjs-default-export", + "1.0.0", + ); + + // should error when `--cache-only` is used now because the version is not in the cache + let output = test_context + .new_command() + .args("run --cached-only main.ts") + .run(); + output.assert_exit_code(1); + output.assert_matches_text("error: Could not find npm package '@denotest/cjs-default-export' matching '^1.0.0'.\n"); + + // now try running without it, it should download the package now + let output = test_context.new_command().args("run main.ts").run(); + output.assert_matches_text(concat!( + "[UNORDERED_START]\n", + "Download http://localhost:4545/npm/registry/@denotest/esm-import-cjs-default\n", + "Download http://localhost:4545/npm/registry/@denotest/cjs-default-export\n", + "[UNORDERED_END]\n", + "Node esm importing node cjs\n[WILDCARD]", + )); + output.assert_exit_code(0); + } + + // test in npm specifier + { + // now remove the information for the top level package + remove_version_for_package( + deno_dir, + "@denotest/esm-import-cjs-default", + "1.0.0", + ); + + // should error for --cached-only + let output = test_context + .new_command() + .args("run --cached-only main.ts") + .run(); + output.assert_matches_text(concat!( + "error: Could not find npm package '@denotest/esm-import-cjs-default' matching '1.0.0'.\n", + " at file:///[WILDCARD]/main.ts:1:8\n", + )); + output.assert_exit_code(1); + + // now try running, it should work + let output = test_context.new_command().args("run main.ts").run(); + output.assert_matches_text(concat!( + "[UNORDERED_START]\n", + "Download http://localhost:4545/npm/registry/@denotest/esm-import-cjs-default\n", + "Download http://localhost:4545/npm/registry/@denotest/cjs-default-export\n", + "[UNORDERED_END]\n", + "Node esm importing node cjs\n[WILDCARD]", + )); + output.assert_exit_code(0); + } + + // test matched specifier in package.json + { + // write out a package.json and a new main.ts with a bare specifier + temp_dir.write("main.ts", "import '@denotest/esm-import-cjs-default';"); + temp_dir.write( + "package.json", + r#"{ "dependencies": { "@denotest/esm-import-cjs-default": "1.0.0" }}"#, + ); + + // remove the top level package information again + remove_version_for_package( + deno_dir, + "@denotest/esm-import-cjs-default", + "1.0.0", + ); + + // should error for --cached-only + let output = test_context + .new_command() + .args("run --cached-only main.ts") + .run(); + output.assert_matches_text(concat!( + "error: Could not find npm package '@denotest/esm-import-cjs-default' matching '1.0.0'.\n", + )); + output.assert_exit_code(1); + + // now try running, it should work + let output = test_context.new_command().args("run main.ts").run(); + output.assert_matches_text(concat!( + "[UNORDERED_START]\n", + "Download http://localhost:4545/npm/registry/@denotest/esm-import-cjs-default\n", + "Download http://localhost:4545/npm/registry/@denotest/cjs-default-export\n", + "[UNORDERED_END]\n", + "[UNORDERED_START]\n", + "Initialize @denotest/cjs-default-export@1.0.0\n", + "Initialize @denotest/esm-import-cjs-default@1.0.0\n", + "[UNORDERED_END]\n", + "Node esm importing node cjs\n[WILDCARD]", + )); + output.assert_exit_code(0); + } + + // temp other dependency in package.json + { + // write out a package.json that has another dependency + temp_dir.write( + "package.json", + r#"{ "dependencies": { "@denotest/esm-import-cjs-default": "1.0.0", "@denotest/esm-basic": "1.0.0" }}"#, + ); + + // remove the dependency's version + remove_version_for_package(deno_dir, "@denotest/esm-basic", "1.0.0"); + + // should error for --cached-only + let output = test_context + .new_command() + .args("run --cached-only main.ts") + .run(); + output.assert_matches_text(concat!( + "error: Could not find npm package '@denotest/esm-basic' matching '1.0.0'.\n", + )); + output.assert_exit_code(1); + + // now try running, it should work and only initialize the new package + let output = test_context.new_command().args("run main.ts").run(); + output.assert_matches_text(concat!( + "[UNORDERED_START]\n", + "Download http://localhost:4545/npm/registry/@denotest/esm-basic\n", + "Download http://localhost:4545/npm/registry/@denotest/esm-import-cjs-default\n", + "Download http://localhost:4545/npm/registry/@denotest/cjs-default-export\n", + "[UNORDERED_END]\n", + "Initialize @denotest/esm-basic@1.0.0\n", + "Node esm importing node cjs\n[WILDCARD]", + )); + output.assert_exit_code(0); + } + + // now try using a lockfile + { + // create it + temp_dir.write("deno.json", r#"{}"#); + test_context.new_command().args("cache main.ts").run(); + assert!(temp_dir.path().join("deno.lock").exists()); + + // remove a version found in the lockfile + remove_version_for_package(deno_dir, "@denotest/esm-basic", "1.0.0"); + + // should error for --cached-only + let output = test_context + .new_command() + .args("run --cached-only main.ts") + .run(); + output.assert_matches_text(concat!( + "error: failed reading lockfile '[WILDCARD]deno.lock'\n", + "\n", + "Caused by:\n", + " 0: Could not find '@denotest/esm-basic@1.0.0' specified in the lockfile.\n", + " 1: Could not find version '1.0.0' for npm package '@denotest/esm-basic'.\n", + )); + output.assert_exit_code(1); + + // now try running, it should work and only initialize the new package + let output = test_context.new_command().args("run main.ts").run(); + output.assert_matches_text(concat!( + "[UNORDERED_START]\n", + "Download http://localhost:4545/npm/registry/@denotest/cjs-default-export\n", + "Download http://localhost:4545/npm/registry/@denotest/esm-basic\n", + "Download http://localhost:4545/npm/registry/@denotest/esm-import-cjs-default\n", + "[UNORDERED_END]\n", + "Node esm importing node cjs\n[WILDCARD]", + )); + output.assert_exit_code(0); + } +} + +#[test] +fn binary_package_with_optional_dependencies() { + let context = TestContextBuilder::for_npm() + .use_copy_temp_dir("npm/binary_package") + .cwd("npm/binary_package") + .build(); + + let temp_dir = context.temp_dir(); + let temp_dir_path = temp_dir.path(); + let project_path = temp_dir_path.join("npm/binary_package"); + + // write empty config file so a lockfile gets created + temp_dir.write("npm/binary_package/deno.json", "{}"); + + // run it twice, with the first time creating the lockfile and the second using it + for i in 0..2 { + if i == 1 { + assert!(project_path.join("deno.lock").exists()); + } + + let output = context + .new_command() + .args("run -A --node-modules-dir main.js") + .run(); + + #[cfg(target_os = "windows")] + { + output.assert_exit_code(0); + output.assert_matches_text( + "[WILDCARD]Hello from binary package on windows[WILDCARD]", + ); + assert!(project_path + .join("node_modules/.deno/@denotest+binary-package-windows@1.0.0") + .exists()); + assert!(!project_path + .join("node_modules/.deno/@denotest+binary-package-linux@1.0.0") + .exists()); + assert!(!project_path + .join("node_modules/.deno/@denotest+binary-package-mac@1.0.0") + .exists()); + assert!(project_path + .join("node_modules/.deno/@denotest+binary-package@1.0.0/node_modules/@denotest/binary-package-windows") + .exists()); + assert!(!project_path + .join("node_modules/.deno/@denotest+binary-package@1.0.0/node_modules/@denotest/binary-package-linux") + .exists()); + assert!(!project_path + .join("node_modules/.deno/@denotest+binary-package@1.0.0/node_modules/@denotest/binary-package-mac") + .exists()); + } + + #[cfg(target_os = "macos")] + { + output.assert_exit_code(0); + output.assert_matches_text( + "[WILDCARD]Hello from binary package on mac[WILDCARD]", + ); + + assert!(!project_path + .join("node_modules/.deno/@denotest+binary-package-windows@1.0.0") + .exists()); + assert!(!project_path + .join("node_modules/.deno/@denotest+binary-package-linux@1.0.0") + .exists()); + assert!(project_path + .join("node_modules/.deno/@denotest+binary-package-mac@1.0.0") + .exists()); + assert!(!project_path + .join("node_modules/.deno/@denotest+binary-package@1.0.0/node_modules/@denotest/binary-package-windows") + .exists()); + assert!(!project_path + .join("node_modules/.deno/@denotest+binary-package@1.0.0/node_modules/@denotest/binary-package-linux") + .exists()); + assert!(project_path + .join("node_modules/.deno/@denotest+binary-package@1.0.0/node_modules/@denotest/binary-package-mac") + .exists()); + } + + #[cfg(target_os = "linux")] + { + output.assert_exit_code(0); + output.assert_matches_text( + "[WILDCARD]Hello from binary package on linux[WILDCARD]", + ); + assert!(!project_path + .join("node_modules/.deno/@denotest+binary-package-windows@1.0.0") + .exists()); + assert!(project_path + .join("node_modules/.deno/@denotest+binary-package-linux@1.0.0") + .exists()); + assert!(!project_path + .join("node_modules/.deno/@denotest+binary-package-mac@1.0.0") + .exists()); + assert!(!project_path + .join("node_modules/.deno/@denotest+binary-package@1.0.0/node_modules/@denotest/binary-package-windows") + .exists()); + assert!(project_path + .join("node_modules/.deno/@denotest+binary-package@1.0.0/node_modules/@denotest/binary-package-linux") + .exists()); + assert!(!project_path + .join("node_modules/.deno/@denotest+binary-package@1.0.0/node_modules/@denotest/binary-package-mac") + .exists()); + } + } +} + +#[test] +fn node_modules_dir_config_file() { + let test_context = TestContextBuilder::for_npm().use_temp_cwd().build(); + let temp_dir = test_context.temp_dir(); + let node_modules_dir = temp_dir.path().join("node_modules"); + let rm_node_modules = || std::fs::remove_dir_all(&node_modules_dir).unwrap(); + + temp_dir.write("deno.json", r#"{ "nodeModulesDir": true }"#); + temp_dir.write("main.ts", "import 'npm:@denotest/esm-basic';"); + + let deno_cache_cmd = test_context.new_command().args("cache --quiet main.ts"); + deno_cache_cmd.run(); + assert!(node_modules_dir.exists()); + + // now try adding a vendor flag, it should exist + rm_node_modules(); + temp_dir.write("deno.json", r#"{ "vendor": true }"#); + deno_cache_cmd.run(); + assert!(node_modules_dir.exists()); + + rm_node_modules(); + temp_dir.write("deno.json", r#"{ "nodeModulesDir": false }"#); + + deno_cache_cmd.run(); + assert!(!node_modules_dir.exists()); + + temp_dir.write("package.json", r#"{}"#); + deno_cache_cmd.run(); + assert!(!node_modules_dir.exists()); + + test_context + .new_command() + .args("cache --quiet --node-modules-dir main.ts") + .run(); + assert!(node_modules_dir.exists()); + + // should override the `--vendor` flag + rm_node_modules(); + test_context + .new_command() + .args("cache --quiet --node-modules-dir=false --vendor main.ts") + .run(); + assert!(!node_modules_dir.exists()); +} + +#[test] +fn top_level_install_package_json_explicit_opt_in() { + let test_context = TestContextBuilder::for_npm().use_temp_cwd().build(); + let temp_dir = test_context.temp_dir(); + let node_modules_dir = temp_dir.path().join("node_modules"); + let rm_created_files = || { + std::fs::remove_dir_all(&node_modules_dir).unwrap(); + std::fs::remove_file(temp_dir.path().join("deno.lock")).unwrap(); + }; + + // when the node_modules_dir is explicitly opted into, we should always + // ensure a top level package.json install occurs + temp_dir.write("deno.json", "{ \"nodeModulesDir\": true }"); + temp_dir.write( + "package.json", + "{ \"dependencies\": { \"@denotest/esm-basic\": \"1.0\" }}", + ); + + temp_dir.write("main.ts", "console.log(5);"); + let output = test_context.new_command().args("cache main.ts").run(); + output.assert_matches_text( + concat!( + "Download http://localhost:4545/npm/registry/@denotest/esm-basic\n", + "Download http://localhost:4545/npm/registry/@denotest/esm-basic/1.0.0.tgz\n", + "Initialize @denotest/esm-basic@1.0.0\n", + ) + ); + + rm_created_files(); + let output = test_context + .new_command() + .args_vec(["eval", "console.log(5)"]) + .run(); + output.assert_matches_text(concat!( + "Initialize @denotest/esm-basic@1.0.0\n", + "5\n" + )); + + rm_created_files(); + let output = test_context + .new_command() + .args("run -") + .stdin_text("console.log(5)") + .run(); + output.assert_matches_text(concat!( + "Initialize @denotest/esm-basic@1.0.0\n", + "5\n" + )); + + // now ensure this is cached in the lsp + rm_created_files(); + let mut client = test_context.new_lsp_command().build(); + client.initialize_default(); + let file_uri = temp_dir.uri().join("file.ts").unwrap(); + client.did_open(json!({ + "textDocument": { + "uri": file_uri, + "languageId": "typescript", + "version": 1, + "text": "", + } + })); + client.write_request( + "workspace/executeCommand", + json!({ + "command": "deno.cache", + "arguments": [[], file_uri], + }), + ); + + assert!(node_modules_dir.join("@denotest").exists()); +} + +itest!(reserved_word_exports { + args: "run npm/reserved_word_exports/main.ts", + output: "npm/reserved_word_exports/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(import_json { + args: "run -A --quiet npm/import_json/main.js", + output: "npm/import_json/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(dynamic_import_json { + args: "run -A --quiet npm/import_json/main.js", + output: "npm/import_json/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(check_package_file_dts_dmts_dcts { + args: "check npm/file_dts_dmts_dcts/main.ts", + output: "npm/file_dts_dmts_dcts/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, + exit_code: 1, +}); + +itest!(require_resolve_url_paths { + args: "run -A --quiet --node-modules-dir url_paths.ts", + output: "npm/require_resolve_url/url_paths.out", + envs: env_vars_for_npm_tests(), + http_server: true, + exit_code: 0, + cwd: Some("npm/require_resolve_url/"), + copy_temp_dir: Some("npm/require_resolve_url/"), +}); + +#[test] +fn byonm_cjs_esm_packages() { + let test_context = TestContextBuilder::for_npm() + .env("DENO_UNSTABLE_BYONM", "1") + .use_temp_cwd() + .build(); + let dir = test_context.temp_dir(); + + test_context.run_npm("init -y"); + test_context.run_npm("install @denotest/esm-basic @denotest/cjs-default-export @denotest/dual-cjs-esm chalk@4 chai@4.3"); + + dir.write( + "main.ts", + r#" +import { getValue, setValue } from "@denotest/esm-basic"; + +setValue(2); +console.log(getValue()); + +import cjsDefault from "@denotest/cjs-default-export"; +console.log(cjsDefault.default()); +console.log(cjsDefault.named()); + +import { getKind } from "@denotest/dual-cjs-esm"; +console.log(getKind()); + + +"#, + ); + let output = test_context.new_command().args("run --check main.ts").run(); + output + .assert_matches_text("Check file:///[WILDCARD]/main.ts\n2\n1\n2\nesm\n"); + + // should not have created the .deno directory + assert!(!dir.path().join("node_modules/.deno").exists()); + + // try chai + dir.write( + "chai.ts", + r#"import { expect } from "chai"; + + const timeout = setTimeout(() => {}, 0); + expect(timeout).to.be.a("number"); + clearTimeout(timeout);"#, + ); + test_context.new_command().args("run chai.ts").run(); + + // try chalk cjs + dir.write( + "chalk.ts", + "import chalk from 'chalk'; console.log(chalk.green('chalk cjs loads'));", + ); + let output = test_context + .new_command() + .args("run --allow-read chalk.ts") + .run(); + output.assert_matches_text("chalk cjs loads\n"); + + // try using an npm specifier for chalk that matches the version we installed + dir.write( + "chalk.ts", + "import chalk from 'npm:chalk@4'; console.log(chalk.green('chalk cjs loads'));", + ); + let output = test_context + .new_command() + .args("run --allow-read chalk.ts") + .run(); + output.assert_matches_text("chalk cjs loads\n"); + + // try with one that doesn't match the package.json + dir.write( + "chalk.ts", + "import chalk from 'npm:chalk@5'; console.log(chalk.green('chalk cjs loads'));", + ); + let output = test_context + .new_command() + .args("run --allow-read chalk.ts") + .run(); + output.assert_matches_text( + r#"error: Could not find a matching package for 'npm:chalk@5' in '[WILDCARD]package.json'. You must specify this as a package.json dependency when the node_modules folder is not managed by Deno. + at file:///[WILDCARD]chalk.ts:1:19 +"#); + output.assert_exit_code(1); +} + +#[test] +fn byonm_import_map() { + let test_context = TestContextBuilder::for_npm().use_temp_cwd().build(); + let dir = test_context.temp_dir(); + dir.write( + "deno.json", + r#"{ + "imports": { + "basic": "npm:@denotest/esm-basic" + }, + "unstable": [ "byonm" ] +}"#, + ); + dir.write( + "package.json", + r#"{ + "name": "my-project", + "version": "1.0.0", + "type": "module", + "dependencies": { + "@denotest/esm-basic": "^1.0" + } +}"#, + ); + test_context.run_npm("install"); + + dir.write( + "main.ts", + r#" +// import map should resolve +import { getValue } from "basic"; +// and resolving via node resolution +import { setValue } from "@denotest/esm-basic"; + +setValue(5); +console.log(getValue()); +"#, + ); + let output = test_context.new_command().args("run main.ts").run(); + output.assert_matches_text("5\n"); + let output = test_context.new_command().args("check main.ts").run(); + output.assert_matches_text("Check file:///[WILDCARD]/main.ts\n"); +} + +#[test] +fn byonm_package_specifier_not_installed_and_invalid_subpath() { + let test_context = TestContextBuilder::for_npm() + .env("DENO_UNSTABLE_BYONM", "1") + .use_temp_cwd() + .build(); + let dir = test_context.temp_dir(); + dir.path().join("package.json").write_json(&json!({ + "dependencies": { + "chalk": "4", + "@denotest/conditional-exports-strict": "1" + } + })); + dir.write( + "main.ts", + "import chalk from 'chalk'; console.log(chalk.green('hi'));", + ); + + // no npm install has been run, so this should give an informative error + let output = test_context.new_command().args("run main.ts").run(); + output.assert_matches_text( + r#"error: Could not resolve "chalk", but found it in a package.json. Deno expects the node_modules/ directory to be up to date. Did you forget to run `npm install`? + at file:///[WILDCARD]/main.ts:1:19 +"#, + ); + output.assert_exit_code(1); + + // now test for an invalid sub path after doing an npm install + dir.write( + "main.ts", + "import '@denotest/conditional-exports-strict/test';", + ); + + test_context.run_npm("install"); + + let output = test_context.new_command().args("run main.ts").run(); + output.assert_matches_text( + r#"error: [ERR_PACKAGE_PATH_NOT_EXPORTED] Package subpath './test' is not defined by "exports" in '[WILDCARD]' imported from '[WILDCARD]main.ts' + at file:///[WILDCARD]/main.ts:1:8 +"#, + ); + output.assert_exit_code(1); +} + +#[test] +fn byonm_package_npm_specifier_not_installed_and_invalid_subpath() { + let test_context = TestContextBuilder::for_npm() + .env("DENO_UNSTABLE_BYONM", "1") + .use_temp_cwd() + .build(); + let dir = test_context.temp_dir(); + dir.path().join("package.json").write_json(&json!({ + "dependencies": { + "chalk": "4", + "@denotest/conditional-exports-strict": "1" + } + })); + dir.write( + "main.ts", + "import chalk from 'npm:chalk'; console.log(chalk.green('hi'));", + ); + + // no npm install has been run, so this should give an informative error + let output = test_context.new_command().args("run main.ts").run(); + output.assert_matches_text( + r#"error: Could not find '[WILDCARD]package.json'. Deno expects the node_modules/ directory to be up to date. Did you forget to run `npm install`? + at file:///[WILDCARD]/main.ts:1:19 +"#, + ); + output.assert_exit_code(1); + + // now test for an invalid sub path after doing an npm install + dir.write( + "main.ts", + "import 'npm:@denotest/conditional-exports-strict/test';", + ); + + test_context.run_npm("install"); + + let output = test_context.new_command().args("run main.ts").run(); + output.assert_matches_text( + r#"error: Failed resolving package subpath './test' for '[WILDCARD]package.json' + at file:///[WILDCARD]/main.ts:1:8 +"#, + ); + output.assert_exit_code(1); +} + +#[test] +fn byonm_npm_workspaces() { + let test_context = TestContextBuilder::for_npm().use_temp_cwd().build(); + let dir = test_context.temp_dir(); + dir.write("deno.json", r#"{ "unstable": [ "byonm" ] }"#); + + dir.write( + "package.json", + r#"{ + "name": "my-workspace", + "workspaces": [ + "project-a", + "project-b" + ] +} +"#, + ); + + let project_a_dir = dir.path().join("project-a"); + project_a_dir.create_dir_all(); + project_a_dir.join("package.json").write_json(&json!({ + "name": "project-a", + "version": "1.0.0", + "main": "./index.js", + "type": "module", + "dependencies": { + "chai": "^4.2", + "project-b": "^1" + } + })); + project_a_dir.join("index.js").write( + r#" +import { expect } from "chai"; + +const timeout = setTimeout(() => {}, 0); +expect(timeout).to.be.a("number"); +clearTimeout(timeout); + +export function add(a, b) { + return a + b; +} +"#, + ); + project_a_dir + .join("index.d.ts") + .write("export function add(a: number, b: number): number;"); + + let project_b_dir = dir.path().join("project-b"); + project_b_dir.create_dir_all(); + project_b_dir.join("package.json").write_json(&json!({ + "name": "project-b", + "version": "1.0.0", + "type": "module", + "dependencies": { + "@denotest/esm-basic": "^1.0", + } + })); + project_b_dir.join("main.ts").write( + r#" +import { getValue, setValue } from "@denotest/esm-basic"; + +setValue(5); +console.log(getValue()); + +import { add } from "project-a"; +console.log(add(1, 2)); +"#, + ); + + test_context.run_npm("install"); + + let output = test_context + .new_command() + .args("run ./project-b/main.ts") + .run(); + output.assert_matches_text("5\n3\n"); + let output = test_context + .new_command() + .args("check ./project-b/main.ts") + .run(); + output.assert_matches_text("Check file:///[WILDCARD]/project-b/main.ts\n"); + + // Now a file in the main directory should just be able to + // import it via node resolution even though a package.json + // doesn't exist here + dir.write( + "main.ts", + r#" +import { getValue, setValue } from "@denotest/esm-basic"; + +setValue(7); +console.log(getValue()); +"#, + ); + let output = test_context.new_command().args("run main.ts").run(); + output.assert_matches_text("7\n"); + let output = test_context.new_command().args("check main.ts").run(); + output.assert_matches_text("Check file:///[WILDCARD]/main.ts\n"); +} + +#[test] +fn cjs_export_analysis_require_re_export() { + let test_context = TestContextBuilder::for_npm().use_temp_cwd().build(); + let dir = test_context.temp_dir(); + dir.write("deno.json", r#"{ "unstable": [ "byonm" ] }"#); + + dir.write( + "package.json", + r#"{ "name": "test", "packages": { "my-package": "1.0.0" } }"#, + ); + dir.write( + "main.js", + "import { value1, value2 } from 'my-package';\nconsole.log(value1);\nconsole.log(value2)\n", + ); + + let node_modules_dir = dir.path().join("node_modules"); + + // create a package at node_modules/.multipart/name/nested without a package.json + { + let pkg_dir = node_modules_dir + .join(".multipart") + .join("name") + .join("nested"); + pkg_dir.create_dir_all(); + pkg_dir.join("index.js").write("module.exports.value1 = 5;"); + } + // create a package at node_modules/.multipart/other with a package.json + { + let pkg_dir = node_modules_dir.join(".multipart").join("other"); + pkg_dir.create_dir_all(); + pkg_dir.join("index.js").write("module.exports.value2 = 6;"); + } + // create a package at node_modules/my-package that requires them both + { + let pkg_dir = node_modules_dir.join("my-package"); + pkg_dir.create_dir_all(); + pkg_dir.join("package.json").write_json(&json!({ + "name": "my-package", + "version": "1.0.0", + })); + pkg_dir + .join("index.js") + .write("module.exports = { ...require('.multipart/name/nested/index'), ...require('.multipart/other/index.js') }"); + } + + // the cjs export analysis was previously failing, but it should + // resolve these exports similar to require + let output = test_context + .new_command() + .args("run --allow-read main.js") + .run(); + output.assert_matches_text("5\n6\n"); +} + +#[test] +fn cjs_rexport_analysis_json() { + let test_context = TestContextBuilder::for_npm().use_temp_cwd().build(); + let dir = test_context.temp_dir(); + dir.write("deno.json", r#"{ "unstable": [ "byonm" ] }"#); + + dir.write( + "package.json", + r#"{ "name": "test", "packages": { "my-package": "1.0.0" } }"#, + ); + dir.write( + "main.js", + "import data from 'my-package';\nconsole.log(data);\n", + ); + + let node_modules_dir = dir.path().join("node_modules"); + + // create a package that has a json file at index.json and data.json then folder/index.json + { + let pkg_dir = node_modules_dir.join("data-package"); + pkg_dir.create_dir_all(); + pkg_dir.join("package.json").write_json(&json!({ + "name": "data-package", + "version": "1.0.0", + })); + pkg_dir.join("index.json").write(r#"{ "value": 2 }"#); + pkg_dir.join("data.json").write(r#"{ "value": 3 }"#); + let folder = pkg_dir.join("folder"); + folder.create_dir_all(); + folder.join("index.json").write(r#"{ "value": 4 }"#); + } + // create a package at node_modules/my-package that re-exports a json file + { + let pkg_dir = node_modules_dir.join("my-package"); + pkg_dir.create_dir_all(); + pkg_dir.join("package.json").write_json(&json!({ + "name": "my-package", + "version": "1.0.0", + })); + pkg_dir.join("data.json").write(r#"{ "value": 1 }"#); + pkg_dir.join("index.js").write( + "module.exports = { + data1: require('./data'), + data2: require('data-package'), + data3: require('data-package/data'), + data4: require('data-package/folder'), +};", + ); + } + + let output = test_context + .new_command() + .args("run --allow-read main.js") + .run(); + output.assert_matches_text( + "{ + data1: { value: 1 }, + data2: { value: 2 }, + data3: { value: 3 }, + data4: { value: 4 } +} +", + ); +} + +itest!(imports_package_json { + args: "run --node-modules-dir=false npm/imports_package_json/main.js", + output: "npm/imports_package_json/main.out", + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(imports_package_json_import_not_defined { + args: + "run --node-modules-dir=false npm/imports_package_json/import_not_defined.js", + output: "npm/imports_package_json/import_not_defined.out", + envs: env_vars_for_npm_tests(), + exit_code: 1, + http_server: true, +}); + +itest!(imports_package_json_sub_path_import_not_defined { + args: + "run --node-modules-dir=false npm/imports_package_json/sub_path_import_not_defined.js", + output: "npm/imports_package_json/sub_path_import_not_defined.out", + envs: env_vars_for_npm_tests(), + exit_code: 1, + http_server: true, +}); + +itest!(different_nested_dep_node_modules_dir_false { + args: "run --quiet --node-modules-dir=false npm/different_nested_dep/main.js", + output: "npm/different_nested_dep/main.out", + envs: env_vars_for_npm_tests(), + exit_code: 0, + http_server: true, +}); + +itest!(different_nested_dep_node_modules_dir_true { + args: "run --quiet --node-modules-dir=true main.js", + output: "npm/different_nested_dep/main.out", + copy_temp_dir: Some("npm/different_nested_dep/"), + cwd: Some("npm/different_nested_dep/"), + envs: env_vars_for_npm_tests(), + exit_code: 0, + http_server: true, +}); + +#[test] +fn different_nested_dep_byonm() { + let test_context = TestContextBuilder::for_npm() + .use_copy_temp_dir("npm/different_nested_dep") + .cwd("npm/different_nested_dep/") + .build(); + + test_context.run_npm("install"); + + let output = test_context + .new_command() + .args("run --unstable-byonm main.js") + .run(); + output.assert_matches_file("npm/different_nested_dep/main.out"); +} + +#[test] +fn run_cjs_in_node_modules_folder() { + let test_context = TestContextBuilder::for_npm().use_temp_cwd().build(); + let temp_dir = test_context.temp_dir(); + temp_dir.write("package.json", "{}"); + temp_dir.write("deno.json", r#"{ "unstable": ["byonm"] }"#); + let pkg_dir = temp_dir.path().join("node_modules/package"); + pkg_dir.create_dir_all(); + pkg_dir + .join("package.json") + .write(r#"{ "name": "package" }"#); + pkg_dir + .join("main.js") + .write("console.log('hi'); module.exports = 'hi';"); + test_context + .new_command() + .args("run node_modules/package/main.js") + .run() + .assert_matches_text("hi\n"); +} diff --git a/tests/integration/publish_tests.rs b/tests/integration/publish_tests.rs new file mode 100644 index 000000000..330a7692b --- /dev/null +++ b/tests/integration/publish_tests.rs @@ -0,0 +1,277 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +use deno_core::serde_json::json; +use test_util::assert_contains; +use test_util::assert_not_contains; +use test_util::env_vars_for_jsr_tests; +use test_util::env_vars_for_npm_tests; +use test_util::TestContextBuilder; + +itest!(no_token { + args: "publish", + cwd: Some("publish/missing_deno_json"), + output: "publish/no_token.out", + exit_code: 1, +}); + +itest!(missing_deno_json { + args: "publish --token 'sadfasdf'", + output: "publish/missing_deno_json.out", + cwd: Some("publish/missing_deno_json"), + exit_code: 1, +}); + +itest!(invalid_fast_check { + args: "publish --token 'sadfasdf'", + output: "publish/invalid_fast_check.out", + cwd: Some("publish/invalid_fast_check"), + exit_code: 1, +}); + +itest!(no_zap { + args: "publish --no-zap --token 'sadfasdf'", + output: "publish/no_zap.out", + cwd: Some("publish/invalid_fast_check"), + envs: env_vars_for_jsr_tests(), + http_server: true, + exit_code: 0, +}); + +itest!(invalid_path { + args: "publish --token 'sadfasdf'", + output: "publish/invalid_path.out", + cwd: Some("publish/invalid_path"), + exit_code: 1, +}); + +itest!(symlink { + args: "publish --token 'sadfasdf' --dry-run", + output: "publish/symlink.out", + cwd: Some("publish/symlink"), + exit_code: 0, +}); + +itest!(invalid_import { + args: "publish --token 'sadfasdf' --dry-run", + output: "publish/invalid_import.out", + cwd: Some("publish/invalid_import"), + envs: env_vars_for_npm_tests(), + exit_code: 1, + http_server: true, +}); + +#[test] +fn publish_non_exported_files_using_import_map() { + let context = publish_context_builder().build(); + let temp_dir = context.temp_dir().path(); + temp_dir.join("deno.json").write_json(&json!({ + "name": "@foo/bar", + "version": "1.0.0", + "exports": "./mod.ts", + "imports": { + "@denotest/add": "jsr:@denotest/add@1" + } + })); + // file not in the graph + let other_ts = temp_dir.join("_other.ts"); + other_ts + .write("import { add } from '@denotest/add'; console.log(add(1, 3));"); + let mod_ts = temp_dir.join("mod.ts"); + mod_ts.write("import { add } from '@denotest/add'; console.log(add(1, 2));"); + let output = context + .new_command() + .args("publish --log-level=debug --token 'sadfasdf'") + .run(); + let lines = output.combined_output().split('\n').collect::>(); + assert!(lines + .iter() + .any(|l| l.contains("Unfurling") && l.ends_with("mod.ts"))); + assert!(lines + .iter() + .any(|l| l.contains("Unfurling") && l.ends_with("other.ts"))); +} + +#[test] +fn publish_warning_not_in_graph() { + let context = publish_context_builder().build(); + let temp_dir = context.temp_dir().path(); + temp_dir.join("deno.json").write_json(&json!({ + "name": "@foo/bar", + "version": "1.0.0", + "exports": "./mod.ts", + })); + // file not in the graph that uses a non-analyzable dynamic import (cause a diagnostic) + let other_ts = temp_dir.join("_other.ts"); + other_ts + .write("const nonAnalyzable = './_other.ts'; await import(nonAnalyzable);"); + let mod_ts = temp_dir.join("mod.ts"); + mod_ts.write( + "export function test(a: number, b: number): number { return a + b; }", + ); + context + .new_command() + .args("publish --token 'sadfasdf'") + .run() + .assert_matches_text( + "[WILDCARD]unable to analyze dynamic import[WILDCARD]", + ); +} + +itest!(javascript_missing_decl_file { + args: "publish --token 'sadfasdf'", + output: "publish/javascript_missing_decl_file.out", + cwd: Some("publish/javascript_missing_decl_file"), + envs: env_vars_for_jsr_tests(), + exit_code: 0, + http_server: true, +}); + +itest!(unanalyzable_dynamic_import { + args: "publish --token 'sadfasdf'", + output: "publish/unanalyzable_dynamic_import.out", + cwd: Some("publish/unanalyzable_dynamic_import"), + envs: env_vars_for_jsr_tests(), + exit_code: 0, + http_server: true, +}); + +itest!(javascript_decl_file { + args: "publish --token 'sadfasdf'", + output: "publish/javascript_decl_file.out", + cwd: Some("publish/javascript_decl_file"), + envs: env_vars_for_jsr_tests(), + http_server: true, + exit_code: 0, +}); + +itest!(successful { + args: "publish --token 'sadfasdf'", + output: "publish/successful.out", + cwd: Some("publish/successful"), + envs: env_vars_for_jsr_tests(), + http_server: true, +}); + +itest!(node_specifier { + args: "publish --token 'sadfasdf'", + output: "publish/node_specifier.out", + cwd: Some("publish/node_specifier"), + envs: env_vars_for_jsr_tests() + .into_iter() + .chain(env_vars_for_npm_tests().into_iter()) + .collect(), + http_server: true, +}); + +itest!(config_file_jsonc { + args: "publish --token 'sadfasdf'", + output: "publish/deno_jsonc.out", + cwd: Some("publish/deno_jsonc"), + envs: env_vars_for_jsr_tests(), + http_server: true, +}); + +itest!(workspace_all { + args: "publish --token 'sadfasdf'", + output: "publish/workspace.out", + cwd: Some("publish/workspace"), + envs: env_vars_for_jsr_tests(), + http_server: true, +}); + +itest!(workspace_individual { + args: "publish --token 'sadfasdf'", + output: "publish/workspace_individual.out", + cwd: Some("publish/workspace/bar"), + envs: env_vars_for_jsr_tests(), + http_server: true, +}); + +itest!(dry_run { + args: "publish --token 'sadfasdf' --dry-run", + cwd: Some("publish/successful"), + output: "publish/dry_run.out", + envs: env_vars_for_jsr_tests(), + http_server: true, +}); + +#[test] +fn ignores_directories() { + let context = publish_context_builder().build(); + let temp_dir = context.temp_dir().path(); + temp_dir.join("deno.json").write_json(&json!({ + "name": "@foo/bar", + "version": "1.0.0", + "exclude": [ "ignore" ], + "publish": { + "exclude": [ "ignore2" ] + }, + "exports": "./main_included.ts" + })); + + let ignored_dirs = vec![ + temp_dir.join(".git"), + temp_dir.join("node_modules"), + temp_dir.join("ignore"), + temp_dir.join("ignore2"), + ]; + for ignored_dir in ignored_dirs { + ignored_dir.create_dir_all(); + ignored_dir.join("ignored.ts").write(""); + } + + let sub_dir = temp_dir.join("sub_dir"); + sub_dir.create_dir_all(); + sub_dir.join("sub_included.ts").write(""); + + temp_dir.join("main_included.ts").write(""); + + let output = context + .new_command() + .arg("publish") + .arg("--log-level=debug") + .arg("--token") + .arg("sadfasdf") + .run(); + output.assert_exit_code(0); + let output = output.combined_output(); + assert_contains!(output, "sub_included.ts"); + assert_contains!(output, "main_included.ts"); + assert_not_contains!(output, "ignored.ts"); +} + +#[test] +fn includes_directories() { + let context = publish_context_builder().build(); + let temp_dir = context.temp_dir().path(); + temp_dir.join("deno.json").write_json(&json!({ + "name": "@foo/bar", + "version": "1.0.0", + "exports": "./main.ts", + "publish": { + "include": [ "deno.json", "main.ts" ] + } + })); + + temp_dir.join("main.ts").write(""); + temp_dir.join("ignored.ts").write(""); + + let output = context + .new_command() + .arg("publish") + .arg("--log-level=debug") + .arg("--token") + .arg("sadfasdf") + .run(); + output.assert_exit_code(0); + let output = output.combined_output(); + assert_contains!(output, "main.ts"); + assert_not_contains!(output, "ignored.ts"); +} + +fn publish_context_builder() -> TestContextBuilder { + TestContextBuilder::new() + .use_http_server() + .envs(env_vars_for_jsr_tests()) + .use_temp_cwd() +} diff --git a/tests/integration/repl_tests.rs b/tests/integration/repl_tests.rs new file mode 100644 index 000000000..0e63f1589 --- /dev/null +++ b/tests/integration/repl_tests.rs @@ -0,0 +1,1121 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +use test_util as util; +use test_util::assert_contains; +use test_util::assert_ends_with; +use test_util::assert_not_contains; +use util::TempDir; +use util::TestContext; +use util::TestContextBuilder; + +#[test] +fn pty_multiline() { + util::with_pty(&["repl"], |mut console| { + console.write_line("(\n1 + 2\n)"); + console.expect("3"); + console.write_line("{\nfoo: \"foo\"\n}"); + console.expect("{ foo: \"foo\" }"); + console.write_line("`\nfoo\n`"); + console.expect("\"\\nfoo\\n\""); + console.write_line("`\n\\`\n`"); + console.expect(r#""\n`\n""#); + console.write_line("'{'"); + console.expect(r#""{""#); + console.write_line("'('"); + console.expect(r#""(""#); + console.write_line("'['"); + console.expect(r#""[""#); + console.write_line("/{/"); + console.expect("/{/"); + console.write_line("/\\(/"); + console.expect("/\\(/"); + console.write_line("/\\[/"); + console.expect("/\\[/"); + console.write_line("console.log(\"{test1} abc {test2} def {{test3}}\".match(/{([^{].+?)}/));"); + console.expect("["); + console.expect(" \"{test1}\","); + console.expect(" \"test1\","); + console.expect(" index: 0,"); + console.expect(" input: \"{test1} abc {test2} def {{test3}}\","); + console.expect(" groups: undefined"); + console.expect("]"); + }); +} + +#[test] +fn pty_null() { + util::with_pty(&["repl"], |mut console| { + console.write_line("null"); + console.expect("null"); + }); +} + +#[test] +fn pty_unpaired_braces() { + for right_brace in &[")", "]", "}"] { + util::with_pty(&["repl"], |mut console| { + console.write_line(right_brace); + console.expect("parse error: Expression expected"); + }); + } +} + +#[test] +fn pty_bad_input() { + util::with_pty(&["repl"], |mut console| { + console.write_line("'\\u{1f3b5}'[0]"); + console.expect("Unterminated string literal"); + }); +} + +#[test] +fn pty_syntax_error_input() { + util::with_pty(&["repl"], |mut console| { + console.write_line("('\\u')"); + console.expect("Bad character escape sequence, expected 4 hex characters"); + + console.write_line("'"); + console.expect("Unterminated string constant"); + + console.write_line("[{'a'}];"); + console.expect("Expected a semicolon"); + }); +} + +#[test] +fn pty_complete_symbol() { + util::with_pty(&["repl"], |mut console| { + console.write_line_raw("Symbol.it\t"); + console.expect("Symbol(Symbol.iterator)"); + }); +} + +#[test] +fn pty_complete_declarations() { + util::with_pty(&["repl"], |mut console| { + console.write_line("class MyClass {}"); + console.expect("undefined"); + console.write_line_raw("My\t"); + console.expect("[class MyClass]"); + console.write_line("let myVar = 2 + 3;"); + console.expect("undefined"); + console.write_line_raw("myV\t"); + console.expect("5"); + }); +} + +#[test] +fn pty_complete_primitives() { + util::with_pty(&["repl"], |mut console| { + console.write_line("let func = function test(){}"); + console.expect("undefined"); + console.write_line_raw("func.appl\t"); + console.expect("func.apply"); + console.write_line("let str = ''"); + console.expect("undefined"); + console.write_line_raw("str.leng\t"); + console.expect("str.length"); + console.write_line_raw("false.valueO\t"); + console.expect("false.valueOf"); + console.write_line_raw("5n.valueO\t"); + console.expect("5n.valueOf"); + console.write_line("let num = 5"); + console.expect("undefined"); + console.write_line_raw("num.toStrin\t"); + console.expect("num.toString"); + }); +} + +#[test] +fn pty_complete_expression() { + util::with_pty(&["repl"], |mut console| { + console.write_raw("Deno.\t\t"); + console.expect("Display all"); + console.write_raw("y"); + console.expect_all(&["symlink", "args", "permissions", "exit"]); + }); +} + +#[test] +fn pty_complete_imports() { + let context = TestContextBuilder::default().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + temp_dir.create_dir_all("subdir"); + temp_dir.write("./subdir/my_file.ts", ""); + temp_dir.create_dir_all("run"); + temp_dir.write("./run/hello.ts", "console.log('Hello World');"); + temp_dir.write( + "./run/output.ts", + r#"export function output(text: string) { + console.log(text); +} +"#, + ); + context + .new_command() + .args_vec(["repl", "-A"]) + .with_pty(|mut console| { + // single quotes + console.write_line_raw("import './run/hel\t'"); + console.expect("Hello World"); + // double quotes + console.write_line_raw("import { output } from \"./run/out\t\""); + console.expect("\"./run/output.ts\""); + console.write_line_raw("output('testing output');"); + console.expect("testing output"); + }); + + // ensure when the directory changes that the suggestions come from the cwd + context + .new_command() + .args_vec(["repl", "-A"]) + .with_pty(|mut console| { + console.write_line("Deno.chdir('./subdir');"); + console.expect("undefined"); + console.write_line_raw("import '../run/he\t'"); + console.expect("Hello World"); + }); +} + +#[test] +fn pty_complete_imports_no_panic_empty_specifier() { + // does not panic when tabbing when empty + util::with_pty(&["repl", "-A"], |mut console| { + if cfg!(windows) { + console.write_line_raw("import '\t'"); + console.expect_any(&["not prefixed with", "https://deno.land"]); + } else { + console.write_raw("import '\t"); + console.expect("import 'https://deno.land"); + } + }); +} + +#[test] +fn pty_ignore_symbols() { + util::with_pty(&["repl"], |mut console| { + console.write_line_raw("Array.Symbol\t"); + console.expect("undefined"); + }); +} + +#[test] +fn pty_assign_global_this() { + util::with_pty(&["repl"], |mut console| { + console.write_line("globalThis = 40 + 2;"); + console.expect("42"); + }); +} + +#[test] +fn pty_assign_deno_keys_and_deno() { + util::with_pty(&["repl"], |mut console| { + console.write_line( + "Object.keys(Deno).forEach((key)=>{try{Deno[key] = undefined} catch {}})", + ); + console.expect("undefined"); + console.write_line("delete globalThis.Deno"); + console.expect("true"); + console.write_line("console.log('testing ' + 'this out');"); + console.expect("testing this out"); + console.expect("undefined"); + }); +} + +#[test] +fn pty_internal_repl() { + util::with_pty(&["repl"], |mut console| { + console.write_line("'Length: ' + Object.keys(globalThis).filter(k => k.startsWith('__DENO_')).length;"); + console.expect("Length: 0"); + + console.write_line_raw("__\t\t"); + console.expect("> __"); + let output = console.read_until("> __"); + assert_contains!(output, "__defineGetter__"); + // should not contain the internal repl variable + // in the `globalThis` or completions output + assert_not_contains!(output, "__DENO_"); + }); +} + +#[test] +fn pty_emoji() { + // windows was having issues displaying this + util::with_pty(&["repl"], |mut console| { + console.write_line(r"console.log('\u{1F995}');"); + console.expect("🦕"); + }); +} + +#[test] +fn console_log() { + util::with_pty(&["repl"], |mut console| { + console.write_line("console.log('hello');"); + console.expect("hello"); + console.write_line("'world'"); + console.expect("\"world\""); + }); +} + +#[test] +fn object_literal() { + util::with_pty(&["repl"], |mut console| { + console.write_line("{}"); + console.expect("{}"); + console.write_line("{ foo: 'bar' }"); + console.expect("{ foo: \"bar\" }"); + }); +} + +#[test] +fn block_expression() { + util::with_pty(&["repl"], |mut console| { + console.write_line("{};"); + console.expect("undefined"); + console.write_line("{\"\"}"); + console.expect("\"\""); + }); +} + +#[test] +fn await_resolve() { + util::with_pty(&["repl"], |mut console| { + console.write_line("await Promise.resolve('done')"); + console.expect("\"done\""); + }); +} + +#[test] +fn await_timeout() { + util::with_pty(&["repl"], |mut console| { + console.write_line("await new Promise((r) => setTimeout(r, 0, 'done'))"); + console.expect("\"done\""); + }); +} + +#[test] +fn let_redeclaration() { + util::with_pty(&["repl"], |mut console| { + console.write_line("let foo = 0;"); + console.expect("undefined"); + console.write_line("foo"); + console.expect("0"); + console.write_line("let foo = 1;"); + console.expect("undefined"); + console.write_line("foo"); + console.expect("1"); + }); +} + +#[test] +fn repl_cwd() { + let context = TestContextBuilder::default().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + context + .new_command() + .args_vec(["repl", "-A"]) + .with_pty(|mut console| { + console.write_line("Deno.cwd()"); + console.expect( + temp_dir + .path() + .as_path() + .file_name() + .unwrap() + .to_str() + .unwrap(), + ); + }); +} + +#[test] +fn typescript() { + util::with_pty(&["repl"], |mut console| { + console.write_line("function add(a: number, b: number) { return a + b }"); + console.expect("undefined"); + console.write_line("const result: number = add(1, 2) as number;"); + console.expect("undefined"); + console.write_line("result"); + console.expect("3"); + }); +} + +#[test] +fn typescript_declarations() { + util::with_pty(&["repl"], |mut console| { + console.write_line("namespace Test { export enum Values { A, B, C } }"); + console.expect("undefined"); + console.write_line("Test.Values.A"); + console.expect("0"); + console.write_line("Test.Values.C"); + console.expect("2"); + console.write_line("interface MyInterface { prop: string; }"); + console.expect("undefined"); + console.write_line("type MyTypeAlias = string;"); + console.expect("undefined"); + }); +} + +#[test] +fn typescript_decorators() { + let context = TestContextBuilder::default().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + temp_dir.write( + "./deno.json", + r#"{ "compilerOptions": { "experimentalDecorators": true } }"#, + ); + let config_path = temp_dir.target_path().join("./deno.json"); + util::with_pty( + &["repl", "--config", config_path.to_string_lossy().as_ref()], + |mut console| { + console.write_line( + "function dec(target) { target.prototype.test = () => 2; }", + ); + console.expect("undefined"); + console.write_line("@dec class Test {}"); + console.expect("[class Test]"); + console.write_line("new Test().test()"); + console.expect("2"); + }, + ); +} + +#[test] +fn eof() { + util::with_pty(&["repl"], |mut console| { + console.write_line("1 + 2"); + console.expect("3"); + }); +} + +#[test] +fn strict() { + util::with_pty(&["repl"], |mut console| { + console.write_line("let a = {};"); + console.expect("undefined"); + console.write_line("Object.preventExtensions(a)"); + console.expect("{}"); + console.write_line("a.c = 1;"); + console.expect( + "Uncaught TypeError: Cannot add property c, object is not extensible", + ); + }); +} + +#[test] +fn close_command() { + let (out, err) = util::run_and_collect_output( + true, + "repl", + Some(vec!["close()", "'ignored'"]), + None, + false, + ); + + assert_not_contains!(out, "ignored"); + assert!(err.is_empty()); +} + +#[test] +fn function() { + util::with_pty(&["repl"], |mut console| { + console.write_line("Deno.writeFileSync"); + console.expect("[Function: writeFileSync]"); + }); +} + +#[test] +fn multiline() { + util::with_pty(&["repl"], |mut console| { + console.write_line("(\n1 + 2\n)"); + console.expect("3"); + }); +} + +#[test] +fn import() { + let context = TestContextBuilder::default() + .use_copy_temp_dir("./subdir") + .build(); + context + .new_command() + .args_vec(["repl", "-A"]) + .with_pty(|mut console| { + console.write_line("import('./subdir/auto_print_hello.ts')"); + console.expect("hello!"); + }); +} + +#[test] +fn import_declarations() { + let context = TestContextBuilder::default() + .use_copy_temp_dir("./subdir") + .build(); + context + .new_command() + .args_vec(["repl", "-A"]) + .with_pty(|mut console| { + console.write_line("import './subdir/auto_print_hello.ts'"); + console.expect("hello!"); + }); +} + +#[test] +fn exports_stripped() { + util::with_pty(&["repl"], |mut console| { + console.write_line("const test = 5 + 1; export default test;"); + console.expect("6"); + console.write_line("export class Test {}"); + console.expect("undefined"); + }); +} + +#[test] +fn call_eval_unterminated() { + util::with_pty(&["repl"], |mut console| { + console.write_line("eval('{')"); + console.expect("Unexpected end of input"); + }); +} + +#[test] +fn unpaired_braces() { + util::with_pty(&["repl"], |mut console| { + for right_brace in &[")", "]", "}"] { + console.write_line(right_brace); + console.expect("Expression expected"); + } + }); +} + +#[test] +fn reference_error() { + util::with_pty(&["repl"], |mut console| { + console.write_line("not_a_variable"); + console.expect("not_a_variable is not defined"); + }); +} + +#[test] +fn syntax_error() { + util::with_pty(&["repl"], |mut console| { + console.write_line("syntax error"); + console.expect("parse error: Expected ';', '}' or "); + // ensure it keeps accepting input after + console.write_line("7 * 6"); + console.expect("42"); + }); +} + +#[test] +fn jsx_errors_without_pragma() { + util::with_pty(&["repl"], |mut console| { + console.write_line("const element =
;"); + console.expect("React is not defined"); + }); +} + +#[test] +fn jsx_import_source() { + let context = TestContextBuilder::default() + .use_temp_cwd() + .use_http_server() + .build(); + context + .new_command() + .args_vec(["repl", "-A"]) + .with_pty(|mut console| { + console.write_line("/** @jsxImportSource http://localhost:4545/jsx */"); + console.expect("undefined"); + console.write_line("const element =
;"); + console.expect("undefined"); + }); +} + +#[test] +fn type_error() { + util::with_pty(&["repl"], |mut console| { + console.write_line("console()"); + console.expect("console is not a function"); + }); +} + +#[test] +fn variable() { + util::with_pty(&["repl"], |mut console| { + console.write_line("var a = 123 + 456;"); + console.expect("undefined"); + console.write_line("a"); + console.expect("579"); + }); +} + +#[test] +fn lexical_scoped_variable() { + util::with_pty(&["repl"], |mut console| { + console.write_line("let a = 123 + 456;"); + console.expect("undefined"); + console.write_line("a"); + console.expect("579"); + }); +} + +#[test] +fn missing_deno_dir() { + use std::fs::read_dir; + let temp_dir = TempDir::new(); + let deno_dir_path = temp_dir.path().join("deno"); + let (out, err) = util::run_and_collect_output( + true, + "repl", + Some(vec!["1"]), + Some(vec![ + ("DENO_DIR".to_owned(), deno_dir_path.to_string()), + ("NO_COLOR".to_owned(), "1".to_owned()), + ]), + false, + ); + assert!(read_dir(deno_dir_path).is_ok()); + assert_ends_with!(out, "1\n"); + assert!(err.is_empty()); +} + +#[test] +fn custom_history_path() { + use std::fs::read; + let temp_dir = TempDir::new(); + let history_path = temp_dir.path().join("history.txt"); + let (out, err) = util::run_and_collect_output( + true, + "repl", + Some(vec!["1"]), + Some(vec![ + ("DENO_REPL_HISTORY".to_owned(), history_path.to_string()), + ("NO_COLOR".to_owned(), "1".to_owned()), + ]), + false, + ); + assert!(read(&history_path).is_ok()); + assert_ends_with!(out, "1\n"); + assert!(err.is_empty()); +} + +#[test] +fn disable_history_file() { + let deno_dir = util::new_deno_dir(); + let default_history_path = deno_dir.path().join("deno_history.txt"); + let (out, err) = util::run_and_collect_output( + true, + "repl", + Some(vec!["1"]), + Some(vec![ + ("DENO_DIR".to_owned(), deno_dir.path().to_string()), + ("DENO_REPL_HISTORY".to_owned(), "".to_owned()), + ("NO_COLOR".to_owned(), "1".to_owned()), + ]), + false, + ); + assert!(!default_history_path.try_exists().unwrap()); + assert_ends_with!(out, "1\n"); + assert!(err.is_empty()); +} + +#[test] +fn save_last_eval() { + util::with_pty(&["repl"], |mut console| { + console.write_line("1 + 2"); + console.expect("3"); + console.write_line("_ + 3"); + console.expect("6"); + }); +} + +#[test] +fn save_last_thrown() { + util::with_pty(&["repl"], |mut console| { + console.write_line("throw 1 + 2"); + console.expect("Uncaught 3"); + console.write_line("_error + 3"); + console.expect("6"); + }); +} + +#[test] +fn assign_underscore() { + util::with_pty(&["repl"], |mut console| { + console.write_line("_ = 1"); + console.expect("Last evaluation result is no longer saved to _."); + console.write_line("2 + 3"); + console.expect("5"); + console.write_line("_"); + console.expect("1"); + }); +} + +#[test] +fn assign_underscore_error() { + util::with_pty(&["repl"], |mut console| { + console.write_line("_error = 1"); + console.expect("Last thrown error is no longer saved to _error."); + console.write_line("throw 2"); + console.expect("Uncaught 2"); + console.write_line("_error"); + console.expect("1"); + }); +} + +#[test] +fn custom_inspect() { + util::with_pty(&["repl"], |mut console| { + console.write_line( + r#"const o = { + [Symbol.for("Deno.customInspect")]() { + throw new Error('Oops custom inspect error'); + }, + };"#, + ); + console.expect("undefined"); + console.write_line("o"); + console.expect("Oops custom inspect error"); + }); +} + +#[test] +fn eval_flag_valid_input() { + util::with_pty(&["repl", "--eval", "const t = 10;"], |mut console| { + console.write_line("t * 500"); + console.expect("5000"); + }); +} + +#[test] +fn eval_flag_parse_error() { + let (out, err) = util::run_and_collect_output_with_args( + true, + vec!["repl", "--eval", "const %"], + Some(vec!["250 * 10"]), + None, + false, + ); + assert_contains!( + test_util::strip_ansi_codes(&out), + "Error in --eval flag: parse error: Unexpected token `%`." + ); + assert_contains!(out, "2500"); // should not prevent input + assert!(err.is_empty()); +} + +#[test] +fn eval_flag_runtime_error() { + let (out, err) = util::run_and_collect_output_with_args( + true, + vec!["repl", "--eval", "throw new Error('Testing')"], + Some(vec!["250 * 10"]), + None, + false, + ); + assert_contains!(out, "Error in --eval flag: Uncaught Error: Testing"); + assert_contains!(out, "2500"); // should not prevent input + assert!(err.is_empty()); +} + +#[test] +fn eval_file_flag_valid_input() { + let (out, err) = util::run_and_collect_output_with_args( + true, + vec!["repl", "--eval-file=./run/001_hello.js"], + None, + None, + false, + ); + assert_contains!(out, "Hello World"); + assert!(err.is_empty()); +} + +#[test] +fn eval_file_flag_call_defined_function() { + let (out, err) = util::run_and_collect_output_with_args( + true, + vec!["repl", "--eval-file=./tsc/d.ts"], + Some(vec!["v4()"]), + None, + false, + ); + assert_contains!(out, "hello"); + assert!(err.is_empty()); +} + +#[test] +fn eval_file_flag_http_input() { + let (out, err) = util::run_and_collect_output_with_args( + true, + vec!["repl", "--eval-file=http://127.0.0.1:4545/tsc/d.ts"], + Some(vec!["v4()"]), + None, + true, + ); + assert_contains!(out, "hello"); + assert!(err.contains("Download")); +} + +#[test] +fn eval_file_flag_multiple_files() { + let (out, err) = util::run_and_collect_output_with_args( + true, + vec!["repl", "--allow-read", "--eval-file=http://127.0.0.1:4545/repl/import_type.ts,./tsc/d.ts,http://127.0.0.1:4545/type_definitions/foo.js"], + Some(vec!["b.method1=v4", "b.method1()+foo.toUpperCase()"]), + None, + true, + ); + assert_contains!(out, "helloFOO"); + assert_contains!(err, "Download"); +} + +#[flaky_test::flaky_test] +fn pty_clear_function() { + util::with_pty(&["repl"], |mut console| { + console.write_line("console.log('h' + 'ello');"); + console.expect_all(&["hello", "undefined"]); + console.write_line_raw("clear();"); + if cfg!(windows) { + // expect a bunch of these in the output + console.expect_raw_in_current_output( + "\r\n\u{1b}[K\r\n\u{1b}[K\r\n\u{1b}[K\r\n\u{1b}[K\r\n\u{1b}[K", + ); + } else { + console.expect_raw_in_current_output("[1;1H"); + } + console.expect("undefined"); // advance past the "clear()"'s undefined + console.expect("> "); + console.write_line("const clear = 1234 + 2000;"); + console.expect("undefined"); + console.write_line("clear;"); + console.expect("3234"); + }); +} + +#[test] +fn pty_tab_handler() { + // If the last character is **not** whitespace, we show the completions + util::with_pty(&["repl"], |mut console| { + console.write_raw("a\t\t"); + console.expect_all(&["addEventListener", "alert", "atob"]); + }); + // If the last character is whitespace, we just insert a tab + util::with_pty(&["repl"], |mut console| { + console.write_line("const a = 5;"); + console.expect("undefined"); + console.write_raw("a; \t\ta + 2;\n"); // last character is whitespace + console.expect_any(&[ + // windows + "a; a + 2;", + // unix + "a; \t\ta + 2;", + ]); + }); +} + +#[test] +fn repl_error() { + util::with_pty(&["repl"], |mut console| { + console.write_line("console.log(1);"); + console.expect_all(&["1", "undefined"]); + console.write_line(r#"throw new Error("foo");"#); + console.expect("Uncaught Error: foo"); + console.expect(" at "); + console.write_line("console.log(2);"); + console.expect("2"); + }); +} + +#[flaky_test::flaky_test] +fn repl_reject() { + util::with_pty(&["repl"], |mut console| { + console.write_line("console.log(1);"); + console.expect_all(&["1", "undefined"]); + console.write_line(r#"Promise.reject(new Error("foo"));"#); + console.expect("Promise {"); + console.expect(" Error: foo"); + console.expect("Uncaught Error: foo"); + console.expect(" at "); + console.write_line("console.log(2);"); + console.expect("2"); + console.write_line(r#"throw "hello";"#); + console.expect(r#"Uncaught "hello""#); + console.write_line(r#"throw `hello ${"world"}`;"#); + console.expect(r#"Uncaught "hello world""#); + }); +} + +#[flaky_test::flaky_test] +fn repl_report_error() { + util::with_pty(&["repl"], |mut console| { + console.write_line("console.log(1);"); + console.expect_all(&["1", "undefined"]); + console.write_line(r#"reportError(new Error("foo"));"#); + console.expect("undefined"); + console.expect("Uncaught Error: foo"); + console.expect(" at "); + console.write_line("console.log(2);"); + console.expect("2"); + }); +} + +#[flaky_test::flaky_test] +fn repl_error_undefined() { + util::with_pty(&["repl"], |mut console| { + console.write_line(r#"throw undefined;"#); + console.expect("Uncaught undefined"); + console.write_line(r#"Promise.reject();"#); + console.expect("Promise { undefined }"); + console.expect("Uncaught undefined"); + console.write_line(r#"reportError(undefined);"#); + console.expect("undefined"); + console.expect("Uncaught undefined"); + }); +} + +#[test] +fn pty_aggregate_error() { + util::with_pty(&["repl"], |mut console| { + console.write_line("await Promise.any([])"); + console.expect("AggregateError"); + }); +} + +#[test] +fn repl_with_quiet_flag() { + let (out, err) = util::run_and_collect_output_with_args( + true, + vec!["repl", "--quiet"], + Some(vec!["await Promise.resolve('done')"]), + Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), + false, + ); + assert!(!out.contains("Deno")); + assert!(!out.contains("exit using ctrl+d, ctrl+c, or close()")); + assert_ends_with!(out, "\"done\"\n"); + assert!(err.is_empty()); +} + +#[test] +fn repl_unit_tests() { + util::with_pty(&["repl"], |mut console| { + console.write_line_raw( + "\ + console.log('Hello from outside of test!'); \ + Deno.test('test1', async (t) => { \ + console.log('Hello from inside of test!'); \ + await t.step('step1', () => {}); \ + }); \ + Deno.test('test2', () => { \ + throw new Error('some message'); \ + }); \ + console.log('Hello again from outside of test!'); \ + ", + ); + + console.expect("Hello from outside of test!"); + console.expect("Hello again from outside of test!"); + // FIXME(nayeemrmn): REPL unit tests don't support output capturing. + console.expect("Hello from inside of test!"); + console.expect("test1 ..."); + console.expect(" step1 ... ok ("); + console.expect("test1 ... ok ("); + console.expect("test2 ... FAILED ("); + console.expect("ERRORS"); + console.expect("test2 => :6:6"); + console.expect("error: Error: some message"); + console.expect(" at :7:9"); + console.expect("FAILURES"); + console.expect("test2 => :6:6"); + console.expect("FAILED | 1 passed (1 step) | 1 failed ("); + console.expect("undefined"); + + console.write_line("Deno.test('test2', () => {});"); + + console.expect("test2 ... ok ("); + console.expect("ok | 1 passed | 0 failed ("); + console.expect("undefined"); + }); +} + +#[test] +fn npm_packages() { + let mut env_vars = util::env_vars_for_npm_tests(); + env_vars.push(("NO_COLOR".to_owned(), "1".to_owned())); + let temp_dir = TempDir::new(); + env_vars.push(("DENO_DIR".to_string(), temp_dir.path().to_string())); + + { + let (out, err) = util::run_and_collect_output_with_args( + true, + vec!["repl", "--quiet", "--allow-read", "--allow-env"], + Some(vec![ + r#"import chalk from "npm:chalk";"#, + "chalk.red('hel' + 'lo')", + ]), + Some(env_vars.clone()), + true, + ); + + assert_contains!(out, "hello"); + assert!(err.is_empty()); + } + + { + let (out, err) = util::run_and_collect_output_with_args( + true, + vec!["repl", "--quiet", "--allow-read", "--allow-env"], + Some(vec![ + r#"const chalk = await import("npm:chalk");"#, + "chalk.default.red('hel' + 'lo')", + ]), + Some(env_vars.clone()), + true, + ); + + assert_contains!(out, "hello"); + assert!(err.is_empty()); + } + + { + let (out, err) = util::run_and_collect_output_with_args( + true, + vec!["repl", "--quiet", "--allow-read", "--allow-env"], + Some(vec![r#"export {} from "npm:chalk";"#]), + Some(env_vars.clone()), + true, + ); + + assert_contains!(out, "[Module: null prototype] {"); + assert_contains!(out, "Chalk: [class Chalk],"); + assert!(err.is_empty()); + } + + { + let (out, err) = util::run_and_collect_output_with_args( + true, + vec!["repl", "--quiet", "--allow-read", "--allow-env"], + Some(vec![r#"import foo from "npm:asdfawe52345asdf""#]), + Some(env_vars.clone()), + true, + ); + + assert_contains!( + out, + "error: npm package 'asdfawe52345asdf' does not exist" + ); + assert!(err.is_empty()); + } + + { + let (out, err) = util::run_and_collect_output_with_args( + true, + vec!["repl", "--quiet", "--allow-read", "--allow-env"], + Some(vec![ + "import path from 'node:path';", + "path.isGlob('asdf') ? 'yes' : 'no'", + ]), + Some(env_vars.clone()), + true, + ); + + assert_contains!(out, "no"); + assert!(err.is_empty()); + } +} + +#[test] +fn pty_tab_indexable_props() { + util::with_pty(&["repl"], |mut console| { + console.write_line("const arr = [1, 2, 3]"); + console.expect("undefined"); + console.write_raw("arr.\t\t"); + console.expect("> arr."); + let output = console.read_until("> arr."); + assert_contains!(output, "constructor"); + assert_contains!(output, "sort"); + assert_contains!(output, "at"); + assert_not_contains!(output, "0", "1", "2"); + }); +} + +#[flaky_test::flaky_test] +fn package_json_uncached_no_error() { + let test_context = TestContextBuilder::for_npm() + .use_temp_cwd() + .use_http_server() + .env("RUST_BACKTRACE", "1") + .build(); + let temp_dir = test_context.temp_dir(); + temp_dir.write( + "package.json", + r#"{ + "dependencies": { + "@denotest/esm-basic": "1.0.0" + } +} +"#, + ); + test_context.new_command().with_pty(|mut console| { + console.write_line("console.log(123 + 456);"); + console.expect_all(&["579", "undefined"]); + assert_not_contains!( + console.all_output(), + "Could not set npm package requirements", + ); + + // should support getting the package now though + console + .write_line("import { getValue, setValue } from '@denotest/esm-basic';"); + console.expect_all(&["undefined", "Download"]); + console.write_line("setValue(12 + 30);"); + console.expect("undefined"); + console.write_line("getValue()"); + console.expect("42"); + + assert!(temp_dir.path().join("node_modules").exists()); + }); +} + +#[test] +fn closed_file_pre_load_does_not_occur() { + TestContext::default() + .new_command() + .args_vec(["repl", "-A", "--log-level=debug"]) + .with_pty(|console| { + assert_contains!(console.all_output(), "Skipping document preload.",); + }); +} + +#[test] +fn env_file() { + TestContext::default() + .new_command() + .args_vec([ + "repl", + "--env=env", + "--allow-env", + "--eval", + "console.log(Deno.env.get('FOO'))", + ]) + .with_pty(|console| { + assert_contains!(console.all_output(), "BAR",); + }); +} + +// Regression test for https://github.com/denoland/deno/issues/20528 +#[test] +fn pty_promise_was_collected_regression_test() { + let (out, err) = util::run_and_collect_output_with_args( + true, + vec!["repl"], + Some(vec!["new Uint8Array(64 * 1024 * 1024)"]), + None, + false, + ); + + assert_contains!(out, "Uint8Array(67108864)"); + assert!(err.is_empty()); +} diff --git a/tests/integration/run_tests.rs b/tests/integration/run_tests.rs new file mode 100644 index 000000000..298ce1715 --- /dev/null +++ b/tests/integration/run_tests.rs @@ -0,0 +1,5142 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +use bytes::Bytes; +use deno_core::serde_json::json; +use deno_core::url; +use deno_fetch::reqwest; +use pretty_assertions::assert_eq; +use std::io::Read; +use std::io::Write; +use std::process::Command; +use std::process::Stdio; +use std::time::Duration; +use test_util as util; +use test_util::TempDir; +use trust_dns_client::serialize::txt::Lexer; +use trust_dns_client::serialize::txt::Parser; +use util::assert_contains; +use util::assert_not_contains; +use util::env_vars_for_npm_tests; +use util::PathRef; +use util::TestContext; +use util::TestContextBuilder; + +itest!(stdout_write_all { + args: "run --quiet run/stdout_write_all.ts", + output: "run/stdout_write_all.out", +}); + +itest!(stdin_read_all { + args: "run --quiet run/stdin_read_all.ts", + output: "run/stdin_read_all.out", + input: Some("01234567890123456789012345678901234567890123456789"), +}); + +itest!(stdout_write_sync_async { + args: "run --quiet run/stdout_write_sync_async.ts", + output: "run/stdout_write_sync_async.out", +}); + +itest!(_001_hello { + args: "run --reload run/001_hello.js", + output: "run/001_hello.js.out", +}); + +itest!(_002_hello { + args: "run --quiet --reload run/002_hello.ts", + output: "run/002_hello.ts.out", +}); + +itest!(_003_relative_import { + args: "run --quiet --reload run/003_relative_import.ts", + output: "run/003_relative_import.ts.out", +}); + +itest!(_004_set_timeout { + args: "run --quiet --reload run/004_set_timeout.ts", + output: "run/004_set_timeout.ts.out", +}); + +itest!(_005_more_imports { + args: "run --quiet --reload run/005_more_imports.ts", + output: "run/005_more_imports.ts.out", +}); + +itest!(_006_url_imports { + args: "run --quiet --reload run/006_url_imports.ts", + output: "run/006_url_imports.ts.out", + http_server: true, +}); + +itest!(_012_async { + args: "run --quiet --reload run/012_async.ts", + output: "run/012_async.ts.out", +}); + +itest!(_013_dynamic_import { + args: "run --quiet --reload --allow-read run/013_dynamic_import.ts", + output: "run/013_dynamic_import.ts.out", +}); + +itest!(_014_duplicate_import { + args: "run --quiet --reload --allow-read run/014_duplicate_import.ts ", + output: "run/014_duplicate_import.ts.out", +}); + +itest!(_015_duplicate_parallel_import { + args: + "run --quiet --reload --allow-read run/015_duplicate_parallel_import.js", + output: "run/015_duplicate_parallel_import.js.out", +}); + +itest!(_016_double_await { + args: "run --quiet --allow-read --reload run/016_double_await.ts", + output: "run/016_double_await.ts.out", +}); + +itest!(_017_import_redirect { + args: "run --quiet --reload run/017_import_redirect.ts", + output: "run/017_import_redirect.ts.out", +}); + +itest!(_017_import_redirect_check { + args: "run --quiet --reload --check run/017_import_redirect.ts", + output: "run/017_import_redirect.ts.out", +}); + +itest!(_017_import_redirect_vendor_dir { + args: + "run --quiet --reload --vendor --check $TESTDATA/run/017_import_redirect.ts", + output: "run/017_import_redirect.ts.out", + temp_cwd: true, +}); + +itest!(_017_import_redirect_info { + args: "info --quiet --reload run/017_import_redirect.ts", + output: "run/017_import_redirect_info.out", +}); + +itest!(_018_async_catch { + args: "run --quiet --reload run/018_async_catch.ts", + output: "run/018_async_catch.ts.out", +}); + +itest!(_019_media_types { + args: "run --reload run/019_media_types.ts", + output: "run/019_media_types.ts.out", + http_server: true, +}); + +itest!(_020_json_modules { + args: "run --reload run/020_json_modules.ts", + output: "run/020_json_modules.ts.out", + exit_code: 1, +}); + +itest!(_021_mjs_modules { + args: "run --quiet --reload run/021_mjs_modules.ts", + output: "run/021_mjs_modules.ts.out", +}); + +itest!(_023_no_ext { + args: "run --reload --check run/023_no_ext", + output: "run/023_no_ext.out", +}); + +itest!(_025_hrtime { + args: "run --quiet --allow-hrtime --reload run/025_hrtime.ts", + output: "run/025_hrtime.ts.out", +}); + +itest!(_025_reload_js_type_error { + args: "run --quiet --reload run/025_reload_js_type_error.js", + output: "run/025_reload_js_type_error.js.out", +}); + +itest!(_026_redirect_javascript { + args: "run --quiet --reload run/026_redirect_javascript.js", + output: "run/026_redirect_javascript.js.out", + http_server: true, +}); + +itest!(_027_redirect_typescript { + args: "run --quiet --reload run/027_redirect_typescript.ts", + output: "run/027_redirect_typescript.ts.out", + http_server: true, +}); + +itest!(_027_redirect_typescript_vendor_dir { + args: + "run --quiet --reload --vendor $TESTDATA/run/027_redirect_typescript.ts", + output: "run/027_redirect_typescript.ts.out", + http_server: true, + temp_cwd: true, +}); + +itest!(_028_args { + args: + "run --quiet --reload run/028_args.ts --arg1 val1 --arg2=val2 -- arg3 arg4", + output: "run/028_args.ts.out", +}); + +itest!(_033_import_map { + args: + "run --quiet --reload --import-map=import_maps/import_map.json import_maps/test.ts", + output: "run/033_import_map.out", +}); + +itest!(_033_import_map_in_config_file { + args: "run --reload --config=import_maps/config.json import_maps/test.ts", + output: "run/033_import_map_in_config_file.out", +}); + +itest!(_033_import_map_in_flag_has_precedence { + args: "run --quiet --reload --import-map=import_maps/import_map_invalid.json --config=import_maps/config.json import_maps/test.ts", + output: "run/033_import_map_in_flag_has_precedence.out", + exit_code: 1, +}); + +itest!(_033_import_map_remote { + args: + "run --quiet --reload --import-map=http://127.0.0.1:4545/import_maps/import_map_remote.json import_maps/test_remote.ts", + output: "run/033_import_map_remote.out", + http_server: true, +}); + +itest!(_033_import_map_vendor_dir_remote { + args: + "run --quiet --reload --import-map=http://127.0.0.1:4545/import_maps/import_map_remote.json --vendor $TESTDATA/import_maps/test_remote.ts", + output: "run/033_import_map_remote.out", + http_server: true, + temp_cwd: true, +}); + +itest!(_033_import_map_data_uri { + args: + "run --quiet --reload --import-map=data:application/json;charset=utf-8;base64,ewogICJpbXBvcnRzIjogewogICAgInRlc3Rfc2VydmVyLyI6ICJodHRwOi8vbG9jYWxob3N0OjQ1NDUvIgogIH0KfQ== run/import_maps/test_data.ts", + output: "run/import_maps/test_data.ts.out", + http_server: true, +}); + +itest!(onload { + args: "run --quiet --reload run/onload/main.ts", + output: "run/onload/main.out", +}); + +itest!(_035_cached_only_flag { + args: "run --reload --check --cached-only http://127.0.0.1:4545/run/019_media_types.ts", + output: "run/035_cached_only_flag.out", + exit_code: 1, + http_server: true, +}); + +itest!(_038_checkjs { + // checking if JS file is run through TS compiler + args: + "run --reload --config run/checkjs.tsconfig.json --check run/038_checkjs.js", + exit_code: 1, + output: "run/038_checkjs.js.out", +}); + +itest!(_042_dyn_import_evalcontext { + args: "run --quiet --allow-read --reload run/042_dyn_import_evalcontext.ts", + output: "run/042_dyn_import_evalcontext.ts.out", +}); + +itest!(_044_bad_resource { + args: "run --quiet --reload --allow-read run/044_bad_resource.ts", + output: "run/044_bad_resource.ts.out", + exit_code: 1, +}); + +itest!(_045_proxy { + args: "run -L debug --allow-net --allow-env --allow-run --allow-read --reload --quiet run/045_proxy_test.ts", + output: "run/045_proxy_test.ts.out", + http_server: true, +}); + +itest!(_046_tsx { + args: "run --quiet --reload run/046_jsx_test.tsx", + output: "run/046_jsx_test.tsx.out", +}); + +itest!(_047_jsx { + args: "run --quiet --reload run/047_jsx_test.jsx", + output: "run/047_jsx_test.jsx.out", +}); + +itest!(_048_media_types_jsx { + args: "run --reload run/048_media_types_jsx.ts", + output: "run/048_media_types_jsx.ts.out", + http_server: true, +}); + +itest!(_052_no_remote_flag { + args: + "run --reload --check --no-remote http://127.0.0.1:4545/run/019_media_types.ts", + output: "run/052_no_remote_flag.out", + exit_code: 1, + http_server: true, +}); + +itest!(_056_make_temp_file_write_perm { + args: + "run --quiet --allow-read --allow-write=./subdir/ run/056_make_temp_file_write_perm.ts", + output: "run/056_make_temp_file_write_perm.out", +}); + +itest!(_058_tasks_microtasks_close { + args: "run --quiet run/058_tasks_microtasks_close.ts", + output: "run/058_tasks_microtasks_close.ts.out", +}); + +itest!(_059_fs_relative_path_perm { + args: "run run/059_fs_relative_path_perm.ts", + output: "run/059_fs_relative_path_perm.ts.out", + exit_code: 1, +}); + +itest!(_070_location { + args: "run --location https://foo/bar?baz#bat run/070_location.ts", + output: "run/070_location.ts.out", +}); + +itest!(_071_location_unset { + args: "run run/071_location_unset.ts", + output: "run/071_location_unset.ts.out", +}); + +itest!(_072_location_relative_fetch { + args: "run --location http://127.0.0.1:4545/ --allow-net run/072_location_relative_fetch.ts", + output: "run/072_location_relative_fetch.ts.out", + http_server: true, +}); + +// tests the beforeunload event +itest!(beforeunload_event { + args: "run run/before_unload.js", + output: "run/before_unload.js.out", +}); + +// tests the serialization of webstorage (both localStorage and sessionStorage) +itest!(webstorage_serialization { + args: "run run/webstorage/serialization.ts", + output: "run/webstorage/serialization.ts.out", +}); + +// tests to ensure that when `--location` is set, all code shares the same +// localStorage cache based on the origin of the location URL. +#[test] +fn webstorage_location_shares_origin() { + let deno_dir = util::new_deno_dir(); + + let output = util::deno_cmd_with_deno_dir(&deno_dir) + .current_dir(util::testdata_path()) + .arg("run") + .arg("--location") + .arg("https://example.com/a.ts") + .arg("run/webstorage/fixture.ts") + .stdout(Stdio::piped()) + .spawn() + .unwrap() + .wait_with_output() + .unwrap(); + assert!(output.status.success()); + assert_eq!(output.stdout, b"Storage { length: 0 }\n"); + + let output = util::deno_cmd_with_deno_dir(&deno_dir) + .current_dir(util::testdata_path()) + .arg("run") + .arg("--location") + .arg("https://example.com/b.ts") + .arg("run/webstorage/logger.ts") + .stdout(Stdio::piped()) + .spawn() + .unwrap() + .wait_with_output() + .unwrap(); + assert!(output.status.success()); + assert_eq!(output.stdout, b"Storage { hello: \"deno\", length: 1 }\n"); +} + +// test to ensure that when a --config file is set, but no --location, that +// storage persists against unique configuration files. +#[test] +fn webstorage_config_file() { + let context = TestContext::default(); + + context + .new_command() + .args( + "run --config run/webstorage/config_a.jsonc run/webstorage/fixture.ts", + ) + .run() + .assert_matches_text("Storage { length: 0 }\n"); + + context + .new_command() + .args("run --config run/webstorage/config_b.jsonc run/webstorage/logger.ts") + .run() + .assert_matches_text("Storage { length: 0 }\n"); + + context + .new_command() + .args("run --config run/webstorage/config_a.jsonc run/webstorage/logger.ts") + .run() + .assert_matches_text("Storage { hello: \"deno\", length: 1 }\n"); +} + +// tests to ensure `--config` does not effect persisted storage when a +// `--location` is provided. +#[test] +fn webstorage_location_precedes_config() { + let context = TestContext::default(); + + context.new_command() + .args("run --location https://example.com/a.ts --config run/webstorage/config_a.jsonc run/webstorage/fixture.ts") + .run() + .assert_matches_text("Storage { length: 0 }\n"); + + context.new_command() + .args("run --location https://example.com/b.ts --config run/webstorage/config_b.jsonc run/webstorage/logger.ts") + .run() + .assert_matches_text("Storage { hello: \"deno\", length: 1 }\n"); +} + +// test to ensure that when there isn't a configuration or location, that the +// main module is used to determine how to persist storage data. +#[test] +fn webstorage_main_module() { + let context = TestContext::default(); + + context + .new_command() + .args("run run/webstorage/fixture.ts") + .run() + .assert_matches_text("Storage { length: 0 }\n"); + + context + .new_command() + .args("run run/webstorage/logger.ts") + .run() + .assert_matches_text("Storage { length: 0 }\n"); + + context + .new_command() + .args("run run/webstorage/fixture.ts") + .run() + .assert_matches_text("Storage { hello: \"deno\", length: 1 }\n"); +} + +itest!(_075_import_local_query_hash { + args: "run run/075_import_local_query_hash.ts", + output: "run/075_import_local_query_hash.ts.out", +}); + +itest!(_077_fetch_empty { + args: "run -A run/077_fetch_empty.ts", + output: "run/077_fetch_empty.ts.out", + exit_code: 1, +}); + +itest!(_078_unload_on_exit { + args: "run run/078_unload_on_exit.ts", + output: "run/078_unload_on_exit.ts.out", + exit_code: 1, +}); + +itest!(_079_location_authentication { + args: + "run --location https://foo:bar@baz/qux run/079_location_authentication.ts", + output: "run/079_location_authentication.ts.out", +}); + +itest!(_081_location_relative_fetch_redirect { + args: "run --location http://127.0.0.1:4546/ --allow-net run/081_location_relative_fetch_redirect.ts", + output: "run/081_location_relative_fetch_redirect.ts.out", + http_server: true, + }); + +itest!(_082_prepare_stack_trace_throw { + args: "run run/082_prepare_stack_trace_throw.js", + output: "run/082_prepare_stack_trace_throw.js.out", + exit_code: 1, +}); + +#[test] +fn _083_legacy_external_source_map() { + let _g = util::http_server(); + let deno_dir = TempDir::new(); + let module_url = url::Url::parse( + "http://localhost:4545/run/083_legacy_external_source_map.ts", + ) + .unwrap(); + // Write a faulty old external source map. + let faulty_map_path = deno_dir.path().join("gen/http/localhost_PORT4545/9576bd5febd0587c5c4d88d57cb3ac8ebf2600c529142abe3baa9a751d20c334.js.map"); + faulty_map_path.parent().create_dir_all(); + faulty_map_path.write(r#"{\"version\":3,\"file\":\"\",\"sourceRoot\":\"\",\"sources\":[\"http://localhost:4545/083_legacy_external_source_map.ts\"],\"names\":[],\"mappings\":\";AAAA,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC\"}"#); + let output = Command::new(util::deno_exe_path()) + .env("DENO_DIR", deno_dir.path()) + .current_dir(util::testdata_path()) + .arg("run") + .arg(module_url.to_string()) + .output() + .unwrap(); + // Before https://github.com/denoland/deno/issues/6965 was fixed, the faulty + // old external source map would cause a panic while formatting the error + // and the exit code would be 101. The external source map should be ignored + // in favor of the inline one. + assert_eq!(output.status.code(), Some(1)); + let out = std::str::from_utf8(&output.stdout).unwrap(); + assert_eq!(out, ""); +} + +itest!(dynamic_import_async_error { + args: "run --allow-read run/dynamic_import_async_error/main.ts", + output: "run/dynamic_import_async_error/main.out", +}); + +itest!(dynamic_import_already_rejected { + args: "run --allow-read run/dynamic_import_already_rejected/main.ts", + output: "run/dynamic_import_already_rejected/main.out", +}); + +itest!(dynamic_import_concurrent_non_statically_analyzable { + args: "run --allow-read --allow-net --quiet run/dynamic_import_concurrent_non_statically_analyzable/main.ts", + output: "run/dynamic_import_concurrent_non_statically_analyzable/main.out", + http_server: true, +}); + +itest!(no_check_imports_not_used_as_values { + args: "run --config run/no_check_imports_not_used_as_values/preserve_imports.tsconfig.json --no-check run/no_check_imports_not_used_as_values/main.ts", + output: "run/no_check_imports_not_used_as_values/main.out", + }); + +itest!(_088_dynamic_import_already_evaluating { + args: "run --allow-read run/088_dynamic_import_already_evaluating.ts", + output: "run/088_dynamic_import_already_evaluating.ts.out", +}); + +// TODO(bartlomieju): remove --unstable once Deno.Command is stabilized +itest!(_089_run_allow_list { + args: "run --unstable --allow-run=curl run/089_run_allow_list.ts", + output: "run/089_run_allow_list.ts.out", +}); + +#[test] +fn _090_run_permissions_request() { + TestContext::default() + .new_command() + .args_vec(["run", "--quiet", "run/090_run_permissions_request.ts"]) + .with_pty(|mut console| { + console.expect(concat!( + "┌ ⚠️ Deno requests run access to \"ls\".\r\n", + "├ Requested by `Deno.permissions.request()` API.\r\n", + "├ Run again with --allow-run to bypass this prompt.\r\n", + "└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all run permissions)", + )); + console.write_line_raw("y"); + console.expect("Granted run access to \"ls\"."); + console.expect(concat!( + "┌ ⚠️ Deno requests run access to \"cat\".\r\n", + "├ Requested by `Deno.permissions.request()` API.\r\n", + "├ Run again with --allow-run to bypass this prompt.\r\n", + "└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all run permissions)", + )); + console.write_line_raw("n"); + console.expect("Denied run access to \"cat\"."); + console.expect("granted"); + console.expect("denied"); + }); +} + +#[test] +fn _090_run_permissions_request_sync() { + TestContext::default() + .new_command() + .args_vec(["run", "--quiet", "run/090_run_permissions_request_sync.ts"]) + .with_pty(|mut console| { + console.expect(concat!( + "┌ ⚠️ Deno requests run access to \"ls\".\r\n", + "├ Requested by `Deno.permissions.request()` API.\r\n", + "├ Run again with --allow-run to bypass this prompt.\r\n", + "└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all run permissions)", + )); + console.write_line_raw("y"); + console.expect("Granted run access to \"ls\"."); + console.expect(concat!( + "┌ ⚠️ Deno requests run access to \"cat\".\r\n", + "├ Requested by `Deno.permissions.request()` API.\r\n", + "├ Run again with --allow-run to bypass this prompt.\r\n", + "└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all run permissions)", + )); + console.write_line_raw("n"); + console.expect("Denied run access to \"cat\"."); + console.expect("granted"); + console.expect("denied"); + }); +} + +#[test] +fn permissions_prompt_allow_all() { + TestContext::default() + .new_command() + .args_vec(["run", "--quiet", "run/permissions_prompt_allow_all.ts"]) + .with_pty(|mut console| { + // "run" permissions + console.expect(concat!( + "┌ ⚠️ Deno requests run access to \"FOO\".\r\n", + "├ Requested by `Deno.permissions.request()` API.\r\n", + "├ Run again with --allow-run to bypass this prompt.\r\n", + "└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all run permissions)", + )); + console.write_line_raw("A"); + console.expect("✅ Granted all run access."); + // "read" permissions + console.expect(concat!( + "┌ ⚠️ Deno requests read access to \"FOO\".\r\n", + "├ Requested by `Deno.permissions.request()` API.\r\n", + "├ Run again with --allow-read to bypass this prompt.\r\n", + "└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)", + )); + console.write_line_raw("A"); + console.expect("✅ Granted all read access."); + // "write" permissions + console.expect(concat!( + "┌ ⚠️ Deno requests write access to \"FOO\".\r\n", + "├ Requested by `Deno.permissions.request()` API.\r\n", + "├ Run again with --allow-write to bypass this prompt.\r\n", + "└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all write permissions)", + )); + console.write_line_raw("A"); + console.expect("✅ Granted all write access."); + // "net" permissions + console.expect(concat!( + "┌ ⚠️ Deno requests net access to \"foo\".\r\n", + "├ Requested by `Deno.permissions.request()` API.\r\n", + "├ Run again with --allow-net to bypass this prompt.\r\n", + "└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all net permissions)", + )); + console.write_line_raw("A\n"); + console.expect("✅ Granted all net access."); + // "env" permissions + console.expect(concat!( + "┌ ⚠️ Deno requests env access to \"FOO\".\r\n", + "├ Requested by `Deno.permissions.request()` API.\r\n", + "├ Run again with --allow-env to bypass this prompt.\r\n", + "└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all env permissions)", + )); + console.write_line_raw("A\n"); + console.expect("✅ Granted all env access."); + // "sys" permissions + console.expect(concat!( + "┌ ⚠️ Deno requests sys access to \"loadavg\".\r\n", + "├ Requested by `Deno.permissions.request()` API.\r\n", + "├ Run again with --allow-sys to bypass this prompt.\r\n", + "└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all sys permissions)", + )); + console.write_line_raw("A\n"); + console.expect("✅ Granted all sys access."); + // "ffi" permissions + console.expect(concat!( + "┌ ⚠️ Deno requests ffi access to \"FOO\".\r\n", + "├ Requested by `Deno.permissions.request()` API.\r\n", + "├ Run again with --allow-ffi to bypass this prompt.\r\n", + "└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all ffi permissions)", + )); + console.write_line_raw("A\n"); + console.expect("✅ Granted all ffi access.") + }, + ); +} + +#[test] +fn permissions_prompt_allow_all_2() { + TestContext::default() + .new_command() + .args_vec(["run", "--quiet", "run/permissions_prompt_allow_all_2.ts"]) + .with_pty(|mut console| { + // "env" permissions + console.expect(concat!( + "┌ ⚠️ Deno requests env access to \"FOO\".\r\n", + "├ Run again with --allow-env to bypass this prompt.\r\n", + "└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all env permissions)", + )); + console.write_line_raw("A"); + console.expect("✅ Granted all env access."); + + // "sys" permissions + console.expect(concat!( + "┌ ⚠️ Deno requests sys access to \"loadavg\".\r\n", + "├ Requested by `Deno.loadavg()` API.\r\n", + "├ Run again with --allow-sys to bypass this prompt.\r\n", + "└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all sys permissions)", + )); + console.write_line_raw("A"); + console.expect("✅ Granted all sys access."); + + // "read" permissions + console.expect(concat!( + "┌ ⚠️ Deno requests read access to .\r\n", + "├ Requested by `Deno.cwd()` API.\r\n", + "├ Run again with --allow-read to bypass this prompt.\r\n", + "└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)", + )); + console.write_line_raw("A"); + console.expect("✅ Granted all read access."); + }); +} + +#[test] +fn permissions_prompt_allow_all_lowercase_a() { + TestContext::default() + .new_command() + .args_vec(["run", "--quiet", "run/permissions_prompt_allow_all.ts"]) + .with_pty(|mut console| { + // "run" permissions + console.expect(concat!( + "┌ ⚠️ Deno requests run access to \"FOO\".\r\n", + "├ Requested by `Deno.permissions.request()` API.\r\n", + "├ Run again with --allow-run to bypass this prompt.\r\n", + "└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all run permissions)", + )); + console.write_line_raw("a"); + console.expect("Unrecognized option."); + }); +} + +#[test] +fn permission_request_long() { + TestContext::default() + .new_command() + .args_vec(["run", "--quiet", "run/permission_request_long.ts"]) + .with_pty(|mut console| { + console.expect(concat!( + "❌ Permission prompt length (100017 bytes) was larger than the configured maximum length (10240 bytes): denying request.\r\n", + "❌ WARNING: This may indicate that code is trying to bypass or hide permission check requests.\r\n", + "❌ Run again with --allow-read to bypass this check if this is really what you want to do.\r\n", + )); + }); +} + +itest!(deny_all_permission_args { + args: "run --deny-env --deny-read --deny-write --deny-ffi --deny-run --deny-sys --deny-net --deny-hrtime run/deny_all_permission_args.js", + output: "run/deny_all_permission_args.out", +}); + +itest!(deny_some_permission_args { + args: "run --allow-env --deny-env=FOO --allow-read --deny-read=/foo --allow-write --deny-write=/foo --allow-ffi --deny-ffi=/foo --allow-run --deny-run=foo --allow-sys --deny-sys=hostname --allow-net --deny-net=127.0.0.1 --allow-hrtime --deny-hrtime run/deny_some_permission_args.js", + output: "run/deny_some_permission_args.out", +}); + +#[test] +fn permissions_cache() { + TestContext::default() + .new_command() + .args_vec(["run", "--quiet", "run/permissions_cache.ts"]) + .with_pty(|mut console| { + console.expect(concat!( + "prompt\r\n", + "┌ ⚠️ Deno requests read access to \"foo\".\r\n", + "├ Requested by `Deno.permissions.request()` API.\r\n", + "├ Run again with --allow-read to bypass this prompt.\r\n", + "└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)", + )); + console.write_line_raw("y"); + console.expect("✅ Granted read access to \"foo\"."); + console.expect("granted"); + console.expect("prompt"); + }); +} + +itest!(env_file { + args: "run --env=env --allow-env run/env_file.ts", + output: "run/env_file.out", +}); + +itest!(env_file_missing { + args: "run --env=missing --allow-env run/env_file.ts", + output: "run/env_file_missing.out", +}); + +itest!(_091_use_define_for_class_fields { + args: "run --check run/091_use_define_for_class_fields.ts", + output: "run/091_use_define_for_class_fields.ts.out", + exit_code: 1, +}); + +itest!(_092_import_map_unmapped_bare_specifier { + args: "run --import-map import_maps/import_map.json run/092_import_map_unmapped_bare_specifier.ts", + output: "run/092_import_map_unmapped_bare_specifier.ts.out", + exit_code: 1, +}); + +itest!(js_import_detect { + args: "run --quiet --reload run/js_import_detect.ts", + output: "run/js_import_detect.ts.out", + exit_code: 0, +}); + +itest!(blob_gc_finalization { + args: "run run/blob_gc_finalization.js", + output: "run/blob_gc_finalization.js.out", + exit_code: 0, +}); + +itest!(fetch_response_finalization { + args: + "run --v8-flags=--expose-gc --allow-net run/fetch_response_finalization.js", + output: "run/fetch_response_finalization.js.out", + http_server: true, + exit_code: 0, +}); + +itest!(import_type { + args: "run --reload run/import_type.ts", + output: "run/import_type.ts.out", +}); + +itest!(import_type_no_check { + args: "run --reload --no-check run/import_type.ts", + output: "run/import_type.ts.out", +}); + +itest!(private_field_presence { + args: "run --reload run/private_field_presence.ts", + output: "run/private_field_presence.ts.out", +}); + +itest!(private_field_presence_no_check { + args: "run --reload --no-check run/private_field_presence.ts", + output: "run/private_field_presence.ts.out", +}); + +itest!(lock_write_fetch { + args: + "run --quiet --allow-read --allow-write --allow-env --allow-run run/lock_write_fetch/main.ts", + output: "run/lock_write_fetch/main.out", + http_server: true, + exit_code: 0, +}); + +itest!(lock_check_ok { + args: + "run --quiet --lock=run/lock_check_ok.json http://127.0.0.1:4545/run/003_relative_import.ts", + output: "run/003_relative_import.ts.out", + http_server: true, +}); + +itest!(lock_check_ok2 { + args: "run --lock=run/lock_check_ok2.json run/019_media_types.ts", + output: "run/019_media_types.ts.out", + http_server: true, +}); + +itest!(lock_dynamic_imports { + args: "run --lock=run/lock_dynamic_imports.json --allow-read --allow-net http://127.0.0.1:4545/run/013_dynamic_import.ts", + output: "run/lock_dynamic_imports.out", + exit_code: 10, + http_server: true, +}); + +itest!(lock_check_err { + args: "run --lock=run/lock_check_err.json http://127.0.0.1:4545/run/003_relative_import.ts", + output: "run/lock_check_err.out", + exit_code: 10, + http_server: true, +}); + +itest!(lock_check_err2 { + args: "run --lock=run/lock_check_err2.json run/019_media_types.ts", + output: "run/lock_check_err2.out", + exit_code: 10, + http_server: true, +}); + +itest!(config_file_lock_path { + args: "run --config=run/config_file_lock_path.json run/019_media_types.ts", + output: "run/config_file_lock_path.out", + exit_code: 10, + http_server: true, +}); + +itest!(lock_flag_overrides_config_file_lock_path { + args: "run --lock=run/lock_check_ok2.json --config=run/config_file_lock_path.json run/019_media_types.ts", + output: "run/019_media_types.ts.out", + http_server: true, +}); + +itest!(lock_v2_check_ok { + args: + "run --quiet --lock=run/lock_v2_check_ok.json http://127.0.0.1:4545/run/003_relative_import.ts", + output: "run/003_relative_import.ts.out", + http_server: true, +}); + +itest!(lock_v2_check_ok2 { + args: "run --lock=run/lock_v2_check_ok2.json run/019_media_types.ts", + output: "run/019_media_types.ts.out", + http_server: true, +}); + +itest!(lock_v2_dynamic_imports { + args: "run --lock=run/lock_v2_dynamic_imports.json --allow-read --allow-net http://127.0.0.1:4545/run/013_dynamic_import.ts", + output: "run/lock_v2_dynamic_imports.out", + exit_code: 10, + http_server: true, +}); + +itest!(lock_v2_check_err { + args: "run --lock=run/lock_v2_check_err.json http://127.0.0.1:4545/run/003_relative_import.ts", + output: "run/lock_v2_check_err.out", + exit_code: 10, + http_server: true, +}); + +itest!(lock_v2_check_err2 { + args: "run --lock=run/lock_v2_check_err2.json run/019_media_types.ts", + output: "run/lock_v2_check_err2.out", + exit_code: 10, + http_server: true, +}); + +itest!(lock_only_http_and_https { + args: "run --lock=run/lock_only_http_and_https/deno.lock run/lock_only_http_and_https/main.ts", + output: "run/lock_only_http_and_https/main.out", + http_server: true, +}); + +#[test] +fn lock_no_declaration_files() { + let context = TestContextBuilder::new() + .use_temp_cwd() + .use_http_server() + .build(); + let output = context + .new_command() + .args("cache --lock --lock-write $TESTDATA/lockfile/no_dts/main.ts") + .run(); + output.assert_matches_file("lockfile/no_dts/main.cache.out"); + let lockfile = context.temp_dir().path().join("deno.lock"); + lockfile.assert_matches_file("lockfile/no_dts/deno.lock.out"); +} + +#[test] +fn lock_redirects() { + let context = TestContextBuilder::new() + .use_temp_cwd() + .use_http_server() + .add_npm_env_vars() + .build(); + let temp_dir = context.temp_dir(); + temp_dir.write("deno.json", "{}"); // cause a lockfile to be created + temp_dir.write( + "main.ts", + "import 'http://localhost:4546/run/001_hello.js';", + ); + context + .new_command() + .args("run main.ts") + .run() + .skip_output_check(); + let initial_lockfile_text = r#"{ + "version": "3", + "redirects": { + "http://localhost:4546/run/001_hello.js": "http://localhost:4545/run/001_hello.js" + }, + "remote": { + "http://localhost:4545/run/001_hello.js": "c479db5ea26965387423ca438bb977d0b4788d5901efcef52f69871e4c1048c5" + } +} +"#; + assert_eq!(temp_dir.read_to_string("deno.lock"), initial_lockfile_text); + context + .new_command() + .args("run main.ts") + .run() + .assert_matches_text("Hello World\n"); + assert_eq!(temp_dir.read_to_string("deno.lock"), initial_lockfile_text); + + // now try changing where the redirect occurs in the lockfile + temp_dir.write("deno.lock", r#"{ + "version": "3", + "redirects": { + "http://localhost:4546/run/001_hello.js": "http://localhost:4545/echo.ts" + }, + "remote": { + "http://localhost:4545/run/001_hello.js": "c479db5ea26965387423ca438bb977d0b4788d5901efcef52f69871e4c1048c5" + } +} +"#); + + // also, add some npm dependency to ensure it doesn't end up in + // the redirects as they're currently stored separately + temp_dir.write( + "main.ts", + "import 'http://localhost:4546/run/001_hello.js';\n import 'npm:@denotest/esm-basic';\n", + ); + + // it should use the echo script instead + context + .new_command() + .args("run main.ts Hi there") + .run() + .assert_matches_text( + concat!( + "Download http://localhost:4545/echo.ts\n", + "Download http://localhost:4545/npm/registry/@denotest/esm-basic\n", + "Download http://localhost:4545/npm/registry/@denotest/esm-basic/1.0.0.tgz\n", + "Hi, there", + )); + util::assertions::assert_wildcard_match( + &temp_dir.read_to_string("deno.lock"), + r#"{ + "version": "3", + "packages": { + "specifiers": { + "npm:@denotest/esm-basic": "npm:@denotest/esm-basic@1.0.0" + }, + "npm": { + "@denotest/esm-basic@1.0.0": { + "integrity": "sha512-[WILDCARD]", + "dependencies": {} + } + } + }, + "redirects": { + "http://localhost:4546/run/001_hello.js": "http://localhost:4545/echo.ts" + }, + "remote": { + "http://localhost:4545/echo.ts": "829eb4d67015a695d70b2a33c78b631b29eea1dbac491a6bfcf394af2a2671c2", + "http://localhost:4545/run/001_hello.js": "c479db5ea26965387423ca438bb977d0b4788d5901efcef52f69871e4c1048c5" + } +} +"#, + ); +} + +#[test] +fn lock_deno_json_package_json_deps() { + let context = TestContextBuilder::new() + .use_temp_cwd() + .use_http_server() + .add_npm_env_vars() + .add_jsr_env_vars() + .build(); + let temp_dir = context.temp_dir().path(); + let deno_json = temp_dir.join("deno.json"); + let package_json = temp_dir.join("package.json"); + + // add a jsr and npm dependency + deno_json.write_json(&json!({ + "imports": { + "esm-basic": "npm:@denotest/esm-basic", + "module_graph": "jsr:@denotest/module_graph@1.4", + } + })); + let main_ts = temp_dir.join("main.ts"); + main_ts.write("import 'esm-basic'; import 'module_graph';"); + context + .new_command() + .args("cache main.ts") + .run() + .skip_output_check(); + let lockfile = temp_dir.join("deno.lock"); + let esm_basic_integrity = + get_lockfile_npm_package_integrity(&lockfile, "@denotest/esm-basic@1.0.0"); + lockfile.assert_matches_json(json!({ + "version": "3", + "packages": { + "specifiers": { + "jsr:@denotest/module_graph@1.4": "jsr:@denotest/module_graph@1.4.0", + "npm:@denotest/esm-basic": "npm:@denotest/esm-basic@1.0.0" + }, + "jsr": { + "@denotest/module_graph@1.4.0": {} + }, + "npm": { + "@denotest/esm-basic@1.0.0": { + "integrity": esm_basic_integrity, + "dependencies": {} + } + } + }, + "remote": { + "http://127.0.0.1:4250/@denotest/module_graph/1.4.0/mod.ts": "5b0ce36e08d759118200d8b4627627b5a89b6261fbb0598e6961a6b287abb699", + "http://127.0.0.1:4250/@denotest/module_graph/1.4.0/other.ts": "9ce27ca439cb0e218b6e1ec26c043dbc0b54c9babc4cb432df478dd1721faade" + }, + "workspace": { + "dependencies": [ + "jsr:@denotest/module_graph@1.4", + "npm:@denotest/esm-basic" + ] + } + })); + + // now remove the npm dependency from the deno.json and move + // it to a package.json that uses an alias + deno_json.write_json(&json!({ + "imports": { + "module_graph": "jsr:@denotest/module_graph@1.4", + } + })); + package_json.write_json(&json!({ + "dependencies": { + "esm-basic": "npm:@denotest/esm-basic" + } + })); + context + .new_command() + .args("cache main.ts") + .run() + .skip_output_check(); + main_ts.write("import 'module_graph';"); + context + .new_command() + // ensure this doesn't clear out packageJson below + .args("cache --no-npm main.ts") + .run() + .skip_output_check(); + lockfile.assert_matches_json(json!({ + "version": "3", + "packages": { + "specifiers": { + "jsr:@denotest/module_graph@1.4": "jsr:@denotest/module_graph@1.4.0", + "npm:@denotest/esm-basic": "npm:@denotest/esm-basic@1.0.0" + }, + "jsr": { + "@denotest/module_graph@1.4.0": {} + }, + "npm": { + "@denotest/esm-basic@1.0.0": { + "integrity": esm_basic_integrity, + "dependencies": {} + } + } + }, + "remote": { + "http://127.0.0.1:4250/@denotest/module_graph/1.4.0/mod.ts": "5b0ce36e08d759118200d8b4627627b5a89b6261fbb0598e6961a6b287abb699", + "http://127.0.0.1:4250/@denotest/module_graph/1.4.0/other.ts": "9ce27ca439cb0e218b6e1ec26c043dbc0b54c9babc4cb432df478dd1721faade" + }, + "workspace": { + "dependencies": [ + "jsr:@denotest/module_graph@1.4" + ], + "packageJson": { + "dependencies": [ + "npm:@denotest/esm-basic" + ] + } + } + })); + + // now remove the package.json + package_json.remove_file(); + + // cache and it will remove the package.json + context + .new_command() + .args("cache main.ts") + .run() + .skip_output_check(); + lockfile.assert_matches_json(json!({ + "version": "3", + "packages": { + "specifiers": { + "jsr:@denotest/module_graph@1.4": "jsr:@denotest/module_graph@1.4.0", + }, + "jsr": { + "@denotest/module_graph@1.4.0": {} + } + }, + "remote": { + "http://127.0.0.1:4250/@denotest/module_graph/1.4.0/mod.ts": "5b0ce36e08d759118200d8b4627627b5a89b6261fbb0598e6961a6b287abb699", + "http://127.0.0.1:4250/@denotest/module_graph/1.4.0/other.ts": "9ce27ca439cb0e218b6e1ec26c043dbc0b54c9babc4cb432df478dd1721faade" + }, + "workspace": { + "dependencies": [ + "jsr:@denotest/module_graph@1.4" + ] + } + })); + + // now remove the deps from the deno.json + deno_json.write("{}"); + main_ts.write(""); + context + .new_command() + .args("cache main.ts") + .run() + .skip_output_check(); + + lockfile.assert_matches_json(json!({ + "version": "3", + "remote": {} + })); +} + +#[test] +fn lock_deno_json_package_json_deps_workspace() { + let context = TestContextBuilder::new() + .use_temp_cwd() + .use_http_server() + .add_npm_env_vars() + .add_jsr_env_vars() + .build(); + let temp_dir = context.temp_dir().path(); + + // deno.json + let deno_json = temp_dir.join("deno.json"); + deno_json.write_json(&json!({})); + + // package.json + let package_json = temp_dir.join("package.json"); + package_json.write_json(&json!({ + "workspaces": ["package-a"], + "dependencies": { + "@denotest/cjs-default-export": "1" + } + })); + // main.ts + let main_ts = temp_dir.join("main.ts"); + main_ts.write("import '@denotest/cjs-default-export';"); + + // package-a/package.json + let a_package = temp_dir.join("package-a"); + a_package.create_dir_all(); + let a_package_json = a_package.join("package.json"); + a_package_json.write_json(&json!({ + "dependencies": { + "@denotest/esm-basic": "1" + } + })); + // package-a/main.ts + let main_ts = a_package.join("main.ts"); + main_ts.write("import '@denotest/esm-basic';"); + context + .new_command() + .args("run package-a/main.ts") + .run() + .skip_output_check(); + let lockfile = temp_dir.join("deno.lock"); + let esm_basic_integrity = + get_lockfile_npm_package_integrity(&lockfile, "@denotest/esm-basic@1.0.0"); + + // no "workspace" because deno isn't smart enough to figure this out yet + // since it discovered the package.json in a folder different from the lockfile + lockfile.assert_matches_json(json!({ + "version": "3", + "packages": { + "specifiers": { + "npm:@denotest/esm-basic@1": "npm:@denotest/esm-basic@1.0.0" + }, + "npm": { + "@denotest/esm-basic@1.0.0": { + "integrity": esm_basic_integrity, + "dependencies": {} + } + } + }, + "remote": {}, + })); + + // run a command that causes discovery of the root package.json beside the lockfile + context + .new_command() + .args("run main.ts") + .run() + .skip_output_check(); + // now we should see the dependencies + let cjs_default_export_integrity = get_lockfile_npm_package_integrity( + &lockfile, + "@denotest/cjs-default-export@1.0.0", + ); + let expected_lockfile = json!({ + "version": "3", + "packages": { + "specifiers": { + "npm:@denotest/cjs-default-export@1": "npm:@denotest/cjs-default-export@1.0.0", + "npm:@denotest/esm-basic@1": "npm:@denotest/esm-basic@1.0.0" + }, + "npm": { + "@denotest/cjs-default-export@1.0.0": { + "integrity": cjs_default_export_integrity, + "dependencies": {} + }, + "@denotest/esm-basic@1.0.0": { + "integrity": esm_basic_integrity, + "dependencies": {} + } + } + }, + "remote": {}, + "workspace": { + "packageJson": { + "dependencies": [ + "npm:@denotest/cjs-default-export@1" + ] + } + } + }); + lockfile.assert_matches_json(expected_lockfile.clone()); + + // now run the command again in the package with the nested package.json + context + .new_command() + .args("run package-a/main.ts") + .run() + .skip_output_check(); + // the lockfile should stay the same as the above because the package.json + // was found in a different directory + lockfile.assert_matches_json(expected_lockfile.clone()); +} + +fn get_lockfile_npm_package_integrity( + lockfile: &PathRef, + package_name: &str, +) -> String { + // todo(dsherret): it would be nice if the test server didn't produce + // different hashes depending on what operating system it's running on + lockfile + .read_json_value() + .get("packages") + .unwrap() + .get("npm") + .unwrap() + .get(package_name) + .unwrap() + .get("integrity") + .unwrap() + .as_str() + .unwrap() + .to_string() +} + +itest!(mts_dmts_mjs { + args: "run subdir/import.mts", + output: "run/mts_dmts_mjs.out", +}); + +itest!(mts_dmts_mjs_no_check { + args: "run --no-check subdir/import.mts", + output: "run/mts_dmts_mjs.out", +}); + +itest!(async_error { + exit_code: 1, + args: "run --reload run/async_error.ts", + output: "run/async_error.ts.out", +}); + +itest!(config { + args: + "run --reload --config run/config/tsconfig.json --check run/config/main.ts", + output: "run/config/main.out", +}); + +itest!(config_types { + args: + "run --reload --quiet --check=all --config run/config_types/tsconfig.json run/config_types/main.ts", + output: "run/config_types/main.out", +}); + +itest!(config_types_remote { + http_server: true, + args: "run --reload --quiet --check=all --config run/config_types/remote.tsconfig.json run/config_types/main.ts", + output: "run/config_types/main.out", +}); + +itest!(empty_typescript { + args: "run --reload --check run/empty.ts", + output_str: Some("Check file:[WILDCARD]/run/empty.ts\n"), +}); + +itest!(error_001 { + args: "run --reload run/error_001.ts", + exit_code: 1, + output: "run/error_001.ts.out", +}); + +itest!(error_002 { + args: "run --reload run/error_002.ts", + exit_code: 1, + output: "run/error_002.ts.out", +}); + +itest!(error_003_typescript { + args: "run --reload --check run/error_003_typescript.ts", + exit_code: 1, + output: "run/error_003_typescript.ts.out", +}); + +// Supposing that we've already attempted to run error_003_typescript.ts +// we want to make sure that JS wasn't emitted. Running again without reload flag +// should result in the same output. +// https://github.com/denoland/deno/issues/2436 +itest!(error_003_typescript2 { + args: "run --check run/error_003_typescript.ts", + exit_code: 1, + output: "run/error_003_typescript.ts.out", +}); + +itest!(error_004_missing_module { + args: "run --reload run/error_004_missing_module.ts", + exit_code: 1, + output: "run/error_004_missing_module.ts.out", +}); + +itest!(error_005_missing_dynamic_import { + args: + "run --reload --allow-read --quiet run/error_005_missing_dynamic_import.ts", + exit_code: 1, + output: "run/error_005_missing_dynamic_import.ts.out", +}); + +itest!(error_006_import_ext_failure { + args: "run --reload run/error_006_import_ext_failure.ts", + exit_code: 1, + output: "run/error_006_import_ext_failure.ts.out", +}); + +itest!(error_007_any { + args: "run --reload run/error_007_any.ts", + exit_code: 1, + output: "run/error_007_any.ts.out", +}); + +itest!(error_008_checkjs { + args: "run --reload run/error_008_checkjs.js", + exit_code: 1, + output: "run/error_008_checkjs.js.out", +}); + +itest!(error_009_extensions_error { + args: "run run/error_009_extensions_error.js", + output: "run/error_009_extensions_error.js.out", + exit_code: 1, +}); + +itest!(error_011_bad_module_specifier { + args: "run --reload run/error_011_bad_module_specifier.ts", + exit_code: 1, + output: "run/error_011_bad_module_specifier.ts.out", +}); + +itest!(error_012_bad_dynamic_import_specifier { + args: "run --reload --check run/error_012_bad_dynamic_import_specifier.ts", + exit_code: 1, + output: "run/error_012_bad_dynamic_import_specifier.ts.out", +}); + +itest!(error_013_missing_script { + args: "run --reload missing_file_name", + exit_code: 1, + output: "run/error_013_missing_script.out", +}); + +itest!(error_014_catch_dynamic_import_error { + args: + "run --reload --allow-read run/error_014_catch_dynamic_import_error.js", + output: "run/error_014_catch_dynamic_import_error.js.out", +}); + +itest!(error_015_dynamic_import_permissions { + args: "run --reload --quiet run/error_015_dynamic_import_permissions.js", + output: "run/error_015_dynamic_import_permissions.out", + exit_code: 1, + http_server: true, +}); + +// We have an allow-net flag but not allow-read, it should still result in error. +itest!(error_016_dynamic_import_permissions2 { + args: "run --reload --allow-net run/error_016_dynamic_import_permissions2.js", + output: "run/error_016_dynamic_import_permissions2.out", + exit_code: 1, + http_server: true, +}); + +itest!(error_017_hide_long_source_ts { + args: "run --reload --check run/error_017_hide_long_source_ts.ts", + output: "run/error_017_hide_long_source_ts.ts.out", + exit_code: 1, +}); + +itest!(error_018_hide_long_source_js { + args: "run run/error_018_hide_long_source_js.js", + output: "run/error_018_hide_long_source_js.js.out", + exit_code: 1, +}); + +itest!(error_019_stack_function { + args: "run run/error_019_stack_function.ts", + output: "run/error_019_stack_function.ts.out", + exit_code: 1, +}); + +itest!(error_020_stack_constructor { + args: "run run/error_020_stack_constructor.ts", + output: "run/error_020_stack_constructor.ts.out", + exit_code: 1, +}); + +itest!(error_021_stack_method { + args: "run run/error_021_stack_method.ts", + output: "run/error_021_stack_method.ts.out", + exit_code: 1, +}); + +itest!(error_022_stack_custom_error { + args: "run run/error_022_stack_custom_error.ts", + output: "run/error_022_stack_custom_error.ts.out", + exit_code: 1, +}); + +itest!(error_023_stack_async { + args: "run run/error_023_stack_async.ts", + output: "run/error_023_stack_async.ts.out", + exit_code: 1, +}); + +itest!(error_024_stack_promise_all { + args: "run run/error_024_stack_promise_all.ts", + output: "run/error_024_stack_promise_all.ts.out", + exit_code: 1, +}); + +itest!(error_025_tab_indent { + args: "run run/error_025_tab_indent", + output: "run/error_025_tab_indent.out", + exit_code: 1, +}); + +itest!(error_026_remote_import_error { + args: "run run/error_026_remote_import_error.ts", + output: "run/error_026_remote_import_error.ts.out", + exit_code: 1, + http_server: true, +}); + +itest!(error_for_await { + args: "run --reload --check run/error_for_await.ts", + output: "run/error_for_await.ts.out", + exit_code: 1, +}); + +itest!(error_missing_module_named_import { + args: "run --reload run/error_missing_module_named_import.ts", + output: "run/error_missing_module_named_import.ts.out", + exit_code: 1, +}); + +itest!(error_no_check { + args: "run --reload --no-check run/error_no_check.ts", + output: "run/error_no_check.ts.out", + exit_code: 1, +}); + +itest!(error_syntax { + args: "run --reload run/error_syntax.js", + exit_code: 1, + output: "run/error_syntax.js.out", +}); + +itest!(error_syntax_empty_trailing_line { + args: "run --reload run/error_syntax_empty_trailing_line.mjs", + exit_code: 1, + output: "run/error_syntax_empty_trailing_line.mjs.out", +}); + +itest!(error_type_definitions { + args: "run --reload --check run/error_type_definitions.ts", + exit_code: 1, + output: "run/error_type_definitions.ts.out", +}); + +itest!(error_local_static_import_from_remote_ts { + args: "run --reload http://localhost:4545/run/error_local_static_import_from_remote.ts", + exit_code: 1, + http_server: true, + output: "run/error_local_static_import_from_remote.ts.out", + }); + +itest!(error_local_static_import_from_remote_js { + args: "run --reload http://localhost:4545/run/error_local_static_import_from_remote.js", + exit_code: 1, + http_server: true, + output: "run/error_local_static_import_from_remote.js.out", + }); + +itest!(exit_error42 { + exit_code: 42, + args: "run --quiet --reload run/exit_error42.ts", + output: "run/exit_error42.ts.out", +}); + +itest!(set_exit_code_0 { + args: "run --no-check run/set_exit_code_0.ts", + output_str: Some(""), + exit_code: 0, +}); + +itest!(set_exit_code_1 { + args: "run --no-check run/set_exit_code_1.ts", + output_str: Some(""), + exit_code: 42, +}); + +itest!(set_exit_code_2 { + args: "run --no-check run/set_exit_code_2.ts", + output_str: Some(""), + exit_code: 42, +}); + +itest!(op_exit_op_set_exit_code_in_worker { + args: "run --no-check --allow-read run/op_exit_op_set_exit_code_in_worker.ts", + exit_code: 21, + output_str: Some(""), +}); + +itest!(deno_exit_tampering { + args: "run --no-check run/deno_exit_tampering.ts", + output_str: Some(""), + exit_code: 42, +}); + +itest!(heapstats { + args: "run --quiet --v8-flags=--expose-gc run/heapstats.js", + output: "run/heapstats.js.out", +}); + +itest!(finalization_registry { + args: "run --quiet --v8-flags=--expose-gc run/finalization_registry.js", + output: "run/finalization_registry.js.out", +}); + +itest!(https_import { + args: "run --quiet --reload --cert tls/RootCA.pem run/https_import.ts", + output: "run/https_import.ts.out", + http_server: true, +}); + +itest!(if_main { + args: "run --quiet --reload run/if_main.ts", + output: "run/if_main.ts.out", +}); + +itest!(import_meta { + args: "run --quiet --reload --import-map=run/import_meta/importmap.json run/import_meta/main.ts", + output: "run/import_meta/main.out", + http_server: true, +}); + +itest!(main_module { + args: "run --quiet --allow-read --reload run/main_module/main.ts", + output: "run/main_module/main.out", +}); + +itest!(no_check { + args: "run --quiet --reload --no-check run/006_url_imports.ts", + output: "run/006_url_imports.ts.out", + http_server: true, +}); + +itest!(no_check_decorators { + args: "run --quiet --reload --no-check run/decorators/experimental/no_check/main.ts", + output: "run/decorators/experimental/no_check/main.out", +}); + +itest!(decorators_tc39_proposal { + args: "run --quiet --reload --check run/decorators/tc39_proposal/main.ts", + output: "run/decorators/tc39_proposal/main.out", +}); + +itest!(check_remote { + args: "run --quiet --reload --check=all run/no_check_remote.ts", + output: "run/no_check_remote.ts.disabled.out", + exit_code: 1, + http_server: true, +}); + +itest!(no_check_remote { + args: "run --quiet --reload --no-check=remote run/no_check_remote.ts", + output: "run/no_check_remote.ts.enabled.out", + http_server: true, +}); + +itest!(runtime_decorators { + args: "run --quiet --reload --no-check run/decorators/experimental/runtime/main.ts", + output: "run/decorators/experimental/runtime/main.out", +}); + +itest!(seed_random { + args: "run --seed=100 run/seed_random.js", + output: "run/seed_random.js.out", +}); + +itest!(type_definitions { + args: "run --reload run/type_definitions.ts", + output: "run/type_definitions.ts.out", +}); + +itest!(type_definitions_for_export { + args: "run --reload --check run/type_definitions_for_export.ts", + output: "run/type_definitions_for_export.ts.out", + exit_code: 1, +}); + +itest!(type_directives_01 { + args: "run --reload --check=all -L debug run/type_directives_01.ts", + output: "run/type_directives_01.ts.out", + http_server: true, +}); + +itest!(type_directives_02 { + args: "run --reload --check=all -L debug run/type_directives_02.ts", + output: "run/type_directives_02.ts.out", +}); + +#[test] +fn type_directives_js_main() { + let context = TestContext::default(); + let output = context + .new_command() + .args("run --reload -L debug --check run/type_directives_js_main.js") + .run(); + output.assert_matches_text("[WILDCARD] - FileFetcher::fetch() - specifier: file:///[WILDCARD]/subdir/type_reference.d.ts[WILDCARD]"); + let output = context + .new_command() + .args("run --reload -L debug run/type_directives_js_main.js") + .run(); + assert_not_contains!(output.combined_output(), "type_reference.d.ts"); +} + +itest!(type_directives_redirect { + args: "run --reload --check run/type_directives_redirect.ts", + output: "run/type_directives_redirect.ts.out", + http_server: true, +}); + +itest!(type_headers_deno_types { + args: "run --reload --check run/type_headers_deno_types.ts", + output: "run/type_headers_deno_types.ts.out", + http_server: true, +}); + +itest!(ts_type_imports { + args: "run --reload --check run/ts_type_imports.ts", + output: "run/ts_type_imports.ts.out", + exit_code: 1, +}); + +itest!(ts_decorators { + args: "run --reload --check run/decorators/experimental/ts/main.ts", + output: "run/decorators/experimental/ts/main.out", +}); + +itest!(ts_type_only_import { + args: "run --reload --check run/ts_type_only_import.ts", + output: "run/ts_type_only_import.ts.out", +}); + +itest!(swc_syntax_error { + args: "run --reload --check run/swc_syntax_error.ts", + output: "run/swc_syntax_error.ts.out", + exit_code: 1, +}); + +itest!(unbuffered_stderr { + args: "run --reload run/unbuffered_stderr.ts", + output: "run/unbuffered_stderr.ts.out", +}); + +itest!(unbuffered_stdout { + args: "run --quiet --reload run/unbuffered_stdout.ts", + output: "run/unbuffered_stdout.ts.out", +}); + +itest!(v8_flags_run { + args: "run --v8-flags=--expose-gc run/v8_flags.js", + output: "run/v8_flags.js.out", +}); + +itest!(v8_flags_env_run { + envs: vec![("DENO_V8_FLAGS".to_string(), "--expose-gc".to_string())], + args: "run run/v8_flags.js", + output: "run/v8_flags.js.out", +}); + +itest!(v8_flags_unrecognized { + args: "repl --v8-flags=--foo,bar,--trace-gc,-baz", + output: "run/v8_flags_unrecognized.out", + exit_code: 1, +}); + +itest!(v8_help { + args: "repl --v8-flags=--help", + output: "run/v8_help.out", +}); + +itest!(unsupported_dynamic_import_scheme { + args: "eval import('xxx:')", + output: "run/unsupported_dynamic_import_scheme.out", + exit_code: 1, +}); + +itest!(wasm { + args: "run --quiet run/wasm.ts", + output: "run/wasm.ts.out", +}); + +itest!(wasm_shared { + args: "run --quiet run/wasm_shared.ts", + output: "run/wasm_shared.out", +}); + +itest!(wasm_async { + args: "run run/wasm_async.js", + output: "run/wasm_async.out", +}); + +itest!(wasm_unreachable { + args: "run --allow-read run/wasm_unreachable.js", + output: "run/wasm_unreachable.out", + exit_code: 1, +}); + +itest!(wasm_url { + args: "run --quiet --allow-net=localhost:4545 run/wasm_url.js", + output: "run/wasm_url.out", + exit_code: 1, + http_server: true, +}); + +itest!(weakref { + args: "run --quiet --reload run/weakref.ts", + output: "run/weakref.ts.out", +}); + +itest!(top_level_await_order { + args: "run --allow-read run/top_level_await/order.js", + output: "run/top_level_await/order.out", +}); + +itest!(top_level_await_loop { + args: "run --allow-read run/top_level_await/loop.js", + output: "run/top_level_await/loop.out", +}); + +itest!(top_level_await_circular { + args: "run --allow-read run/top_level_await/circular.js", + output: "run/top_level_await/circular.out", + exit_code: 1, +}); + +// Regression test for https://github.com/denoland/deno/issues/11238. +itest!(top_level_await_nested { + args: "run --allow-read run/top_level_await/nested/main.js", + output: "run/top_level_await/nested.out", +}); + +itest!(top_level_await_unresolved { + args: "run run/top_level_await/unresolved.js", + output: "run/top_level_await/unresolved.out", + exit_code: 1, +}); + +itest!(top_level_await { + args: "run --allow-read run/top_level_await/top_level_await.js", + output: "run/top_level_await/top_level_await.out", +}); + +itest!(top_level_await_ts { + args: "run --quiet --allow-read run/top_level_await/top_level_await.ts", + output: "run/top_level_await/top_level_await.out", +}); + +itest!(top_level_for_await { + args: "run --quiet run/top_level_await/top_level_for_await.js", + output: "run/top_level_await/top_level_for_await.out", +}); + +itest!(top_level_for_await_ts { + args: "run --quiet run/top_level_await/top_level_for_await.ts", + output: "run/top_level_await/top_level_for_await.out", +}); + +itest!(unstable_disabled_js { + args: "run --reload run/unstable.js", + output: "run/unstable_disabled_js.out", +}); + +itest!(unstable_enabled_js { + args: "run --quiet --reload --unstable-fs run/unstable.ts", + output: "run/unstable_enabled_js.out", +}); + +itest!(unstable_worker { + args: "run --reload --quiet --allow-read run/unstable_worker.ts", + output: "run/unstable_worker.ts.out", +}); + +itest!(unstable_worker_options_disabled { + args: "run --quiet --reload --allow-read run/unstable_worker_options.js", + output: "run/unstable_worker_options.disabled.out", + exit_code: 70, +}); + +itest!(unstable_worker_options_enabled { + args: "run --quiet --reload --allow-read --unstable-worker-options run/unstable_worker_options.js", + output: "run/unstable_worker_options.enabled.out", +}); + +itest!(unstable_broadcast_channel_disabled { + args: "run --quiet --reload --allow-read run/unstable_broadcast_channel.js", + output: "run/unstable_broadcast_channel.disabled.out", +}); + +itest!(unstable_broadcast_channel_enabled { + args: "run --quiet --reload --allow-read --unstable-broadcast-channel run/unstable_broadcast_channel.js", + output: "run/unstable_broadcast_channel.enabled.out", +}); + +itest!(unstable_cron_disabled { + args: "run --quiet --reload --allow-read run/unstable_cron.js", + output: "run/unstable_cron.disabled.out", +}); + +itest!(unstable_cron_enabled { + args: + "run --quiet --reload --allow-read --unstable-cron run/unstable_cron.js", + output: "run/unstable_cron.enabled.out", +}); + +itest!(unstable_ffi_disabled { + args: "run --quiet --reload --allow-read run/unstable_ffi.js", + output: "run/unstable_ffi.disabled.out", +}); + +itest!(unstable_ffi_enabled { + args: "run --quiet --reload --allow-read --unstable-ffi run/unstable_ffi.js", + output: "run/unstable_ffi.enabled.out", +}); + +itest!(unstable_fs_disabled { + args: "run --quiet --reload --allow-read run/unstable_fs.js", + output: "run/unstable_fs.disabled.out", +}); + +itest!(unstable_fs_enabled { + args: "run --quiet --reload --allow-read --unstable-fs run/unstable_fs.js", + output: "run/unstable_fs.enabled.out", +}); + +itest!(unstable_http_disabled { + args: "run --quiet --reload --allow-read run/unstable_http.js", + output: "run/unstable_http.disabled.out", +}); + +itest!(unstable_http_enabled { + args: + "run --quiet --reload --allow-read --unstable-http run/unstable_http.js", + output: "run/unstable_http.enabled.out", +}); + +itest!(unstable_net_disabled { + args: "run --quiet --reload --allow-read run/unstable_net.js", + output: "run/unstable_net.disabled.out", +}); + +itest!(unstable_net_enabled { + args: "run --quiet --reload --allow-read --unstable-net run/unstable_net.js", + output: "run/unstable_net.enabled.out", +}); + +itest!(unstable_kv_disabled { + args: "run --quiet --reload --allow-read run/unstable_kv.js", + output: "run/unstable_kv.disabled.out", +}); + +itest!(unstable_kv_enabled { + args: "run --quiet --reload --allow-read --unstable-kv run/unstable_kv.js", + output: "run/unstable_kv.enabled.out", +}); + +itest!(unstable_webgpu_disabled { + args: "run --quiet --reload --allow-read run/unstable_webgpu.js", + output: "run/unstable_webgpu.disabled.out", +}); + +itest!(unstable_webgpu_enabled { + args: + "run --quiet --reload --allow-read --unstable-webgpu run/unstable_webgpu.js", + output: "run/unstable_webgpu.enabled.out", +}); + +itest!(import_compression { + args: "run --quiet --reload --allow-net run/import_compression/main.ts", + output: "run/import_compression/main.out", + http_server: true, +}); + +itest!(disallow_http_from_https_js { + args: "run --quiet --reload --cert tls/RootCA.pem https://localhost:5545/run/disallow_http_from_https.js", + output: "run/disallow_http_from_https_js.out", + http_server: true, + exit_code: 1, +}); + +itest!(disallow_http_from_https_ts { + args: "run --quiet --reload --cert tls/RootCA.pem https://localhost:5545/run/disallow_http_from_https.ts", + output: "run/disallow_http_from_https_ts.out", + http_server: true, + exit_code: 1, +}); + +itest!(dynamic_import_conditional { + args: "run --quiet --reload run/dynamic_import_conditional.js", + output: "run/dynamic_import_conditional.js.out", +}); + +itest!(tsx_imports { + args: "run --reload --check run/tsx_imports/tsx_imports.ts", + output: "run/tsx_imports/tsx_imports.ts.out", +}); + +itest!(fix_dynamic_import_errors { + args: "run --reload run/fix_dynamic_import_errors.js", + output: "run/fix_dynamic_import_errors.js.out", +}); + +itest!(fix_emittable_skipped { + args: "run --reload run/fix_emittable_skipped.js", + output: "run/fix_emittable_skipped.ts.out", +}); + +itest!(fix_js_import_js { + args: "run --quiet --reload run/fix_js_import_js.ts", + output: "run/fix_js_import_js.ts.out", +}); + +itest!(fix_js_imports { + args: "run --quiet --reload run/fix_js_imports.ts", + output: "run/fix_js_imports.ts.out", +}); + +itest!(fix_tsc_file_exists { + args: "run --quiet --reload tsc/test.js", + output: "run/fix_tsc_file_exists.out", +}); + +itest!(fix_worker_dispatchevent { + args: "run --quiet --reload run/fix_worker_dispatchevent.ts", + output: "run/fix_worker_dispatchevent.ts.out", +}); + +itest!(es_private_fields { + args: "run --quiet --reload run/es_private_fields.js", + output: "run/es_private_fields.js.out", +}); + +itest!(cjs_imports { + args: "run --quiet --reload run/cjs_imports/main.ts", + output: "run/cjs_imports/main.out", +}); + +itest!(ts_import_from_js { + args: "run --quiet --reload run/ts_import_from_js/main.js", + output: "run/ts_import_from_js/main.out", + http_server: true, +}); + +itest!(jsx_import_from_ts { + args: "run --quiet --reload run/jsx_import_from_ts.ts", + output: "run/jsx_import_from_ts.ts.out", +}); + +itest!(jsx_import_source_pragma { + args: "run --reload run/jsx_import_source_pragma.tsx", + output: "run/jsx_import_source.out", + http_server: true, +}); + +itest!(jsx_import_source_pragma_with_config { + args: + "run --reload --config jsx/deno-jsx.jsonc --no-lock run/jsx_import_source_pragma.tsx", + output: "run/jsx_import_source.out", + http_server: true, +}); + +itest!(jsx_import_source_pragma_with_dev_config { + args: + "run --reload --config jsx/deno-jsxdev.jsonc --no-lock run/jsx_import_source_pragma.tsx", + output: "run/jsx_import_source_dev.out", + http_server: true, +}); + +itest!(jsx_import_source_no_pragma { + args: + "run --reload --config jsx/deno-jsx.jsonc --no-lock run/jsx_import_source_no_pragma.tsx", + output: "run/jsx_import_source.out", + http_server: true, +}); + +itest!(jsx_import_source_no_pragma_dev { + args: "run --reload --config jsx/deno-jsxdev.jsonc --no-lock run/jsx_import_source_no_pragma.tsx", + output: "run/jsx_import_source_dev.out", + http_server: true, +}); + +itest!(jsx_import_source_pragma_import_map { + args: "run --reload --import-map jsx/import-map.json run/jsx_import_source_pragma_import_map.tsx", + output: "run/jsx_import_source_import_map.out", + http_server: true, +}); + +itest!(jsx_import_source_pragma_import_map_dev { + args: "run --reload --import-map jsx/import-map.json --config jsx/deno-jsxdev-import-map.jsonc run/jsx_import_source_pragma_import_map.tsx", + output: "run/jsx_import_source_import_map_dev.out", + http_server: true, +}); + +itest!(jsx_import_source_precompile_import_map { + args: "run --reload --check --import-map jsx/import-map.json --no-lock --config jsx/deno-jsx-precompile.jsonc run/jsx_precompile/no_pragma.tsx", + output: "run/jsx_precompile/no_pragma.out", + http_server: true, +}); + +itest!(jsx_import_source_import_map { + args: "run --reload --import-map jsx/import-map.json --no-lock --config jsx/deno-jsx-import-map.jsonc run/jsx_import_source_no_pragma.tsx", + output: "run/jsx_import_source_import_map.out", + http_server: true, +}); + +itest!(jsx_import_source_import_map_dev { + args: "run --reload --import-map jsx/import-map.json --no-lock --config jsx/deno-jsxdev-import-map.jsonc run/jsx_import_source_no_pragma.tsx", + output: "run/jsx_import_source_import_map_dev.out", + http_server: true, +}); + +itest!(jsx_import_source_import_map_scoped { + args: "run --reload --import-map jsx/import-map-scoped.json --no-lock --config jsx/deno-jsx-import-map.jsonc subdir/jsx_import_source_no_pragma.tsx", + output: "run/jsx_import_source_import_map.out", + http_server: true, +}); + +itest!(jsx_import_source_import_map_scoped_dev { + args: "run --reload --import-map jsx/import-map-scoped.json --no-lock --config jsx/deno-jsxdev-import-map.jsonc subdir/jsx_import_source_no_pragma.tsx", + output: "run/jsx_import_source_import_map_dev.out", + http_server: true, +}); + +itest!(jsx_import_source_pragma_no_check { + args: "run --reload --no-check run/jsx_import_source_pragma.tsx", + output: "run/jsx_import_source.out", + http_server: true, +}); + +itest!(jsx_import_source_pragma_with_config_no_check { + args: "run --reload --config jsx/deno-jsx.jsonc --no-lock --no-check run/jsx_import_source_pragma.tsx", + output: "run/jsx_import_source.out", + http_server: true, +}); + +itest!(jsx_import_source_pragma_with_config_vendor_dir { + args: "run --reload --config jsx/deno-jsx.jsonc --no-lock --vendor $TESTDATA/run/jsx_import_source_pragma.tsx", + output: "run/jsx_import_source.out", + http_server: true, + temp_cwd: true, + copy_temp_dir: Some("jsx/"), +}); + +itest!(jsx_import_source_no_pragma_no_check { + args: + "run --reload --config jsx/deno-jsx.jsonc --no-lock --no-check run/jsx_import_source_no_pragma.tsx", + output: "run/jsx_import_source.out", + http_server: true, +}); + +itest!(jsx_import_source_pragma_import_map_no_check { + args: "run --reload --import-map jsx/import-map.json --no-check run/jsx_import_source_pragma_import_map.tsx", + output: "run/jsx_import_source_import_map.out", + http_server: true, +}); + +itest!(jsx_import_source_import_map_no_check { + args: "run --reload --import-map jsx/import-map.json --no-lock --config jsx/deno-jsx-import-map.jsonc --no-check run/jsx_import_source_no_pragma.tsx", + output: "run/jsx_import_source_import_map.out", + http_server: true, +}); + +itest!(jsx_import_source_error { + args: "run --config jsx/deno-jsx-error.jsonc --check run/jsx_import_source_no_pragma.tsx", + output: "run/jsx_import_source_error.out", + exit_code: 1, +}); + +itest!(single_compile_with_reload { + args: "run --reload --allow-read run/single_compile_with_reload.ts", + output: "run/single_compile_with_reload.ts.out", +}); + +itest!(proto_exploit { + args: "run run/proto_exploit.js", + output: "run/proto_exploit.js.out", +}); + +itest!(reference_types { + args: "run --reload --quiet run/reference_types.ts", + output: "run/reference_types.ts.out", +}); + +itest!(references_types_remote { + http_server: true, + args: "run --reload --quiet run/reference_types_remote.ts", + output: "run/reference_types_remote.ts.out", +}); + +itest!(reference_types_error { + args: + "run --config run/checkjs.tsconfig.json --check run/reference_types_error.js", + output: "run/reference_types_error.js.out", + exit_code: 1, +}); + +itest!(reference_types_error_vendor_dir { + args: + "run --config run/checkjs.tsconfig.json --check --vendor $TESTDATA/run/reference_types_error.js", + output: "run/reference_types_error.js.out", + exit_code: 1, +}); + +itest!(reference_types_error_no_check { + args: "run --no-check run/reference_types_error.js", + output_str: Some(""), +}); + +itest!(import_data_url_error_stack { + args: "run --quiet --reload run/import_data_url_error_stack.ts", + output: "run/import_data_url_error_stack.ts.out", + exit_code: 1, +}); + +itest!(import_data_url_import_relative { + args: "run --quiet --reload run/import_data_url_import_relative.ts", + output: "run/import_data_url_import_relative.ts.out", + exit_code: 1, +}); + +itest!(import_data_url_import_map { + args: "run --quiet --reload --import-map import_maps/import_map.json run/import_data_url.ts", + output: "run/import_data_url.ts.out", + }); + +itest!(import_data_url_imports { + args: "run --quiet --reload run/import_data_url_imports.ts", + output: "run/import_data_url_imports.ts.out", + http_server: true, +}); + +itest!(import_data_url_jsx { + args: "run --quiet --reload run/import_data_url_jsx.ts", + output: "run/import_data_url_jsx.ts.out", +}); + +itest!(import_data_url { + args: "run --quiet --reload run/import_data_url.ts", + output: "run/import_data_url.ts.out", +}); + +itest!(import_dynamic_data_url { + args: "run --quiet --reload run/import_dynamic_data_url.ts", + output: "run/import_dynamic_data_url.ts.out", +}); + +itest!(import_blob_url_error_stack { + args: "run --quiet --reload run/import_blob_url_error_stack.ts", + output: "run/import_blob_url_error_stack.ts.out", + exit_code: 1, +}); + +itest!(import_blob_url_import_relative { + args: "run --quiet --reload run/import_blob_url_import_relative.ts", + output: "run/import_blob_url_import_relative.ts.out", + exit_code: 1, +}); + +itest!(import_blob_url_imports { + args: + "run --quiet --reload --allow-net=localhost:4545 run/import_blob_url_imports.ts", + output: "run/import_blob_url_imports.ts.out", + http_server: true, +}); + +itest!(import_blob_url_jsx { + args: "run --quiet --reload run/import_blob_url_jsx.ts", + output: "run/import_blob_url_jsx.ts.out", +}); + +itest!(import_blob_url { + args: "run --quiet --reload run/import_blob_url.ts", + output: "run/import_blob_url.ts.out", +}); + +itest!(import_file_with_colon { + args: "run --quiet --reload run/import_file_with_colon.ts", + output: "run/import_file_with_colon.ts.out", + http_server: true, +}); + +itest!(import_extensionless { + args: "run --quiet --reload run/import_extensionless.ts", + output: "run/import_extensionless.ts.out", + http_server: true, +}); + +itest!(classic_workers_event_loop { + args: + "run --enable-testing-features-do-not-use run/classic_workers_event_loop.js", + output: "run/classic_workers_event_loop.js.out", +}); + +// FIXME(bartlomieju): disabled, because this test is very flaky on CI +// itest!(local_sources_not_cached_in_memory { +// args: "run --allow-read --allow-write run/no_mem_cache.js", +// output: "run/no_mem_cache.js.out", +// }); + +// This test checks that inline source map data is used. It uses a hand crafted +// source map that maps to a file that exists, but is not loaded into the module +// graph (inline_js_source_map_2.ts) (because there are no direct dependencies). +// Source line is not remapped because no inline source contents are included in +// the sourcemap and the file is not present in the dependency graph. +itest!(inline_js_source_map_2 { + args: "run --quiet run/inline_js_source_map_2.js", + output: "run/inline_js_source_map_2.js.out", + exit_code: 1, +}); + +// This test checks that inline source map data is used. It uses a hand crafted +// source map that maps to a file that exists, but is not loaded into the module +// graph (inline_js_source_map_2.ts) (because there are no direct dependencies). +// Source line remapped using th inline source contents that are included in the +// inline source map. +itest!(inline_js_source_map_2_with_inline_contents { + args: "run --quiet run/inline_js_source_map_2_with_inline_contents.js", + output: "run/inline_js_source_map_2_with_inline_contents.js.out", + exit_code: 1, +}); + +// This test checks that inline source map data is used. It uses a hand crafted +// source map that maps to a file that exists, and is loaded into the module +// graph because of a direct import statement (inline_js_source_map.ts). The +// source map was generated from an earlier version of this file, where the throw +// was not commented out. The source line is remapped using source contents that +// from the module graph. +itest!(inline_js_source_map_with_contents_from_graph { + args: "run --quiet run/inline_js_source_map_with_contents_from_graph.js", + output: "run/inline_js_source_map_with_contents_from_graph.js.out", + exit_code: 1, + http_server: true, +}); + +// This test ensures that a descriptive error is shown when we're unable to load +// the import map. Even though this tests only the `run` subcommand, we can be sure +// that the error message is similar for other subcommands as they all use +// `program_state.maybe_import_map` to access the import map underneath. +itest!(error_import_map_unable_to_load { + args: "run --import-map=import_maps/does_not_exist.json import_maps/test.ts", + output: "run/error_import_map_unable_to_load.out", + exit_code: 1, +}); + +// Test that setting `self` in the main thread to some other value doesn't break +// the world. +itest!(replace_self { + args: "run run/replace_self.js", + output: "run/replace_self.js.out", +}); + +itest!(worker_event_handler_test { + args: "run --quiet --reload --allow-read run/worker_event_handler_test.js", + output: "run/worker_event_handler_test.js.out", +}); + +itest!(worker_close_race { + args: "run --quiet --reload --allow-read run/worker_close_race.js", + output: "run/worker_close_race.js.out", +}); + +itest!(worker_drop_handle_race { + args: "run --quiet --reload --allow-read run/worker_drop_handle_race.js", + output: "run/worker_drop_handle_race.js.out", + exit_code: 1, +}); + +itest!(worker_drop_handle_race_terminate { + args: "run run/worker_drop_handle_race_terminate.js", + output: "run/worker_drop_handle_race_terminate.js.out", +}); + +itest!(worker_close_nested { + args: "run --quiet --reload --allow-read run/worker_close_nested.js", + output: "run/worker_close_nested.js.out", +}); + +itest!(worker_message_before_close { + args: "run --quiet --reload --allow-read run/worker_message_before_close.js", + output: "run/worker_message_before_close.js.out", +}); + +itest!(worker_close_in_wasm_reactions { + args: + "run --quiet --reload --allow-read run/worker_close_in_wasm_reactions.js", + output: "run/worker_close_in_wasm_reactions.js.out", +}); + +itest!(shebang_tsc { + args: "run --quiet --check run/shebang.ts", + output: "run/shebang.ts.out", +}); + +itest!(shebang_swc { + args: "run --quiet run/shebang.ts", + output: "run/shebang.ts.out", +}); + +itest!(shebang_with_json_imports_tsc { + args: "run --quiet import_attributes/json_with_shebang.ts", + output: "import_attributes/json_with_shebang.ts.out", + exit_code: 1, +}); + +itest!(shebang_with_json_imports_swc { + args: "run --quiet --no-check import_attributes/json_with_shebang.ts", + output: "import_attributes/json_with_shebang.ts.out", + exit_code: 1, +}); + +#[test] +fn no_validate_asm() { + let output = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg("run/no_validate_asm.js") + .piped_output() + .spawn() + .unwrap() + .wait_with_output() + .unwrap(); + assert!(output.status.success()); + assert!(output.stderr.is_empty()); + assert!(output.stdout.is_empty()); +} + +#[test] +fn exec_path() { + let output = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg("--allow-read") + .arg("run/exec_path.ts") + .stdout(Stdio::piped()) + .spawn() + .unwrap() + .wait_with_output() + .unwrap(); + assert!(output.status.success()); + let stdout_str = std::str::from_utf8(&output.stdout).unwrap().trim(); + let actual = PathRef::new(std::path::Path::new(stdout_str)).canonicalize(); + let expected = util::deno_exe_path().canonicalize(); + assert_eq!(expected, actual); +} + +#[test] +fn run_from_stdin_defaults_to_ts() { + let source_code = r#" +interface Lollipop { + _: number; +} +console.log("executing typescript"); +"#; + + let mut p = util::deno_cmd() + .arg("run") + .arg("--check") + .arg("-") + .stdin(std::process::Stdio::piped()) + .stdout_piped() + .spawn() + .unwrap(); + let stdin = p.stdin.as_mut().unwrap(); + stdin.write_all(source_code.as_bytes()).unwrap(); + let result = p.wait_with_output().unwrap(); + assert!(result.status.success()); + let stdout_str = std::str::from_utf8(&result.stdout).unwrap().trim(); + assert_eq!(stdout_str, "executing typescript"); +} + +#[test] +fn run_from_stdin_ext() { + let source_code = r#" +let i = 123; +i = "hello" +console.log("executing javascript"); +"#; + + let mut p = util::deno_cmd() + .args("run --ext js --check -") + .stdin(std::process::Stdio::piped()) + .stdout_piped() + .spawn() + .unwrap(); + let stdin = p.stdin.as_mut().unwrap(); + stdin.write_all(source_code.as_bytes()).unwrap(); + let result = p.wait_with_output().unwrap(); + assert!(result.status.success()); + let stdout_str = std::str::from_utf8(&result.stdout).unwrap().trim(); + assert_eq!(stdout_str, "executing javascript"); +} + +#[cfg(windows)] +// Clippy suggests to remove the `NoStd` prefix from all variants. I disagree. +#[allow(clippy::enum_variant_names)] +enum WinProcConstraints { + NoStdIn, + NoStdOut, + NoStdErr, +} + +#[cfg(windows)] +fn run_deno_script_constrained( + script_path: test_util::PathRef, + constraints: WinProcConstraints, +) -> Result<(), i64> { + let file_path = "assets/DenoWinRunner.ps1"; + let constraints = match constraints { + WinProcConstraints::NoStdIn => "1", + WinProcConstraints::NoStdOut => "2", + WinProcConstraints::NoStdErr => "4", + }; + let deno_exe_path = util::deno_exe_path().to_string(); + let deno_script_path = script_path.to_string(); + let args = vec![&deno_exe_path[..], &deno_script_path[..], constraints]; + util::run_powershell_script_file(file_path, args) +} + +#[cfg(windows)] +#[test] +fn should_not_panic_on_no_stdin() { + let output = run_deno_script_constrained( + util::testdata_path().join("echo.ts"), + WinProcConstraints::NoStdIn, + ); + output.unwrap(); +} + +#[cfg(windows)] +#[test] +fn should_not_panic_on_no_stdout() { + let output = run_deno_script_constrained( + util::testdata_path().join("echo.ts"), + WinProcConstraints::NoStdOut, + ); + output.unwrap(); +} + +#[cfg(windows)] +#[test] +fn should_not_panic_on_no_stderr() { + let output = run_deno_script_constrained( + util::testdata_path().join("echo.ts"), + WinProcConstraints::NoStdErr, + ); + output.unwrap(); +} + +#[cfg(not(windows))] +#[test] +fn should_not_panic_on_undefined_home_environment_variable() { + let output = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg("echo.ts") + .env_remove("HOME") + .spawn() + .unwrap() + .wait_with_output() + .unwrap(); + assert!(output.status.success()); +} + +#[test] +fn should_not_panic_on_undefined_deno_dir_environment_variable() { + let output = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg("echo.ts") + .env_remove("DENO_DIR") + .spawn() + .unwrap() + .wait_with_output() + .unwrap(); + assert!(output.status.success()); +} + +#[cfg(not(windows))] +#[test] +fn should_not_panic_on_undefined_deno_dir_and_home_environment_variables() { + let output = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg("echo.ts") + .env_remove("DENO_DIR") + .env_remove("HOME") + .spawn() + .unwrap() + .wait_with_output() + .unwrap(); + assert!(output.status.success()); +} + +#[test] +fn rust_log() { + // Without RUST_LOG the stderr is empty. + let output = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg("run/001_hello.js") + .stderr_piped() + .spawn() + .unwrap() + .wait_with_output() + .unwrap(); + assert!(output.status.success()); + assert!(output.stderr.is_empty()); + + // With RUST_LOG the stderr is not empty. + let output = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg("run/001_hello.js") + .env("RUST_LOG", "debug") + .stderr_piped() + .spawn() + .unwrap() + .wait_with_output() + .unwrap(); + assert!(output.status.success()); + assert!(!output.stderr.is_empty()); +} + +#[test] +fn dont_cache_on_check_fail() { + let context = TestContext::default(); + let output = context + .new_command() + .args("run --check=all --reload run/error_003_typescript.ts") + .split_output() + .run(); + assert!(!output.stderr().is_empty()); + output.skip_stdout_check(); + output.assert_exit_code(1); + + let output = context + .new_command() + .args("run --check=all run/error_003_typescript.ts") + .split_output() + .run(); + assert!(!output.stderr().is_empty()); + output.skip_stdout_check(); + output.assert_exit_code(1); +} + +mod permissions { + use test_util as util; + use util::TestContext; + + // TODO(bartlomieju): remove --unstable once Deno.Command is stabilized + #[test] + fn with_allow() { + for permission in &util::PERMISSION_VARIANTS { + let status = util::deno_cmd() + .current_dir(&util::testdata_path()) + .arg("run") + .arg("--unstable") + .arg(format!("--allow-{permission}")) + .arg("run/permission_test.ts") + .arg(format!("{permission}Required")) + .spawn() + .unwrap() + .wait() + .unwrap(); + assert!(status.success()); + } + } + + // TODO(bartlomieju): remove --unstable once Deno.Command is stabilized + #[test] + fn without_allow() { + for permission in &util::PERMISSION_VARIANTS { + let (_, err) = util::run_and_collect_output( + false, + &format!("run --unstable run/permission_test.ts {permission}Required"), + None, + None, + false, + ); + assert!(err.contains(util::PERMISSION_DENIED_PATTERN)); + } + } + + #[test] + fn rw_inside_project_dir() { + const PERMISSION_VARIANTS: [&str; 2] = ["read", "write"]; + for permission in &PERMISSION_VARIANTS { + let status = util::deno_cmd() + .current_dir(&util::testdata_path()) + .arg("run") + .arg(format!( + "--allow-{0}={1}", + permission, + util::testdata_path() + )) + .arg("run/complex_permissions_test.ts") + .arg(permission) + .arg("run/complex_permissions_test.ts") + .spawn() + .unwrap() + .wait() + .unwrap(); + assert!(status.success()); + } + } + + #[test] + fn rw_outside_test_dir() { + const PERMISSION_VARIANTS: [&str; 2] = ["read", "write"]; + for permission in &PERMISSION_VARIANTS { + let (_, err) = util::run_and_collect_output( + false, + &format!( + "run --allow-{0}={1} run/complex_permissions_test.ts {0} {2}", + permission, + util::testdata_path(), + util::root_path().join("Cargo.toml"), + ), + None, + None, + false, + ); + assert!(err.contains(util::PERMISSION_DENIED_PATTERN)); + } + } + + #[test] + fn rw_inside_test_dir() { + const PERMISSION_VARIANTS: [&str; 2] = ["read", "write"]; + for permission in &PERMISSION_VARIANTS { + let status = util::deno_cmd() + .current_dir(&util::testdata_path()) + .arg("run") + .arg(format!( + "--allow-{0}={1}", + permission, + util::testdata_path(), + )) + .arg("run/complex_permissions_test.ts") + .arg(permission) + .arg("run/complex_permissions_test.ts") + .spawn() + .unwrap() + .wait() + .unwrap(); + assert!(status.success()); + } + } + + #[test] + fn rw_outside_test_and_js_dir() { + const PERMISSION_VARIANTS: [&str; 2] = ["read", "write"]; + let test_dir = util::testdata_path(); + let js_dir = util::root_path().join("js"); + for permission in &PERMISSION_VARIANTS { + let (_, err) = util::run_and_collect_output( + false, + &format!( + "run --allow-{0}={1},{2} run/complex_permissions_test.ts {0} {3}", + permission, + test_dir, + js_dir, + util::root_path().join("Cargo.toml"), + ), + None, + None, + false, + ); + assert!(err.contains(util::PERMISSION_DENIED_PATTERN)); + } + } + + #[test] + fn rw_inside_test_and_js_dir() { + const PERMISSION_VARIANTS: [&str; 2] = ["read", "write"]; + let test_dir = util::testdata_path(); + let js_dir = util::root_path().join("js"); + for permission in &PERMISSION_VARIANTS { + let status = util::deno_cmd() + .current_dir(&util::testdata_path()) + .arg("run") + .arg(format!("--allow-{permission}={test_dir},{js_dir}")) + .arg("run/complex_permissions_test.ts") + .arg(permission) + .arg("run/complex_permissions_test.ts") + .spawn() + .unwrap() + .wait() + .unwrap(); + assert!(status.success()); + } + } + + #[test] + fn rw_relative() { + const PERMISSION_VARIANTS: [&str; 2] = ["read", "write"]; + for permission in &PERMISSION_VARIANTS { + let status = util::deno_cmd() + .current_dir(&util::testdata_path()) + .arg("run") + .arg(format!("--allow-{permission}=.")) + .arg("run/complex_permissions_test.ts") + .arg(permission) + .arg("run/complex_permissions_test.ts") + .spawn() + .unwrap() + .wait() + .unwrap(); + assert!(status.success()); + } + } + + #[test] + fn rw_no_prefix() { + const PERMISSION_VARIANTS: [&str; 2] = ["read", "write"]; + for permission in &PERMISSION_VARIANTS { + let status = util::deno_cmd() + .current_dir(&util::testdata_path()) + .arg("run") + .arg(format!("--allow-{permission}=tls/../")) + .arg("run/complex_permissions_test.ts") + .arg(permission) + .arg("run/complex_permissions_test.ts") + .spawn() + .unwrap() + .wait() + .unwrap(); + assert!(status.success()); + } + } + + #[test] + fn net_fetch_allow_localhost_4545() { + let (_, err) = util::run_and_collect_output( + true, + "run --allow-net=localhost:4545 run/complex_permissions_test.ts netFetch http://localhost:4545/", + None, + None, + true, + ); + assert!(!err.contains(util::PERMISSION_DENIED_PATTERN)); + } + + #[test] + fn net_fetch_allow_deno_land() { + let (_, err) = util::run_and_collect_output( + false, + "run --allow-net=deno.land run/complex_permissions_test.ts netFetch http://localhost:4545/", + None, + None, + true, + ); + assert!(err.contains(util::PERMISSION_DENIED_PATTERN)); + } + + #[test] + fn net_fetch_localhost_4545_fail() { + let (_, err) = util::run_and_collect_output( + false, + "run --allow-net=localhost:4545 run/complex_permissions_test.ts netFetch http://localhost:4546/", + None, + None, + true, + ); + assert!(err.contains(util::PERMISSION_DENIED_PATTERN)); + } + + #[test] + fn net_fetch_localhost() { + let (_, err) = util::run_and_collect_output( + true, + "run --allow-net=localhost run/complex_permissions_test.ts netFetch http://localhost:4545/ http://localhost:4546/ http://localhost:4547/", + None, + None, + true, + ); + assert!(!err.contains(util::PERMISSION_DENIED_PATTERN)); + } + + #[test] + fn net_connect_allow_localhost_ip_4555() { + let (_, err) = util::run_and_collect_output( + true, + "run --allow-net=127.0.0.1:4545 run/complex_permissions_test.ts netConnect 127.0.0.1:4545", + None, + None, + true, + ); + assert!(!err.contains(util::PERMISSION_DENIED_PATTERN)); + } + + #[test] + fn net_connect_allow_deno_land() { + let (_, err) = util::run_and_collect_output( + false, + "run --allow-net=deno.land run/complex_permissions_test.ts netConnect 127.0.0.1:4546", + None, + None, + true, + ); + assert!(err.contains(util::PERMISSION_DENIED_PATTERN)); + } + + #[test] + fn net_connect_allow_localhost_ip_4545_fail() { + let (_, err) = util::run_and_collect_output( + false, + "run --allow-net=127.0.0.1:4545 run/complex_permissions_test.ts netConnect 127.0.0.1:4546", + None, + None, + true, + ); + assert!(err.contains(util::PERMISSION_DENIED_PATTERN)); + } + + #[test] + fn net_connect_allow_localhost_ip() { + let (_, err) = util::run_and_collect_output( + true, + "run --allow-net=127.0.0.1 run/complex_permissions_test.ts netConnect 127.0.0.1:4545 127.0.0.1:4546 127.0.0.1:4547", + None, + None, + true, + ); + assert!(!err.contains(util::PERMISSION_DENIED_PATTERN)); + } + + #[test] + fn net_listen_allow_localhost_4555() { + let (_, err) = util::run_and_collect_output( + true, + "run --allow-net=localhost:4558 run/complex_permissions_test.ts netListen localhost:4558", + None, + None, + false, + ); + assert!(!err.contains(util::PERMISSION_DENIED_PATTERN)); + } + + #[test] + fn net_listen_allow_deno_land() { + let (_, err) = util::run_and_collect_output( + false, + "run --allow-net=deno.land run/complex_permissions_test.ts netListen localhost:4545", + None, + None, + false, + ); + assert!(err.contains(util::PERMISSION_DENIED_PATTERN)); + } + + #[test] + fn net_listen_allow_localhost_4555_fail() { + let (_, err) = util::run_and_collect_output( + false, + "run --allow-net=localhost:4555 run/complex_permissions_test.ts netListen localhost:4556", + None, + None, + false, + ); + assert!(err.contains(util::PERMISSION_DENIED_PATTERN)); + } + + #[test] + fn net_listen_allow_localhost() { + // Port 4600 is chosen to not collide with those used by + // target/debug/test_server + let (_, err) = util::run_and_collect_output( + true, + "run --allow-net=localhost run/complex_permissions_test.ts netListen localhost:4600", + None, + None, + false, + ); + assert!(!err.contains(util::PERMISSION_DENIED_PATTERN)); + } + + #[test] + fn _061_permissions_request() { + TestContext::default() + .new_command() + .args_vec(["run", "--quiet", "run/061_permissions_request.ts"]) + .with_pty(|mut console| { + console.expect(concat!( + "┌ ⚠️ Deno requests read access to \"foo\".\r\n", + "├ Requested by `Deno.permissions.request()` API.\r\n", + "├ Run again with --allow-read to bypass this prompt.\r\n", + "└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)", + )); + console.write_line_raw("y"); + console.expect(concat!( + "┌ ⚠️ Deno requests read access to \"bar\".\r\n", + "├ Requested by `Deno.permissions.request()` API.\r\n", + "├ Run again with --allow-read to bypass this prompt.\r\n", + "└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)", + )); + console.write_line_raw("n"); + console.expect("granted"); + console.expect("prompt"); + console.expect("denied"); + }); + } + + #[test] + fn _061_permissions_request_sync() { + TestContext::default() + .new_command() + .args_vec(["run", "--quiet", "run/061_permissions_request_sync.ts"]) + .with_pty(|mut console| { + console.expect(concat!( + "┌ ⚠️ Deno requests read access to \"foo\".\r\n", + "├ Requested by `Deno.permissions.request()` API.\r\n", + "├ Run again with --allow-read to bypass this prompt.\r\n", + "└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)", + )); + console.write_line_raw("y"); + console.expect(concat!( + "┌ ⚠️ Deno requests read access to \"bar\".\r\n", + "├ Requested by `Deno.permissions.request()` API.\r\n", + "├ Run again with --allow-read to bypass this prompt.\r\n", + "└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)", + )); + console.write_line_raw("n"); + console.expect("granted"); + console.expect("prompt"); + console.expect("denied"); + }); + } + + #[test] + fn _062_permissions_request_global() { + TestContext::default() + .new_command() + .args_vec(["run", "--quiet", "run/062_permissions_request_global.ts"]) + .with_pty(|mut console| { + console.expect(concat!( + "┌ ⚠️ Deno requests read access.\r\n", + "├ Requested by `Deno.permissions.request()` API.\r\n", + "├ Run again with --allow-read to bypass this prompt.\r\n", + "└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)", + )); + console.write_line_raw("y\n"); + console + .expect("PermissionStatus { state: \"granted\", onchange: null }"); + console + .expect("PermissionStatus { state: \"granted\", onchange: null }"); + console + .expect("PermissionStatus { state: \"granted\", onchange: null }"); + }); + } + + #[test] + fn _062_permissions_request_global_sync() { + TestContext::default() + .new_command() + .args_vec(["run", "--quiet", "run/062_permissions_request_global_sync.ts"]) + .with_pty(|mut console| { + console.expect(concat!( + "┌ ⚠️ Deno requests read access.\r\n", + "├ Requested by `Deno.permissions.request()` API.\r\n", + "├ Run again with --allow-read to bypass this prompt.\r\n", + "└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)", + )); + console.write_line_raw("y"); + console + .expect("PermissionStatus { state: \"granted\", onchange: null }"); + console + .expect("PermissionStatus { state: \"granted\", onchange: null }"); + console + .expect("PermissionStatus { state: \"granted\", onchange: null }"); + }); + } + + itest!(_063_permissions_revoke { + args: "run --allow-read=foo,bar run/063_permissions_revoke.ts", + output: "run/063_permissions_revoke.ts.out", + }); + + itest!(_063_permissions_revoke_sync { + args: "run --allow-read=foo,bar run/063_permissions_revoke_sync.ts", + output: "run/063_permissions_revoke.ts.out", + }); + + itest!(_064_permissions_revoke_global { + args: "run --allow-read=foo,bar run/064_permissions_revoke_global.ts", + output: "run/064_permissions_revoke_global.ts.out", + }); + + itest!(_064_permissions_revoke_global_sync { + args: "run --allow-read=foo,bar run/064_permissions_revoke_global_sync.ts", + output: "run/064_permissions_revoke_global.ts.out", + }); + + itest!(_065_permissions_revoke_net { + args: "run --allow-net run/065_permissions_revoke_net.ts", + output: "run/065_permissions_revoke_net.ts.out", + }); + + #[test] + fn _066_prompt() { + TestContext::default() + .new_command() + .args_vec(["run", "--quiet", "--unstable", "run/066_prompt.ts"]) + .with_pty(|mut console| { + console.expect("What is your name? Jane Doe"); + console.write_line_raw(""); + console.expect("Your name is Jane Doe."); + + console.expect("Prompt "); + console.write_line_raw("foo"); + console.expect("Your input is foo."); + console.expect("Question 0 [y/N] "); + console.write_line_raw("Y"); + console.expect("Your answer is true"); + console.expect("Question 1 [y/N] "); + console.write_line_raw("N"); + console.expect("Your answer is false"); + console.expect("Question 2 [y/N] "); + console.write_line_raw("yes"); + console.expect("Your answer is false"); + console.expect("Confirm [y/N] "); + console.write_line(""); + console.expect("Your answer is false"); + console.expect("What is Windows EOL? "); + console.write_line("windows"); + console.expect("Your answer is \"windows\""); + console.expect("Hi [Enter] "); + console.write_line(""); + console.expect("Alert [Enter] "); + console.write_line(""); + console.expect("The end of test"); + }); + } + + itest!(dynamic_import_static_analysis_no_permissions { + args: "run --quiet --reload --no-prompt dynamic_import/static_analysis_no_permissions.ts", + output: "dynamic_import/static_analysis_no_permissions.ts.out", + }); + + itest!(dynamic_import_permissions_remote_remote { + args: "run --quiet --reload --allow-net=localhost:4545 dynamic_import/permissions_remote_remote.ts", + output: "dynamic_import/permissions_remote_remote.ts.out", + http_server: true, + exit_code: 1, + }); + + itest!(dynamic_import_permissions_data_remote { + args: "run --quiet --reload --allow-net=localhost:4545 dynamic_import/permissions_data_remote.ts", + output: "dynamic_import/permissions_data_remote.ts.out", + http_server: true, + exit_code: 1, + }); + + itest!(dynamic_import_permissions_blob_remote { + args: "run --quiet --reload --allow-net=localhost:4545 dynamic_import/permissions_blob_remote.ts", + output: "dynamic_import/permissions_blob_remote.ts.out", + http_server: true, + exit_code: 1, + }); + + itest!(dynamic_import_permissions_data_local { + args: "run --quiet --reload --allow-net=localhost:4545 dynamic_import/permissions_data_local.ts", + output: "dynamic_import/permissions_data_local.ts.out", + http_server: true, + exit_code: 1, + }); + + itest!(dynamic_import_permissions_blob_local { + args: "run --quiet --reload --allow-net=localhost:4545 dynamic_import/permissions_blob_local.ts", + output: "dynamic_import/permissions_blob_local.ts.out", + http_server: true, + exit_code: 1, + }); +} + +itest!(tls_starttls { + args: "run --quiet --reload --allow-net --allow-read --cert tls/RootCA.pem run/tls_starttls.js", + output: "run/tls.out", +}); + +itest!(tls_connecttls { + args: "run --quiet --reload --allow-net --allow-read --cert tls/RootCA.pem run/tls_connecttls.js", + output: "run/tls.out", +}); + +itest!(byte_order_mark { + args: "run --no-check run/byte_order_mark.ts", + output: "run/byte_order_mark.out", +}); + +#[test] +fn issue9750() { + TestContext::default() + .new_command() + .args_vec(["run", "run/issue9750.js"]) + .with_pty(|mut console| { + console.expect("Enter 'yy':"); + console.write_line_raw("yy"); + console.expect(concat!( + "┌ ⚠️ Deno requests env access.\r\n", + "├ Requested by `Deno.permissions.request()` API.\r\n", + "├ Run again with --allow-env to bypass this prompt.\r\n", + "└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all env permissions)", + )); + console.write_line_raw("n"); + console.expect("Denied env access."); + console.expect(concat!( + "┌ ⚠️ Deno requests env access to \"SECRET\".\r\n", + "├ Run again with --allow-env to bypass this prompt.\r\n", + "└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all env permissions)", + )); + console.write_line_raw("n"); + console.expect_all(&[ + "Denied env access to \"SECRET\".", + "PermissionDenied: Requires env access to \"SECRET\", run again with the --allow-env flag", + ]); + }); +} + +// Regression test for https://github.com/denoland/deno/issues/11451. +itest!(dom_exception_formatting { + args: "run run/dom_exception_formatting.ts", + output: "run/dom_exception_formatting.ts.out", + exit_code: 1, +}); + +itest!(long_data_url_formatting { + args: "run run/long_data_url_formatting.ts", + output: "run/long_data_url_formatting.ts.out", + exit_code: 1, +}); + +itest!(eval_context_throw_dom_exception { + args: "run run/eval_context_throw_dom_exception.js", + output: "run/eval_context_throw_dom_exception.js.out", +}); + +#[test] +#[cfg(unix)] +fn navigator_language_unix() { + let (res, _) = util::run_and_collect_output( + true, + "run navigator_language.ts", + None, + Some(vec![("LC_ALL".to_owned(), "pl_PL".to_owned())]), + false, + ); + assert_eq!(res, "pl-PL\n") +} + +#[test] +fn navigator_language() { + let (res, _) = util::run_and_collect_output( + true, + "run navigator_language.ts", + None, + None, + false, + ); + assert!(!res.is_empty()) +} + +#[test] +#[cfg(unix)] +fn navigator_languages_unix() { + let (res, _) = util::run_and_collect_output( + true, + "run navigator_languages.ts", + None, + Some(vec![ + ("LC_ALL".to_owned(), "pl_PL".to_owned()), + ("NO_COLOR".to_owned(), "1".to_owned()), + ]), + false, + ); + assert_eq!(res, "[ \"pl-PL\" ]\n") +} + +#[test] +fn navigator_languages() { + let (res, _) = util::run_and_collect_output( + true, + "run navigator_languages.ts", + None, + None, + false, + ); + assert!(!res.is_empty()) +} + +/// Regression test for https://github.com/denoland/deno/issues/12740. +#[test] +fn issue12740() { + let mod_dir = TempDir::new(); + let mod1_path = mod_dir.path().join("mod1.ts"); + let mod2_path = mod_dir.path().join("mod2.ts"); + mod1_path.write(""); + let status = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg(&mod1_path) + .stderr(Stdio::null()) + .stdout(Stdio::null()) + .spawn() + .unwrap() + .wait() + .unwrap(); + assert!(status.success()); + mod1_path.write("export { foo } from \"./mod2.ts\";"); + mod2_path.write("("); + let status = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg(&mod1_path) + .stderr(Stdio::null()) + .stdout(Stdio::null()) + .spawn() + .unwrap() + .wait() + .unwrap(); + assert!(!status.success()); +} + +/// Regression test for https://github.com/denoland/deno/issues/12807. +#[test] +fn issue12807() { + let mod_dir = TempDir::new(); + let mod1_path = mod_dir.path().join("mod1.ts"); + let mod2_path = mod_dir.path().join("mod2.ts"); + // With a fresh `DENO_DIR`, run a module with a dependency and a type error. + mod1_path.write("import './mod2.ts'; Deno.exit('0');"); + mod2_path.write("console.log('Hello, world!');"); + let status = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg("--check") + .arg(&mod1_path) + .stderr(Stdio::null()) + .stdout(Stdio::null()) + .spawn() + .unwrap() + .wait() + .unwrap(); + assert!(!status.success()); + // Fix the type error and run again. + std::fs::write(&mod1_path, "import './mod2.ts'; Deno.exit(0);").unwrap(); + let status = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg("--check") + .arg(&mod1_path) + .stderr(Stdio::null()) + .stdout(Stdio::null()) + .spawn() + .unwrap() + .wait() + .unwrap(); + assert!(status.success()); +} + +itest!(issue_13562 { + args: "run run/issue13562.ts", + output: "run/issue13562.ts.out", +}); + +itest!(import_attributes_static_import { + args: "run --allow-read import_attributes/static_import.ts", + output: "import_attributes/static_import.out", +}); + +itest!(import_attributes_static_export { + args: "run --allow-read import_attributes/static_export.ts", + output: "import_attributes/static_export.out", +}); + +itest!(import_attributes_static_error { + args: "run --allow-read import_attributes/static_error.ts", + output: "import_attributes/static_error.out", + exit_code: 1, +}); + +itest!(import_attributes_dynamic_import { + args: "run --allow-read --check import_attributes/dynamic_import.ts", + output: "import_attributes/dynamic_import.out", +}); + +itest!(import_attributes_dynamic_error { + args: "run --allow-read import_attributes/dynamic_error.ts", + output: "import_attributes/dynamic_error.out", + exit_code: 1, +}); + +itest!(import_attributes_type_check { + args: "run --allow-read --check import_attributes/type_check.ts", + output: "import_attributes/type_check.out", + exit_code: 1, +}); + +itest!(delete_window { + args: "run run/delete_window.js", + output_str: Some("true\n"), +}); + +itest!(colors_without_global_this { + args: "run run/colors_without_globalThis.js", + output_str: Some("true\n"), +}); + +itest!(config_auto_discovered_for_local_script { + args: "run --quiet run/with_config/frontend_work.ts", + output_str: Some("ok\n"), +}); + +itest!(config_auto_discovered_for_local_script_log { + args: "run -L debug run/with_config/frontend_work.ts", + output: "run/with_config/auto_discovery_log.out", +}); + +itest!(no_config_auto_discovery_for_local_script { + args: "run --quiet --no-config --check run/with_config/frontend_work.ts", + output: "run/with_config/no_auto_discovery.out", + exit_code: 1, +}); + +itest!(config_not_auto_discovered_for_remote_script { + args: "run --quiet http://127.0.0.1:4545/run/with_config/server_side_work.ts", + output_str: Some("ok\n"), + http_server: true, +}); + +itest!(package_json_auto_discovered_for_local_script_arg { + args: "run -L debug -A no_deno_json/main.ts", + output: "run/with_package_json/no_deno_json/main.out", + // notice this is not in no_deno_json + cwd: Some("run/with_package_json/"), + // prevent creating a node_modules dir in the code directory + copy_temp_dir: Some("run/with_package_json/"), + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +// In this case we shouldn't discover `package.json` file, because it's in a +// directory that is above the directory containing `deno.json` file. +itest!( + package_json_auto_discovered_for_local_script_arg_with_stop { + args: "run -L debug with_stop/some/nested/dir/main.ts", + output: "run/with_package_json/with_stop/main.out", + cwd: Some("run/with_package_json/"), + copy_temp_dir: Some("run/with_package_json/"), + envs: env_vars_for_npm_tests(), + http_server: true, + exit_code: 1, + } +); + +itest!(package_json_not_auto_discovered_no_config { + args: "run -L debug -A --no-config noconfig.ts", + output: "run/with_package_json/no_deno_json/noconfig.out", + cwd: Some("run/with_package_json/no_deno_json/"), +}); + +itest!(package_json_not_auto_discovered_no_npm { + args: "run -L debug -A --no-npm noconfig.ts", + output: "run/with_package_json/no_deno_json/noconfig.out", + cwd: Some("run/with_package_json/no_deno_json/"), +}); + +itest!(package_json_not_auto_discovered_env_var { + args: "run -L debug -A noconfig.ts", + output: "run/with_package_json/no_deno_json/noconfig.out", + cwd: Some("run/with_package_json/no_deno_json/"), + envs: vec![("DENO_NO_PACKAGE_JSON".to_string(), "1".to_string())], +}); + +itest!( + package_json_auto_discovered_node_modules_relative_package_json { + args: "run -A main.js", + output: "run/with_package_json/no_deno_json/sub_dir/main.out", + cwd: Some("run/with_package_json/no_deno_json/sub_dir"), + copy_temp_dir: Some("run/with_package_json/no_deno_json/"), + envs: env_vars_for_npm_tests(), + http_server: true, + } +); + +itest!(package_json_auto_discovered_for_npm_binary { + args: "run -L debug -A npm:@denotest/bin/cli-esm this is a test", + output: "run/with_package_json/npm_binary/main.out", + cwd: Some("run/with_package_json/npm_binary/"), + copy_temp_dir: Some("run/with_package_json/"), + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(package_json_auto_discovered_no_package_json_imports { + // this should not use --quiet because we should ensure no package.json install occurs + args: "run -A no_package_json_imports.ts", + output: "run/with_package_json/no_deno_json/no_package_json_imports.out", + cwd: Some("run/with_package_json/no_deno_json"), + copy_temp_dir: Some("run/with_package_json/no_deno_json"), +}); + +#[test] +fn package_json_with_deno_json() { + let context = TestContextBuilder::for_npm() + .use_copy_temp_dir("package_json/deno_json/") + .cwd("package_json/deno_json/") + .build(); + let output = context.new_command().args("run --quiet -A main.ts").run(); + output.assert_matches_file("package_json/deno_json/main.out"); + + assert!(context + .temp_dir() + .path() + .join("package_json/deno_json/deno.lock") + .exists()); + + // run again and ensure the top level install doesn't happen twice + let output = context + .new_command() + .args("run --log-level=debug -A main.ts") + .run(); + let output = output.combined_output(); + assert_contains!(output, "Skipping top level install."); +} + +#[test] +fn package_json_error_dep_value_test() { + let context = TestContextBuilder::for_npm() + .use_copy_temp_dir("package_json/invalid_value") + .cwd("package_json/invalid_value") + .build(); + + // should run fine when not referencing a failing dep entry + context + .new_command() + .args("run ok.ts") + .run() + .assert_matches_file("package_json/invalid_value/ok.ts.out"); + + // should fail when referencing a failing dep entry + context + .new_command() + .args("run error.ts") + .run() + .assert_exit_code(1) + .assert_matches_file("package_json/invalid_value/error.ts.out"); + + // should output a warning about the failing dep entry + context + .new_command() + .args("task test") + .run() + .assert_matches_file("package_json/invalid_value/task.out"); +} + +#[test] +fn package_json_no_node_modules_dir_created() { + // it should not create a node_modules directory + let context = TestContextBuilder::new() + .add_npm_env_vars() + .use_temp_cwd() + .build(); + let temp_dir = context.temp_dir(); + + temp_dir.write("deno.json", "{}"); + temp_dir.write("package.json", "{}"); + temp_dir.write("main.ts", ""); + + context.new_command().args("run main.ts").run(); + + assert!(!temp_dir.path().join("node_modules").exists()); +} + +#[test] +fn node_modules_dir_no_npm_specifiers_no_dir_created() { + // it should not create a node_modules directory + let context = TestContextBuilder::new() + .add_npm_env_vars() + .use_temp_cwd() + .build(); + let temp_dir = context.temp_dir(); + + temp_dir.write("deno.json", "{}"); + temp_dir.write("main.ts", ""); + + context + .new_command() + .args("run --node-modules-dir main.ts") + .run(); + + assert!(!temp_dir.path().join("node_modules").exists()); +} + +itest!(wasm_streaming_panic_test { + args: "run run/wasm_streaming_panic_test.js", + output: "run/wasm_streaming_panic_test.js.out", + exit_code: 1, +}); + +// Regression test for https://github.com/denoland/deno/issues/13897. +itest!(fetch_async_error_stack { + args: "run --quiet -A run/fetch_async_error_stack.ts", + output: "run/fetch_async_error_stack.ts.out", + exit_code: 1, +}); + +itest!(event_listener_error { + args: "run --quiet run/event_listener_error.ts", + output: "run/event_listener_error.ts.out", + exit_code: 1, +}); + +itest!(event_listener_error_handled { + args: "run --quiet run/event_listener_error_handled.ts", + output: "run/event_listener_error_handled.ts.out", +}); + +// https://github.com/denoland/deno/pull/14159#issuecomment-1092285446 +itest!(event_listener_error_immediate_exit { + args: "run --quiet run/event_listener_error_immediate_exit.ts", + output: "run/event_listener_error_immediate_exit.ts.out", + exit_code: 1, +}); + +// https://github.com/denoland/deno/pull/14159#issuecomment-1092285446 +itest!(event_listener_error_immediate_exit_worker { + args: "run --quiet -A run/event_listener_error_immediate_exit_worker.ts", + output: "run/event_listener_error_immediate_exit_worker.ts.out", + exit_code: 1, +}); + +itest!(set_timeout_error { + args: "run --quiet run/set_timeout_error.ts", + output: "run/set_timeout_error.ts.out", + exit_code: 1, +}); + +itest!(set_timeout_error_handled { + args: "run --quiet run/set_timeout_error_handled.ts", + output: "run/set_timeout_error_handled.ts.out", +}); + +itest!(aggregate_error { + args: "run --quiet run/aggregate_error.ts", + output: "run/aggregate_error.out", + exit_code: 1, +}); + +itest!(complex_error { + args: "run --quiet run/complex_error.ts", + output: "run/complex_error.ts.out", + exit_code: 1, +}); + +// Regression test for https://github.com/denoland/deno/issues/16340. +itest!(error_with_errors_prop { + args: "run --quiet run/error_with_errors_prop.js", + output: "run/error_with_errors_prop.js.out", + exit_code: 1, +}); + +// Regression test for https://github.com/denoland/deno/issues/12143. +itest!(js_root_with_ts_check { + args: "run --quiet --check run/js_root_with_ts_check.js", + output: "run/js_root_with_ts_check.js.out", + exit_code: 1, +}); + +#[test] +fn check_local_then_remote() { + let _http_guard = util::http_server(); + let deno_dir = util::new_deno_dir(); + let output = util::deno_cmd_with_deno_dir(&deno_dir) + .current_dir(util::testdata_path()) + .arg("run") + .arg("--check") + .arg("run/remote_type_error/main.ts") + .spawn() + .unwrap() + .wait_with_output() + .unwrap(); + assert!(output.status.success()); + let output = util::deno_cmd_with_deno_dir(&deno_dir) + .current_dir(util::testdata_path()) + .arg("run") + .arg("--check=all") + .arg("run/remote_type_error/main.ts") + .env("NO_COLOR", "1") + .stderr_piped() + .spawn() + .unwrap() + .wait_with_output() + .unwrap(); + assert!(!output.status.success()); + let stderr = std::str::from_utf8(&output.stderr).unwrap(); + assert_contains!(stderr, "Type 'string' is not assignable to type 'number'."); +} + +// Regression test for https://github.com/denoland/deno/issues/15163 +itest!(check_js_points_to_ts { + args: "run --quiet --check --config run/checkjs.tsconfig.json run/check_js_points_to_ts/test.js", + output: "run/check_js_points_to_ts/test.js.out", + exit_code: 1, +}); + +itest!(no_prompt_flag { + args: "run --quiet --no-prompt run/no_prompt.ts", + output_str: Some(""), +}); + +#[test] +fn deno_no_prompt_environment_variable() { + let output = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg("--unstable") + .arg("run/no_prompt.ts") + .env("DENO_NO_PROMPT", "1") + .spawn() + .unwrap() + .wait_with_output() + .unwrap(); + assert!(output.status.success()); +} + +itest!(report_error { + args: "run --quiet run/report_error.ts", + output: "run/report_error.ts.out", + exit_code: 1, +}); + +itest!(report_error_handled { + args: "run --quiet run/report_error_handled.ts", + output: "run/report_error_handled.ts.out", +}); + +// Regression test for https://github.com/denoland/deno/issues/15513. +itest!(report_error_end_of_program { + args: "run --quiet run/report_error_end_of_program.ts", + output: "run/report_error_end_of_program.ts.out", + exit_code: 1, +}); + +itest!(queue_microtask_error { + args: "run --quiet run/queue_microtask_error.ts", + output: "run/queue_microtask_error.ts.out", + exit_code: 1, +}); + +itest!(queue_microtask_error_handled { + args: "run --quiet run/queue_microtask_error_handled.ts", + output: "run/queue_microtask_error_handled.ts.out", +}); + +itest!(spawn_stdout_inherit { + args: "run --quiet -A run/spawn_stdout_inherit.ts", + output: "run/spawn_stdout_inherit.ts.out", +}); + +itest!(error_name_non_string { + args: "run --quiet run/error_name_non_string.js", + output: "run/error_name_non_string.js.out", + exit_code: 1, +}); + +itest!(custom_inspect_url { + args: "run run/custom_inspect_url.js", + output: "run/custom_inspect_url.js.out", +}); + +itest!(config_json_import { + args: "run --quiet -c jsx/deno-jsx.json run/config_json_import.ts", + output: "run/config_json_import.ts.out", + http_server: true, +}); + +#[test] +fn running_declaration_files() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + let files = vec!["file.d.ts", "file.d.cts", "file.d.mts"]; + + for file in files { + temp_dir.write(file, ""); + context + .new_command() + .args_vec(["run", file]) + .run() + .skip_output_check() + .assert_exit_code(0); + } +} + +itest!(test_and_bench_are_noops_in_run { + args: "run run/test_and_bench_in_run.js", + output_str: Some(""), +}); + +#[cfg(not(target_os = "windows"))] +itest!(spawn_kill_permissions { + args: "run --quiet --allow-run=cat spawn_kill_permissions.ts", + output_str: Some(""), +}); + +itest!(followup_dyn_import_resolved { + args: "run --allow-read run/followup_dyn_import_resolves/main.ts", + output: "run/followup_dyn_import_resolves/main.ts.out", +}); + +itest!(allow_run_allowlist_resolution { + args: "run --quiet -A allow_run_allowlist_resolution.ts", + output: "allow_run_allowlist_resolution.ts.out", +}); + +itest!(unhandled_rejection { + args: "run --check run/unhandled_rejection.ts", + output: "run/unhandled_rejection.ts.out", +}); + +itest!(unhandled_rejection_sync_error { + args: "run --check run/unhandled_rejection_sync_error.ts", + output: "run/unhandled_rejection_sync_error.ts.out", +}); + +// Regression test for https://github.com/denoland/deno/issues/15661 +itest!(unhandled_rejection_dynamic_import { + args: "run --allow-read run/unhandled_rejection_dynamic_import/main.ts", + output: "run/unhandled_rejection_dynamic_import/main.ts.out", + exit_code: 1, +}); + +// Regression test for https://github.com/denoland/deno/issues/16909 +itest!(unhandled_rejection_dynamic_import2 { + args: "run --allow-read run/unhandled_rejection_dynamic_import2/main.ts", + output: "run/unhandled_rejection_dynamic_import2/main.ts.out", +}); + +itest!(rejection_handled { + args: "run --check run/rejection_handled.ts", + output: "run/rejection_handled.out", +}); + +itest!(nested_error { + args: "run run/nested_error/main.ts", + output: "run/nested_error/main.ts.out", + exit_code: 1, +}); + +itest!(node_env_var_allowlist { + args: "run --no-prompt run/node_env_var_allowlist.ts", + output: "run/node_env_var_allowlist.ts.out", + exit_code: 1, +}); + +#[test] +fn cache_test() { + let _g = util::http_server(); + let deno_dir = TempDir::new(); + let module_url = + url::Url::parse("http://localhost:4545/run/006_url_imports.ts").unwrap(); + let output = Command::new(util::deno_exe_path()) + .env("DENO_DIR", deno_dir.path()) + .current_dir(util::testdata_path()) + .arg("cache") + .arg("--check=all") + .arg("-L") + .arg("debug") + .arg(module_url.to_string()) + .output() + .expect("Failed to spawn script"); + assert!(output.status.success()); + + let prg = util::deno_exe_path(); + let output = Command::new(prg) + .env("DENO_DIR", deno_dir.path()) + .env("HTTP_PROXY", "http://nil") + .env("NO_COLOR", "1") + .current_dir(util::testdata_path()) + .arg("run") + .arg(module_url.to_string()) + .output() + .expect("Failed to spawn script"); + + let str_output = std::str::from_utf8(&output.stdout).unwrap(); + + let module_output_path = + util::testdata_path().join("run/006_url_imports.ts.out"); + let mut module_output = String::new(); + let mut module_output_file = std::fs::File::open(module_output_path).unwrap(); + module_output_file + .read_to_string(&mut module_output) + .unwrap(); + + assert_eq!(module_output, str_output); +} + +#[test] +fn cache_invalidation_test() { + let deno_dir = TempDir::new(); + let fixture_path = deno_dir.path().join("fixture.ts"); + fixture_path.write("console.log(\"42\");"); + let output = Command::new(util::deno_exe_path()) + .env("DENO_DIR", deno_dir.path()) + .current_dir(util::testdata_path()) + .arg("run") + .arg(&fixture_path) + .output() + .expect("Failed to spawn script"); + assert!(output.status.success()); + let actual = std::str::from_utf8(&output.stdout).unwrap(); + assert_eq!(actual, "42\n"); + fixture_path.write("console.log(\"43\");"); + let output = Command::new(util::deno_exe_path()) + .env("DENO_DIR", deno_dir.path()) + .current_dir(util::testdata_path()) + .arg("run") + .arg(fixture_path) + .output() + .expect("Failed to spawn script"); + assert!(output.status.success()); + let actual = std::str::from_utf8(&output.stdout).unwrap(); + assert_eq!(actual, "43\n"); +} + +#[test] +fn cache_invalidation_test_no_check() { + let deno_dir = TempDir::new(); + let fixture_path = deno_dir.path().join("fixture.ts"); + fixture_path.write("console.log(\"42\");"); + let output = Command::new(util::deno_exe_path()) + .env("DENO_DIR", deno_dir.path()) + .current_dir(util::testdata_path()) + .arg("run") + .arg("--no-check") + .arg(&fixture_path) + .output() + .expect("Failed to spawn script"); + assert!(output.status.success()); + let actual = std::str::from_utf8(&output.stdout).unwrap(); + assert_eq!(actual, "42\n"); + fixture_path.write("console.log(\"43\");"); + let output = Command::new(util::deno_exe_path()) + .env("DENO_DIR", deno_dir.path()) + .current_dir(util::testdata_path()) + .arg("run") + .arg("--no-check") + .arg(fixture_path) + .output() + .expect("Failed to spawn script"); + assert!(output.status.success()); + let actual = std::str::from_utf8(&output.stdout).unwrap(); + assert_eq!(actual, "43\n"); +} + +#[test] +fn ts_dependency_recompilation() { + let t = TempDir::new(); + let ats = t.path().join("a.ts"); + + std::fs::write( + &ats, + " + import { foo } from \"./b.ts\"; + + function print(str: string): void { + console.log(str); + } + + print(foo);", + ) + .unwrap(); + + let bts = t.path().join("b.ts"); + std::fs::write( + &bts, + " + export const foo = \"foo\";", + ) + .unwrap(); + + let output = util::deno_cmd() + .current_dir(util::testdata_path()) + .env("NO_COLOR", "1") + .arg("run") + .arg("--check") + .arg(&ats) + .output() + .expect("failed to spawn script"); + + let stdout_output = std::str::from_utf8(&output.stdout).unwrap().trim(); + let stderr_output = std::str::from_utf8(&output.stderr).unwrap().trim(); + + assert!(stdout_output.ends_with("foo")); + assert!(stderr_output.starts_with("Check")); + + // Overwrite contents of b.ts and run again + std::fs::write( + &bts, + " + export const foo = 5;", + ) + .expect("error writing file"); + + let output = util::deno_cmd() + .current_dir(util::testdata_path()) + .env("NO_COLOR", "1") + .arg("run") + .arg("--check") + .arg(&ats) + .output() + .expect("failed to spawn script"); + + let stdout_output = std::str::from_utf8(&output.stdout).unwrap().trim(); + let stderr_output = std::str::from_utf8(&output.stderr).unwrap().trim(); + + // error: TS2345 [ERROR]: Argument of type '5' is not assignable to parameter of type 'string'. + assert!(stderr_output.contains("TS2345")); + assert!(!output.status.success()); + assert!(stdout_output.is_empty()); +} + +#[test] +fn basic_auth_tokens() { + let _g = util::http_server(); + + let output = util::deno_cmd() + .current_dir(util::root_path()) + .arg("run") + .arg("http://127.0.0.1:4554/run/001_hello.js") + .piped_output() + .spawn() + .unwrap() + .wait_with_output() + .unwrap(); + + assert!(!output.status.success()); + + let stdout_str = std::str::from_utf8(&output.stdout).unwrap().trim(); + assert!(stdout_str.is_empty()); + + let stderr_str = std::str::from_utf8(&output.stderr).unwrap().trim(); + eprintln!("{stderr_str}"); + + assert!(stderr_str + .contains("Module not found \"http://127.0.0.1:4554/run/001_hello.js\".")); + + let output = util::deno_cmd() + .current_dir(util::root_path()) + .arg("run") + .arg("http://127.0.0.1:4554/run/001_hello.js") + .env("DENO_AUTH_TOKENS", "testuser123:testpassabc@127.0.0.1:4554") + .piped_output() + .spawn() + .unwrap() + .wait_with_output() + .unwrap(); + + let stderr_str = std::str::from_utf8(&output.stderr).unwrap().trim(); + eprintln!("{stderr_str}"); + + assert!(output.status.success()); + + let stdout_str = std::str::from_utf8(&output.stdout).unwrap().trim(); + assert_eq!(util::strip_ansi_codes(stdout_str), "Hello World"); +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +async fn test_resolve_dns() { + use std::net::SocketAddr; + use std::str::FromStr; + use std::sync::Arc; + use std::time::Duration; + use tokio::net::TcpListener; + use tokio::net::UdpSocket; + use tokio::sync::oneshot; + use trust_dns_server::authority::Catalog; + use trust_dns_server::authority::ZoneType; + use trust_dns_server::proto::rr::Name; + use trust_dns_server::store::in_memory::InMemoryAuthority; + use trust_dns_server::ServerFuture; + + const DNS_PORT: u16 = 4553; + + // Setup DNS server for testing + async fn run_dns_server(tx: oneshot::Sender<()>) { + let zone_file = std::fs::read_to_string( + util::testdata_path().join("run/resolve_dns.zone.in"), + ) + .unwrap(); + let lexer = Lexer::new(&zone_file); + let records = Parser::new().parse( + lexer, + Some(Name::from_str("example.com").unwrap()), + None, + ); + if records.is_err() { + panic!("failed to parse: {:?}", records.err()) + } + let (origin, records) = records.unwrap(); + let authority = Box::new(Arc::new( + InMemoryAuthority::new(origin, records, ZoneType::Primary, false) + .unwrap(), + )); + let mut catalog: Catalog = Catalog::new(); + catalog.upsert(Name::root().into(), authority); + + let mut server_fut = ServerFuture::new(catalog); + let socket_addr = SocketAddr::from(([127, 0, 0, 1], DNS_PORT)); + let tcp_listener = TcpListener::bind(socket_addr).await.unwrap(); + let udp_socket = UdpSocket::bind(socket_addr).await.unwrap(); + server_fut.register_socket(udp_socket); + server_fut.register_listener(tcp_listener, Duration::from_secs(2)); + + // Notifies that the DNS server is ready + tx.send(()).unwrap(); + + server_fut.block_until_done().await.unwrap(); + } + + let (ready_tx, ready_rx) = oneshot::channel(); + let dns_server_fut = run_dns_server(ready_tx); + let handle = tokio::spawn(dns_server_fut); + + // Waits for the DNS server to be ready + ready_rx.await.unwrap(); + + // Pass: `--allow-net` + { + let output = util::deno_cmd() + .current_dir(util::testdata_path()) + .env("NO_COLOR", "1") + .arg("run") + .arg("--check") + .arg("--allow-net") + .arg("run/resolve_dns.ts") + .piped_output() + .spawn() + .unwrap() + .wait_with_output() + .unwrap(); + let err = String::from_utf8_lossy(&output.stderr); + let out = String::from_utf8_lossy(&output.stdout); + println!("{err}"); + assert!(output.status.success()); + assert!(err.starts_with("Check file")); + + let expected = std::fs::read_to_string( + util::testdata_path().join("run/resolve_dns.ts.out"), + ) + .unwrap(); + assert_eq!(expected, out); + } + + // Pass: `--allow-net=127.0.0.1:4553` + { + let output = util::deno_cmd() + .current_dir(util::testdata_path()) + .env("NO_COLOR", "1") + .arg("run") + .arg("--check") + .arg("--allow-net=127.0.0.1:4553") + .arg("run/resolve_dns.ts") + .piped_output() + .spawn() + .unwrap() + .wait_with_output() + .unwrap(); + let err = String::from_utf8_lossy(&output.stderr); + let out = String::from_utf8_lossy(&output.stdout); + if !output.status.success() { + eprintln!("stderr: {err}"); + } + assert!(output.status.success()); + assert!(err.starts_with("Check file")); + + let expected = std::fs::read_to_string( + util::testdata_path().join("run/resolve_dns.ts.out"), + ) + .unwrap(); + assert_eq!(expected, out); + } + + // Permission error: `--allow-net=deno.land` + { + let output = util::deno_cmd() + .current_dir(util::testdata_path()) + .env("NO_COLOR", "1") + .arg("run") + .arg("--check") + .arg("--allow-net=deno.land") + .arg("run/resolve_dns.ts") + .piped_output() + .spawn() + .unwrap() + .wait_with_output() + .unwrap(); + let err = String::from_utf8_lossy(&output.stderr); + let out = String::from_utf8_lossy(&output.stdout); + assert!(!output.status.success()); + assert!(err.starts_with("Check file")); + assert!(err.contains(r#"error: Uncaught (in promise) PermissionDenied: Requires net access to "127.0.0.1:4553""#)); + assert!(out.is_empty()); + } + + // Permission error: no permission specified + { + let output = util::deno_cmd() + .current_dir(util::testdata_path()) + .env("NO_COLOR", "1") + .arg("run") + .arg("--check") + .arg("run/resolve_dns.ts") + .piped_output() + .spawn() + .unwrap() + .wait_with_output() + .unwrap(); + let err = String::from_utf8_lossy(&output.stderr); + let out = String::from_utf8_lossy(&output.stdout); + assert!(!output.status.success()); + assert!(err.starts_with("Check file")); + assert!(err.contains(r#"error: Uncaught (in promise) PermissionDenied: Requires net access to "127.0.0.1:4553""#)); + assert!(out.is_empty()); + } + + handle.abort(); +} + +#[tokio::test] +async fn http2_request_url() { + let mut child = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg("--unstable") + .arg("--quiet") + .arg("--allow-net") + .arg("--allow-read") + .arg("./run/http2_request_url.ts") + .arg("4506") + .stdout_piped() + .spawn() + .unwrap(); + let stdout = child.stdout.as_mut().unwrap(); + let mut buffer = [0; 5]; + let read = stdout.read(&mut buffer).unwrap(); + assert_eq!(read, 5); + let msg = std::str::from_utf8(&buffer).unwrap(); + assert_eq!(msg, "READY"); + + let cert = reqwest::Certificate::from_pem(include_bytes!( + "../testdata/tls/RootCA.crt" + )) + .unwrap(); + + let client = reqwest::Client::builder() + .add_root_certificate(cert) + .http2_prior_knowledge() + .build() + .unwrap(); + + let res = client.get("http://127.0.0.1:4506").send().await.unwrap(); + assert_eq!(200, res.status()); + + let body = res.text().await.unwrap(); + assert_eq!(body, "http://127.0.0.1:4506/"); + + child.kill().unwrap(); + child.wait().unwrap(); +} + +#[cfg(not(windows))] +#[test] +fn set_raw_should_not_panic_on_no_tty() { + let output = util::deno_cmd() + .arg("eval") + .arg("Deno.stdin.setRaw(true)") + // stdin set to piped so it certainly does not refer to TTY + .stdin(std::process::Stdio::piped()) + // stderr is piped so we can capture output. + .stderr_piped() + .spawn() + .unwrap() + .wait_with_output() + .unwrap(); + assert!(!output.status.success()); + let stderr = std::str::from_utf8(&output.stderr).unwrap().trim(); + assert!(stderr.contains("BadResource")); +} + +#[test] +fn timeout_clear() { + // https://github.com/denoland/deno/issues/7599 + + use std::time::Duration; + use std::time::Instant; + + let source_code = r#" +const handle = setTimeout(() => { + console.log("timeout finish"); +}, 10000); +clearTimeout(handle); +console.log("finish"); +"#; + + let mut p = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg("-") + .stdin(std::process::Stdio::piped()) + .spawn() + .unwrap(); + let stdin = p.stdin.as_mut().unwrap(); + stdin.write_all(source_code.as_bytes()).unwrap(); + let start = Instant::now(); + let status = p.wait().unwrap(); + let end = Instant::now(); + assert!(status.success()); + // check that program did not run for 10 seconds + // for timeout to clear + assert!(end - start < Duration::new(10, 0)); +} + +#[test] +fn broken_stdout() { + let (reader, writer) = os_pipe::pipe().unwrap(); + // drop the reader to create a broken pipe + drop(reader); + + let output = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("eval") + .arg("console.log(3.14)") + .stdout(writer) + .stderr_piped() + .spawn() + .unwrap() + .wait_with_output() + .unwrap(); + + assert!(!output.status.success()); + let stderr = std::str::from_utf8(output.stderr.as_ref()).unwrap().trim(); + assert!(stderr.contains("Uncaught (in promise) BrokenPipe")); + assert!(!stderr.contains("panic")); +} + +itest!(error_cause { + args: "run run/error_cause.ts", + output: "run/error_cause.ts.out", + exit_code: 1, +}); + +itest!(error_cause_recursive_aggregate { + args: "run error_cause_recursive_aggregate.ts", + output: "error_cause_recursive_aggregate.ts.out", + exit_code: 1, +}); + +itest!(error_cause_recursive_tail { + args: "run error_cause_recursive_tail.ts", + output: "error_cause_recursive_tail.ts.out", + exit_code: 1, +}); + +itest!(error_cause_recursive { + args: "run run/error_cause_recursive.ts", + output: "run/error_cause_recursive.ts.out", + exit_code: 1, +}); + +itest!(default_file_extension_is_js { + args: "run --check file_extensions/js_without_extension", + output: "file_extensions/js_without_extension.out", + exit_code: 0, +}); + +itest!(js_without_extension { + args: "run --ext js --check file_extensions/js_without_extension", + output: "file_extensions/js_without_extension.out", + exit_code: 0, +}); + +itest!(ts_without_extension { + args: "run --ext ts --check file_extensions/ts_without_extension", + output: "file_extensions/ts_without_extension.out", + exit_code: 0, +}); + +itest!(ext_flag_takes_precedence_over_extension { + args: "run --ext ts --check file_extensions/ts_with_js_extension.js", + output: "file_extensions/ts_with_js_extension.out", + exit_code: 0, +}); + +#[tokio::test(flavor = "multi_thread")] +async fn websocketstream_ping() { + let _g = util::http_server(); + + let script = util::testdata_path().join("run/websocketstream_ping_test.ts"); + let root_ca = util::testdata_path().join("tls/RootCA.pem"); + + let srv_fn = hyper::service::service_fn(|mut req| async move { + let (response, upgrade_fut) = + fastwebsockets::upgrade::upgrade(&mut req).unwrap(); + tokio::spawn(async move { + let mut ws = upgrade_fut.await.unwrap(); + + ws.write_frame(fastwebsockets::Frame::text(b"A"[..].into())) + .await + .unwrap(); + ws.write_frame(fastwebsockets::Frame::new( + true, + fastwebsockets::OpCode::Ping, + None, + vec![].into(), + )) + .await + .unwrap(); + ws.write_frame(fastwebsockets::Frame::text(b"B"[..].into())) + .await + .unwrap(); + let message = ws.read_frame().await.unwrap(); + assert_eq!(message.opcode, fastwebsockets::OpCode::Pong); + ws.write_frame(fastwebsockets::Frame::text(b"C"[..].into())) + .await + .unwrap(); + ws.write_frame(fastwebsockets::Frame::close_raw(vec![].into())) + .await + .unwrap(); + }); + Ok::<_, std::convert::Infallible>(response) + }); + + let child = util::deno_cmd() + .arg("test") + .arg("--unstable") + .arg("--allow-net") + .arg("--cert") + .arg(root_ca) + .arg(script) + .stdout_piped() + .spawn() + .unwrap(); + let server = tokio::net::TcpListener::bind("127.0.0.1:4513") + .await + .unwrap(); + tokio::spawn(async move { + let (stream, _) = server.accept().await.unwrap(); + let io = hyper_util::rt::TokioIo::new(stream); + let conn_fut = hyper::server::conn::http1::Builder::new() + .serve_connection(io, srv_fn) + .with_upgrades(); + + if let Err(e) = conn_fut.await { + eprintln!("websocket server error: {e:?}"); + } + }); + + let r = child.wait_with_output().unwrap(); + assert!(r.status.success()); +} + +struct SpawnExecutor; + +impl hyper::rt::Executor for SpawnExecutor +where + Fut: std::future::Future + Send + 'static, + Fut::Output: Send + 'static, +{ + fn execute(&self, fut: Fut) { + deno_core::unsync::spawn(fut); + } +} + +#[tokio::test] +async fn websocket_server_multi_field_connection_header() { + let script = util::testdata_path() + .join("run/websocket_server_multi_field_connection_header_test.ts"); + let root_ca = util::testdata_path().join("tls/RootCA.pem"); + let mut child = util::deno_cmd() + .arg("run") + .arg("--unstable") + .arg("--allow-net") + .arg("--cert") + .arg(root_ca) + .arg(script) + .stdout_piped() + .spawn() + .unwrap(); + + let stdout = child.stdout.as_mut().unwrap(); + let mut buffer = [0; 5]; + let read = stdout.read(&mut buffer).unwrap(); + assert_eq!(read, 5); + let msg = std::str::from_utf8(&buffer).unwrap(); + assert_eq!(msg, "READY"); + + let stream = tokio::net::TcpStream::connect("localhost:4319") + .await + .unwrap(); + let req = http::Request::builder() + .header(http::header::UPGRADE, "websocket") + .header(http::header::CONNECTION, "keep-alive, Upgrade") + .header( + "Sec-WebSocket-Key", + fastwebsockets::handshake::generate_key(), + ) + .header("Sec-WebSocket-Version", "13") + .uri("ws://localhost:4319") + .body(http_body_util::Empty::::new()) + .unwrap(); + + let (mut socket, _) = + fastwebsockets::handshake::client(&SpawnExecutor, req, stream) + .await + .unwrap(); + + let message = socket.read_frame().await.unwrap(); + assert_eq!(message.opcode, fastwebsockets::OpCode::Close); + assert!(message.payload.is_empty()); + socket + .write_frame(fastwebsockets::Frame::close_raw(vec![].into())) + .await + .unwrap(); + assert!(child.wait().unwrap().success()); +} + +// TODO(bartlomieju): this should use `deno run`, not `deno test`; but the +// test hangs then. https://github.com/denoland/deno/issues/14283 +#[tokio::test] +async fn websocket_server_idletimeout() { + let script = + util::testdata_path().join("run/websocket_server_idletimeout.ts"); + let root_ca = util::testdata_path().join("tls/RootCA.pem"); + let mut child = util::deno_cmd() + .arg("test") + .arg("--unstable") + .arg("--allow-net") + .arg("--cert") + .arg(root_ca) + .arg(script) + .stdout_piped() + .spawn() + .unwrap(); + + let stdout = child.stdout.as_mut().unwrap(); + let mut buffer = [0; 5]; + let read = stdout.read(&mut buffer).unwrap(); + assert_eq!(read, 5); + let msg = std::str::from_utf8(&buffer).unwrap(); + assert_eq!(msg, "READY"); + + let stream = tokio::net::TcpStream::connect("localhost:4509") + .await + .unwrap(); + let req = http::Request::builder() + .header(http::header::UPGRADE, "websocket") + .header(http::header::CONNECTION, "keep-alive, Upgrade") + .header( + "Sec-WebSocket-Key", + fastwebsockets::handshake::generate_key(), + ) + .header("Sec-WebSocket-Version", "13") + .uri("ws://localhost:4509") + .body(http_body_util::Empty::::new()) + .unwrap(); + + let (_socket, _) = + fastwebsockets::handshake::client(&SpawnExecutor, req, stream) + .await + .unwrap(); + + assert!(child.wait().unwrap().success()); +} + +itest!(auto_discover_lockfile { + args: "run run/auto_discover_lockfile/main.ts", + output: "run/auto_discover_lockfile/main.out", + http_server: true, + exit_code: 10, +}); + +itest!(no_lock_flag { + args: "run --no-lock run/no_lock_flag/main.ts", + output: "run/no_lock_flag/main.out", + http_server: true, + exit_code: 0, +}); + +itest!(config_file_lock_false { + args: "run --config=run/config_file_lock_boolean/false.json run/config_file_lock_boolean/main.ts", + output: "run/config_file_lock_boolean/false.main.out", + http_server: true, + exit_code: 0, +}); + +itest!(config_file_lock_true { + args: "run --config=run/config_file_lock_boolean/true.json run/config_file_lock_boolean/main.ts", + output: "run/config_file_lock_boolean/true.main.out", + http_server: true, + exit_code: 10, +}); + +itest!(permission_args { + args: "run run/001_hello.js --allow-net", + output: "run/permission_args.out", + envs: vec![("NO_COLOR".to_string(), "1".to_string())], +}); + +itest!(permission_args_quiet { + args: "run --quiet run/001_hello.js --allow-net", + output: "run/001_hello.js.out", +}); + +// Regression test for https://github.com/denoland/deno/issues/16772 +#[test] +fn file_fetcher_preserves_permissions() { + let context = TestContext::with_http_server(); + context + .new_command() + .args("repl --quiet") + .with_pty(|mut console| { + console.write_line( + "const a = await import('http://localhost:4545/run/019_media_types.ts');", + ); + console.expect("Allow?"); + console.write_line_raw("y"); + console.expect_all(&["success", "true"]); + }); +} + +#[test] +fn stdio_streams_are_locked_in_permission_prompt() { + if !util::pty::Pty::is_supported() { + // Don't deal with the logic below if the with_pty + // block doesn't even run (ex. on Windows CI) + return; + } + + let context = TestContextBuilder::new() + .use_http_server() + .use_copy_temp_dir("run/stdio_streams_are_locked_in_permission_prompt") + .build(); + let mut passed_test = false; + let mut i = 0; + while !passed_test { + i += 1; + if i > 5 { + panic!("Output happened before permission prompt too many times"); + } + + context + .new_command() + .args("repl --allow-read") + .with_pty(|mut console| { + let malicious_output = r#"Are you sure you want to continue?"#; + + console.write_line(r#"const url = "file://" + Deno.cwd().replace("\\", "/") + "/run/stdio_streams_are_locked_in_permission_prompt/worker.js";"#); + console.expect("undefined"); + // ensure this file exists + console.write_line(r#"const _file = Deno.readTextFileSync("./run/stdio_streams_are_locked_in_permission_prompt/worker.js");"#); + console.expect("undefined"); + console.write_line(r#"new Worker(url, { type: "module" }); await Deno.writeTextFile("./text.txt", "some code");"#); + console.expect("Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all write permissions)"); + + // Due to the main thread being slow, it may occur that the worker thread outputs + // before the permission prompt is shown. This is not a bug and just a timing issue + // when dealing with multiple threads. If this occurs, detect such a case and then + // retry running the test. + if let Some(malicious_index) = console.all_output().find(malicious_output) { + let prompt_index = console.all_output().find("Allow?").unwrap(); + // Ensure the malicious output is shown before the prompt as we + // expect in this scenario. If not, that would indicate a bug. + assert!(malicious_index < prompt_index); + return; + } + + std::thread::sleep(Duration::from_millis(50)); // give the other thread some time to output + console.write_line_raw("invalid"); + console.expect("Unrecognized option."); + console.expect("Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all write permissions)"); + console.write_line_raw("y"); + console.expect("Granted write access to"); + + // this output should now be shown below and not above + console.expect(malicious_output); + passed_test = true; + }); + } +} + +#[test] +fn permission_prompt_strips_ansi_codes_and_control_chars() { + util::with_pty(&["repl"], |mut console| { + console.write_line( + r#"Deno.permissions.request({ name: "env", variable: "\rDo you like ice cream? y/n" });"# + ); + // will be uppercase on windows + let env_name = if cfg!(windows) { + "DO YOU LIKE ICE CREAM? Y/N" + } else { + "Do you like ice cream? y/n" + }; + console.expect(format!( + "┌ ⚠️ Deno requests env access to \"{}\".", + env_name + )) + }); + + util::with_pty(&["repl"], |mut console| { + console.write_line_raw(r#"const boldANSI = "\u001b[1m";"#); + console.expect("undefined"); + console.write_line_raw(r#"const unboldANSI = "\u001b[22m";"#); + console.expect("undefined"); + console.write_line_raw(r#"const prompt = `┌ ⚠️ ${boldANSI}Deno requests run access to "echo"${unboldANSI}\n ├ Requested by \`Deno.Command().output()`"#); + console.expect("undefined"); + console.write_line_raw(r#"const moveANSIUp = "\u001b[1A";"#); + console.expect("undefined"); + console.write_line_raw(r#"const clearANSI = "\u001b[2K";"#); + console.expect("undefined"); + console.write_line_raw(r#"const moveANSIStart = "\u001b[1000D";"#); + console.expect("undefined"); + }); +} + +itest!(node_builtin_modules_ts { + args: "run --quiet --allow-read run/node_builtin_modules/mod.ts hello there", + output: "run/node_builtin_modules/mod.ts.out", + envs: env_vars_for_npm_tests(), + exit_code: 0, +}); + +itest!(node_builtin_modules_js { + args: "run --quiet --allow-read run/node_builtin_modules/mod.js hello there", + output: "run/node_builtin_modules/mod.js.out", + envs: env_vars_for_npm_tests(), + exit_code: 0, +}); + +itest!(node_prefix_missing { + args: "run --quiet run/node_prefix_missing/main.ts", + output: "run/node_prefix_missing/main.ts.out", + envs: env_vars_for_npm_tests(), + exit_code: 1, +}); + +itest!(node_prefix_missing_unstable_bare_node_builtins_enbaled { + args: "run --unstable-bare-node-builtins run/node_prefix_missing/main.ts", + output: "run/node_prefix_missing/main.ts.out_feature_enabled", + envs: env_vars_for_npm_tests(), + exit_code: 0, +}); + +itest!( + node_prefix_missing_unstable_bare_node_builtins_enbaled_by_env { + args: "run run/node_prefix_missing/main.ts", + output: "run/node_prefix_missing/main.ts.out_feature_enabled", + envs: [ + env_vars_for_npm_tests(), + vec![( + "DENO_UNSTABLE_BARE_NODE_BUILTINS".to_string(), + "1".to_string() + )] + ] + .concat(), + exit_code: 0, + } +); + +itest!(node_prefix_missing_unstable_bare_node_builtins_enbaled_by_config { + args: "run --config=run/node_prefix_missing/config.json run/node_prefix_missing/main.ts", + output: "run/node_prefix_missing/main.ts.out_feature_enabled", + envs: env_vars_for_npm_tests(), + exit_code: 0, +}); + +itest!(node_prefix_missing_unstable_bare_node_builtins_enbaled_with_import_map { + args: "run --unstable-bare-node-builtins --import-map run/node_prefix_missing/import_map.json run/node_prefix_missing/main.ts", + output: "run/node_prefix_missing/main.ts.out_feature_enabled", + envs: env_vars_for_npm_tests(), + exit_code: 0, +}); + +itest!(dynamic_import_syntax_error { + args: "run -A run/dynamic_import_syntax_error.js", + output: "run/dynamic_import_syntax_error.js.out", + exit_code: 1, +}); + +itest!(extension_import { + args: "run run/extension_import.ts", + output: "run/extension_import.ts.out", + exit_code: 1, +}); + +itest!(extension_dynamic_import { + args: "run run/extension_dynamic_import.ts", + output: "run/extension_dynamic_import.ts.out", + exit_code: 1, +}); + +#[test] +pub fn vendor_dir_config_file() { + let test_context = TestContextBuilder::new() + .use_http_server() + .use_temp_cwd() + .build(); + let temp_dir = test_context.temp_dir(); + let vendor_dir = temp_dir.path().join("vendor"); + let rm_vendor_dir = || std::fs::remove_dir_all(&vendor_dir).unwrap(); + + temp_dir.write("deno.json", r#"{ "vendor": true }"#); + temp_dir.write( + "main.ts", + r#"import { returnsHi } from 'http://localhost:4545/subdir/mod1.ts'; +console.log(returnsHi());"#, + ); + + let deno_run_cmd = test_context.new_command().args("run --quiet main.ts"); + deno_run_cmd.run().assert_matches_text("Hi\n"); + + assert!(vendor_dir.exists()); + rm_vendor_dir(); + temp_dir.write("deno.json", r#"{ "vendor": false }"#); + + deno_run_cmd.run().assert_matches_text("Hi\n"); + assert!(!vendor_dir.exists()); + test_context + .new_command() + .args("cache --quiet --vendor main.ts") + .run(); + assert!(vendor_dir.exists()); + rm_vendor_dir(); + + temp_dir.write("deno.json", r#"{ "vendor": true }"#); + let cache_command = test_context.new_command().args("cache --quiet main.ts"); + cache_command.run(); + + assert!(vendor_dir.exists()); + let mod1_file = vendor_dir + .join("http_localhost_4545") + .join("subdir") + .join("mod1.ts"); + mod1_file.write("export function returnsHi() { return 'bye bye bye'; }"); + + // won't match the lockfile now + deno_run_cmd + .run() + .assert_matches_text(r#"error: The source code is invalid, as it does not match the expected hash in the lock file. + Specifier: http://localhost:4545/subdir/mod1.ts + Lock file: [WILDCARD]deno.lock +"#) + .assert_exit_code(10); + + // try updating by deleting the lockfile + let lockfile = temp_dir.path().join("deno.lock"); + lockfile.remove_file(); + cache_command.run(); + + // now it should run + deno_run_cmd.run().assert_matches_text("bye bye bye\n"); + assert!(lockfile.exists()); + + // ensure we can add and execute files in directories that have a hash in them + test_context + .new_command() + // http_localhost_4545/subdir/#capitals_c75d7/main.js + .args("cache http://localhost:4545/subdir/CAPITALS/main.js") + .run() + .skip_output_check(); + assert_eq!( + vendor_dir.join("manifest.json").read_json_value(), + json!({ + "folders": { + "http://localhost:4545/subdir/CAPITALS/": "http_localhost_4545/subdir/#capitals_c75d7" + } + }) + ); + vendor_dir + .join("http_localhost_4545/subdir/#capitals_c75d7/hello_there.ts") + .write("console.log('hello there');"); + test_context + .new_command() + // todo(dsherret): seems wrong that we don't auto-discover the config file to get the vendor directory for this + .args("run --vendor http://localhost:4545/subdir/CAPITALS/hello_there.ts") + .run() + .assert_matches_text("hello there\n"); + + // now try importing directly from the vendor folder + temp_dir.write( + "main.ts", + r#"import { returnsHi } from './vendor/http_localhost_4545/subdir/mod1.ts'; +console.log(returnsHi());"#, + ); + deno_run_cmd + .run() + .assert_matches_text("error: Importing from the vendor directory is not permitted. Use a remote specifier instead or disable vendoring. + at [WILDCARD]/main.ts:1:27 +") + .assert_exit_code(1); +} + +itest!(explicit_resource_management { + args: "run --quiet --check run/explicit_resource_management/main.ts", + output: "run/explicit_resource_management/main.out", +}); + +itest!(workspaces_basic { + args: "run -L debug -A main.ts", + output: "run/workspaces/basic/main.out", + cwd: Some("run/workspaces/basic/"), + copy_temp_dir: Some("run/workspaces/basic/"), + envs: env_vars_for_npm_tests(), + http_server: true, +}); + +itest!(workspaces_member_outside_root_dir { + args: "run -A main.ts", + output: "run/workspaces/member_outside_root_dir/main.out", + cwd: Some("run/workspaces/member_outside_root_dir/"), + copy_temp_dir: Some("run/workspaces/member_outside_root_dir/"), + envs: env_vars_for_npm_tests(), + http_server: true, + exit_code: 1, +}); + +itest!(workspaces_nested_member { + args: "run -A main.ts", + output: "run/workspaces/nested_member/main.out", + cwd: Some("run/workspaces/nested_member/"), + copy_temp_dir: Some("run/workspaces/nested_member/"), + envs: env_vars_for_npm_tests(), + http_server: true, + exit_code: 1, +}); + +itest!(unsafe_proto { + args: "run -A run/unsafe_proto/main.js", + output: "run/unsafe_proto/main.out", + http_server: false, + exit_code: 0, +}); + +itest!(unsafe_proto_flag { + args: "run -A --unstable-unsafe-proto run/unsafe_proto/main.js", + output: "run/unsafe_proto/main_with_unsafe_proto_flag.out", + http_server: false, + exit_code: 0, +}); + +#[test] +fn test_unstable_sloppy_imports() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + temp_dir.write("a.ts", "export class A {}"); + temp_dir.write("b.js", "export class B {}"); + temp_dir.write("c.mts", "export class C {}"); + temp_dir.write("d.mjs", "export class D {}"); + temp_dir.write("e.tsx", "export class E {}"); + temp_dir.write("f.jsx", "export class F {}"); + let dir = temp_dir.path().join("dir"); + dir.create_dir_all(); + dir.join("index.tsx").write("export class G {}"); + temp_dir.write( + "main.ts", + r#"import * as a from "./a.js"; +import * as b from "./b"; +import * as c from "./c"; +import * as d from "./d"; +import * as e from "./e"; +import * as e2 from "./e.js"; +import * as f from "./f"; +import * as g from "./dir"; +console.log(a.A); +console.log(b.B); +console.log(c.C); +console.log(d.D); +console.log(e.E); +console.log(e2.E); +console.log(f.F); +console.log(g.G); +"#, + ); + + // run without sloppy imports + context + .new_command() + .args("run main.ts") + .run() + .assert_matches_text(r#"error: Module not found "file:///[WILDCARD]/a.js". Maybe change the extension to '.ts' or run with --unstable-sloppy-imports + at file:///[WILDCARD]/main.ts:1:20 +"#) + .assert_exit_code(1); + + // now run with sloppy imports + temp_dir.write("deno.json", r#"{ "unstable": ["sloppy-imports"] }"#); + context + .new_command() + .args("run main.ts") + .run() + .assert_matches_text( + "Warning Sloppy imports are not recommended and have a negative impact on performance. +Warning Sloppy module resolution (hint: update .js extension to .ts) + at file:///[WILDCARD]/main.ts:1:20 +Warning Sloppy module resolution (hint: add .js extension) + at file:///[WILDCARD]/main.ts:2:20 +Warning Sloppy module resolution (hint: add .mts extension) + at file:///[WILDCARD]/main.ts:3:20 +Warning Sloppy module resolution (hint: add .mjs extension) + at file:///[WILDCARD]/main.ts:4:20 +Warning Sloppy module resolution (hint: add .tsx extension) + at file:///[WILDCARD]/main.ts:5:20 +Warning Sloppy module resolution (hint: update .js extension to .tsx) + at file:///[WILDCARD]/main.ts:6:21 +Warning Sloppy module resolution (hint: add .jsx extension) + at file:///[WILDCARD]/main.ts:7:20 +Warning Sloppy module resolution (hint: specify path to index.tsx file in directory instead) + at file:///[WILDCARD]/main.ts:8:20 +[class A] +[class B] +[class C] +[class D] +[class E] +[class E] +[class F] +[class G] +", + ); +} + +itest!(unstable_temporal_api { + args: "run --unstable-temporal --check run/unstable_temporal_api/main.ts", + output: "run/unstable_temporal_api/main.out", + http_server: false, + exit_code: 0, +}); + +itest!(unstable_temporal_api_missing_flag { + args: "run run/unstable_temporal_api/missing_flag.js", + output: "run/unstable_temporal_api/missing_flag.out", + http_server: false, + exit_code: 1, +}); + +// TODO(bartlomieju): temporary disabled +// itest!(warn_on_deprecated_api { +// args: "run -A run/warn_on_deprecated_api/main.js", +// output: "run/warn_on_deprecated_api/main.out", +// http_server: true, +// exit_code: 0, +// }); + +// itest!(warn_on_deprecated_api_verbose { +// args: "run -A run/warn_on_deprecated_api/main.js", +// output: "run/warn_on_deprecated_api/main.verbose.out", +// envs: vec![("DENO_VERBOSE_WARNINGS".to_string(), "1".to_string())], +// http_server: true, +// exit_code: 0, +// }); + +// itest!(warn_on_deprecated_api_with_flag { +// args: "run -A --quiet run/warn_on_deprecated_api/main.js", +// output: "run/warn_on_deprecated_api/main_disabled_flag.out", +// http_server: true, +// exit_code: 0, +// }); + +// itest!(warn_on_deprecated_api_with_env_var { +// args: "run -A run/warn_on_deprecated_api/main.js", +// envs: vec![("DENO_NO_DEPRECATION_WARNINGS".to_string(), "1".to_string())], +// output: "run/warn_on_deprecated_api/main_disabled_env.out", +// http_server: true, +// exit_code: 0, +// }); + +#[test] +fn deno_json_imports_expand() { + let test_context = TestContextBuilder::for_npm().use_temp_cwd().build(); + let dir = test_context.temp_dir(); + dir.write( + "deno.json", + r#"{ + "imports": { + "basic": "npm:@denotest/esm-basic" + } +}"#, + ); + + dir.write( + "main.ts", + r#" +// import map should resolve +import { setValue, getValue } from "basic"; +// this entry should have been added automatically +import { hello } from "basic/other.mjs"; + +setValue(5); +console.log(getValue()); +console.log(hello()); +"#, + ); + let output = test_context.new_command().args("run main.ts").run(); + output.assert_matches_text("[WILDCARD]5\nhello, world!\n"); +} + +#[test] +fn deno_json_imports_expand_doesnt_overwrite_existing_entries() { + let test_context = TestContextBuilder::for_npm().use_temp_cwd().build(); + let dir = test_context.temp_dir(); + dir.write( + "deno.json", + r#"{ + "imports": { + "basic": "npm:@denotest/esm-basic", + "basic/": "npm:/@denotest/sub-folders/folder_index_js/" + } +}"#, + ); + + dir.write( + "main.ts", + r#" +// import map should resolve +import { setValue, getValue } from "basic"; +// this entry should map to explicitly specified "basic/" mapping +import { add } from "basic/index.js"; + +setValue(5); +console.log(getValue()); +console.log(add(3, 4)); +"#, + ); + let output = test_context.new_command().args("run main.ts").run(); + output.assert_matches_text("[WILDCARD]5\n7\n"); +} diff --git a/tests/integration/shared_library_tests.rs b/tests/integration/shared_library_tests.rs new file mode 100644 index 000000000..4d33e6584 --- /dev/null +++ b/tests/integration/shared_library_tests.rs @@ -0,0 +1,85 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +#[cfg(all(target_os = "linux", target_arch = "x86_64"))] +#[test] +// https://github.com/denoland/deno/issues/18266 +fn linux_shared_libraries() { + use test_util as util; + + const EXPECTED: [&str; 7] = [ + "linux-vdso.so.1", + "libdl.so.2", + "libgcc_s.so.1", + "libpthread.so.0", + "libm.so.6", + "libc.so.6", + "/lib64/ld-linux-x86-64.so.2", + ]; + + let ldd = std::process::Command::new("ldd") + .arg("-L") + .arg(util::deno_exe_path()) + .output() + .expect("Failed to execute ldd"); + + let output = std::str::from_utf8(&ldd.stdout).unwrap(); + // Ensure that the output contains only the expected shared libraries. + for line in output.lines().skip(1) { + let path = line.split_whitespace().next().unwrap(); + assert!( + EXPECTED.contains(&path), + "Unexpected shared library: {}", + path + ); + } +} + +#[cfg(target_os = "macos")] +#[test] +// https://github.com/denoland/deno/issues/18243 +// This test is to prevent inadvertently linking to more shared system libraries that usually +// increases dyld startup time. +fn macos_shared_libraries() { + use test_util as util; + + // target/release/deno: + // /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1953.1.0) + // /System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices (compatibility version 1.0.0, current version 1228.0.0) + // /System/Library/Frameworks/QuartzCore.framework/Versions/A/QuartzCore (compatibility version 1.2.0, current version 1.11.0, weak) + // /System/Library/Frameworks/Metal.framework/Versions/A/Metal (compatibility version 1.0.0, current version 341.16.0, weak) + // /System/Library/Frameworks/CoreGraphics.framework/Versions/A/CoreGraphics (compatibility version 64.0.0, current version 1774.0.4, weak) + // /System/Library/Frameworks/MetalPerformanceShaders.framework/Versions/A/MetalPerformanceShaders (compatibility version 1.0.0, current version 127.0.19, weak) + // /usr/lib/libiconv.2.dylib (compatibility version 7.0.0, current version 7.0.0) + // /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1319.0.0) + // /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0) + + // path and whether its weak or not + const EXPECTED: [(&str, bool); 9] = [ + ("/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation", false), + ("/System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices", false), + ("/System/Library/Frameworks/QuartzCore.framework/Versions/A/QuartzCore", true), + ("/System/Library/Frameworks/Metal.framework/Versions/A/Metal", true), + ("/System/Library/Frameworks/CoreGraphics.framework/Versions/A/CoreGraphics", true), + ("/System/Library/Frameworks/MetalPerformanceShaders.framework/Versions/A/MetalPerformanceShaders", true), + ("/usr/lib/libiconv.2.dylib", false), + ("/usr/lib/libSystem.B.dylib", false), + ("/usr/lib/libobjc.A.dylib", false), + ]; + + let otool = std::process::Command::new("otool") + .arg("-L") + .arg(util::deno_exe_path()) + .output() + .expect("Failed to execute otool"); + + let output = std::str::from_utf8(&otool.stdout).unwrap(); + // Ensure that the output contains only the expected shared libraries. + for line in output.lines().skip(1) { + let (path, attributes) = line.trim().split_once(' ').unwrap(); + assert!( + EXPECTED.contains(&(path, attributes.ends_with("weak)"))), + "Unexpected shared library: {}", + path + ); + } +} diff --git a/tests/integration/task_tests.rs b/tests/integration/task_tests.rs new file mode 100644 index 000000000..c8531c13f --- /dev/null +++ b/tests/integration/task_tests.rs @@ -0,0 +1,357 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +// Most of the tests for this are in deno_task_shell. +// These tests are intended to only test integration. + +use deno_core::serde_json::json; +use test_util::env_vars_for_npm_tests; +use test_util::TestContext; +use test_util::TestContextBuilder; + +itest!(task_no_args { + args: "task -q --config task/deno_json/deno.json", + output: "task/deno_json/task_no_args.out", + envs: vec![("NO_COLOR".to_string(), "1".to_string())], + exit_code: 1, +}); + +itest!(task_cwd { + args: "task -q --config task/deno_json/deno.json --cwd .. echo_cwd", + output: "task/deno_json/task_cwd.out", + envs: vec![("NO_COLOR".to_string(), "1".to_string())], + exit_code: 0, +}); + +itest!(task_init_cwd { + args: "task -q --config task/deno_json/deno.json --cwd .. echo_init_cwd", + output: "task/deno_json/task_init_cwd.out", + envs: vec![("NO_COLOR".to_string(), "1".to_string())], + exit_code: 0, +}); + +itest!(task_init_cwd_already_set { + args: "task -q --config task/deno_json/deno.json echo_init_cwd", + output: "task/deno_json/task_init_cwd_already_set.out", + envs: vec![ + ("NO_COLOR".to_string(), "1".to_string()), + ("INIT_CWD".to_string(), "HELLO".to_string()) + ], + exit_code: 0, +}); + +itest!(task_cwd_resolves_config_from_specified_dir { + args: "task -q --cwd task/deno_json", + output: "task/deno_json/task_no_args.out", + envs: vec![("NO_COLOR".to_string(), "1".to_string())], + exit_code: 1, +}); + +itest!(task_non_existent { + args: "task --config task/deno_json/deno.json non_existent", + output: "task/deno_json/task_non_existent.out", + envs: vec![("NO_COLOR".to_string(), "1".to_string())], + exit_code: 1, +}); + +#[test] +fn task_emoji() { + // this bug only appears when using a pty/tty + TestContext::default() + .new_command() + .args_vec(["task", "--config", "task/deno_json/deno.json", "echo_emoji"]) + .with_pty(|mut console| { + console.expect("Task echo_emoji echo 🔥\r\n🔥"); + }); +} + +itest!(task_boolean_logic { + args: "task -q --config task/deno_json/deno.json boolean_logic", + output: "task/deno_json/task_boolean_logic.out", + envs: vec![("NO_COLOR".to_string(), "1".to_string())], +}); + +itest!(task_exit_code_5 { + args: "task --config task/deno_json/deno.json exit_code_5", + output: "task/deno_json/task_exit_code_5.out", + envs: vec![("NO_COLOR".to_string(), "1".to_string())], + exit_code: 5, +}); + +itest!(task_additional_args { + args: "task -q --config task/deno_json/deno.json echo 2", + output: "task/deno_json/task_additional_args.out", + envs: vec![("NO_COLOR".to_string(), "1".to_string())], +}); + +itest!(task_additional_args_no_shell_expansion { + args_vec: vec![ + "task", + "-q", + "--config", + "task/deno_json/deno.json", + "echo", + "$(echo 5)" + ], + output: "task/deno_json/task_additional_args_no_shell_expansion.out", + envs: vec![("NO_COLOR".to_string(), "1".to_string())], +}); + +itest!(task_additional_args_nested_strings { + args_vec: vec![ + "task", + "-q", + "--config", + "task/deno_json/deno.json", + "echo", + "string \"quoted string\"" + ], + output: "task/deno_json/task_additional_args_nested_strings.out", + envs: vec![("NO_COLOR".to_string(), "1".to_string())], +}); + +itest!(task_additional_args_no_logic { + args_vec: vec![ + "task", + "-q", + "--config", + "task/deno_json/deno.json", + "echo", + "||", + "echo", + "5" + ], + output: "task/deno_json/task_additional_args_no_logic.out", + envs: vec![("NO_COLOR".to_string(), "1".to_string())], +}); + +itest!(task_deno_exe_no_env { + args_vec: vec![ + "task", + "-q", + "--config", + "task/deno_json/deno.json", + "deno_echo" + ], + output: "task/deno_json/task_deno_exe_no_env.out", + envs: vec![("NO_COLOR".to_string(), "1".to_string())], + env_clear: true, +}); + +itest!(task_piped_stdin { + args_vec: vec![ + "task", + "-q", + "--config", + "task/deno_json/deno.json", + "piped" + ], + output: "task/deno_json/task_piped_stdin.out", + envs: vec![("NO_COLOR".to_string(), "1".to_string())], +}); + +itest!(task_package_json_no_arg { + args: "task", + cwd: Some("task/package_json/"), + output: "task/package_json/no_args.out", + envs: vec![("NO_COLOR".to_string(), "1".to_string())], + exit_code: 1, +}); + +itest!(task_package_json_echo { + args: "task --quiet echo", + cwd: Some("task/package_json/"), + output: "task/package_json/echo.out", + // use a temp dir because the node_modules folder will be created + copy_temp_dir: Some("task/package_json/"), + envs: env_vars_for_npm_tests(), + exit_code: 0, + http_server: true, +}); + +itest!(task_package_json_npm_bin { + args: "task bin extra", + cwd: Some("task/package_json/"), + output: "task/package_json/bin.out", + copy_temp_dir: Some("task/package_json/"), + envs: env_vars_for_npm_tests(), + exit_code: 0, + http_server: true, +}); + +// should not auto-install the packages in the package.json +// when using nodeModulesDir: false +itest!(task_package_json_node_modules_dir_false { + args: "task echo", + cwd: Some("task/package_json_node_modules_dir_false/"), + output: "task/package_json_node_modules_dir_false/bin.out", + copy_temp_dir: Some("task/package_json_node_modules_dir_false/"), + envs: env_vars_for_npm_tests(), + exit_code: 0, + http_server: true, +}); + +itest!(task_both_no_arg { + args: "task", + cwd: Some("task/both/"), + output: "task/both/no_args.out", + envs: vec![("NO_COLOR".to_string(), "1".to_string())], + exit_code: 1, +}); + +itest!(task_both_deno_json_selected { + args: "task other", + cwd: Some("task/both/"), + output: "task/both/deno_selected.out", + copy_temp_dir: Some("task/both/"), + envs: env_vars_for_npm_tests(), + exit_code: 0, + http_server: true, +}); + +itest!(task_both_package_json_selected { + args: "task bin asdf", + cwd: Some("task/both/"), + output: "task/both/package_json_selected.out", + copy_temp_dir: Some("task/both/"), + envs: env_vars_for_npm_tests(), + exit_code: 0, + http_server: true, +}); + +itest!(task_both_prefers_deno { + args: "task output some text", + cwd: Some("task/both/"), + output: "task/both/prefers_deno.out", + copy_temp_dir: Some("task/both/"), + envs: env_vars_for_npm_tests(), + exit_code: 0, + http_server: true, +}); + +itest!(task_npx_non_existent { + args: "task non-existent", + cwd: Some("task/npx/"), + output: "task/npx/non_existent.out", + copy_temp_dir: Some("task/npx/"), + envs: env_vars_for_npm_tests(), + exit_code: 1, + http_server: true, +}); + +itest!(task_npx_on_own { + args: "task on-own", + cwd: Some("task/npx/"), + output: "task/npx/on_own.out", + copy_temp_dir: Some("task/npx/"), + envs: env_vars_for_npm_tests(), + exit_code: 1, + http_server: true, +}); + +itest!(task_pre_post { + args: "task test", + cwd: Some("task/package_json_pre_post/"), + output: "task/package_json_pre_post/bin.out", + copy_temp_dir: Some("task/package_json_pre_post/"), + exit_code: 0, + envs: vec![("NO_COLOR".to_string(), "1".to_string())], +}); + +itest!(task_pre { + args: "task test", + cwd: Some("task/package_json_pre/"), + output: "task/package_json_pre/bin.out", + copy_temp_dir: Some("task/package_json_pre/"), + exit_code: 0, + envs: vec![("NO_COLOR".to_string(), "1".to_string())], +}); + +itest!(task_post { + args: "task test", + cwd: Some("task/package_json_post/"), + output: "task/package_json_post/bin.out", + copy_temp_dir: Some("task/package_json_post/"), + exit_code: 0, + envs: vec![("NO_COLOR".to_string(), "1".to_string())], +}); + +itest!(task_post_only { + args: "task test", + cwd: Some("task/package_json_post_only/"), + output: "task/package_json_post_only/bin.out", + copy_temp_dir: Some("task/package_json_post_only/"), + exit_code: 1, + envs: vec![("NO_COLOR".to_string(), "1".to_string())], +}); + +itest!(task_pre_only { + args: "task test", + cwd: Some("task/package_json_pre_only/"), + output: "task/package_json_pre_only/bin.out", + copy_temp_dir: Some("task/package_json_pre_only/"), + exit_code: 1, + envs: vec![("NO_COLOR".to_string(), "1".to_string())], +}); + +itest!(task_deno_no_pre_post { + args: "task test", + cwd: Some("task/deno_json_pre_post/"), + output: "task/deno_json_pre_post/bin.out", + copy_temp_dir: Some("task/deno_json_pre_post/"), + exit_code: 0, + envs: vec![("NO_COLOR".to_string(), "1".to_string())], +}); + +#[test] +fn task_byonm() { + let context = TestContextBuilder::for_npm().use_temp_cwd().build(); + let temp_dir = context.temp_dir().path(); + temp_dir.join("package.json").write_json(&json!({ + "name": "example", + "scripts": { + "say": "cowsay 'do make say'", + "think": "cowthink think" + }, + "dependencies": { + "cowsay": "*" + } + })); + temp_dir.join("deno.json").write_json(&json!({ + "unstable": ["byonm"], + })); + context.run_npm("install"); + + context + .new_command() + .args_vec(["task", "say"]) + .run() + .assert_matches_text( + r#"Task say cowsay 'do make say' + _____________ +< do make say > + ------------- + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || +"#, + ); + + context + .new_command() + .args_vec(["task", "think"]) + .run() + .assert_matches_text( + r#"Task think cowthink think + _______ +( think ) + ------- + o ^__^ + o (oo)\_______ + (__)\ )\/\ + ||----w | + || || +"#, + ); +} diff --git a/tests/integration/test_tests.rs b/tests/integration/test_tests.rs new file mode 100644 index 000000000..27bef8007 --- /dev/null +++ b/tests/integration/test_tests.rs @@ -0,0 +1,671 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +use deno_core::url::Url; +use test_util as util; +use util::assert_contains; +use util::assert_not_contains; +use util::env_vars_for_npm_tests; +use util::wildcard_match; +use util::TestContext; +use util::TestContextBuilder; + +#[test] +fn no_color() { + let (out, _) = util::run_and_collect_output( + false, + "test test/no_color.ts", + None, + Some(vec![("NO_COLOR".to_owned(), "true".to_owned())]), + false, + ); + // ANSI escape codes should be stripped. + assert!(out.contains("success ... ok")); + assert!(out.contains("fail ... FAILED")); + assert!(out.contains("ignored ... ignored")); + assert!(out.contains("FAILED | 1 passed | 1 failed | 1 ignored")); +} + +itest!(overloads { + args: "test test/overloads.ts", + exit_code: 0, + output: "test/overloads.out", +}); + +itest!(meta { + args: "test test/meta.ts", + exit_code: 0, + output: "test/meta.out", +}); + +itest!(pass { + args: "test test/pass.ts", + exit_code: 0, + output: "test/pass.out", +}); + +itest!(ignore { + args: "test test/ignore.ts", + exit_code: 0, + output: "test/ignore.out", +}); + +itest!(ignore_permissions { + args: "test test/ignore_permissions.ts", + exit_code: 0, + output: "test/ignore_permissions.out", +}); + +itest!(fail { + args: "test test/fail.ts", + exit_code: 1, + output: "test/fail.out", +}); + +itest!(collect { + args: "test --ignore=test/collect/ignore test/collect", + exit_code: 0, + output: "test/collect.out", +}); + +itest!(test_with_config { + args: "test --config test/collect/deno.jsonc test/collect", + exit_code: 0, + output: "test/collect.out", +}); + +itest!(test_with_config2 { + args: "test --config test/collect/deno2.jsonc test/collect", + exit_code: 0, + output: "test/collect2.out", +}); + +itest!(test_with_deprecated_config { + args: "test --config test/collect/deno.deprecated.jsonc test/collect", + exit_code: 0, + output: "test/collect.deprecated.out", +}); + +itest!(test_with_malformed_config { + args: "test --config test/collect/deno.malformed.jsonc", + exit_code: 1, + output: "test/collect_with_malformed_config.out", +}); + +itest!(test_filtered_out_only { + args: "test --quiet --filter foo test/filtered_out_only.ts", + output: "test/filtered_out_only.out", +}); + +itest!(parallel_flag { + args: "test test/short-pass.ts --parallel", + exit_code: 0, + output: "test/short-pass.out", +}); + +itest!(parallel_flag_with_env_variable { + args: "test test/short-pass.ts --parallel", + envs: vec![("DENO_JOBS".to_owned(), "2".to_owned())], + exit_code: 0, + output: "test/short-pass.out", +}); + +itest!(jobs_flag { + args: "test test/short-pass.ts --jobs", + exit_code: 0, + output: "test/short-pass-jobs-flag-warning.out", +}); + +itest!(jobs_flag_with_numeric_value { + args: "test test/short-pass.ts --jobs=2", + exit_code: 0, + output: "test/short-pass-jobs-flag-warning.out", +}); + +itest!(load_unload { + args: "test test/load_unload.ts", + exit_code: 0, + output: "test/load_unload.out", +}); + +itest!(interval { + args: "test test/interval.ts", + exit_code: 0, + output: "test/interval.out", +}); + +itest!(doc { + args: "test --doc --allow-all test/doc.ts", + exit_code: 1, + output: "test/doc.out", +}); + +itest!(doc_only { + args: "test --doc --allow-all test/doc_only", + exit_code: 0, + output: "test/doc_only.out", +}); + +itest!(markdown { + args: "test --doc --allow-all test/markdown.md", + exit_code: 1, + output: "test/markdown.out", +}); + +itest!(markdown_windows { + args: "test --doc --allow-all test/markdown_windows.md", + exit_code: 1, + output: "test/markdown_windows.out", +}); + +itest!(markdown_full_block_names { + args: "test --doc --allow-all test/markdown_full_block_names.md", + exit_code: 1, + output: "test/markdown_full_block_names.out", +}); + +itest!(markdown_ignore_html_comment { + args: "test --doc --allow-all test/markdown_with_comment.md", + exit_code: 1, + output: "test/markdown_with_comment.out", +}); + +itest!(text { + args: "test --doc --allow-all test/text.md", + exit_code: 0, + output: "test/text.out", +}); + +itest!(quiet { + args: "test --quiet test/quiet.ts", + exit_code: 0, + output: "test/quiet.out", +}); + +itest!(fail_fast { + args: "test --fail-fast test/fail_fast.ts test/fail_fast_other.ts", + exit_code: 1, + output: "test/fail_fast.out", +}); + +itest!(only { + args: "test test/only.ts", + exit_code: 1, + output: "test/only.out", +}); + +itest!(no_check { + args: "test --no-check test/no_check.ts", + exit_code: 1, + output: "test/no_check.out", +}); + +itest!(no_run { + args: "test --no-run test/no_run.ts", + output: "test/no_run.out", + exit_code: 1, +}); + +itest!(allow_all { + args: "test --allow-all test/allow_all.ts", + exit_code: 0, + output: "test/allow_all.out", +}); + +itest!(allow_none { + args: "test test/allow_none.ts", + exit_code: 1, + output: "test/allow_none.out", +}); + +itest!(ops_sanitizer_unstable { + args: "test --trace-ops test/ops_sanitizer_unstable.ts", + exit_code: 1, + output: "test/ops_sanitizer_unstable.out", +}); + +itest!(ops_sanitizer_timeout_failure { + args: "test test/ops_sanitizer_timeout_failure.ts", + output: "test/ops_sanitizer_timeout_failure.out", +}); + +itest!(ops_sanitizer_multiple_timeout_tests { + args: "test --trace-ops test/ops_sanitizer_multiple_timeout_tests.ts", + exit_code: 1, + output: "test/ops_sanitizer_multiple_timeout_tests.out", +}); + +itest!(ops_sanitizer_multiple_timeout_tests_no_trace { + args: "test test/ops_sanitizer_multiple_timeout_tests.ts", + exit_code: 1, + output: "test/ops_sanitizer_multiple_timeout_tests_no_trace.out", +}); + +itest!(trace_ops_catch_error { + args: "test -A --trace-ops test/trace_ops_caught_error/main.ts", + exit_code: 0, + output: "test/trace_ops_caught_error/main.out", +}); + +// TODO(@littledivy): re-enable this test, recent optimizations made output non deterministic. +// https://github.com/denoland/deno/issues/14268 +// +// itest!(ops_sanitizer_missing_details { +// args: "test --allow-write --allow-read test/ops_sanitizer_missing_details.ts", +// exit_code: 1, +// output: "test/ops_sanitizer_missing_details.out", +// }); + +itest!(ops_sanitizer_closed_inside_started_before { + args: "test --trace-ops test/ops_sanitizer_closed_inside_started_before.ts", + exit_code: 1, + output: "test/ops_sanitizer_closed_inside_started_before.out", +}); + +itest!(ops_sanitizer_nexttick { + args: "test --no-check test/ops_sanitizer_nexttick.ts", + output: "test/ops_sanitizer_nexttick.out", +}); + +itest!(resource_sanitizer { + args: "test --allow-read test/resource_sanitizer.ts", + exit_code: 1, + output: "test/resource_sanitizer.out", +}); + +itest!(exit_sanitizer { + args: "test test/exit_sanitizer.ts", + output: "test/exit_sanitizer.out", + exit_code: 1, +}); + +itest!(junit { + args: "test --reporter junit test/pass.ts", + output: "test/pass.junit.out", +}); + +#[test] +fn junit_path() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + temp_dir.write("test.js", "Deno.test('does test', () => {});"); + let output = context + .new_command() + .args("test --junit-path=sub_dir/output.xml test.js") + .run(); + output.skip_output_check(); + output.assert_exit_code(0); + temp_dir + .path() + .join("sub_dir/output.xml") + .assert_matches_text(">(); + // the output is racy on either stdout or stderr being flushed + // from the runtime into the rust code, so sort it... the main + // thing here to ensure is that we're capturing the output in + // this block on stdout + lines.sort_unstable(); + assert_eq!(lines.join(" "), "0 1 2 3 4 5 6 7 8 9"); +} + +#[test] +fn recursive_permissions_pledge() { + let context = TestContext::default(); + let output = context + .new_command() + .args("test test/recursive_permissions_pledge.js") + .run(); + output.assert_exit_code(1); + assert_contains!( + output.combined_output(), + "pledge test permissions called before restoring previous pledge" + ); +} + +#[test] +fn file_protocol() { + let file_url = + Url::from_file_path(util::testdata_path().join("test/file_protocol.ts")) + .unwrap() + .to_string(); + + TestContext::default() + .new_command() + .args_vec(["test", file_url.as_str()]) + .run() + .assert_matches_file("test/file_protocol.out"); +} + +itest!(uncaught_errors { + args: "test --quiet test/uncaught_errors_1.ts test/uncaught_errors_2.ts test/uncaught_errors_3.ts", + output: "test/uncaught_errors.out", + exit_code: 1, +}); + +itest!(report_error { + args: "test --quiet test/report_error.ts", + output: "test/report_error.out", + exit_code: 1, +}); + +itest!(check_local_by_default { + args: "test --quiet test/check_local_by_default.ts", + output: "test/check_local_by_default.out", + http_server: true, +}); + +itest!(check_local_by_default2 { + args: "test --quiet test/check_local_by_default2.ts", + output: "test/check_local_by_default2.out", + http_server: true, + exit_code: 1, +}); + +itest!(non_error_thrown { + args: "test --quiet test/non_error_thrown.ts", + output: "test/non_error_thrown.out", + exit_code: 1, +}); + +itest!(parallel_output { + args: "test --parallel --reload test/parallel_output.ts", + output: "test/parallel_output.out", + exit_code: 1, +}); + +#[test] +// todo(#18480): re-enable +#[ignore] +fn sigint_with_hanging_test() { + util::with_pty( + &[ + "test", + "--quiet", + "--no-check", + "test/sigint_with_hanging_test.ts", + ], + |mut console| { + std::thread::sleep(std::time::Duration::from_secs(1)); + console.write_line("\x03"); + let text = console.read_until("hanging_test.ts:10:15"); + wildcard_match( + include_str!("../testdata/test/sigint_with_hanging_test.out"), + &text, + ); + }, + ); +} + +itest!(package_json_basic { + args: "test", + output: "package_json/basic/lib.test.out", + envs: env_vars_for_npm_tests(), + http_server: true, + cwd: Some("package_json/basic"), + copy_temp_dir: Some("package_json/basic"), + exit_code: 0, +}); + +itest!(test_lock { + args: "test", + http_server: true, + cwd: Some("lockfile/basic"), + exit_code: 10, + output: "lockfile/basic/fail.out", +}); + +itest!(test_no_lock { + args: "test --no-lock", + http_server: true, + cwd: Some("lockfile/basic"), + output: "lockfile/basic/test.nolock.out", +}); + +itest!(test_replace_timers { + args: "test test/replace_timers.js", + output: "test/replace_timers.js.out", +}); + +#[test] +fn test_with_glob_config() { + let context = TestContextBuilder::new().cwd("test").build(); + + let cmd_output = context + .new_command() + .args("test --config deno.glob.json") + .run(); + + cmd_output.assert_exit_code(0); + + let output = cmd_output.combined_output(); + assert_contains!(output, "glob/nested/fizz/fizz.ts"); + assert_contains!(output, "glob/pages/[id].ts"); + assert_contains!(output, "glob/nested/fizz/bar.ts"); + assert_contains!(output, "glob/nested/foo/foo.ts"); + assert_contains!(output, "glob/data/test1.js"); + assert_contains!(output, "glob/nested/foo/bar.ts"); + assert_contains!(output, "glob/nested/foo/fizz.ts"); + assert_contains!(output, "glob/nested/fizz/foo.ts"); + assert_contains!(output, "glob/data/test1.ts"); +} + +#[test] +fn test_with_glob_config_and_flags() { + let context = TestContextBuilder::new().cwd("test").build(); + + let cmd_output = context + .new_command() + .args("test --config deno.glob.json --ignore=glob/nested/**/bar.ts") + .run(); + + cmd_output.assert_exit_code(0); + + let output = cmd_output.combined_output(); + assert_contains!(output, "glob/nested/fizz/fizz.ts"); + assert_contains!(output, "glob/pages/[id].ts"); + assert_contains!(output, "glob/nested/fizz/bazz.ts"); + assert_contains!(output, "glob/nested/foo/foo.ts"); + assert_contains!(output, "glob/data/test1.js"); + assert_contains!(output, "glob/nested/foo/bazz.ts"); + assert_contains!(output, "glob/nested/foo/fizz.ts"); + assert_contains!(output, "glob/nested/fizz/foo.ts"); + assert_contains!(output, "glob/data/test1.ts"); + + let cmd_output = context + .new_command() + .args("test --config deno.glob.json glob/data/test1.?s") + .run(); + + cmd_output.assert_exit_code(0); + + let output = cmd_output.combined_output(); + assert_contains!(output, "glob/data/test1.js"); + assert_contains!(output, "glob/data/test1.ts"); +} + +#[test] +fn conditionally_loads_type_graph() { + let context = TestContext::default(); + let output = context + .new_command() + .args("test --reload -L debug run/type_directives_js_main.js") + .run(); + output.assert_matches_text("[WILDCARD] - FileFetcher::fetch() - specifier: file:///[WILDCARD]/subdir/type_reference.d.ts[WILDCARD]"); + let output = context + .new_command() + .args("test --reload -L debug --no-check run/type_directives_js_main.js") + .run(); + assert_not_contains!(output.combined_output(), "type_reference.d.ts"); +} + +itest!(test_include_relative_pattern_dot_slash { + args: "test", + output: "test/relative_pattern_dot_slash/output.out", + cwd: Some("test/relative_pattern_dot_slash"), +}); diff --git a/tests/integration/upgrade_tests.rs b/tests/integration/upgrade_tests.rs new file mode 100644 index 000000000..c016b61fc --- /dev/null +++ b/tests/integration/upgrade_tests.rs @@ -0,0 +1,259 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +use std::process::Command; +use std::process::Stdio; +use std::time::Instant; +use test_util as util; +use test_util::TempDir; +use util::TestContextBuilder; + +// Warning: this test requires internet access. +// TODO(#7412): reenable. test is flaky +#[test] +#[ignore] +fn upgrade_in_tmpdir() { + let temp_dir = TempDir::new(); + let exe_path = temp_dir.path().join("deno"); + util::deno_exe_path().copy(&exe_path); + assert!(exe_path.exists()); + let _mtime1 = std::fs::metadata(&exe_path).unwrap().modified().unwrap(); + let status = Command::new(&exe_path) + .arg("upgrade") + .arg("--force") + .spawn() + .unwrap() + .wait() + .unwrap(); + assert!(status.success()); + let _mtime2 = std::fs::metadata(&exe_path).unwrap().modified().unwrap(); + // TODO(ry) assert!(mtime1 < mtime2); +} + +// Warning: this test requires internet access. +// TODO(#7412): reenable. test is flaky +#[test] +#[ignore] +fn upgrade_with_space_in_path() { + let temp_dir = TempDir::new_with_prefix("directory with spaces"); + let exe_path = temp_dir.path().join("deno"); + util::deno_exe_path().copy(&exe_path); + assert!(exe_path.exists()); + let status = Command::new(&exe_path) + .arg("upgrade") + .arg("--force") + .env("TMP", temp_dir.path()) + .spawn() + .unwrap() + .wait() + .unwrap(); + assert!(status.success()); +} + +// Warning: this test requires internet access. +// TODO(#7412): reenable. test is flaky +#[test] +#[ignore] +fn upgrade_with_version_in_tmpdir() { + let temp_dir = TempDir::new(); + let exe_path = temp_dir.path().join("deno"); + util::deno_exe_path().copy(&exe_path); + assert!(exe_path.exists()); + let _mtime1 = std::fs::metadata(&exe_path).unwrap().modified().unwrap(); + let status = Command::new(&exe_path) + .arg("upgrade") + .arg("--force") + .arg("--version") + .arg("1.11.5") + .spawn() + .unwrap() + .wait() + .unwrap(); + assert!(status.success()); + let upgraded_deno_version = String::from_utf8( + Command::new(&exe_path).arg("-V").output().unwrap().stdout, + ) + .unwrap(); + assert!(upgraded_deno_version.contains("1.11.5")); + let _mtime2 = std::fs::metadata(&exe_path).unwrap().modified().unwrap(); + // TODO(ry) assert!(mtime1 < mtime2); +} + +// Warning: this test requires internet access. +// TODO(#7412): reenable. test is flaky +#[test] +#[ignore] +fn upgrade_with_canary_in_tmpdir() { + let temp_dir = TempDir::new(); + let exe_path = temp_dir.path().join("deno"); + util::deno_exe_path().copy(&exe_path); + assert!(exe_path.exists()); + let _mtime1 = std::fs::metadata(&exe_path).unwrap().modified().unwrap(); + let status = Command::new(&exe_path) + .arg("upgrade") + .arg("--canary") + .arg("--version") + .arg("e6685f0f01b8a11a5eaff020f5babcfde76b3038") + .spawn() + .unwrap() + .wait() + .unwrap(); + assert!(status.success()); + let upgraded_deno_version = String::from_utf8( + Command::new(&exe_path).arg("-V").output().unwrap().stdout, + ) + .unwrap(); + assert!(upgraded_deno_version.contains("e6685f0")); + let _mtime2 = std::fs::metadata(&exe_path).unwrap().modified().unwrap(); + // TODO(ry) assert!(mtime1 < mtime2); +} + +// Warning: this test requires internet access. +// TODO(#7412): reenable. test is flaky +#[test] +#[ignore] +fn upgrade_with_out_in_tmpdir() { + let temp_dir = TempDir::new(); + let exe_path = temp_dir.path().join("deno"); + let new_exe_path = temp_dir.path().join("foo"); + util::deno_exe_path().copy(&exe_path); + assert!(exe_path.exists()); + let mtime1 = std::fs::metadata(&exe_path).unwrap().modified().unwrap(); + let status = Command::new(&exe_path) + .arg("upgrade") + .arg("--version") + .arg("1.11.5") + .arg("--output") + .arg(&new_exe_path) + .spawn() + .unwrap() + .wait() + .unwrap(); + assert!(status.success()); + assert!(new_exe_path.exists()); + let mtime2 = std::fs::metadata(&exe_path).unwrap().modified().unwrap(); + assert_eq!(mtime1, mtime2); // Original exe_path was not changed. + + let v = String::from_utf8( + Command::new(&new_exe_path) + .arg("-V") + .output() + .unwrap() + .stdout, + ) + .unwrap(); + assert!(v.contains("1.11.5")); +} + +// Warning: this test requires internet access. +// TODO(#7412): reenable. test is flaky +#[test] +#[ignore] +fn upgrade_invalid_stable_version() { + let temp_dir = TempDir::new(); + let exe_path = temp_dir.path().join("deno"); + util::deno_exe_path().copy(&exe_path); + assert!(exe_path.exists()); + let output = Command::new(&exe_path) + .arg("upgrade") + .arg("--version") + .arg("foobar") + .stderr(Stdio::piped()) + .spawn() + .unwrap() + .wait_with_output() + .unwrap(); + assert!(!output.status.success()); + assert_eq!( + "error: Invalid semver passed\n", + util::strip_ansi_codes(&String::from_utf8(output.stderr).unwrap()) + ); +} + +// Warning: this test requires internet access. +// TODO(#7412): reenable. test is flaky +#[test] +#[ignore] +fn upgrade_invalid_canary_version() { + let temp_dir = TempDir::new(); + let exe_path = temp_dir.path().join("deno"); + util::deno_exe_path().copy(&exe_path); + assert!(exe_path.exists()); + let output = Command::new(&exe_path) + .arg("upgrade") + .arg("--canary") + .arg("--version") + .arg("foobar") + .stderr(Stdio::piped()) + .spawn() + .unwrap() + .wait_with_output() + .unwrap(); + assert!(!output.status.success()); + assert_eq!( + "error: Invalid commit hash passed\n", + util::strip_ansi_codes(&String::from_utf8(output.stderr).unwrap()) + ); +} + +#[test] +fn upgrade_prompt() { + let context = TestContextBuilder::new() + .use_http_server() + .use_temp_cwd() + .env( + "DENO_DONT_USE_INTERNAL_BASE_UPGRADE_URL", + "http://localhost:4545", + ) + .build(); + let temp_dir = context.temp_dir(); + // start a task that goes indefinitely in order to allow + // the upgrade check to occur + temp_dir.write("main.js", "setInterval(() => {}, 1_000)"); + let cmd = context + .new_command() + .args("run --log-level=debug main.js") + .env_remove("DENO_NO_UPDATE_CHECK"); + // run once and wait for the version to be stored + cmd.with_pty(|mut pty| { + pty.expect("Finished upgrade checker."); + }); + // now check that the upgrade prompt is shown the next time this is run + temp_dir.write("main.js", ""); + cmd.with_pty(|mut pty| { + // - We need to use a pty here because the upgrade prompt + // doesn't occur except when there's a pty. + // - Version comes from the test server. + pty.expect_any(&[ + " 99999.99.99 Run `deno upgrade` to install it.", + // it builds canary releases on main, so check for this in that case + "Run `deno upgrade --canary` to install it.", + ]); + }); +} + +#[test] +fn upgrade_lsp_repl_sleeps() { + let context = TestContextBuilder::new() + .use_http_server() + .use_temp_cwd() + .env( + "DENO_DONT_USE_INTERNAL_BASE_UPGRADE_URL", + "http://localhost:4545/upgrade/sleep", + ) + .build(); + let start_instant = Instant::now(); + // ensure this works even though the upgrade check is taking + // a long time to complete + context + .new_command() + .args("repl") + .env_remove("DENO_NO_UPDATE_CHECK") + .with_pty(|mut pty| { + pty.write_line("123 + 456\n"); + pty.expect("579"); + }); + + // the test server will sleep for 95 seconds, so ensure this is less + let elapsed_secs = start_instant.elapsed().as_secs(); + assert!(elapsed_secs < 94, "elapsed_secs: {}", elapsed_secs); +} diff --git a/tests/integration/vendor_tests.rs b/tests/integration/vendor_tests.rs new file mode 100644 index 000000000..c38fb653a --- /dev/null +++ b/tests/integration/vendor_tests.rs @@ -0,0 +1,704 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +use deno_core::serde_json; +use deno_core::serde_json::json; +use pretty_assertions::assert_eq; +use std::fmt::Write as _; +use std::path::PathBuf; +use test_util as util; +use test_util::TempDir; +use util::http_server; +use util::new_deno_dir; +use util::TestContextBuilder; + +#[test] +fn output_dir_exists() { + let t = TempDir::new(); + t.write("mod.ts", ""); + t.create_dir_all("vendor"); + t.write("vendor/mod.ts", ""); + + let deno = util::deno_cmd() + .current_dir(t.path()) + .env("NO_COLOR", "1") + .arg("vendor") + .arg("mod.ts") + .stderr_piped() + .spawn() + .unwrap(); + let output = deno.wait_with_output().unwrap(); + assert_eq!( + String::from_utf8_lossy(&output.stderr).trim(), + concat!( + "error: Output directory was not empty. Please specify an empty ", + "directory or use --force to ignore this error and potentially ", + "overwrite its contents.", + ), + ); + assert!(!output.status.success()); + + // ensure it errors when using the `--output` arg too + let deno = util::deno_cmd() + .current_dir(t.path()) + .env("NO_COLOR", "1") + .arg("vendor") + .arg("--output") + .arg("vendor") + .arg("mod.ts") + .stderr_piped() + .spawn() + .unwrap(); + let output = deno.wait_with_output().unwrap(); + assert_eq!( + String::from_utf8_lossy(&output.stderr).trim(), + concat!( + "error: Output directory was not empty. Please specify an empty ", + "directory or use --force to ignore this error and potentially ", + "overwrite its contents.", + ), + ); + assert!(!output.status.success()); + + // now use `--force` + let status = util::deno_cmd() + .current_dir(t.path()) + .env("NO_COLOR", "1") + .arg("vendor") + .arg("mod.ts") + .arg("--force") + .spawn() + .unwrap() + .wait() + .unwrap(); + assert!(status.success()); +} + +#[test] +fn standard_test() { + let _server = http_server(); + let t = TempDir::new(); + let vendor_dir = t.path().join("vendor2"); + t.write( + "my_app.ts", + "import {Logger} from 'http://localhost:4545/vendor/query_reexport.ts?testing'; new Logger().log('outputted');", + ); + + let deno = util::deno_cmd() + .current_dir(t.path()) + .arg("vendor") + .arg("my_app.ts") + .arg("--output") + .arg("vendor2") + .env("NO_COLOR", "1") + .piped_output() + .spawn() + .unwrap(); + let output = deno.wait_with_output().unwrap(); + assert_eq!( + String::from_utf8_lossy(&output.stderr).trim(), + format!( + concat!( + "Download http://localhost:4545/vendor/query_reexport.ts?testing\n", + "Download http://localhost:4545/vendor/logger.ts?test\n", + "{}", + ), + success_text("2 modules", "vendor2", true), + ) + ); + assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), ""); + assert!(output.status.success()); + + assert!(vendor_dir.exists()); + assert!(!t.path().join("vendor").exists()); + let import_map: serde_json::Value = + serde_json::from_str(&t.read_to_string("vendor2/import_map.json")).unwrap(); + assert_eq!( + import_map, + json!({ + "imports": { + "http://localhost:4545/vendor/query_reexport.ts?testing": "./localhost_4545/vendor/query_reexport.ts", + "http://localhost:4545/": "./localhost_4545/", + }, + "scopes": { + "./localhost_4545/": { + "./localhost_4545/vendor/logger.ts?test": "./localhost_4545/vendor/logger.ts" + } + } + }), + ); + + // try running the output with `--no-remote` + let deno = util::deno_cmd() + .current_dir(t.path()) + .env("NO_COLOR", "1") + .arg("run") + .arg("--no-remote") + .arg("--check") + .arg("--quiet") + .arg("--import-map") + .arg("vendor2/import_map.json") + .arg("my_app.ts") + .piped_output() + .spawn() + .unwrap(); + let output = deno.wait_with_output().unwrap(); + assert_eq!(String::from_utf8_lossy(&output.stderr).trim(), ""); + assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), "outputted"); + assert!(output.status.success()); +} + +#[test] +fn import_map_output_dir() { + let _server = http_server(); + let t = TempDir::new(); + t.write("mod.ts", ""); + t.create_dir_all("vendor"); + t.write( + "vendor/import_map.json", + // will be ignored + "{ \"imports\": { \"https://localhost:4545/\": \"./localhost/\" }}", + ); + t.write( + "deno.json", + "{ \"import_map\": \"./vendor/import_map.json\" }", + ); + t.write( + "my_app.ts", + "import {Logger} from 'http://localhost:4545/vendor/logger.ts'; new Logger().log('outputted');", + ); + + let deno = util::deno_cmd() + .current_dir(t.path()) + .env("NO_COLOR", "1") + .arg("vendor") + .arg("--force") + .arg("--import-map") + .arg("vendor/import_map.json") + .arg("my_app.ts") + .piped_output() + .spawn() + .unwrap(); + let output = deno.wait_with_output().unwrap(); + assert_eq!( + String::from_utf8_lossy(&output.stderr).trim(), + format!( + concat!( + "{}\n", + "Download http://localhost:4545/vendor/logger.ts\n", + "{}\n\n{}", + ), + ignoring_import_map_text(), + vendored_text("1 module", "vendor/"), + success_text_updated_deno_json("vendor/"), + ) + ); + assert!(output.status.success()); +} + +#[test] +fn remote_module_test() { + let _server = http_server(); + let t = TempDir::new(); + let vendor_dir = t.path().join("vendor"); + + let deno = util::deno_cmd() + .current_dir(t.path()) + .env("NO_COLOR", "1") + .arg("vendor") + .arg("http://localhost:4545/vendor/query_reexport.ts") + .piped_output() + .spawn() + .unwrap(); + let output = deno.wait_with_output().unwrap(); + assert_eq!( + String::from_utf8_lossy(&output.stderr).trim(), + format!( + concat!( + "Download http://localhost:4545/vendor/query_reexport.ts\n", + "Download http://localhost:4545/vendor/logger.ts?test\n", + "{}", + ), + success_text("2 modules", "vendor/", true), + ) + ); + assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), ""); + assert!(output.status.success()); + assert!(vendor_dir.exists()); + assert!(vendor_dir + .join("localhost_4545/vendor/query_reexport.ts") + .exists()); + assert!(vendor_dir.join("localhost_4545/vendor/logger.ts").exists()); + let import_map: serde_json::Value = + serde_json::from_str(&t.read_to_string("vendor/import_map.json")).unwrap(); + assert_eq!( + import_map, + json!({ + "imports": { + "http://localhost:4545/": "./localhost_4545/", + }, + "scopes": { + "./localhost_4545/": { + "./localhost_4545/vendor/logger.ts?test": "./localhost_4545/vendor/logger.ts", + } + } + }), + ); +} + +#[test] +fn existing_import_map_no_remote() { + let _server = http_server(); + let t = TempDir::new(); + t.write( + "mod.ts", + "import {Logger} from 'http://localhost:4545/vendor/logger.ts';", + ); + let import_map_filename = "imports2.json"; + let import_map_text = + r#"{ "imports": { "http://localhost:4545/vendor/": "./logger/" } }"#; + t.write(import_map_filename, import_map_text); + t.create_dir_all("logger"); + t.write("logger/logger.ts", "export class Logger {}"); + + let deno = util::deno_cmd() + .current_dir(t.path()) + .env("NO_COLOR", "1") + .arg("vendor") + .arg("mod.ts") + .arg("--import-map") + .arg(import_map_filename) + .stderr_piped() + .spawn() + .unwrap(); + let output = deno.wait_with_output().unwrap(); + assert_eq!( + String::from_utf8_lossy(&output.stderr).trim(), + success_text("0 modules", "vendor/", false) + ); + assert!(output.status.success()); + // it should not have found any remote dependencies because + // the provided import map mapped it to a local directory + assert_eq!(t.read_to_string(import_map_filename), import_map_text); +} + +#[test] +fn existing_import_map_mixed_with_remote() { + let _server = http_server(); + let deno_dir = new_deno_dir(); + let t = TempDir::new(); + t.write( + "mod.ts", + "import {Logger} from 'http://localhost:4545/vendor/logger.ts';", + ); + + let status = util::deno_cmd_with_deno_dir(&deno_dir) + .current_dir(t.path()) + .arg("vendor") + .arg("mod.ts") + .spawn() + .unwrap() + .wait() + .unwrap(); + assert!(status.success()); + + assert_eq!( + t.read_to_string("vendor/import_map.json"), + r#"{ + "imports": { + "http://localhost:4545/": "./localhost_4545/" + } +} +"#, + ); + + // make the import map specific to support vendoring mod.ts in the next step + t.write( + "vendor/import_map.json", + r#"{ + "imports": { + "http://localhost:4545/vendor/logger.ts": "./localhost_4545/vendor/logger.ts" + } +} +"#, + ); + + t.write( + "mod.ts", + concat!( + "import {Logger} from 'http://localhost:4545/vendor/logger.ts';\n", + "import {Logger as OtherLogger} from 'http://localhost:4545/vendor/mod.ts';\n", + ), + ); + + // now vendor with the existing import map in a separate vendor directory + let deno = util::deno_cmd_with_deno_dir(&deno_dir) + .env("NO_COLOR", "1") + .current_dir(t.path()) + .arg("vendor") + .arg("mod.ts") + .arg("--import-map") + .arg("vendor/import_map.json") + .arg("--output") + .arg("vendor2") + .piped_output() + .spawn() + .unwrap(); + let output = deno.wait_with_output().unwrap(); + assert_eq!( + String::from_utf8_lossy(&output.stderr).trim(), + format!( + concat!("Download http://localhost:4545/vendor/mod.ts\n", "{}",), + success_text("1 module", "vendor2", true), + ) + ); + assert!(output.status.success()); + + // tricky scenario here where the output directory now contains a mapping + // back to the previous vendor location + assert_eq!( + t.read_to_string("vendor2/import_map.json"), + r#"{ + "imports": { + "http://localhost:4545/vendor/logger.ts": "../vendor/localhost_4545/vendor/logger.ts", + "http://localhost:4545/": "./localhost_4545/" + }, + "scopes": { + "./localhost_4545/": { + "./localhost_4545/vendor/logger.ts": "../vendor/localhost_4545/vendor/logger.ts" + } + } +} +"#, + ); + + // ensure it runs + let status = util::deno_cmd() + .current_dir(t.path()) + .arg("run") + .arg("--check") + .arg("--no-remote") + .arg("--import-map") + .arg("vendor2/import_map.json") + .arg("mod.ts") + .spawn() + .unwrap() + .wait() + .unwrap(); + assert!(status.success()); +} + +#[test] +fn dynamic_import() { + let _server = http_server(); + let t = TempDir::new(); + t.write( + "mod.ts", + "import {Logger} from 'http://localhost:4545/vendor/dynamic.ts'; new Logger().log('outputted');", + ); + + let status = util::deno_cmd() + .current_dir(t.path()) + .arg("vendor") + .arg("mod.ts") + .spawn() + .unwrap() + .wait() + .unwrap(); + assert!(status.success()); + let import_map: serde_json::Value = + serde_json::from_str(&t.read_to_string("vendor/import_map.json")).unwrap(); + assert_eq!( + import_map, + json!({ + "imports": { + "http://localhost:4545/": "./localhost_4545/", + } + }), + ); + + // try running the output with `--no-remote` + let deno = util::deno_cmd() + .current_dir(t.path()) + .env("NO_COLOR", "1") + .arg("run") + .arg("--allow-read=.") + .arg("--no-remote") + .arg("--check") + .arg("--quiet") + .arg("--import-map") + .arg("vendor/import_map.json") + .arg("mod.ts") + .piped_output() + .spawn() + .unwrap(); + let output = deno.wait_with_output().unwrap(); + assert_eq!(String::from_utf8_lossy(&output.stderr).trim(), ""); + assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), "outputted"); + assert!(output.status.success()); +} + +#[test] +fn dynamic_non_analyzable_import() { + let _server = http_server(); + let t = TempDir::new(); + t.write( + "mod.ts", + "import {Logger} from 'http://localhost:4545/vendor/dynamic_non_analyzable.ts'; new Logger().log('outputted');", + ); + + let deno = util::deno_cmd() + .current_dir(t.path()) + .env("NO_COLOR", "1") + .arg("vendor") + .arg("--reload") + .arg("mod.ts") + .piped_output() + .spawn() + .unwrap(); + let output = deno.wait_with_output().unwrap(); + // todo(https://github.com/denoland/deno_graph/issues/138): it should warn about + // how it couldn't analyze the dynamic import + assert_eq!( + String::from_utf8_lossy(&output.stderr).trim(), + format!( + "Download http://localhost:4545/vendor/dynamic_non_analyzable.ts\n{}", + success_text("1 module", "vendor/", true), + ) + ); + assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), ""); + assert!(output.status.success()); +} + +itest!(dynamic_non_existent { + args: "vendor http://localhost:4545/vendor/dynamic_non_existent.ts", + temp_cwd: true, + exit_code: 0, + http_server: true, + output: "vendor/dynamic_non_existent.ts.out", +}); + +#[test] +fn update_existing_config_test() { + let _server = http_server(); + let t = TempDir::new(); + t.write( + "my_app.ts", + "import {Logger} from 'http://localhost:4545/vendor/logger.ts'; new Logger().log('outputted');", + ); + t.write("deno.json", "{\n}"); + + let deno = util::deno_cmd() + .current_dir(t.path()) + .arg("vendor") + .arg("my_app.ts") + .arg("--output") + .arg("vendor2") + .env("NO_COLOR", "1") + .piped_output() + .spawn() + .unwrap(); + let output = deno.wait_with_output().unwrap(); + assert_eq!( + String::from_utf8_lossy(&output.stderr).trim(), + format!( + "Download http://localhost:4545/vendor/logger.ts\n{}\n\n{}", + vendored_text("1 module", "vendor2"), + success_text_updated_deno_json("vendor2",) + ) + ); + assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), ""); + assert!(output.status.success()); + + // try running the output with `--no-remote` and not specifying a `--vendor` + let deno = util::deno_cmd() + .current_dir(t.path()) + .env("NO_COLOR", "1") + .arg("run") + .arg("--no-remote") + .arg("--check") + .arg("--quiet") + .arg("my_app.ts") + .piped_output() + .spawn() + .unwrap(); + let output = deno.wait_with_output().unwrap(); + assert_eq!(String::from_utf8_lossy(&output.stderr).trim(), ""); + assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), "outputted"); + assert!(output.status.success()); +} + +#[test] +fn vendor_npm_node_specifiers() { + let context = TestContextBuilder::for_npm().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + temp_dir.write( + "my_app.ts", + concat!( + "import { path, getValue, setValue } from 'http://localhost:4545/vendor/npm_and_node_specifier.ts';\n", + "setValue(5);\n", + "console.log(path.isAbsolute(Deno.cwd()), getValue());", + ), + ); + temp_dir.write("deno.json", "{}"); + + let output = context.new_command().args("vendor my_app.ts").run(); + output.assert_matches_text( + format!( + concat!( + "Download http://localhost:4545/vendor/npm_and_node_specifier.ts\n", + "Download http://localhost:4545/npm/registry/@denotest/esm-basic\n", + "Download http://localhost:4545/npm/registry/@denotest/esm-basic/1.0.0.tgz\n", + "{}\n", + "Initialize @denotest/esm-basic@1.0.0\n", + "{}\n\n", + "{}\n", + ), + vendored_text("1 module", "vendor/"), + vendored_npm_package_text("1 npm package"), + success_text_updated_deno_json("vendor/") + ) + ); + let output = context.new_command().args("run -A my_app.ts").run(); + output.assert_matches_text("true 5\n"); + assert!(temp_dir.path().join("node_modules").exists()); + assert!(temp_dir.path().join("deno.lock").exists()); + + // now try re-vendoring with a lockfile + let output = context.new_command().args("vendor --force my_app.ts").run(); + output.assert_matches_text(format!( + "{}\n{}\n\n{}\n", + ignoring_import_map_text(), + vendored_text("1 module", "vendor/"), + success_text_updated_deno_json("vendor/"), + )); + + // delete the node_modules folder + temp_dir.remove_dir_all("node_modules"); + + // vendor with --node-modules-dir=false + let output = context + .new_command() + .args("vendor --node-modules-dir=false --force my_app.ts") + .run(); + output.assert_matches_text(format!( + "{}\n{}\n\n{}\n", + ignoring_import_map_text(), + vendored_text("1 module", "vendor/"), + success_text_updated_deno_json("vendor/") + )); + assert!(!temp_dir.path().join("node_modules").exists()); + + // delete the deno.json + temp_dir.remove_file("deno.json"); + + // vendor with --node-modules-dir + let output = context + .new_command() + .args("vendor --node-modules-dir --force my_app.ts") + .run(); + output.assert_matches_text(format!( + "Initialize @denotest/esm-basic@1.0.0\n{}\n\n{}\n", + vendored_text("1 module", "vendor/"), + use_import_map_text("vendor/") + )); +} + +#[test] +fn vendor_only_npm_specifiers() { + let context = TestContextBuilder::for_npm().use_temp_cwd().build(); + let temp_dir = context.temp_dir(); + temp_dir.write( + "my_app.ts", + concat!( + "import { getValue, setValue } from 'npm:@denotest/esm-basic';\n", + "setValue(5);\n", + "console.log(path.isAbsolute(Deno.cwd()), getValue());", + ), + ); + temp_dir.write("deno.json", "{}"); + + let output = context.new_command().args("vendor my_app.ts").run(); + output.assert_matches_text( + format!( + concat!( + "Download http://localhost:4545/npm/registry/@denotest/esm-basic\n", + "Download http://localhost:4545/npm/registry/@denotest/esm-basic/1.0.0.tgz\n", + "{}\n", + "Initialize @denotest/esm-basic@1.0.0\n", + "{}\n", + ), + vendored_text("0 modules", "vendor/"), + vendored_npm_package_text("1 npm package"), + ) + ); +} + +fn success_text(module_count: &str, dir: &str, has_import_map: bool) -> String { + let mut text = format!("Vendored {module_count} into {dir} directory."); + if has_import_map { + write!(text, "\n\n{}", use_import_map_text(dir)).unwrap(); + } + text +} + +fn use_import_map_text(dir: &str) -> String { + format!( + concat!( + "To use vendored modules, specify the `--import-map {}import_map.json` flag when ", + r#"invoking Deno subcommands or add an `"importMap": ""` "#, + "entry to a deno.json file.", + ), + if dir != "vendor/" { + format!("{}{}", dir.trim_end_matches('/'), if cfg!(windows) { '\\' } else {'/'}) + } else { + dir.to_string() + } + ) +} + +fn vendored_text(module_count: &str, dir: &str) -> String { + format!("Vendored {} into {} directory.", module_count, dir) +} + +fn vendored_npm_package_text(package_count: &str) -> String { + format!( + concat!( + "Vendored {} into node_modules directory. Set `nodeModulesDir: false` ", + "in the Deno configuration file to disable vendoring npm packages in the future.", + ), + package_count + ) +} + +fn success_text_updated_deno_json(dir: &str) -> String { + format!( + concat!( + "Updated your local Deno configuration file with a reference to the ", + "new vendored import map at {}import_map.json. Invoking Deno subcommands will ", + "now automatically resolve using the vendored modules. You may override ", + "this by providing the `--import-map ` flag or by ", + "manually editing your Deno configuration file.", + ), + if dir != "vendor/" { + format!( + "{}{}", + dir.trim_end_matches('/'), + if cfg!(windows) { '\\' } else { '/' } + ) + } else { + dir.to_string() + } + ) +} + +fn ignoring_import_map_text() -> String { + format!( + concat!( + "Ignoring import map. Specifying an import map file ({}) in the deno ", + "vendor output directory is not supported. If you wish to use an ", + "import map while vendoring, please specify one located outside this ", + "directory.", + ), + PathBuf::from("vendor").join("import_map.json").display(), + ) +} diff --git a/tests/integration/watcher_tests.rs b/tests/integration/watcher_tests.rs new file mode 100644 index 000000000..6a2cab08a --- /dev/null +++ b/tests/integration/watcher_tests.rs @@ -0,0 +1,1864 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +use flaky_test::flaky_test; +use test_util as util; +use test_util::assert_contains; +use test_util::TempDir; +use tokio::io::AsyncBufReadExt; +use util::DenoChild; + +use util::assert_not_contains; + +const CLEAR_SCREEN: &str = r#"[2J"#; + +/// Logs to stderr every time next_line() is called +struct LoggingLines +where + R: tokio::io::AsyncBufRead + Unpin, +{ + pub lines: tokio::io::Lines, + pub stream_name: String, +} + +impl LoggingLines +where + R: tokio::io::AsyncBufRead + Unpin, +{ + pub async fn next_line(&mut self) -> tokio::io::Result> { + let line = self.lines.next_line().await; + eprintln!( + "{}: {}", + self.stream_name, + line.as_ref().unwrap().clone().unwrap() + ); + line + } +} + +// Helper function to skip watcher output that contains "Restarting" +// phrase. +async fn skip_restarting_line(stderr_lines: &mut LoggingLines) -> String +where + R: tokio::io::AsyncBufRead + Unpin, +{ + loop { + let msg = next_line(stderr_lines).await.unwrap(); + if !msg.contains("Restarting") { + return msg; + } + } +} + +async fn read_all_lints(stderr_lines: &mut LoggingLines) -> String +where + R: tokio::io::AsyncBufRead + Unpin, +{ + let mut str = String::new(); + while let Some(t) = next_line(stderr_lines).await { + let t = util::strip_ansi_codes(&t); + if t.starts_with("Watcher File change detected") { + continue; + } + if t.starts_with("Watcher") { + break; + } + if t.starts_with("error[") { + str.push_str(&t); + str.push('\n'); + } + } + str +} + +async fn next_line(lines: &mut LoggingLines) -> Option +where + R: tokio::io::AsyncBufRead + Unpin, +{ + let timeout = tokio::time::Duration::from_secs(60); + + tokio::time::timeout(timeout, lines.next_line()) + .await + .unwrap_or_else(|_| { + panic!( + "Output did not contain a new line after {} seconds", + timeout.as_secs() + ) + }) + .unwrap() +} + +/// Returns the matched line or None if there are no more lines in this stream +async fn wait_for( + condition: impl Fn(&str) -> bool, + lines: &mut LoggingLines, +) -> Option +where + R: tokio::io::AsyncBufRead + Unpin, +{ + while let Some(line) = lines.next_line().await.unwrap() { + if condition(line.as_str()) { + return Some(line); + } + } + + None +} + +async fn wait_contains(s: &str, lines: &mut LoggingLines) -> String +where + R: tokio::io::AsyncBufRead + Unpin, +{ + let timeout = tokio::time::Duration::from_secs(60); + + tokio::time::timeout(timeout, wait_for(|line| line.contains(s), lines)) + .await + .unwrap_or_else(|_| { + panic!( + "Output did not contain \"{}\" after {} seconds", + s, + timeout.as_secs() + ) + }) + .unwrap_or_else(|| panic!("Output ended without containing \"{}\"", s)) +} + +/// Before test cases touch files, they need to wait for the watcher to be +/// ready. Waiting for subcommand output is insufficient. +/// The file watcher takes a moment to start watching files due to +/// asynchronicity. It is possible for the watched subcommand to finish before +/// any files are being watched. +/// deno must be running with --log-level=debug +/// file_name should be the file name and, optionally, extension. file_name +/// may not be a full path, as it is not portable. +async fn wait_for_watcher( + file_name: &str, + stderr_lines: &mut LoggingLines, +) -> String +where + R: tokio::io::AsyncBufRead + Unpin, +{ + let timeout = tokio::time::Duration::from_secs(60); + + tokio::time::timeout( + timeout, + wait_for( + |line| line.contains("Watching paths") && line.contains(file_name), + stderr_lines, + ), + ) + .await + .unwrap_or_else(|_| { + panic!( + "Watcher did not start for file \"{}\" after {} seconds", + file_name, + timeout.as_secs() + ) + }) + .unwrap_or_else(|| { + panic!( + "Output ended without before the watcher started watching file \"{}\"", + file_name + ) + }) +} + +fn check_alive_then_kill(mut child: DenoChild) { + assert!(child.try_wait().unwrap().is_none()); + child.kill().unwrap(); +} + +fn child_lines( + child: &mut std::process::Child, +) -> ( + LoggingLines>, + LoggingLines>, +) { + let stdout_lines = LoggingLines { + lines: tokio::io::BufReader::new( + tokio::process::ChildStdout::from_std(child.stdout.take().unwrap()) + .unwrap(), + ) + .lines(), + stream_name: "STDOUT".to_string(), + }; + let stderr_lines = LoggingLines { + lines: tokio::io::BufReader::new( + tokio::process::ChildStderr::from_std(child.stderr.take().unwrap()) + .unwrap(), + ) + .lines(), + stream_name: "STDERR".to_string(), + }; + (stdout_lines, stderr_lines) +} + +#[tokio::test] +async fn lint_watch_test() { + let t = TempDir::new(); + let badly_linted_original = + util::testdata_path().join("lint/watch/badly_linted.js"); + let badly_linted_output = + util::testdata_path().join("lint/watch/badly_linted.js.out"); + let badly_linted_fixed1 = + util::testdata_path().join("lint/watch/badly_linted_fixed1.js"); + let badly_linted_fixed1_output = + util::testdata_path().join("lint/watch/badly_linted_fixed1.js.out"); + let badly_linted_fixed2 = + util::testdata_path().join("lint/watch/badly_linted_fixed2.js"); + let badly_linted_fixed2_output = + util::testdata_path().join("lint/watch/badly_linted_fixed2.js.out"); + let badly_linted = t.path().join("badly_linted.js"); + + std::fs::copy(badly_linted_original, &badly_linted).unwrap(); + + let mut child = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("lint") + .arg(&badly_linted) + .arg("--watch") + .piped_output() + .spawn() + .unwrap(); + let (_stdout_lines, mut stderr_lines) = child_lines(&mut child); + let next_line = next_line(&mut stderr_lines).await.unwrap(); + + assert_contains!(&next_line, "Lint started"); + let mut output = read_all_lints(&mut stderr_lines).await; + let expected = std::fs::read_to_string(badly_linted_output).unwrap(); + assert_eq!(output, expected); + + // Change content of the file again to be badly-linted + std::fs::copy(badly_linted_fixed1, &badly_linted).unwrap(); + std::thread::sleep(std::time::Duration::from_secs(1)); + + output = read_all_lints(&mut stderr_lines).await; + let expected = std::fs::read_to_string(badly_linted_fixed1_output).unwrap(); + assert_eq!(output, expected); + + // Change content of the file again to be badly-linted + std::fs::copy(badly_linted_fixed2, &badly_linted).unwrap(); + + output = read_all_lints(&mut stderr_lines).await; + let expected = std::fs::read_to_string(badly_linted_fixed2_output).unwrap(); + assert_eq!(output, expected); + + // the watcher process is still alive + assert!(child.try_wait().unwrap().is_none()); + + child.kill().unwrap(); + drop(t); +} + +#[tokio::test] +async fn lint_watch_without_args_test() { + let t = TempDir::new(); + let badly_linted_original = + util::testdata_path().join("lint/watch/badly_linted.js"); + let badly_linted_output = + util::testdata_path().join("lint/watch/badly_linted.js.out"); + let badly_linted_fixed1 = + util::testdata_path().join("lint/watch/badly_linted_fixed1.js"); + let badly_linted_fixed1_output = + util::testdata_path().join("lint/watch/badly_linted_fixed1.js.out"); + let badly_linted_fixed2 = + util::testdata_path().join("lint/watch/badly_linted_fixed2.js"); + let badly_linted_fixed2_output = + util::testdata_path().join("lint/watch/badly_linted_fixed2.js.out"); + let badly_linted = t.path().join("badly_linted.js"); + + std::fs::copy(badly_linted_original, &badly_linted).unwrap(); + + let mut child = util::deno_cmd() + .current_dir(t.path()) + .arg("lint") + .arg("--watch") + .piped_output() + .spawn() + .unwrap(); + let (_stdout_lines, mut stderr_lines) = child_lines(&mut child); + + let next_line = next_line(&mut stderr_lines).await.unwrap(); + assert_contains!(&next_line, "Lint started"); + let mut output = read_all_lints(&mut stderr_lines).await; + let expected = std::fs::read_to_string(badly_linted_output).unwrap(); + assert_eq!(output, expected); + + // Change content of the file again to be badly-linted + std::fs::copy(badly_linted_fixed1, &badly_linted).unwrap(); + + output = read_all_lints(&mut stderr_lines).await; + let expected = std::fs::read_to_string(badly_linted_fixed1_output).unwrap(); + assert_eq!(output, expected); + + // Change content of the file again to be badly-linted + std::fs::copy(badly_linted_fixed2, &badly_linted).unwrap(); + std::thread::sleep(std::time::Duration::from_secs(1)); + + output = read_all_lints(&mut stderr_lines).await; + let expected = std::fs::read_to_string(badly_linted_fixed2_output).unwrap(); + assert_eq!(output, expected); + + // the watcher process is still alive + assert!(child.try_wait().unwrap().is_none()); + + child.kill().unwrap(); + drop(t); +} + +#[tokio::test] +async fn lint_all_files_on_each_change_test() { + let t = TempDir::new(); + let badly_linted_fixed0 = + util::testdata_path().join("lint/watch/badly_linted.js"); + let badly_linted_fixed1 = + util::testdata_path().join("lint/watch/badly_linted_fixed1.js"); + let badly_linted_fixed2 = + util::testdata_path().join("lint/watch/badly_linted_fixed2.js"); + + let badly_linted_1 = t.path().join("badly_linted_1.js"); + let badly_linted_2 = t.path().join("badly_linted_2.js"); + std::fs::copy(badly_linted_fixed0, badly_linted_1).unwrap(); + std::fs::copy(badly_linted_fixed1, &badly_linted_2).unwrap(); + + let mut child = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("lint") + .arg(t.path()) + .arg("--watch") + .arg("--unstable") + .piped_output() + .spawn() + .unwrap(); + let (_stdout_lines, mut stderr_lines) = child_lines(&mut child); + + assert_contains!( + wait_contains("Checked", &mut stderr_lines).await, + "Checked 2 files" + ); + + std::fs::copy(badly_linted_fixed2, badly_linted_2).unwrap(); + + assert_contains!( + wait_contains("Checked", &mut stderr_lines).await, + "Checked 2 files" + ); + + assert!(child.try_wait().unwrap().is_none()); + + child.kill().unwrap(); + drop(t); +} + +#[tokio::test] +async fn fmt_watch_test() { + let fmt_testdata_path = util::testdata_path().join("fmt"); + let t = TempDir::new(); + let fixed = fmt_testdata_path.join("badly_formatted_fixed.js"); + let badly_formatted_original = fmt_testdata_path.join("badly_formatted.mjs"); + let badly_formatted = t.path().join("badly_formatted.js"); + std::fs::copy(&badly_formatted_original, &badly_formatted).unwrap(); + + let mut child = util::deno_cmd() + .current_dir(&fmt_testdata_path) + .arg("fmt") + .arg(&badly_formatted) + .arg("--watch") + .piped_output() + .spawn() + .unwrap(); + let (_stdout_lines, mut stderr_lines) = child_lines(&mut child); + + let next_line = next_line(&mut stderr_lines).await.unwrap(); + assert_contains!(&next_line, "Fmt started"); + assert_contains!( + skip_restarting_line(&mut stderr_lines).await, + "badly_formatted.js" + ); + assert_contains!( + wait_contains("Checked", &mut stderr_lines).await, + "Checked 1 file" + ); + wait_contains("Fmt finished", &mut stderr_lines).await; + + let expected = std::fs::read_to_string(fixed.clone()).unwrap(); + let actual = std::fs::read_to_string(badly_formatted.clone()).unwrap(); + assert_eq!(actual, expected); + + // Change content of the file again to be badly formatted + std::fs::copy(&badly_formatted_original, &badly_formatted).unwrap(); + + assert_contains!( + skip_restarting_line(&mut stderr_lines).await, + "badly_formatted.js" + ); + assert_contains!( + wait_contains("Checked", &mut stderr_lines).await, + "Checked 1 file" + ); + wait_contains("Fmt finished", &mut stderr_lines).await; + + // Check if file has been automatically formatted by watcher + let expected = std::fs::read_to_string(fixed).unwrap(); + let actual = std::fs::read_to_string(badly_formatted).unwrap(); + assert_eq!(actual, expected); + check_alive_then_kill(child); +} + +#[tokio::test] +async fn fmt_watch_without_args_test() { + let fmt_testdata_path = util::testdata_path().join("fmt"); + let t = TempDir::new(); + let fixed = fmt_testdata_path.join("badly_formatted_fixed.js"); + let badly_formatted_original = fmt_testdata_path.join("badly_formatted.mjs"); + let badly_formatted = t.path().join("badly_formatted.js"); + std::fs::copy(&badly_formatted_original, &badly_formatted).unwrap(); + + let mut child = util::deno_cmd() + .current_dir(t.path()) + .arg("fmt") + .arg("--watch") + .piped_output() + .spawn() + .unwrap(); + let (_stdout_lines, mut stderr_lines) = child_lines(&mut child); + + let next_line = next_line(&mut stderr_lines).await.unwrap(); + assert_contains!(&next_line, "Fmt started"); + assert_contains!( + skip_restarting_line(&mut stderr_lines).await, + "badly_formatted.js" + ); + assert_contains!( + wait_contains("Checked", &mut stderr_lines).await, + "Checked 1 file" + ); + + let expected = std::fs::read_to_string(fixed.clone()).unwrap(); + let actual = std::fs::read_to_string(badly_formatted.clone()).unwrap(); + assert_eq!(actual, expected); + + // Change content of the file again to be badly formatted + std::fs::copy(&badly_formatted_original, &badly_formatted).unwrap(); + assert_contains!( + skip_restarting_line(&mut stderr_lines).await, + "badly_formatted.js" + ); + assert_contains!( + wait_contains("Checked", &mut stderr_lines).await, + "Checked 1 file" + ); + + // Check if file has been automatically formatted by watcher + let expected = std::fs::read_to_string(fixed).unwrap(); + let actual = std::fs::read_to_string(badly_formatted).unwrap(); + assert_eq!(actual, expected); + check_alive_then_kill(child); +} + +#[ignore = "https://github.com/denoland/deno/issues/19629"] +#[tokio::test] +async fn fmt_check_all_files_on_each_change_test() { + let t = TempDir::new(); + let fmt_testdata_path = util::testdata_path().join("fmt"); + let badly_formatted_original = fmt_testdata_path.join("badly_formatted.mjs"); + let badly_formatted_1 = t.path().join("badly_formatted_1.js"); + let badly_formatted_2 = t.path().join("badly_formatted_2.js"); + std::fs::copy(&badly_formatted_original, &badly_formatted_1).unwrap(); + std::fs::copy(&badly_formatted_original, badly_formatted_2).unwrap(); + + let mut child = util::deno_cmd() + .current_dir(&fmt_testdata_path) + .arg("fmt") + .arg(t.path()) + .arg("--watch") + .arg("--check") + .arg("--unstable") + .piped_output() + .spawn() + .unwrap(); + let (_stdout_lines, mut stderr_lines) = child_lines(&mut child); + + assert_contains!( + wait_contains("error", &mut stderr_lines).await, + "Found 2 not formatted files in 2 files" + ); + + // Change content of the file again to be badly formatted + std::fs::copy(&badly_formatted_original, &badly_formatted_1).unwrap(); + + assert_contains!( + wait_contains("error", &mut stderr_lines).await, + "Found 2 not formatted files in 2 files" + ); + + check_alive_then_kill(child); +} + +#[tokio::test] +async fn bundle_js_watch() { + use std::path::PathBuf; + // Test strategy extends this of test bundle_js by adding watcher + let t = TempDir::new(); + let file_to_watch = t.path().join("file_to_watch.ts"); + file_to_watch.write("console.log('Hello world');"); + assert!(file_to_watch.is_file()); + let t = TempDir::new(); + let bundle = t.path().join("mod6.bundle.js"); + let mut deno = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("bundle") + .arg(&file_to_watch) + .arg(&bundle) + .arg("--watch") + .env("NO_COLOR", "1") + .piped_output() + .spawn() + .unwrap(); + + let (_stdout_lines, mut stderr_lines) = child_lines(&mut deno); + + assert_contains!(next_line(&mut stderr_lines).await.unwrap(), "Warning"); + assert_contains!(next_line(&mut stderr_lines).await.unwrap(), "deno_emit"); + assert_contains!( + next_line(&mut stderr_lines).await.unwrap(), + "Bundle started" + ); + let line = next_line(&mut stderr_lines).await.unwrap(); + assert_contains!(line, "file_to_watch.ts"); + assert_contains!(line, "Check"); + assert_contains!(next_line(&mut stderr_lines).await.unwrap(), "Bundle"); + assert_contains!( + next_line(&mut stderr_lines).await.unwrap(), + "mod6.bundle.js" + ); + let file = PathBuf::from(&bundle); + assert!(file.is_file()); + + wait_contains("Bundle finished", &mut stderr_lines).await; + + file_to_watch.write("console.log('Hello world2');"); + + let line = next_line(&mut stderr_lines).await.unwrap(); + // Should not clear screen, as we are in non-TTY environment + assert_not_contains!(&line, CLEAR_SCREEN); + assert_contains!(&line, "File change detected!"); + assert_contains!(next_line(&mut stderr_lines).await.unwrap(), "Check"); + assert_contains!( + next_line(&mut stderr_lines).await.unwrap(), + "file_to_watch.ts" + ); + assert_contains!( + next_line(&mut stderr_lines).await.unwrap(), + "mod6.bundle.js" + ); + let file = PathBuf::from(&bundle); + assert!(file.is_file()); + wait_contains("Bundle finished", &mut stderr_lines).await; + + // Confirm that the watcher keeps on working even if the file is updated and has invalid syntax + file_to_watch.write("syntax error ^^"); + + assert_contains!( + next_line(&mut stderr_lines).await.unwrap(), + "File change detected!" + ); + assert_contains!(next_line(&mut stderr_lines).await.unwrap(), "error: "); + wait_contains("Bundle failed", &mut stderr_lines).await; + check_alive_then_kill(deno); +} + +/// Confirm that the watcher continues to work even if module resolution fails at the *first* attempt +#[tokio::test] +async fn bundle_watch_not_exit() { + let t = TempDir::new(); + let file_to_watch = t.path().join("file_to_watch.ts"); + file_to_watch.write("syntax error ^^"); + let target_file = t.path().join("target.js"); + + let mut deno = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("bundle") + .arg(&file_to_watch) + .arg(&target_file) + .arg("--watch") + .env("NO_COLOR", "1") + .piped_output() + .spawn() + .unwrap(); + let (_stdout_lines, mut stderr_lines) = child_lines(&mut deno); + + assert_contains!(next_line(&mut stderr_lines).await.unwrap(), "Warning"); + assert_contains!(next_line(&mut stderr_lines).await.unwrap(), "deno_emit"); + assert_contains!( + next_line(&mut stderr_lines).await.unwrap(), + "Bundle started" + ); + assert_contains!(next_line(&mut stderr_lines).await.unwrap(), "error:"); + assert_eq!(next_line(&mut stderr_lines).await.unwrap(), ""); + assert_eq!( + next_line(&mut stderr_lines).await.unwrap(), + " syntax error ^^" + ); + assert_eq!( + next_line(&mut stderr_lines).await.unwrap(), + " ~~~~~" + ); + assert_contains!( + next_line(&mut stderr_lines).await.unwrap(), + "Bundle failed" + ); + // the target file hasn't been created yet + assert!(!target_file.is_file()); + + // Make sure the watcher actually restarts and works fine with the proper syntax + file_to_watch.write("console.log(42);"); + + assert_contains!( + next_line(&mut stderr_lines).await.unwrap(), + "File change detected" + ); + assert_contains!(next_line(&mut stderr_lines).await.unwrap(), "Check"); + let line = next_line(&mut stderr_lines).await.unwrap(); + // Should not clear screen, as we are in non-TTY environment + assert_not_contains!(&line, CLEAR_SCREEN); + assert_contains!(line, "file_to_watch.ts"); + assert_contains!(next_line(&mut stderr_lines).await.unwrap(), "target.js"); + + wait_contains("Bundle finished", &mut stderr_lines).await; + + // bundled file is created + assert!(target_file.is_file()); + check_alive_then_kill(deno); +} + +#[tokio::test] +async fn run_watch_no_dynamic() { + let t = TempDir::new(); + let file_to_watch = t.path().join("file_to_watch.js"); + file_to_watch.write("console.log('Hello world');"); + + let mut child = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg("--watch") + .arg("--unstable") + .arg("-L") + .arg("debug") + .arg(&file_to_watch) + .env("NO_COLOR", "1") + .piped_output() + .spawn() + .unwrap(); + let (mut stdout_lines, mut stderr_lines) = child_lines(&mut child); + + wait_contains("Hello world", &mut stdout_lines).await; + wait_for_watcher("file_to_watch.js", &mut stderr_lines).await; + + // Change content of the file + file_to_watch.write("console.log('Hello world2');"); + + wait_contains("Restarting", &mut stderr_lines).await; + wait_contains("Hello world2", &mut stdout_lines).await; + wait_for_watcher("file_to_watch.js", &mut stderr_lines).await; + + // Add dependency + let another_file = t.path().join("another_file.js"); + another_file.write("export const foo = 0;"); + file_to_watch + .write("import { foo } from './another_file.js'; console.log(foo);"); + + wait_contains("Restarting", &mut stderr_lines).await; + wait_contains("0", &mut stdout_lines).await; + wait_for_watcher("another_file.js", &mut stderr_lines).await; + + // Confirm that restarting occurs when a new file is updated + another_file.write("export const foo = 42;"); + + wait_contains("Restarting", &mut stderr_lines).await; + wait_contains("42", &mut stdout_lines).await; + wait_for_watcher("file_to_watch.js", &mut stderr_lines).await; + + // Confirm that the watcher keeps on working even if the file is updated and has invalid syntax + file_to_watch.write("syntax error ^^"); + + wait_contains("Restarting", &mut stderr_lines).await; + wait_contains("error:", &mut stderr_lines).await; + wait_for_watcher("file_to_watch.js", &mut stderr_lines).await; + + // Then restore the file + file_to_watch + .write("import { foo } from './another_file.js'; console.log(foo);"); + + wait_contains("Restarting", &mut stderr_lines).await; + wait_contains("42", &mut stdout_lines).await; + wait_for_watcher("another_file.js", &mut stderr_lines).await; + + // Update the content of the imported file with invalid syntax + another_file.write("syntax error ^^"); + + wait_contains("Restarting", &mut stderr_lines).await; + wait_contains("error:", &mut stderr_lines).await; + wait_for_watcher("another_file.js", &mut stderr_lines).await; + + // Modify the imported file and make sure that restarting occurs + another_file.write("export const foo = 'modified!';"); + + wait_contains("Restarting", &mut stderr_lines).await; + wait_contains("modified!", &mut stdout_lines).await; + wait_contains("Watching paths", &mut stderr_lines).await; + check_alive_then_kill(child); +} + +// TODO(bartlomieju): this test became flaky on macOS runner; it is unclear +// if that's because of a bug in code or the runner itself. We should reenable +// it once we upgrade to XL runners for macOS. +#[cfg(not(target_os = "macos"))] +#[tokio::test] +async fn run_watch_external_watch_files() { + let t = TempDir::new(); + let file_to_watch = t.path().join("file_to_watch.js"); + file_to_watch.write("console.log('Hello world');"); + + let external_file_to_watch = t.path().join("external_file_to_watch.txt"); + external_file_to_watch.write("Hello world"); + + let mut watch_arg = "--watch=".to_owned(); + let external_file_to_watch_str = external_file_to_watch.to_string(); + watch_arg.push_str(&external_file_to_watch_str); + + let mut child = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg(watch_arg) + .arg("-L") + .arg("debug") + .arg("--unstable") + .arg(&file_to_watch) + .env("NO_COLOR", "1") + .piped_output() + .spawn() + .unwrap(); + let (mut stdout_lines, mut stderr_lines) = child_lines(&mut child); + wait_contains("Process started", &mut stderr_lines).await; + wait_contains("Hello world", &mut stdout_lines).await; + wait_for_watcher("external_file_to_watch.txt", &mut stderr_lines).await; + + // Change content of the external file + external_file_to_watch.write("Hello world2"); + wait_contains("Restarting", &mut stderr_lines).await; + wait_contains("Process finished", &mut stderr_lines).await; + + // Again (https://github.com/denoland/deno/issues/17584) + external_file_to_watch.write("Hello world3"); + wait_contains("Restarting", &mut stderr_lines).await; + wait_contains("Process finished", &mut stderr_lines).await; + + check_alive_then_kill(child); +} + +#[tokio::test] +async fn run_watch_load_unload_events() { + let t = TempDir::new(); + let file_to_watch = t.path().join("file_to_watch.js"); + file_to_watch.write( + r#" + setInterval(() => {}, 0); + window.addEventListener("load", () => { + console.log("load"); + }); + + window.addEventListener("unload", () => { + console.log("unload"); + }); + "#, + ); + + let mut child = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg("--watch") + .arg("--unstable") + .arg("-L") + .arg("debug") + .arg(&file_to_watch) + .env("NO_COLOR", "1") + .piped_output() + .spawn() + .unwrap(); + let (mut stdout_lines, mut stderr_lines) = child_lines(&mut child); + + // Wait for the first load event to fire + wait_contains("load", &mut stdout_lines).await; + wait_for_watcher("file_to_watch.js", &mut stderr_lines).await; + + // Change content of the file, this time without an interval to keep it alive. + file_to_watch.write( + r#" + window.addEventListener("load", () => { + console.log("load"); + }); + + window.addEventListener("unload", () => { + console.log("unload"); + }); + "#, + ); + + // Wait for the restart + wait_contains("Restarting", &mut stderr_lines).await; + + // Confirm that the unload event was dispatched from the first run + wait_contains("unload", &mut stdout_lines).await; + + // Followed by the load event of the second run + wait_contains("load", &mut stdout_lines).await; + + // Which is then unloaded as there is nothing keeping it alive. + wait_contains("unload", &mut stdout_lines).await; + check_alive_then_kill(child); +} + +/// Confirm that the watcher continues to work even if module resolution fails at the *first* attempt +#[tokio::test] +async fn run_watch_not_exit() { + let t = TempDir::new(); + let file_to_watch = t.path().join("file_to_watch.js"); + file_to_watch.write("syntax error ^^"); + + let mut child = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg("--watch") + .arg("--unstable") + .arg("-L") + .arg("debug") + .arg(&file_to_watch) + .env("NO_COLOR", "1") + .piped_output() + .spawn() + .unwrap(); + let (mut stdout_lines, mut stderr_lines) = child_lines(&mut child); + + wait_contains("Process started", &mut stderr_lines).await; + wait_contains("error:", &mut stderr_lines).await; + wait_for_watcher("file_to_watch.js", &mut stderr_lines).await; + + // Make sure the watcher actually restarts and works fine with the proper syntax + file_to_watch.write("console.log(42);"); + + wait_contains("Restarting", &mut stderr_lines).await; + wait_contains("42", &mut stdout_lines).await; + wait_contains("Process finished", &mut stderr_lines).await; + check_alive_then_kill(child); +} + +#[tokio::test] +async fn run_watch_with_import_map_and_relative_paths() { + fn create_relative_tmp_file( + directory: &TempDir, + filename: &'static str, + filecontent: &'static str, + ) -> std::path::PathBuf { + let absolute_path = directory.path().join(filename); + absolute_path.write(filecontent); + let relative_path = absolute_path + .as_path() + .strip_prefix(directory.path()) + .unwrap() + .to_owned(); + assert!(relative_path.is_relative()); + relative_path + } + + let temp_directory = TempDir::new(); + let file_to_watch = create_relative_tmp_file( + &temp_directory, + "file_to_watch.js", + "console.log('Hello world');", + ); + let import_map_path = create_relative_tmp_file( + &temp_directory, + "import_map.json", + "{\"imports\": {}}", + ); + + let mut child = util::deno_cmd() + .current_dir(temp_directory.path()) + .arg("run") + .arg("--watch") + .arg("--import-map") + .arg(&import_map_path) + .arg(&file_to_watch) + .env("NO_COLOR", "1") + .piped_output() + .spawn() + .unwrap(); + let (mut stdout_lines, mut stderr_lines) = child_lines(&mut child); + let line = next_line(&mut stderr_lines).await.unwrap(); + assert_contains!(&line, "Process started"); + assert_contains!( + next_line(&mut stderr_lines).await.unwrap(), + "Process finished" + ); + assert_contains!(next_line(&mut stdout_lines).await.unwrap(), "Hello world"); + + check_alive_then_kill(child); +} + +#[tokio::test] +async fn run_watch_with_ext_flag() { + let t = TempDir::new(); + let file_to_watch = t.path().join("file_to_watch"); + file_to_watch.write("interface I{}; console.log(42);"); + + let mut child = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg("--watch") + .arg("--log-level") + .arg("debug") + .arg("--ext") + .arg("ts") + .arg(&file_to_watch) + .env("NO_COLOR", "1") + .piped_output() + .spawn() + .unwrap(); + let (mut stdout_lines, mut stderr_lines) = child_lines(&mut child); + + wait_contains("42", &mut stdout_lines).await; + + // Make sure the watcher actually restarts and works fine with the proper language + wait_for_watcher("file_to_watch", &mut stderr_lines).await; + wait_contains("Process finished", &mut stderr_lines).await; + + file_to_watch.write("type Bear = 'polar' | 'grizzly'; console.log(123);"); + + wait_contains("Restarting!", &mut stderr_lines).await; + wait_contains("123", &mut stdout_lines).await; + wait_contains("Process finished", &mut stderr_lines).await; + + check_alive_then_kill(child); +} + +#[tokio::test] +async fn run_watch_error_messages() { + let t = TempDir::new(); + let file_to_watch = t.path().join("file_to_watch.js"); + file_to_watch + .write("throw SyntaxError(`outer`, {cause: TypeError(`inner`)})"); + + let mut child = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg("--watch") + .arg(&file_to_watch) + .env("NO_COLOR", "1") + .piped_output() + .spawn() + .unwrap(); + let (_, mut stderr_lines) = child_lines(&mut child); + + wait_contains("Process started", &mut stderr_lines).await; + wait_contains( + "error: Uncaught (in promise) SyntaxError: outer", + &mut stderr_lines, + ) + .await; + wait_contains("Caused by: TypeError: inner", &mut stderr_lines).await; + wait_contains("Process failed", &mut stderr_lines).await; + + check_alive_then_kill(child); +} + +#[tokio::test] +async fn test_watch_basic() { + let t = TempDir::new(); + + let mut child = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("test") + .arg("--watch") + .arg("--unstable") + .arg("--no-check") + .arg(t.path()) + .env("NO_COLOR", "1") + .piped_output() + .spawn() + .unwrap(); + let (mut stdout_lines, mut stderr_lines) = child_lines(&mut child); + + assert_eq!(next_line(&mut stdout_lines).await.unwrap(), ""); + assert_contains!( + next_line(&mut stdout_lines).await.unwrap(), + "0 passed | 0 failed" + ); + wait_contains("Test finished", &mut stderr_lines).await; + + let foo_file = t.path().join("foo.js"); + let bar_file = t.path().join("bar.js"); + let foo_test = t.path().join("foo_test.js"); + let bar_test = t.path().join("bar_test.js"); + foo_file.write("export default function foo() { 1 + 1 }"); + bar_file.write("export default function bar() { 2 + 2 }"); + foo_test.write("import foo from './foo.js'; Deno.test('foo', foo);"); + bar_test.write("import bar from './bar.js'; Deno.test('bar', bar);"); + + assert_eq!(next_line(&mut stdout_lines).await.unwrap(), ""); + assert_contains!( + next_line(&mut stdout_lines).await.unwrap(), + "running 1 test" + ); + assert_contains!(next_line(&mut stdout_lines).await.unwrap(), "foo", "bar"); + assert_contains!( + next_line(&mut stdout_lines).await.unwrap(), + "running 1 test" + ); + assert_contains!(next_line(&mut stdout_lines).await.unwrap(), "foo", "bar"); + next_line(&mut stdout_lines).await; + next_line(&mut stdout_lines).await; + next_line(&mut stdout_lines).await; + wait_contains("Test finished", &mut stderr_lines).await; + + // Change content of the file + foo_test.write("import foo from './foo.js'; Deno.test('foobar', foo);"); + + assert_contains!(next_line(&mut stderr_lines).await.unwrap(), "Restarting"); + assert_contains!( + next_line(&mut stdout_lines).await.unwrap(), + "running 1 test" + ); + assert_contains!(next_line(&mut stdout_lines).await.unwrap(), "foobar"); + next_line(&mut stdout_lines).await; + next_line(&mut stdout_lines).await; + next_line(&mut stdout_lines).await; + wait_contains("Test finished", &mut stderr_lines).await; + + // Add test + let another_test = t.path().join("new_test.js"); + another_test.write("Deno.test('another one', () => 3 + 3)"); + assert_contains!(next_line(&mut stderr_lines).await.unwrap(), "Restarting"); + assert_contains!( + next_line(&mut stdout_lines).await.unwrap(), + "running 1 test" + ); + assert_contains!(next_line(&mut stdout_lines).await.unwrap(), "another one"); + next_line(&mut stdout_lines).await; + next_line(&mut stdout_lines).await; + next_line(&mut stdout_lines).await; + wait_contains("Test finished", &mut stderr_lines).await; + + // Confirm that restarting occurs when a new file is updated + another_test.write("Deno.test('another one', () => 3 + 3); Deno.test('another another one', () => 4 + 4)"); + assert_contains!(next_line(&mut stderr_lines).await.unwrap(), "Restarting"); + assert_contains!( + next_line(&mut stdout_lines).await.unwrap(), + "running 2 tests" + ); + assert_contains!(next_line(&mut stdout_lines).await.unwrap(), "another one"); + assert_contains!( + next_line(&mut stdout_lines).await.unwrap(), + "another another one" + ); + next_line(&mut stdout_lines).await; + next_line(&mut stdout_lines).await; + next_line(&mut stdout_lines).await; + wait_contains("Test finished", &mut stderr_lines).await; + + // Confirm that the watcher keeps on working even if the file is updated and has invalid syntax + another_test.write("syntax error ^^"); + assert_contains!(next_line(&mut stderr_lines).await.unwrap(), "Restarting"); + assert_contains!(next_line(&mut stderr_lines).await.unwrap(), "error:"); + assert_eq!(next_line(&mut stderr_lines).await.unwrap(), ""); + assert_eq!( + next_line(&mut stderr_lines).await.unwrap(), + " syntax error ^^" + ); + assert_eq!( + next_line(&mut stderr_lines).await.unwrap(), + " ~~~~~" + ); + assert_contains!(next_line(&mut stderr_lines).await.unwrap(), "Test failed"); + + // Then restore the file + another_test.write("Deno.test('another one', () => 3 + 3)"); + assert_contains!(next_line(&mut stderr_lines).await.unwrap(), "Restarting"); + assert_contains!( + next_line(&mut stdout_lines).await.unwrap(), + "running 1 test" + ); + assert_contains!(next_line(&mut stdout_lines).await.unwrap(), "another one"); + next_line(&mut stdout_lines).await; + next_line(&mut stdout_lines).await; + next_line(&mut stdout_lines).await; + wait_contains("Test finished", &mut stderr_lines).await; + + // Confirm that the watcher keeps on working even if the file is updated and the test fails + // This also confirms that it restarts when dependencies change + foo_file + .write("export default function foo() { throw new Error('Whoops!'); }"); + assert_contains!(next_line(&mut stderr_lines).await.unwrap(), "Restarting"); + assert_contains!( + next_line(&mut stdout_lines).await.unwrap(), + "running 1 test" + ); + assert_contains!(next_line(&mut stdout_lines).await.unwrap(), "FAILED"); + wait_contains("FAILED", &mut stdout_lines).await; + next_line(&mut stdout_lines).await; + wait_contains("Test failed", &mut stderr_lines).await; + + // Then restore the file + foo_file.write("export default function foo() { 1 + 1 }"); + assert_contains!(next_line(&mut stderr_lines).await.unwrap(), "Restarting"); + assert_contains!( + next_line(&mut stdout_lines).await.unwrap(), + "running 1 test" + ); + assert_contains!(next_line(&mut stdout_lines).await.unwrap(), "foo"); + next_line(&mut stdout_lines).await; + next_line(&mut stdout_lines).await; + next_line(&mut stdout_lines).await; + wait_contains("Test finished", &mut stderr_lines).await; + + // Test that circular dependencies work fine + foo_file.write("import './bar.js'; export default function foo() { 1 + 1 }"); + bar_file.write("import './foo.js'; export default function bar() { 2 + 2 }"); + check_alive_then_kill(child); +} + +#[flaky_test] +#[tokio::main] +async fn test_watch_doc() { + let t = TempDir::new(); + + let mut child = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("test") + .arg("--watch") + .arg("--doc") + .arg("--unstable") + .arg(t.path()) + .env("NO_COLOR", "1") + .piped_output() + .spawn() + .unwrap(); + let (mut stdout_lines, mut stderr_lines) = child_lines(&mut child); + + assert_eq!(next_line(&mut stdout_lines).await.unwrap(), ""); + assert_contains!( + next_line(&mut stdout_lines).await.unwrap(), + "0 passed | 0 failed" + ); + wait_contains("Test finished", &mut stderr_lines).await; + + let foo_file = t.path().join("foo.ts"); + foo_file.write( + r#" + export default function foo() {} + "#, + ); + + foo_file.write( + r#" + /** + * ```ts + * import foo from "./foo.ts"; + * ``` + */ + export default function foo() {} + "#, + ); + + // We only need to scan for a Check file://.../foo.ts$3-6 line that + // corresponds to the documentation block being type-checked. + assert_contains!(skip_restarting_line(&mut stderr_lines).await, "foo.ts$3-6"); + check_alive_then_kill(child); +} + +#[tokio::test] +async fn test_watch_module_graph_error_referrer() { + let t = TempDir::new(); + let file_to_watch = t.path().join("file_to_watch.js"); + file_to_watch.write("import './nonexistent.js';"); + let mut child = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg("--watch") + .arg(&file_to_watch) + .env("NO_COLOR", "1") + .piped_output() + .spawn() + .unwrap(); + let (_, mut stderr_lines) = child_lines(&mut child); + let line1 = next_line(&mut stderr_lines).await.unwrap(); + assert_contains!(&line1, "Process started"); + let line2 = next_line(&mut stderr_lines).await.unwrap(); + assert_contains!(&line2, "error: Module not found"); + assert_contains!(&line2, "nonexistent.js"); + let line3 = next_line(&mut stderr_lines).await.unwrap(); + assert_contains!(&line3, " at "); + assert_contains!(&line3, "file_to_watch.js"); + wait_contains("Process failed", &mut stderr_lines).await; + check_alive_then_kill(child); +} + +// Regression test for https://github.com/denoland/deno/issues/15428. +#[tokio::test] +async fn test_watch_unload_handler_error_on_drop() { + let t = TempDir::new(); + let file_to_watch = t.path().join("file_to_watch.js"); + file_to_watch.write( + r#" + addEventListener("unload", () => { + throw new Error("foo"); + }); + setTimeout(() => { + throw new Error("bar"); + }); + "#, + ); + let mut child = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg("--watch") + .arg(&file_to_watch) + .env("NO_COLOR", "1") + .piped_output() + .spawn() + .unwrap(); + let (_, mut stderr_lines) = child_lines(&mut child); + wait_contains("Process started", &mut stderr_lines).await; + wait_contains("Uncaught Error: bar", &mut stderr_lines).await; + wait_contains("Process failed", &mut stderr_lines).await; + check_alive_then_kill(child); +} + +#[tokio::test] +async fn run_watch_blob_urls_reset() { + let _g = util::http_server(); + let t = TempDir::new(); + let file_to_watch = t.path().join("file_to_watch.js"); + let file_content = r#" + const prevUrl = localStorage.getItem("url"); + if (prevUrl == null) { + console.log("first run, storing blob url"); + const url = URL.createObjectURL( + new Blob(["export {}"], { type: "application/javascript" }), + ); + await import(url); // this shouldn't insert into the fs module cache + localStorage.setItem("url", url); + } else { + await import(prevUrl) + .then(() => console.log("importing old blob url incorrectly works")) + .catch(() => console.log("importing old blob url correctly failed")); + } + "#; + file_to_watch.write(file_content); + let mut child = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg("--watch") + .arg(&file_to_watch) + .env("NO_COLOR", "1") + .piped_output() + .spawn() + .unwrap(); + let (mut stdout_lines, mut stderr_lines) = child_lines(&mut child); + wait_contains("first run, storing blob url", &mut stdout_lines).await; + wait_contains("finished", &mut stderr_lines).await; + file_to_watch.write(file_content); + wait_contains("importing old blob url correctly failed", &mut stdout_lines) + .await; + wait_contains("finished", &mut stderr_lines).await; + check_alive_then_kill(child); +} + +#[cfg(unix)] +#[tokio::test] +async fn test_watch_sigint() { + use nix::sys::signal; + use nix::sys::signal::Signal; + use nix::unistd::Pid; + use util::TestContext; + + let context = TestContext::default(); + let t = context.temp_dir(); + let file_to_watch = t.path().join("file_to_watch.js"); + file_to_watch.write(r#"Deno.test("foo", () => {});"#); + let mut child = context + .new_command() + .args_vec(["test", "--watch", &file_to_watch.to_string_lossy()]) + .env("NO_COLOR", "1") + .spawn_with_piped_output(); + let (mut stdout_lines, mut stderr_lines) = child_lines(&mut child); + wait_contains("Test started", &mut stderr_lines).await; + wait_contains("ok | 1 passed | 0 failed", &mut stdout_lines).await; + wait_contains("Test finished", &mut stderr_lines).await; + signal::kill(Pid::from_raw(child.id() as i32), Signal::SIGINT).unwrap(); + let exit_status = child.wait().unwrap(); + assert_eq!(exit_status.code(), Some(130)); +} + +#[tokio::test] +async fn bench_watch_basic() { + let t = TempDir::new(); + + let mut child = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("bench") + .arg("--watch") + .arg("--no-check") + .arg(t.path()) + .env("NO_COLOR", "1") + .piped_output() + .spawn() + .unwrap(); + let (mut stdout_lines, mut stderr_lines) = child_lines(&mut child); + + assert_contains!( + next_line(&mut stderr_lines).await.unwrap(), + "Bench started" + ); + assert_contains!( + next_line(&mut stderr_lines).await.unwrap(), + "Bench finished" + ); + + let foo_file = t.path().join("foo.js"); + let bar_file = t.path().join("bar.js"); + let foo_bench = t.path().join("foo_bench.js"); + let bar_bench = t.path().join("bar_bench.js"); + foo_file.write("export default function foo() { 1 + 1 }"); + bar_file.write("export default function bar() { 2 + 2 }"); + foo_bench.write("import foo from './foo.js'; Deno.bench('foo bench', foo);"); + bar_bench.write("import bar from './bar.js'; Deno.bench('bar bench', bar);"); + + wait_contains("bar_bench.js", &mut stdout_lines).await; + wait_contains("bar bench", &mut stdout_lines).await; + wait_contains("foo_bench.js", &mut stdout_lines).await; + wait_contains("foo bench", &mut stdout_lines).await; + wait_contains("Bench finished", &mut stderr_lines).await; + + // Change content of the file + foo_bench.write("import foo from './foo.js'; Deno.bench('foo asdf', foo);"); + + assert_contains!(next_line(&mut stderr_lines).await.unwrap(), "Restarting"); + loop { + let line = next_line(&mut stdout_lines).await.unwrap(); + assert_not_contains!(line, "bar"); + if line.contains("foo asdf") { + break; // last line + } + } + wait_contains("Bench finished", &mut stderr_lines).await; + + // Add bench + let another_test = t.path().join("new_bench.js"); + another_test.write("Deno.bench('another one', () => 3 + 3)"); + loop { + let line = next_line(&mut stdout_lines).await.unwrap(); + assert_not_contains!(line, "bar"); + assert_not_contains!(line, "foo"); + if line.contains("another one") { + break; // last line + } + } + wait_contains("Bench finished", &mut stderr_lines).await; + + // Confirm that restarting occurs when a new file is updated + another_test.write("Deno.bench('another one', () => 3 + 3); Deno.bench('another another one', () => 4 + 4)"); + loop { + let line = next_line(&mut stdout_lines).await.unwrap(); + assert_not_contains!(line, "bar"); + assert_not_contains!(line, "foo"); + if line.contains("another another one") { + break; // last line + } + } + wait_contains("Bench finished", &mut stderr_lines).await; + + // Confirm that the watcher keeps on working even if the file is updated and has invalid syntax + another_test.write("syntax error ^^"); + assert_contains!(next_line(&mut stderr_lines).await.unwrap(), "Restarting"); + assert_contains!(next_line(&mut stderr_lines).await.unwrap(), "error:"); + assert_eq!(next_line(&mut stderr_lines).await.unwrap(), ""); + assert_eq!( + next_line(&mut stderr_lines).await.unwrap(), + " syntax error ^^" + ); + assert_eq!( + next_line(&mut stderr_lines).await.unwrap(), + " ~~~~~" + ); + assert_contains!(next_line(&mut stderr_lines).await.unwrap(), "Bench failed"); + + // Then restore the file + another_test.write("Deno.bench('another one', () => 3 + 3)"); + assert_contains!(next_line(&mut stderr_lines).await.unwrap(), "Restarting"); + loop { + let line = next_line(&mut stdout_lines).await.unwrap(); + assert_not_contains!(line, "bar"); + assert_not_contains!(line, "foo"); + if line.contains("another one") { + break; // last line + } + } + wait_contains("Bench finished", &mut stderr_lines).await; + + // Test that circular dependencies work fine + foo_file.write("import './bar.js'; export default function foo() { 1 + 1 }"); + bar_file.write("import './foo.js'; export default function bar() { 2 + 2 }"); + check_alive_then_kill(child); +} + +// Regression test for https://github.com/denoland/deno/issues/15465. +#[tokio::test] +async fn run_watch_reload_once() { + let _g = util::http_server(); + let t = TempDir::new(); + let file_to_watch = t.path().join("file_to_watch.js"); + let file_content = r#" + import { time } from "http://localhost:4545/dynamic_module.ts"; + console.log(time); + "#; + file_to_watch.write(file_content); + + let mut child = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg("--watch") + .arg("--reload") + .arg(&file_to_watch) + .env("NO_COLOR", "1") + .piped_output() + .spawn() + .unwrap(); + let (mut stdout_lines, mut stderr_lines) = child_lines(&mut child); + + wait_contains("finished", &mut stderr_lines).await; + let first_output = next_line(&mut stdout_lines).await.unwrap(); + + file_to_watch.write(file_content); + // The remote dynamic module should not have been reloaded again. + + wait_contains("finished", &mut stderr_lines).await; + let second_output = next_line(&mut stdout_lines).await.unwrap(); + assert_eq!(second_output, first_output); + + check_alive_then_kill(child); +} + +/// Regression test for https://github.com/denoland/deno/issues/18960. Ensures that Deno.serve +/// operates properly after a watch restart. +#[tokio::test] +async fn test_watch_serve() { + let t = TempDir::new(); + let file_to_watch = t.path().join("file_to_watch.js"); + let file_content = r#" + console.error("serving"); + await Deno.serve({port: 4600, handler: () => new Response("hello")}); + "#; + file_to_watch.write(file_content); + + let mut child = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg("--watch") + .arg("--allow-net") + .arg("-L") + .arg("debug") + .arg(&file_to_watch) + .env("NO_COLOR", "1") + .piped_output() + .spawn() + .unwrap(); + let (mut stdout_lines, mut stderr_lines) = child_lines(&mut child); + + wait_contains("Listening on", &mut stdout_lines).await; + // Note that we start serving very quickly, so we specifically want to wait for this message + wait_contains(r#"Watching paths: [""#, &mut stderr_lines).await; + + file_to_watch.write(file_content); + + wait_contains("serving", &mut stderr_lines).await; + wait_contains("Listening on", &mut stdout_lines).await; + + check_alive_then_kill(child); +} + +#[tokio::test] +async fn run_watch_dynamic_imports() { + let t = TempDir::new(); + let file_to_watch = t.path().join("file_to_watch.js"); + file_to_watch.write( + r#" + console.log("Hopefully dynamic import will be watched..."); + await import("./imported.js"); + "#, + ); + let file_to_watch2 = t.path().join("imported.js"); + file_to_watch2.write( + r#" + import "./imported2.js"; + console.log("I'm dynamically imported and I cause restarts!"); + "#, + ); + let file_to_watch3 = t.path().join("imported2.js"); + file_to_watch3.write( + r#" + console.log("I'm statically imported from the dynamic import"); + "#, + ); + + let mut child = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg("--watch") + .arg("--unstable") + .arg("--allow-read") + .arg("-L") + .arg("debug") + .arg(&file_to_watch) + .env("NO_COLOR", "1") + .piped_output() + .spawn() + .unwrap(); + let (mut stdout_lines, mut stderr_lines) = child_lines(&mut child); + wait_contains("Process started", &mut stderr_lines).await; + wait_contains("No package.json file found", &mut stderr_lines).await; + + wait_contains( + "Hopefully dynamic import will be watched...", + &mut stdout_lines, + ) + .await; + wait_contains( + "I'm statically imported from the dynamic import", + &mut stdout_lines, + ) + .await; + wait_contains( + "I'm dynamically imported and I cause restarts!", + &mut stdout_lines, + ) + .await; + + wait_for_watcher("imported2.js", &mut stderr_lines).await; + wait_contains("finished", &mut stderr_lines).await; + + file_to_watch3.write( + r#" + console.log("I'm statically imported from the dynamic import and I've changed"); + "#, + ); + + wait_contains("Restarting", &mut stderr_lines).await; + wait_contains( + "Hopefully dynamic import will be watched...", + &mut stdout_lines, + ) + .await; + wait_contains( + "I'm statically imported from the dynamic import and I've changed", + &mut stdout_lines, + ) + .await; + wait_contains( + "I'm dynamically imported and I cause restarts!", + &mut stdout_lines, + ) + .await; + + check_alive_then_kill(child); +} + +#[tokio::test] +async fn run_watch_inspect() { + let t = TempDir::new(); + let file_to_watch = t.path().join("file_to_watch.js"); + file_to_watch.write( + r#" + console.log("hello world"); + "#, + ); + + let mut child = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg("--watch") + .arg("--inspect") + .arg("-L") + .arg("debug") + .arg(&file_to_watch) + .env("NO_COLOR", "1") + .piped_output() + .spawn() + .unwrap(); + let (mut stdout_lines, mut stderr_lines) = child_lines(&mut child); + + wait_contains("Debugger listening", &mut stderr_lines).await; + wait_for_watcher("file_to_watch.js", &mut stderr_lines).await; + wait_contains("hello world", &mut stdout_lines).await; + + file_to_watch.write( + r#" + console.log("updated file"); + "#, + ); + + wait_contains("Restarting", &mut stderr_lines).await; + wait_contains("Debugger listening", &mut stderr_lines).await; + wait_contains("updated file", &mut stdout_lines).await; + + check_alive_then_kill(child); +} + +#[tokio::test] +async fn run_hmr_server() { + let t = TempDir::new(); + let file_to_watch = t.path().join("file_to_watch.js"); + file_to_watch.write( + r#" +globalThis.state = { i: 0 }; + +function bar() { + globalThis.state.i = 0; + console.log("got request", globalThis.state.i); +} + +function handler(_req) { + bar(); + return new Response("Hello world!"); +} + +Deno.serve({ port: 11111 }, handler); +console.log("Listening...") + "#, + ); + + let mut child = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg("--unstable-hmr") + .arg("--allow-net") + .arg("-L") + .arg("debug") + .arg(&file_to_watch) + .env("NO_COLOR", "1") + .piped_output() + .spawn() + .unwrap(); + let (mut stdout_lines, mut stderr_lines) = child_lines(&mut child); + wait_contains("Process started", &mut stderr_lines).await; + wait_contains("No package.json file found", &mut stderr_lines).await; + + wait_for_watcher("file_to_watch.js", &mut stderr_lines).await; + wait_contains("Listening...", &mut stdout_lines).await; + + file_to_watch.write( + r#" +globalThis.state = { i: 0 }; + +function bar() { + globalThis.state.i = 0; + console.log("got request1", globalThis.state.i); +} + +function handler(_req) { + bar(); + return new Response("Hello world!"); +} + +Deno.serve({ port: 11111 }, handler); +console.log("Listening...") + "#, + ); + + wait_contains("Failed to reload module", &mut stderr_lines).await; + wait_contains("File change detected", &mut stderr_lines).await; + + check_alive_then_kill(child); +} + +#[tokio::test] +async fn run_hmr_jsx() { + let t = TempDir::new(); + let file_to_watch = t.path().join("file_to_watch.js"); + file_to_watch.write( + r#" +import { foo } from "./foo.jsx"; + +let i = 0; +setInterval(() => { + console.log(i++, foo()); +}, 100); +"#, + ); + let file_to_watch2 = t.path().join("foo.jsx"); + file_to_watch2.write( + r#" +export function foo() { + return `

Hello

`; +} +"#, + ); + + let mut child = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg("--unstable-hmr") + .arg("-L") + .arg("debug") + .arg(&file_to_watch) + .env("NO_COLOR", "1") + .piped_output() + .spawn() + .unwrap(); + let (mut stdout_lines, mut stderr_lines) = child_lines(&mut child); + wait_contains("Process started", &mut stderr_lines).await; + wait_contains("No package.json file found", &mut stderr_lines).await; + + wait_for_watcher("file_to_watch.js", &mut stderr_lines).await; + wait_contains("5

Hello

", &mut stdout_lines).await; + + file_to_watch2.write( + r#" +export function foo() { + return `

Hello world

`; +} + "#, + ); + + wait_contains("Replaced changed module", &mut stderr_lines).await; + wait_contains("

Hello world

", &mut stdout_lines).await; + + check_alive_then_kill(child); +} + +#[tokio::test] +async fn run_hmr_uncaught_error() { + let t = TempDir::new(); + let file_to_watch = t.path().join("file_to_watch.js"); + file_to_watch.write( + r#" +import { foo } from "./foo.jsx"; + +let i = 0; +setInterval(() => { + console.log(i++, foo()); +}, 100); +"#, + ); + let file_to_watch2 = t.path().join("foo.jsx"); + file_to_watch2.write( + r#" +export function foo() { + setTimeout(() => { + throw new Error("fail"); + }); + return `

asd1

`; +} +"#, + ); + + let mut child = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg("--unstable-hmr") + .arg("-L") + .arg("debug") + .arg(&file_to_watch) + .env("NO_COLOR", "1") + .piped_output() + .spawn() + .unwrap(); + let (mut stdout_lines, mut stderr_lines) = child_lines(&mut child); + wait_contains("Process started", &mut stderr_lines).await; + wait_contains("No package.json file found", &mut stderr_lines).await; + + wait_for_watcher("file_to_watch.js", &mut stderr_lines).await; + wait_contains("

asd1

", &mut stdout_lines).await; + wait_contains("fail", &mut stderr_lines).await; + + file_to_watch2.write( + r#" +export function foo() { + return `

asd2

`; +} + "#, + ); + + wait_contains("Process failed", &mut stderr_lines).await; + wait_contains("File change detected", &mut stderr_lines).await; + wait_contains("

asd2

", &mut stdout_lines).await; + + check_alive_then_kill(child); +} + +#[tokio::test] +async fn run_hmr_unhandled_rejection() { + let t = TempDir::new(); + let file_to_watch = t.path().join("file_to_watch.js"); + file_to_watch.write( + r#" +import { foo } from "./foo.jsx"; + +// deno-lint-ignore require-await +async function rejection() { + throw new Error("boom!"); +} + +let i = 0; +setInterval(() => { + if (i == 3) { + rejection(); + } + console.log(i++, foo()); +}, 100); +"#, + ); + let file_to_watch2 = t.path().join("foo.jsx"); + file_to_watch2.write( + r#" +export function foo() { + return `

asd1

`; +} +"#, + ); + + let mut child = util::deno_cmd() + .current_dir(util::testdata_path()) + .arg("run") + .arg("--unstable-hmr") + .arg("-L") + .arg("debug") + .arg(&file_to_watch) + .env("NO_COLOR", "1") + .piped_output() + .spawn() + .unwrap(); + let (mut stdout_lines, mut stderr_lines) = child_lines(&mut child); + wait_contains("Process started", &mut stderr_lines).await; + wait_contains("No package.json file found", &mut stderr_lines).await; + + wait_for_watcher("file_to_watch.js", &mut stderr_lines).await; + wait_contains("2

asd1

", &mut stdout_lines).await; + wait_contains("boom", &mut stderr_lines).await; + + file_to_watch.write( + r#" +import { foo } from "./foo.jsx"; + +let i = 0; +setInterval(() => { + console.log(i++, foo()); +}, 100); + "#, + ); + + wait_contains("Process failed", &mut stderr_lines).await; + wait_contains("File change detected", &mut stderr_lines).await; + wait_contains("

asd1

", &mut stdout_lines).await; + + check_alive_then_kill(child); +} diff --git a/tests/integration/worker_tests.rs b/tests/integration/worker_tests.rs new file mode 100644 index 000000000..e2d1ef868 --- /dev/null +++ b/tests/integration/worker_tests.rs @@ -0,0 +1,111 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +itest!(worker_error { + args: "run -A workers/worker_error.ts", + output: "workers/worker_error.ts.out", + exit_code: 1, +}); + +itest!(worker_nested_error { + args: "run -A workers/worker_nested_error.ts", + output: "workers/worker_nested_error.ts.out", + exit_code: 1, +}); + +itest!(worker_async_error { + args: "run -A --quiet --reload workers/worker_async_error.ts", + output: "workers/worker_async_error.ts.out", + http_server: true, + exit_code: 1, +}); + +itest!(worker_message_handler_error { + args: "run -A --quiet --reload workers/worker_message_handler_error.ts", + output: "workers/worker_message_handler_error.ts.out", + http_server: true, + exit_code: 1, +}); + +itest!(nonexistent_worker { + args: "run --allow-read workers/nonexistent_worker.ts", + output: "workers/nonexistent_worker.out", + exit_code: 1, +}); + +itest!(_084_worker_custom_inspect { + args: "run --allow-read workers/custom_inspect/main.ts", + output: "workers/custom_inspect/main.out", +}); + +itest!(error_worker_permissions_local { + args: "run --reload workers/error_worker_permissions_local.ts", + output: "workers/error_worker_permissions_local.ts.out", + exit_code: 1, +}); + +itest!(error_worker_permissions_remote { + args: "run --reload workers/error_worker_permissions_remote.ts", + http_server: true, + output: "workers/error_worker_permissions_remote.ts.out", + exit_code: 1, +}); + +itest!(worker_permissions_remote_remote { + args: "run --quiet --reload --allow-net=localhost:4545 workers/permissions_remote_remote.ts", + output: "workers/permissions_remote_remote.ts.out", + http_server: true, + exit_code: 1, + }); + +itest!(worker_permissions_dynamic_remote { + args: "run --quiet --reload --allow-net --unstable-worker-options workers/permissions_dynamic_remote.ts", + output: "workers/permissions_dynamic_remote.ts.out", + http_server: true, + exit_code: 1, + }); + +itest!(worker_permissions_data_remote { + args: "run --quiet --reload --allow-net=localhost:4545 workers/permissions_data_remote.ts", + output: "workers/permissions_data_remote.ts.out", + http_server: true, + exit_code: 1, + }); + +itest!(worker_permissions_blob_remote { + args: "run --quiet --reload --allow-net=localhost:4545 workers/permissions_blob_remote.ts", + output: "workers/permissions_blob_remote.ts.out", + http_server: true, + exit_code: 1, + }); + +itest!(worker_permissions_data_local { + args: "run --quiet --reload --allow-net=localhost:4545 workers/permissions_data_local.ts", + output: "workers/permissions_data_local.ts.out", + http_server: true, + exit_code: 1, + }); + +itest!(worker_permissions_blob_local { + args: "run --quiet --reload --allow-net=localhost:4545 workers/permissions_blob_local.ts", + output: "workers/permissions_blob_local.ts.out", + http_server: true, + exit_code: 1, + }); + +itest!(worker_terminate_tla_crash { + args: "run --quiet --reload workers/terminate_tla_crash.js", + output: "workers/terminate_tla_crash.js.out", +}); + +itest!(worker_error_event { + args: "run --quiet -A workers/error_event.ts", + output: "workers/error_event.ts.out", + exit_code: 1, +}); + +// Regression test for https://github.com/denoland/deno/issues/19903 +itest!(worker_doest_stall_event_loop { + args: "run --quiet -A workers/worker_doest_stall_event_loop.ts", + output: "workers/worker_doest_stall_event_loop.ts.out", + exit_code: 0, +}); diff --git a/tests/integration_tests.rs b/tests/integration_tests.rs new file mode 100644 index 000000000..8469b5416 --- /dev/null +++ b/tests/integration_tests.rs @@ -0,0 +1,7 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +// The tests exist in a sub folder instead of as separate files in +// this directory so that cargo doesn't compile each file as a new crate. + +#[cfg(test)] +mod integration; diff --git a/tests/integration_tests_runner.rs b/tests/integration_tests_runner.rs new file mode 100644 index 000000000..12e83a019 --- /dev/null +++ b/tests/integration_tests_runner.rs @@ -0,0 +1,18 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +pub fn main() { + let mut args = vec!["cargo", "test", "-p", "cli_tests", "--features", "run"]; + + if !cfg!(debug_assertions) { + args.push("--release"); + } + + args.push("--"); + + // If any args were passed to this process, pass them through to the child + let orig_args = std::env::args().skip(1).collect::>(); + let orig_args: Vec<&str> = + orig_args.iter().map(|x| x.as_ref()).collect::>(); + args.extend(orig_args); + + test_util::spawn::exec_replace("cargo", &args).unwrap(); +} diff --git a/tests/lib.rs b/tests/lib.rs new file mode 100644 index 000000000..0a39b9f87 --- /dev/null +++ b/tests/lib.rs @@ -0,0 +1 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. diff --git a/tests/node_compat/common.ts b/tests/node_compat/common.ts new file mode 100644 index 000000000..e079c6aaf --- /dev/null +++ b/tests/node_compat/common.ts @@ -0,0 +1,64 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +import { partition } from "@test_util/std/collections/partition.ts"; +import { join } from "@test_util/std/path/mod.ts"; +import * as JSONC from "@test_util/std/jsonc/mod.ts"; +/** + * The test suite matches the folders inside the `test` folder inside the + * node repo + * + * Each test suite contains a list of files (which can be paths + * or a regex to match) that will be pulled from the node repo + */ +type TestSuites = Record; + +interface Config { + nodeVersion: string; + /** Ignored files won't regenerated by the update script */ + ignore: TestSuites; + /** + * The files that will be run by the test suite + * + * The files to be generated with the update script must be listed here as well, + * but they won't be regenerated if they are listed in the `ignore` configuration + */ + tests: TestSuites; + windowsIgnore: TestSuites; + darwinIgnore: TestSuites; +} + +export const config: Config = JSONC.parse( + await Deno.readTextFile(new URL("./config.jsonc", import.meta.url)), +) as unknown as Config; + +export const ignoreList = Object.entries(config.ignore).reduce( + (total: RegExp[], [suite, paths]) => { + paths.forEach((path) => total.push(new RegExp(join(suite, path)))); + return total; + }, + [/package\.json/], +); + +export function getPathsFromTestSuites(suites: TestSuites): string[] { + const testPaths: string[] = []; + for (const [dir, paths] of Object.entries(suites)) { + if ( + ["parallel", "internet", "pummel", "sequential", "pseudo-tty"].includes( + dir, + ) + ) { + for (const path of paths) { + testPaths.push(join(dir, path)); + } + } + } + return testPaths; +} + +const PARALLEL_PATTERN = /^parallel[\/\\]/; + +export function partitionParallelTestPaths( + testPaths: string[], +): { parallel: string[]; sequential: string[] } { + const partitions = partition(testPaths, (p) => !!p.match(PARALLEL_PATTERN)); + return { parallel: partitions[0], sequential: partitions[1] }; +} diff --git a/tests/node_compat/config.jsonc b/tests/node_compat/config.jsonc new file mode 100644 index 000000000..d84cc4dd2 --- /dev/null +++ b/tests/node_compat/config.jsonc @@ -0,0 +1,736 @@ +{ + "nodeVersion": "18.12.1", + "ignore": { + "common": ["index.js", "internet.js"], + "fixtures": [ + "child-process-spawn-node.js", + "echo.js", + "elipses.txt", + "empty.txt", + "exit.js", + "print-chars.js", + "x.txt" + ], + "internet": [ + "test-dns-any.js", + "test-dns-ipv4.js", + "test-dns-ipv6.js", + "test-dns.js" + ], + "parallel": [ + "test-assert.js", + "test-buffer-alloc.js", + "test-buffer-arraybuffer.js", + "test-buffer-from.js", + "test-buffer-includes.js", + "test-buffer-indexof.js", + "test-child-process-exec-abortcontroller-promisified.js", + "test-child-process-exec-encoding.js", + "test-child-process-exec-kill-throws.js", + "test-child-process-exec-maxbuf.js", + "test-child-process-exec-std-encoding.js", + // TODO(bartlomieju): this test was flaky on macOS CI + // "test-child-process-exec-timeout-expire.js", + // TODO(bartlomieju): this test was flaky on macOS CI + // "test-child-process-exec-timeout-kill.js", + "test-child-process-exec-timeout-not-expired.js", + "test-child-process-execFile-promisified-abortController.js", + "test-child-process-execfile.js", + "test-child-process-execsync-maxbuf.js", + "test-child-process-exit-code.js", + // TODO(littledivy): windows ipc streams not yet implemented + "test-child-process-fork-ref.js", + "test-child-process-fork-ref2.js", + "test-child-process-ipc-next-tick.js", + "test-child-process-ipc.js", + "test-child-process-spawnsync-env.js", + "test-child-process-stdio-inherit.js", + "test-child-process-stdout-flush-exit.js", + "test-child-process-stdout-flush.js", + "test-console-instance.js", + "test-crypto-dh.js", + "test-crypto-hkdf.js", + "test-crypto-hmac.js", + "test-crypto-prime.js", + "test-crypto-stream.js", + "test-crypto-x509.js", + "test-dgram-custom-lookup.js", + "test-dgram-ipv6only.js", + "test-dgram-send-cb-quelches-error.js", + "test-dgram-socket-buffer-size.js", + "test-dgram-udp6-link-local-address.js", + "test-dns-lookup.js", + "test-dns-resolveany.js", + "test-dns.js", + "test-event-emitter-max-listeners.js", + "test-event-emitter-no-error-provided-to-error-event.js", + "test-event-emitter-prepend.js", + "test-events-once.js", + "test-fs-append-file.js", + "test-fs-chmod-mask.js", + "test-fs-chmod.js", + "test-fs-mkdir.js", + "test-fs-open.js", + "test-fs-opendir.js", + "test-fs-rmdir-recursive.js", + "test-fs-write-file.js", + "test-fs-write.js", + "test-http-url.parse-https.request.js", + "test-net-better-error-messages-path.js", + "test-net-connect-buffer.js", + "test-net-connect-buffer2.js", + "test-net-end-close.js", + "test-net-listen-invalid-port.js", + "test-net-server-call-listen-multiple-times.js", + "test-net-server-listen-path.js", + "test-net-server-try-ports.js", + "test-net-socket-timeout.js", + "test-net-write-arguments.js", + "test-os.js", + "test-path-resolve.js", + "test-querystring.js", + "test-readline-interface.js", + "test-stdin-from-file-spawn.js", + "test-stream-duplex-from.js", + "test-ttywrap-invalid-fd.js", + "test-url-urltooptions.js", + "test-util-format.js", + "test-util-inspect-namespace.js", + "test-util-inspect-proxy.js", + "test-util-inspect.js", + "test-util-isDeepStrictEqual.js", + "test-util-promisify.js", + "test-util-types.js", + "test-util.js", + "test-webcrypto-sign-verify.js", + "test-whatwg-url-properties.js", + "test-zlib-convenience-methods.js", + "test-zlib-empty-buffer.js", + "test-zlib-invalid-input.js", + "test-zlib-random-byte-pipes.js", + "test-zlib-write-after-flush.js", + "test-zlib-zero-byte.js", + "test-zlib-zero-windowBits.js" + ], + "pummel": [], + "sequential": ["test-child-process-exit.js"] + }, + "tests": { + "common": [ + "child_process.js", + "countdown.js", + "dns.js", + "duplexpair.js", + "fixtures.js", + "hijackstdio.js", + "index.mjs", + "internet.js", + "tmpdir.js" + ], + "fixtures": [ + "GH-1899-output.js", + "a.js", + "child-process-spawn-node.js", + "child_process_should_emit_error.js", + "echo.js", + "elipses.txt", + "empty.txt", + "exit.js", + "loop.js", + "print-chars.js", + "x.txt" + ], + "fixtures/keys": ["agent1-cert.pem", "agent1-key.pem", "ca1-cert.pem"], + "internet": [ + "test-dns-any.js", + "test-dns-idna2008.js", + "test-dns-ipv4.js", + "test-dns-ipv6.js", + "test-dns-lookup.js", + "test-dns-promises-resolve.js", + "test-dns-regress-6244.js", + "test-dns-setserver-in-callback-of-resolve4.js", + "test-dns.js", + "test-http-https-default-ports.js" + ], + "parallel": [ + "test-assert-async.js", + "test-assert-fail.js", + "test-assert-strict-exists.js", + "test-assert.js", + "test-bad-unicode.js", + "test-btoa-atob.js", + "test-buffer-alloc.js", + "test-buffer-arraybuffer.js", + "test-buffer-ascii.js", + "test-buffer-badhex.js", + "test-buffer-bigint64.js", + "test-buffer-bytelength.js", + "test-buffer-compare-offset.js", + "test-buffer-concat.js", + "test-buffer-constants.js", + "test-buffer-copy.js", + "test-buffer-equals.js", + "test-buffer-failed-alloc-typed-arrays.js", + "test-buffer-fakes.js", + "test-buffer-from.js", + "test-buffer-includes.js", + "test-buffer-indexof.js", + "test-buffer-inheritance.js", + "test-buffer-isencoding.js", + "test-buffer-iterator.js", + "test-buffer-new.js", + "test-buffer-no-negative-allocation.js", + "test-buffer-nopendingdep-map.js", + "test-buffer-of-no-deprecation.js", + "test-buffer-over-max-length.js", + "test-buffer-parent-property.js", + "test-buffer-read.js", + "test-buffer-readdouble.js", + "test-buffer-readfloat.js", + "test-buffer-readint.js", + "test-buffer-readuint.js", + "test-buffer-safe-unsafe.js", + "test-buffer-slice.js", + "test-buffer-slow.js", + "test-buffer-swap.js", + "test-buffer-tojson.js", + "test-buffer-tostring-range.js", + "test-buffer-tostring-rangeerror.js", + "test-buffer-tostring.js", + "test-buffer-writedouble.js", + "test-buffer-writefloat.js", + "test-buffer-writeint.js", + "test-buffer-writeuint.js", + "test-buffer-zero-fill-cli.js", + "test-buffer-zero-fill-reset.js", + "test-buffer-zero-fill.js", + // TODO(bartlomieju): this test was flaky on macOS CI + // "test-child-process-can-write-to-stdout.js", + "test-child-process-default-options.js", + "test-child-process-double-pipe.js", + "test-child-process-exec-abortcontroller-promisified.js", + "test-child-process-exec-cwd.js", + "test-child-process-exec-env.js", + "test-child-process-exec-error.js", + "test-child-process-exec-kill-throws.js", + "test-child-process-exec-maxbuf.js", + "test-child-process-exec-stdout-stderr-data-string.js", + // TODO(bartlomieju): this test was flaky on macOS CI + // "test-child-process-exec-timeout-expire.js", + // TODO(bartlomieju): this test was flaky on macOS CI + // "test-child-process-exec-timeout-kill.js", + // TODO(bartlomieju): this test was flaky on macOS CI + // "test-child-process-execFile-promisified-abortController.js", + "test-child-process-execfile-maxbuf.js", + "test-child-process-execfilesync-maxbuf.js", + "test-child-process-execsync-maxbuf.js", + "test-child-process-flush-stdio.js", + "test-child-process-kill.js", + "test-child-process-set-blocking.js", + "test-child-process-spawn-args.js", + "test-child-process-spawn-event.js", + "test-child-process-spawnsync-args.js", + "test-child-process-spawnsync-maxbuf.js", + "test-child-process-spawnsync-validation-errors.js", + "test-child-process-spawnsync.js", + // TODO(crowlKats): socket is not yet polyfilled + // "test-client-request-destroy.js", + "test-console-async-write-error.js", + "test-console-group.js", + "test-console-log-stdio-broken-dest.js", + "test-console-log-throw-primitive.js", + "test-console-no-swallow-stack-overflow.js", + "test-console-sync-write-error.js", + "test-console-table.js", + "test-console-tty-colors.js", + "test-crypto-dh-shared.js", + "test-crypto-dh.js", + "test-crypto-hkdf.js", + "test-crypto-hmac.js", + "test-crypto-prime.js", + "test-crypto-secret-keygen.js", + "test-crypto-stream.js", + "test-crypto-update-encoding.js", + "test-crypto-x509.js", + "test-dgram-close-during-bind.js", + "test-dgram-close-signal.js", + "test-diagnostics-channel-has-subscribers.js", + "test-diagnostics-channel-object-channel-pub-sub.js", + "test-diagnostics-channel-pub-sub.js", + "test-diagnostics-channel-symbol-named.js", + "test-diagnostics-channel-udp.js", + "test-dns-lookup.js", + "test-dns-memory-error.js", + "test-dns-promises-exists.js", + "test-dns-resolvens-typeerror.js", + "test-dns-setservers-type-check.js", + "test-eval-strict-referenceerror.js", + "test-eval.js", + "test-event-emitter-add-listeners.js", + "test-event-emitter-emit-context.js", + "test-event-emitter-error-monitor.js", + "test-event-emitter-errors.js", + "test-event-emitter-get-max-listeners.js", + "test-event-emitter-invalid-listener.js", + "test-event-emitter-listener-count.js", + "test-event-emitter-listeners-side-effects.js", + "test-event-emitter-listeners.js", + "test-event-emitter-max-listeners.js", + "test-event-emitter-method-names.js", + "test-event-emitter-modify-in-emit.js", + "test-event-emitter-no-error-provided-to-error-event.js", + "test-event-emitter-num-args.js", + "test-event-emitter-once.js", + "test-event-emitter-prepend.js", + "test-event-emitter-remove-all-listeners.js", + "test-event-emitter-remove-listeners.js", + "test-event-emitter-set-max-listeners-side-effects.js", + "test-event-emitter-special-event-names.js", + "test-event-emitter-subclass.js", + "test-event-emitter-symbols.js", + "test-events-list.js", + "test-events-on-async-iterator.js", + "test-events-once.js", + "test-events-uncaught-exception-stack.js", + "test-eventtarget-brandcheck.js", + "test-exception-handler.js", + "test-exception-handler2.js", + "test-file-read-noexist.js", + "test-file-write-stream.js", + "test-file-write-stream2.js", + "test-file-write-stream3.js", + "test-file-write-stream4.js", + "test-fs-access.js", + "test-fs-append-file-sync.js", + "test-fs-append-file.js", + "test-fs-chmod-mask.js", + "test-fs-chmod.js", + "test-fs-chown-type-check.js", + "test-fs-copyfile.js", + "test-fs-empty-readStream.js", + "test-fs-mkdir.js", + "test-fs-open-flags.js", + "test-fs-open-mode-mask.js", + "test-fs-open-no-close.js", + "test-fs-open-numeric-flags.js", + "test-fs-open.js", + "test-fs-opendir.js", + "test-fs-read-stream-autoClose.js", + "test-fs-read-stream-concurrent-reads.js", + "test-fs-read-stream-double-close.js", + "test-fs-read-stream-encoding.js", + "test-fs-read-stream-fd.js", + "test-fs-read-stream-inherit.js", + "test-fs-read-stream-patch-open.js", + "test-fs-read-stream-resume.js", + "test-fs-read-stream-throw-type-error.js", + "test-fs-read-stream.js", + "test-fs-read-type.js", + "test-fs-read-zero-length.js", + "test-fs-read.js", + "test-fs-readdir-stack-overflow.js", + "test-fs-readdir.js", + "test-fs-readfile-empty.js", + "test-fs-realpath-native.js", + "test-fs-rmdir-recursive-sync-warns-not-found.js", + "test-fs-rmdir-recursive-sync-warns-on-file.js", + "test-fs-rmdir-recursive-throws-not-found.js", + "test-fs-rmdir-recursive-throws-on-file.js", + "test-fs-rmdir-recursive-warns-not-found.js", + "test-fs-rmdir-recursive-warns-on-file.js", + "test-fs-rmdir-recursive.js", + "test-fs-rmdir-type-check.js", + "test-fs-watchfile.js", + "test-fs-write-buffer.js", + "test-fs-write-file-buffer.js", + "test-fs-write-file-invalid-path.js", + "test-fs-write-file-sync.js", + "test-fs-write-file.js", + "test-fs-write-no-fd.js", + "test-fs-write-stream-autoclose-option.js", + "test-fs-write-stream-close-without-callback.js", + "test-fs-write-stream-double-close.js", + "test-fs-write-stream-end.js", + "test-fs-write-stream-fs.js", + "test-fs-write-stream-throw-type-error.js", + "test-fs-write-stream.js", + "test-fs-write-sync.js", + "test-fs-write.js", + "test-fs-writev-sync.js", + "test-handle-wrap-close-abort.js", + "test-http-agent-getname.js", + "test-http-client-get-url.js", + "test-http-client-read-in-error.js", + // TODO(lev): ClientRequest.socket is not polyfilled so this test keeps + // failing + //"test-http-client-set-timeout.js", + "test-http-localaddress.js", + // TODO(bartlomieju): temporarily disabled while we iterate on the HTTP client + // "test-http-outgoing-buffer.js", + "test-http-outgoing-internal-headernames-getter.js", + "test-http-outgoing-internal-headernames-setter.js", + "test-http-outgoing-internal-headers.js", + // TODO(bartlomieju): temporarily disabled while we iterate on the HTTP client + // "test-http-outgoing-message-inheritance.js", + "test-http-outgoing-renderHeaders.js", + "test-http-outgoing-settimeout.js", + "test-http-url.parse-auth-with-header-in-request.js", + "test-http-url.parse-auth.js", + "test-http-url.parse-basic.js", + "test-http-url.parse-https.request.js", + "test-http-url.parse-only-support-http-https-protocol.js", + "test-http-url.parse-path.js", + "test-http-url.parse-post.js", + "test-http-url.parse-search.js", + "test-net-access-byteswritten.js", + "test-net-better-error-messages-listen-path.js", + "test-net-better-error-messages-path.js", + "test-net-better-error-messages-port-hostname.js", + "test-net-connect-after-destroy.js", + "test-net-connect-destroy.js", + "test-net-connect-immediate-destroy.js", + "test-net-connect-immediate-finish.js", + "test-net-connect-no-arg.js", + "test-net-dns-error.js", + "test-net-during-close.js", + "test-net-end-close.js", + "test-net-end-without-connect.js", + "test-net-isip.js", + "test-net-isipv4.js", + "test-net-isipv6.js", + "test-net-listen-close-server-callback-is-not-function.js", + "test-net-listen-close-server.js", + "test-net-listen-invalid-port.js", + "test-net-listening.js", + "test-net-localerror.js", + "test-net-options-lookup.js", + "test-net-pipe-connect-errors.js", + "test-net-server-listen-options-signal.js", + "test-net-server-listen-options.js", + "test-net-server-listen-path.js", + "test-net-server-listen-remove-callback.js", + "test-net-server-options.js", + "test-net-server-unref-persistent.js", + "test-net-server-unref.js", + "test-net-socket-destroy-twice.js", + "test-net-socket-no-halfopen-enforcer.js", + "test-net-timeout-no-handle.js", + "test-net-write-arguments.js", + "test-next-tick-doesnt-hang.js", + "test-next-tick-fixed-queue-regression.js", + "test-next-tick-intentional-starvation.js", + "test-next-tick-ordering.js", + "test-next-tick-ordering2.js", + "test-next-tick-when-exiting.js", + "test-next-tick.js", + "test-nodeeventtarget.js", + "test-outgoing-message-destroy.js", + "test-outgoing-message-pipe.js", + "test-parse-args.mjs", + "test-path-basename.js", + "test-path-dirname.js", + "test-path-extname.js", + "test-path-isabsolute.js", + "test-path-join.js", + "test-path-makelong.js", + "test-path-normalize.js", + "test-path-parse-format.js", + "test-path-posix-exists.js", + "test-path-relative.js", + "test-path-resolve.js", + "test-path-win32-exists.js", + "test-path-zero-length-strings.js", + "test-path.js", + "test-process-beforeexit.js", + "test-process-binding-internalbinding-allowlist.js", + "test-process-env-allowed-flags.js", + "test-process-exit-from-before-exit.js", + "test-process-exit-handler.js", + "test-process-exit-recursive.js", + "test-process-exit.js", + "test-process-kill-pid.js", + "test-process-uptime.js", + "test-promise-unhandled-silent.js", + "test-promise-unhandled-throw-handler.js", + "test-querystring-escape.js", + "test-querystring-maxKeys-non-finite.js", + "test-querystring-multichar-separator.js", + "test-querystring.js", + "test-readline-emit-keypress-events.js", + "test-readline-interface-escapecodetimeout.js", + "test-readline-keys.js", + "test-readline-position.js", + "test-readline-reopen.js", + "test-readline-set-raw-mode.js", + "test-readline-undefined-columns.js", + "test-readline.js", + "test-stdin-from-file-spawn.js", + "test-stream-add-abort-signal.js", + "test-stream-aliases-legacy.js", + "test-stream-auto-destroy.js", + "test-stream-await-drain-writers-in-synchronously-recursion-write.js", + "test-stream-backpressure.js", + "test-stream-big-packet.js", + "test-stream-big-push.js", + "test-stream-buffer-list.js", + "test-stream-construct.js", + "test-stream-destroy-event-order.js", + "test-stream-duplex-destroy.js", + "test-stream-duplex-end.js", + "test-stream-duplex-from.js", + "test-stream-duplex-props.js", + "test-stream-duplex-readable-end.js", + "test-stream-duplex-writable-finished.js", + "test-stream-duplex.js", + "test-stream-end-paused.js", + "test-stream-error-once.js", + "test-stream-events-prepend.js", + "test-stream-inheritance.js", + "test-stream-ispaused.js", + "test-stream-objectmode-undefined.js", + "test-stream-once-readable-pipe.js", + "test-stream-pipe-after-end.js", + "test-stream-pipe-await-drain-manual-resume.js", + "test-stream-pipe-await-drain-push-while-write.js", + "test-stream-pipe-await-drain.js", + "test-stream-pipe-cleanup-pause.js", + "test-stream-pipe-cleanup.js", + "test-stream-pipe-error-handling.js", + "test-stream-pipe-event.js", + "test-stream-pipe-flow-after-unpipe.js", + "test-stream-pipe-flow.js", + "test-stream-pipe-manual-resume.js", + "test-stream-pipe-multiple-pipes.js", + "test-stream-pipe-needDrain.js", + "test-stream-pipe-same-destination-twice.js", + "test-stream-pipe-unpipe-streams.js", + "test-stream-pipe-without-listenerCount.js", + "test-stream-pipeline-async-iterator.js", + "test-stream-pipeline-queued-end-in-destroy.js", + "test-stream-pipeline-with-empty-string.js", + "test-stream-push-strings.js", + "test-stream-readable-aborted.js", + "test-stream-readable-add-chunk-during-data.js", + "test-stream-readable-constructor-set-methods.js", + "test-stream-readable-data.js", + "test-stream-readable-destroy.js", + "test-stream-readable-didRead.js", + "test-stream-readable-emit-readable-short-stream.js", + "test-stream-readable-emittedReadable.js", + "test-stream-readable-end-destroyed.js", + "test-stream-readable-ended.js", + "test-stream-readable-error-end.js", + "test-stream-readable-event.js", + "test-stream-readable-flow-recursion.js", + "test-stream-readable-hwm-0-async.js", + "test-stream-readable-hwm-0-no-flow-data.js", + "test-stream-readable-hwm-0.js", + "test-stream-readable-infinite-read.js", + "test-stream-readable-invalid-chunk.js", + "test-stream-readable-needReadable.js", + "test-stream-readable-next-no-null.js", + "test-stream-readable-no-unneeded-readable.js", + "test-stream-readable-object-multi-push-async.js", + "test-stream-readable-pause-and-resume.js", + "test-stream-readable-readable-then-resume.js", + "test-stream-readable-readable.js", + "test-stream-readable-reading-readingMore.js", + "test-stream-readable-resume-hwm.js", + "test-stream-readable-resumeScheduled.js", + "test-stream-readable-setEncoding-existing-buffers.js", + "test-stream-readable-setEncoding-null.js", + "test-stream-readable-unshift.js", + "test-stream-readable-with-unimplemented-_read.js", + "test-stream-readableListening-state.js", + "test-stream-transform-callback-twice.js", + "test-stream-transform-constructor-set-methods.js", + "test-stream-transform-destroy.js", + "test-stream-transform-final-sync.js", + "test-stream-transform-final.js", + "test-stream-transform-flush-data.js", + "test-stream-transform-objectmode-falsey-value.js", + "test-stream-transform-split-highwatermark.js", + "test-stream-transform-split-objectmode.js", + "test-stream-uint8array.js", + "test-stream-unpipe-event.js", + "test-stream-unshift-empty-chunk.js", + "test-stream-unshift-read-race.js", + "test-stream-writable-change-default-encoding.js", + "test-stream-writable-clear-buffer.js", + "test-stream-writable-constructor-set-methods.js", + "test-stream-writable-decoded-encoding.js", + "test-stream-writable-destroy.js", + "test-stream-writable-end-cb-error.js", + "test-stream-writable-end-multiple.js", + "test-stream-writable-ended-state.js", + "test-stream-writable-finish-destroyed.js", + "test-stream-writable-finished-state.js", + "test-stream-writable-finished.js", + "test-stream-writable-invalid-chunk.js", + "test-stream-writable-needdrain-state.js", + "test-stream-writable-null.js", + "test-stream-writable-properties.js", + "test-stream-writable-writable.js", + "test-stream-writable-write-cb-error.js", + "test-stream-writable-write-cb-twice.js", + "test-stream-writable-write-error.js", + "test-stream-writable-write-writev-finish.js", + "test-stream-writableState-ending.js", + "test-stream-writableState-uncorked-bufferedRequestCount.js", + "test-stream-write-destroy.js", + "test-stream-write-drain.js", + "test-stream-write-final.js", + "test-stream-writev.js", + "test-stream2-base64-single-char-read-end.js", + "test-stream2-basic.js", + "test-stream2-compatibility.js", + "test-stream2-decode-partial.js", + "test-stream2-finish-pipe.js", + "test-stream2-large-read-stall.js", + "test-stream2-objects.js", + "test-stream2-pipe-error-handling.js", + "test-stream2-pipe-error-once-listener.js", + "test-stream2-push.js", + "test-stream2-read-sync-stack.js", + "test-stream2-readable-empty-buffer-no-eof.js", + "test-stream2-readable-from-list.js", + "test-stream2-readable-legacy-drain.js", + "test-stream2-readable-non-empty-end.js", + "test-stream2-readable-wrap-destroy.js", + "test-stream2-readable-wrap-empty.js", + "test-stream2-readable-wrap-error.js", + "test-stream2-readable-wrap.js", + "test-stream2-set-encoding.js", + "test-stream2-transform.js", + "test-stream2-unpipe-drain.js", + "test-stream2-unpipe-leak.js", + "test-stream2-writable.js", + "test-stream3-cork-end.js", + "test-stream3-cork-uncork.js", + "test-stream3-pause-then-read.js", + "test-streams-highwatermark.js", + "test-timers-api-refs.js", + "test-timers-args.js", + "test-timers-clear-null-does-not-throw-error.js", + "test-timers-clear-object-does-not-throw-error.js", + "test-timers-clear-timeout-interval-equivalent.js", + "test-timers-clearImmediate.js", + "test-timers-interval-throw.js", + "test-timers-non-integer-delay.js", + "test-timers-refresh.js", + "test-timers-same-timeout-wrong-list-deleted.js", + "test-timers-timeout-with-non-integer.js", + "test-timers-uncaught-exception.js", + "test-timers-unref-throw-then-ref.js", + "test-timers-user-call.js", + "test-timers-zero-timeout.js", + "test-tty-stdin-end.js", + "test-url-domain-ascii-unicode.js", + "test-url-fileurltopath.js", + "test-url-format-invalid-input.js", + "test-url-format-whatwg.js", + "test-url-format.js", + "test-url-parse-invalid-input.js", + "test-url-parse-query.js", + "test-url-pathtofileurl.js", + "test-url-relative.js", + "test-url-urltooptions.js", + "test-util-deprecate-invalid-code.js", + "test-util-deprecate.js", + "test-util-format.js", + "test-util-inherits.js", + "test-util-inspect-long-running.js", + "test-util-inspect-namespace.js", + "test-util-inspect-proxy.js", + "test-util-inspect.js", + "test-util-isDeepStrictEqual.js", + "test-util-promisify.js", + "test-util-types-exists.js", + "test-util-types.js", + "test-util.js", + "test-vm-new-script-this-context.js", + "test-vm-static-this.js", + "test-webcrypto-sign-verify.js", + "test-whatwg-encoding-custom-api-basics.js", + "test-whatwg-encoding-custom-textdecoder-ignorebom.js", + "test-whatwg-encoding-custom-textdecoder-streaming.js", + "test-whatwg-events-add-event-listener-options-passive.js", + "test-whatwg-events-add-event-listener-options-signal.js", + "test-whatwg-events-customevent.js", + "test-whatwg-url-custom-deepequal.js", + "test-whatwg-url-custom-global.js", + "test-whatwg-url-custom-href-side-effect.js", + "test-whatwg-url-custom-tostringtag.js", + "test-whatwg-url-override-hostname.js", + "test-whatwg-url-properties.js", + "test-zlib-close-after-error.js", + "test-zlib-close-after-write.js", + "test-zlib-convenience-methods.js", + "test-zlib-deflate-raw-inherits.js", + "test-zlib-destroy-pipe.js", + "test-zlib-empty-buffer.js", + "test-zlib-from-string.js", + "test-zlib-invalid-input.js", + "test-zlib-no-stream.js", + "test-zlib-random-byte-pipes.js", + "test-zlib-sync-no-event.js", + "test-zlib-truncated.js", + "test-zlib-unzip-one-byte-chunks.js", + "test-zlib-write-after-end.js", + "test-zlib-write-after-flush.js", + "test-zlib-zero-byte.js", + "test-zlib-zero-windowBits.js" + ], + "pseudo-tty": [ + "console-dumb-tty.js", + "console_colors.js", + "no_dropped_stdio.js", + "no_interleaved_stdio.js", + "test-tty-color-support-warning-2.js", + "test-tty-color-support-warning.js", + "test-tty-stdin-end.js", + "test-tty-stdout-end.js" + ], + "pummel": [], + "sequential": ["test-child-process-exit.js"] + }, + "windowsIgnore": { + "parallel": [ + "test-child-process-exec-abortcontroller-promisified.js", + "test-console-log-throw-primitive.js", + "test-console-no-swallow-stack-overflow.js", + "test-console-sync-write-error.js", + "test-dns.js", + "test-dns-resolveany.js", + "test-fs-access.js", + "test-fs-mkdir.js", + "test-fs-open-mode-mask.js", + "test-fs-readdir-stack-overflow.js", + "test-fs-rm.js", + "test-fs-watchfile.js", + "test-fs-write-file-invalid-path.js", + "test-fs-write-file-sync.js", + "test-fs-write-file.js", + "test-http-client-get-url.js", + "test-http-client-reject-cr-no-lf.js", + "test-net-allow-half-open.js", + "test-net-better-error-messages-listen-path.js", + "test-net-better-error-messages-path.js", + "test-net-pipe-connect-errors.js", + "test-net-server-listen-path.js", + "test-net-socket-close-after-end.js", + "test-util-inspect-long-running.js", + "test-util-inspect.js" + ] + }, + "darwinIgnore": { + "parallel": [ + "test-net-allow-half-open.js", + "test-net-socket-close-after-end.js", + "test-fs-watchfile.js" + ] + }, + "suitesFolder": "test", + "versionsFolder": "versions" +} diff --git a/tests/node_compat/deno.json b/tests/node_compat/deno.json new file mode 100644 index 000000000..ec93111fd --- /dev/null +++ b/tests/node_compat/deno.json @@ -0,0 +1,5 @@ +{ + "imports": { + "@test_util/": "../../test_util/" + } +} diff --git a/tests/node_compat/polyfill_globals.js b/tests/node_compat/polyfill_globals.js new file mode 100644 index 000000000..93246d2ef --- /dev/null +++ b/tests/node_compat/polyfill_globals.js @@ -0,0 +1,25 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +import process from "node:process"; +import { Buffer } from "node:buffer"; +import { + clearImmediate, + clearInterval, + clearTimeout, + setImmediate, + setInterval, + setTimeout, +} from "node:timers"; +import { performance } from "node:perf_hooks"; +import console from "node:console"; +globalThis.Buffer = Buffer; +globalThis.clearImmediate = clearImmediate; +globalThis.clearInterval = clearInterval; +globalThis.clearTimeout = clearTimeout; +globalThis.console = console; +globalThis.global = globalThis; +globalThis.performance = performance; +globalThis.process = process; +globalThis.setImmediate = setImmediate; +globalThis.setInterval = setInterval; +globalThis.setTimeout = setTimeout; +delete globalThis.window; diff --git a/tests/node_compat/runner.ts b/tests/node_compat/runner.ts new file mode 100644 index 000000000..4695037cc --- /dev/null +++ b/tests/node_compat/runner.ts @@ -0,0 +1,14 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +import "./polyfill_globals.js"; +import { createRequire } from "node:module"; +import { toFileUrl } from "@test_util/std/path/mod.ts"; +const file = Deno.args[0]; +if (!file) { + throw new Error("No file provided"); +} + +if (file.endsWith(".mjs")) { + await import(toFileUrl(file).href); +} else { + createRequire(import.meta.url)(file); +} diff --git a/tests/node_compat/test.ts b/tests/node_compat/test.ts new file mode 100644 index 000000000..13ff429b5 --- /dev/null +++ b/tests/node_compat/test.ts @@ -0,0 +1,168 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +/** + * This script will run the test files specified in the configuration file. + * + * Each test file will be run independently (in a separate process as this is + * what Node.js is doing) and we wait until it completes. If the process reports + * an abnormal code, the test is reported and the test suite will fail + * immediately. + * + * Some tests check for presence of certain `process.exitCode`. + * Some tests depends on directories/files created by other tests - they must + * all share the same working directory. + */ + +import { magenta } from "@test_util/std/fmt/colors.ts"; +import { pooledMap } from "@test_util/std/async/pool.ts"; +import { dirname, fromFileUrl, join } from "@test_util/std/path/mod.ts"; +import { fail } from "@test_util/std/assert/mod.ts"; +import { + config, + getPathsFromTestSuites, + partitionParallelTestPaths, +} from "./common.ts"; + +// If the test case is invoked like +// deno test -A cli/tests/node_compat/test.ts -- +// Use the as filters +const filters = Deno.args; +const hasFilters = filters.length > 0; +const toolsPath = dirname(fromFileUrl(import.meta.url)); +const testPaths = partitionParallelTestPaths( + getPathsFromTestSuites(config.tests), +); +const cwd = new URL(".", import.meta.url); +const windowsIgnorePaths = new Set( + getPathsFromTestSuites(config.windowsIgnore), +); +const darwinIgnorePaths = new Set( + getPathsFromTestSuites(config.darwinIgnore), +); + +const decoder = new TextDecoder(); +let testSerialId = 0; + +async function runTest(t: Deno.TestContext, path: string): Promise { + // If filter patterns are given and any pattern doesn't match + // to the file path, then skip the case + if ( + filters.length > 0 && + filters.every((pattern) => !path.includes(pattern)) + ) { + return; + } + const ignore = + (Deno.build.os === "windows" && windowsIgnorePaths.has(path)) || + (Deno.build.os === "darwin" && darwinIgnorePaths.has(path)); + await t.step({ + name: `Node.js compatibility "${path}"`, + ignore, + sanitizeOps: false, + sanitizeResources: false, + sanitizeExit: false, + fn: async () => { + const testCase = join(toolsPath, "test", path); + + const v8Flags = ["--stack-size=4000"]; + const testSource = await Deno.readTextFile(testCase); + const envVars: Record = {}; + // TODO(kt3k): Parse `Flags` directive correctly + if (testSource.includes("Flags: --expose_externalize_string")) { + v8Flags.push("--expose-externalize-string"); + // TODO(bartlomieju): disable verifying globals if that V8 flag is + // present. Even though we should be able to pass a list of globals + // that are allowed, it doesn't work, because the list is expected to + // contain actual JS objects, not strings :)). + envVars["NODE_TEST_KNOWN_GLOBALS"] = "0"; + } + + const args = [ + "run", + "-A", + "--quiet", + //"--unsafely-ignore-certificate-errors", + "--unstable-bare-node-builtins", + "--v8-flags=" + v8Flags.join(), + "runner.ts", + testCase, + ]; + + // Pipe stdout in order to output each test result as Deno.test output + // That way the tests will respect the `--quiet` option when provided + const command = new Deno.Command(Deno.execPath(), { + args, + env: { + TEST_SERIAL_ID: String(testSerialId++), + ...envVars, + }, + cwd, + }); + const { code, stdout, stderr } = await command.output(); + + if (code !== 0) { + // If the test case failed, show the stdout, stderr, and instruction + // for repeating the single test case. + if (stdout.length) { + console.log(decoder.decode(stdout)); + } + const stderrOutput = decoder.decode(stderr); + const repeatCmd = magenta( + `./target/debug/deno test -A cli/tests/node_compat/test.ts -- ${path}`, + ); + const msg = `"${magenta(path)}" failed: + +${stderrOutput} + +You can repeat only this test with the command: + + ${repeatCmd} +`; + console.log(msg); + fail(msg); + } else if (hasFilters) { + // Even if the test case is successful, shows the stdout and stderr + // when test case filtering is specified. + if (stdout.length) console.log(decoder.decode(stdout)); + if (stderr.length) console.log(decoder.decode(stderr)); + } + }, + }); +} + +Deno.test("Node.js compatibility", async (t) => { + for (const path of testPaths.sequential) { + await runTest(t, path); + } + const testPool = pooledMap( + navigator.hardwareConcurrency, + testPaths.parallel, + (path) => runTest(t, path), + ); + const testCases = []; + for await (const testCase of testPool) { + testCases.push(testCase); + } + await Promise.all(testCases); +}); + +function checkConfigTestFilesOrder(testFileLists: Array) { + for (const testFileList of testFileLists) { + const sortedTestList = JSON.parse(JSON.stringify(testFileList)); + sortedTestList.sort(); + if (JSON.stringify(testFileList) !== JSON.stringify(sortedTestList)) { + throw new Error( + `File names in \`config.json\` are not correct order.`, + ); + } + } +} + +if (!hasFilters) { + Deno.test("checkConfigTestFilesOrder", function () { + checkConfigTestFilesOrder([ + ...Object.keys(config.ignore).map((suite) => config.ignore[suite]), + ...Object.keys(config.tests).map((suite) => config.tests[suite]), + ]); + }); +} diff --git a/tests/node_compat/test/common/child_process.js b/tests/node_compat/test/common/child_process.js new file mode 100644 index 000000000..b860d7697 --- /dev/null +++ b/tests/node_compat/test/common/child_process.js @@ -0,0 +1,56 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const assert = require('assert'); +const common = require('./'); + +// Workaround for Windows Server 2008R2 +// When CMD is used to launch a process and CMD is killed too quickly, the +// process can stay behind running in suspended state, never completing. +function cleanupStaleProcess(filename) { + if (!common.isWindows) { + return; + } + process.once('beforeExit', () => { + const basename = filename.replace(/.*[/\\]/g, ''); + try { + require('child_process') + .execFileSync(`${process.env.SystemRoot}\\System32\\wbem\\WMIC.exe`, [ + 'process', + 'where', + `commandline like '%${basename}%child'`, + 'delete', + '/nointeractive', + ]); + } catch { + // Ignore failures, there might not be any stale process to clean up. + } + }); +} + +// This should keep the child process running long enough to expire +// the timeout. +const kExpiringChildRunTime = common.platformTimeout(20 * 1000); +const kExpiringParentTimer = 1; +assert(kExpiringChildRunTime > kExpiringParentTimer); + +function logAfterTime(time) { + setTimeout(() => { + // The following console statements are part of the test. + console.log('child stdout'); + console.error('child stderr'); + }, time); +} + +module.exports = { + cleanupStaleProcess, + logAfterTime, + kExpiringChildRunTime, + kExpiringParentTimer, +}; diff --git a/tests/node_compat/test/common/countdown.js b/tests/node_compat/test/common/countdown.js new file mode 100644 index 000000000..a7ae0d029 --- /dev/null +++ b/tests/node_compat/test/common/countdown.js @@ -0,0 +1,35 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const assert = require('assert'); +const kLimit = Symbol('limit'); +const kCallback = Symbol('callback'); +const common = require('./'); + +class Countdown { + constructor(limit, cb) { + assert.strictEqual(typeof limit, 'number'); + assert.strictEqual(typeof cb, 'function'); + this[kLimit] = limit; + this[kCallback] = common.mustCall(cb); + } + + dec() { + assert(this[kLimit] > 0, 'Countdown expired'); + if (--this[kLimit] === 0) + this[kCallback](); + return this[kLimit]; + } + + get remaining() { + return this[kLimit]; + } +} + +module.exports = Countdown; diff --git a/tests/node_compat/test/common/dns.js b/tests/node_compat/test/common/dns.js new file mode 100644 index 000000000..54df6a55e --- /dev/null +++ b/tests/node_compat/test/common/dns.js @@ -0,0 +1,327 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const assert = require('assert'); +const os = require('os'); + +const types = { + A: 1, + AAAA: 28, + NS: 2, + CNAME: 5, + SOA: 6, + PTR: 12, + MX: 15, + TXT: 16, + ANY: 255, + CAA: 257, +}; + +const classes = { + IN: 1, +}; + +// Naïve DNS parser/serializer. + +function readDomainFromPacket(buffer, offset) { + assert.ok(offset < buffer.length); + const length = buffer[offset]; + if (length === 0) { + return { nread: 1, domain: '' }; + } else if ((length & 0xC0) === 0) { + offset += 1; + const chunk = buffer.toString('ascii', offset, offset + length); + // Read the rest of the domain. + const { nread, domain } = readDomainFromPacket(buffer, offset + length); + return { + nread: 1 + length + nread, + domain: domain ? `${chunk}.${domain}` : chunk, + }; + } + // Pointer to another part of the packet. + assert.strictEqual(length & 0xC0, 0xC0); + // eslint-disable-next-line space-infix-ops, space-unary-ops + const pointeeOffset = buffer.readUInt16BE(offset) &~ 0xC000; + return { + nread: 2, + domain: readDomainFromPacket(buffer, pointeeOffset), + }; +} + +function parseDNSPacket(buffer) { + assert.ok(buffer.length > 12); + + const parsed = { + id: buffer.readUInt16BE(0), + flags: buffer.readUInt16BE(2), + }; + + const counts = [ + ['questions', buffer.readUInt16BE(4)], + ['answers', buffer.readUInt16BE(6)], + ['authorityAnswers', buffer.readUInt16BE(8)], + ['additionalRecords', buffer.readUInt16BE(10)], + ]; + + let offset = 12; + for (const [ sectionName, count ] of counts) { + parsed[sectionName] = []; + for (let i = 0; i < count; ++i) { + const { nread, domain } = readDomainFromPacket(buffer, offset); + offset += nread; + + const type = buffer.readUInt16BE(offset); + + const rr = { + domain, + cls: buffer.readUInt16BE(offset + 2), + }; + offset += 4; + + for (const name in types) { + if (types[name] === type) + rr.type = name; + } + + if (sectionName !== 'questions') { + rr.ttl = buffer.readInt32BE(offset); + const dataLength = buffer.readUInt16BE(offset); + offset += 6; + + switch (type) { + case types.A: + assert.strictEqual(dataLength, 4); + rr.address = `${buffer[offset + 0]}.${buffer[offset + 1]}.` + + `${buffer[offset + 2]}.${buffer[offset + 3]}`; + break; + case types.AAAA: + assert.strictEqual(dataLength, 16); + rr.address = buffer.toString('hex', offset, offset + 16) + .replace(/(.{4}(?!$))/g, '$1:'); + break; + case types.TXT: + { + let position = offset; + rr.entries = []; + while (position < offset + dataLength) { + const txtLength = buffer[offset]; + rr.entries.push(buffer.toString('utf8', + position + 1, + position + 1 + txtLength)); + position += 1 + txtLength; + } + assert.strictEqual(position, offset + dataLength); + break; + } + case types.MX: + { + rr.priority = buffer.readInt16BE(buffer, offset); + offset += 2; + const { nread, domain } = readDomainFromPacket(buffer, offset); + rr.exchange = domain; + assert.strictEqual(nread, dataLength); + break; + } + case types.NS: + case types.CNAME: + case types.PTR: + { + const { nread, domain } = readDomainFromPacket(buffer, offset); + rr.value = domain; + assert.strictEqual(nread, dataLength); + break; + } + case types.SOA: + { + const mname = readDomainFromPacket(buffer, offset); + const rname = readDomainFromPacket(buffer, offset + mname.nread); + rr.nsname = mname.domain; + rr.hostmaster = rname.domain; + const trailerOffset = offset + mname.nread + rname.nread; + rr.serial = buffer.readUInt32BE(trailerOffset); + rr.refresh = buffer.readUInt32BE(trailerOffset + 4); + rr.retry = buffer.readUInt32BE(trailerOffset + 8); + rr.expire = buffer.readUInt32BE(trailerOffset + 12); + rr.minttl = buffer.readUInt32BE(trailerOffset + 16); + + assert.strictEqual(trailerOffset + 20, dataLength); + break; + } + default: + throw new Error(`Unknown RR type ${rr.type}`); + } + offset += dataLength; + } + + parsed[sectionName].push(rr); + + assert.ok(offset <= buffer.length); + } + } + + assert.strictEqual(offset, buffer.length); + return parsed; +} + +function writeIPv6(ip) { + const parts = ip.replace(/^:|:$/g, '').split(':'); + const buf = Buffer.alloc(16); + + let offset = 0; + for (const part of parts) { + if (part === '') { + offset += 16 - 2 * (parts.length - 1); + } else { + buf.writeUInt16BE(parseInt(part, 16), offset); + offset += 2; + } + } + + return buf; +} + +function writeDomainName(domain) { + return Buffer.concat(domain.split('.').map((label) => { + assert(label.length < 64); + return Buffer.concat([ + Buffer.from([label.length]), + Buffer.from(label, 'ascii'), + ]); + }).concat([Buffer.alloc(1)])); +} + +function writeDNSPacket(parsed) { + const buffers = []; + const kStandardResponseFlags = 0x8180; + + buffers.push(new Uint16Array([ + parsed.id, + parsed.flags === undefined ? kStandardResponseFlags : parsed.flags, + parsed.questions && parsed.questions.length, + parsed.answers && parsed.answers.length, + parsed.authorityAnswers && parsed.authorityAnswers.length, + parsed.additionalRecords && parsed.additionalRecords.length, + ])); + + for (const q of parsed.questions) { + assert(types[q.type]); + buffers.push(writeDomainName(q.domain)); + buffers.push(new Uint16Array([ + types[q.type], + q.cls === undefined ? classes.IN : q.cls, + ])); + } + + for (const rr of [].concat(parsed.answers, + parsed.authorityAnswers, + parsed.additionalRecords)) { + if (!rr) continue; + + assert(types[rr.type]); + buffers.push(writeDomainName(rr.domain)); + buffers.push(new Uint16Array([ + types[rr.type], + rr.cls === undefined ? classes.IN : rr.cls, + ])); + buffers.push(new Int32Array([rr.ttl])); + + const rdLengthBuf = new Uint16Array(1); + buffers.push(rdLengthBuf); + + switch (rr.type) { + case 'A': + rdLengthBuf[0] = 4; + buffers.push(new Uint8Array(rr.address.split('.'))); + break; + case 'AAAA': + rdLengthBuf[0] = 16; + buffers.push(writeIPv6(rr.address)); + break; + case 'TXT': { + const total = rr.entries.map((s) => s.length).reduce((a, b) => a + b); + // Total length of all strings + 1 byte each for their lengths. + rdLengthBuf[0] = rr.entries.length + total; + for (const txt of rr.entries) { + buffers.push(new Uint8Array([Buffer.byteLength(txt)])); + buffers.push(Buffer.from(txt)); + } + break; + } + case 'MX': + rdLengthBuf[0] = 2; + buffers.push(new Uint16Array([rr.priority])); + // fall through + case 'NS': + case 'CNAME': + case 'PTR': + { + const domain = writeDomainName(rr.exchange || rr.value); + rdLengthBuf[0] += domain.length; + buffers.push(domain); + break; + } + case 'SOA': + { + const mname = writeDomainName(rr.nsname); + const rname = writeDomainName(rr.hostmaster); + rdLengthBuf[0] = mname.length + rname.length + 20; + buffers.push(mname, rname); + buffers.push(new Uint32Array([ + rr.serial, rr.refresh, rr.retry, rr.expire, rr.minttl, + ])); + break; + } + case 'CAA': + { + rdLengthBuf[0] = 5 + rr.issue.length + 2; + buffers.push(Buffer.from([Number(rr.critical)])); + buffers.push(Buffer.from([Number(5)])); + buffers.push(Buffer.from('issue' + rr.issue)); + break; + } + default: + throw new Error(`Unknown RR type ${rr.type}`); + } + } + + return Buffer.concat(buffers.map((typedArray) => { + const buf = Buffer.from(typedArray.buffer, + typedArray.byteOffset, + typedArray.byteLength); + if (os.endianness() === 'LE') { + if (typedArray.BYTES_PER_ELEMENT === 2) buf.swap16(); + if (typedArray.BYTES_PER_ELEMENT === 4) buf.swap32(); + } + return buf; + })); +} + +const mockedErrorCode = 'ENOTFOUND'; +const mockedSysCall = 'getaddrinfo'; + +function errorLookupMock(code = mockedErrorCode, syscall = mockedSysCall) { + return function lookupWithError(hostname, dnsopts, cb) { + const err = new Error(`${syscall} ${code} ${hostname}`); + err.code = code; + err.errno = code; + err.syscall = syscall; + err.hostname = hostname; + cb(err); + }; +} + +module.exports = { + types, + classes, + writeDNSPacket, + parseDNSPacket, + errorLookupMock, + mockedErrorCode, + mockedSysCall, +}; diff --git a/tests/node_compat/test/common/duplexpair.js b/tests/node_compat/test/common/duplexpair.js new file mode 100644 index 000000000..6e5286cc8 --- /dev/null +++ b/tests/node_compat/test/common/duplexpair.js @@ -0,0 +1,55 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const { Duplex } = require('stream'); +const assert = require('assert'); + +const kCallback = Symbol('Callback'); +const kOtherSide = Symbol('Other'); + +class DuplexSocket extends Duplex { + constructor() { + super(); + this[kCallback] = null; + this[kOtherSide] = null; + } + + _read() { + const callback = this[kCallback]; + if (callback) { + this[kCallback] = null; + callback(); + } + } + + _write(chunk, encoding, callback) { + assert.notStrictEqual(this[kOtherSide], null); + assert.strictEqual(this[kOtherSide][kCallback], null); + if (chunk.length === 0) { + process.nextTick(callback); + } else { + this[kOtherSide].push(chunk); + this[kOtherSide][kCallback] = callback; + } + } + + _final(callback) { + this[kOtherSide].on('end', callback); + this[kOtherSide].push(null); + } +} + +function makeDuplexPair() { + const clientSide = new DuplexSocket(); + const serverSide = new DuplexSocket(); + clientSide[kOtherSide] = serverSide; + serverSide[kOtherSide] = clientSide; + return { clientSide, serverSide }; +} + +module.exports = makeDuplexPair; diff --git a/tests/node_compat/test/common/fixtures.js b/tests/node_compat/test/common/fixtures.js new file mode 100644 index 000000000..64b888eb6 --- /dev/null +++ b/tests/node_compat/test/common/fixtures.js @@ -0,0 +1,45 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const path = require('path'); +const fs = require('fs'); +const { pathToFileURL } = require('url'); + +const fixturesDir = path.join(__dirname, '..', 'fixtures'); + +function fixturesPath(...args) { + return path.join(fixturesDir, ...args); +} + +function fixturesFileURL(...args) { + return pathToFileURL(fixturesPath(...args)); +} + +function readFixtureSync(args, enc) { + if (Array.isArray(args)) + return fs.readFileSync(fixturesPath(...args), enc); + return fs.readFileSync(fixturesPath(args), enc); +} + +function readFixtureKey(name, enc) { + return fs.readFileSync(fixturesPath('keys', name), enc); +} + +function readFixtureKeys(enc, ...names) { + return names.map((name) => readFixtureKey(name, enc)); +} + +module.exports = { + fixturesDir, + path: fixturesPath, + fileURL: fixturesFileURL, + readSync: readFixtureSync, + readKey: readFixtureKey, + readKeys: readFixtureKeys, +}; diff --git a/tests/node_compat/test/common/hijackstdio.js b/tests/node_compat/test/common/hijackstdio.js new file mode 100644 index 000000000..38582ece2 --- /dev/null +++ b/tests/node_compat/test/common/hijackstdio.js @@ -0,0 +1,39 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +// Hijack stdout and stderr +const stdWrite = {}; +function hijackStdWritable(name, listener) { + const stream = process[name]; + const _write = stdWrite[name] = stream.write; + + stream.writeTimes = 0; + stream.write = function(data, callback) { + try { + listener(data); + } catch (e) { + process.nextTick(() => { throw e; }); + } + + _write.call(stream, data, callback); + stream.writeTimes++; + }; +} + +function restoreWritable(name) { + process[name].write = stdWrite[name]; + delete process[name].writeTimes; +} + +module.exports = { + hijackStdout: hijackStdWritable.bind(null, 'stdout'), + hijackStderr: hijackStdWritable.bind(null, 'stderr'), + restoreStdout: restoreWritable.bind(null, 'stdout'), + restoreStderr: restoreWritable.bind(null, 'stderr'), +}; diff --git a/tests/node_compat/test/common/index.js b/tests/node_compat/test/common/index.js new file mode 100644 index 000000000..9f5b4814c --- /dev/null +++ b/tests/node_compat/test/common/index.js @@ -0,0 +1,496 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. + +/** + * This file is meant as a replacement for the original common/index.js + * + * That file has a lot of node functionality not currently supported, so this is a lite + * version of that file, which most tests should be able to use + */ +'use strict'; +const assert = require("assert"); +const path = require("path"); +const util = require("util"); +const tmpdir = require("./tmpdir"); + +function platformTimeout(ms) { + return ms; +} + +let localhostIPv4 = null; + +let knownGlobals = [ + AbortSignal, + addEventListener, + alert, + atob, + btoa, + Buffer, + caches, + clearImmediate, + close, + closed, + confirm, + console, + createImageBitmap, + crypto, + Deno, + dispatchEvent, + EventSource, + fetch, + getParent, + global, + global.clearInterval, + global.clearTimeout, + global.setInterval, + global.setTimeout, + localStorage, + location, + name, + navigator, + onload, + onunload, + process, + prompt, + queueMicrotask, + removeEventListener, + reportError, + self, + sessionStorage, + setImmediate, + window, +]; + +if (global.AbortController) + knownGlobals.push(global.AbortController); + +if (global.gc) { + knownGlobals.push(global.gc); +} + +if (global.performance) { + knownGlobals.push(global.performance); +} +if (global.PerformanceMark) { + knownGlobals.push(global.PerformanceMark); +} +if (global.PerformanceMeasure) { + knownGlobals.push(global.PerformanceMeasure); +} + +if (global.structuredClone) { + knownGlobals.push(global.structuredClone); +} + +function allowGlobals(...allowlist) { + knownGlobals = knownGlobals.concat(allowlist); +} + +if (process.env.NODE_TEST_KNOWN_GLOBALS !== '0') { + if (process.env.NODE_TEST_KNOWN_GLOBALS) { + const knownFromEnv = process.env.NODE_TEST_KNOWN_GLOBALS.split(','); + allowGlobals(...knownFromEnv); + } + + function leakedGlobals() { + const leaked = []; + + for (const val in global) { + if (!knownGlobals.includes(global[val])) { + leaked.push(val); + } + } + + return leaked; + } + + process.on('exit', function() { + const leaked = leakedGlobals(); + if (leaked.length > 0) { + assert.fail(`Unexpected global(s) found: ${leaked.join(', ')}`); + } + }); +} + +function _expectWarning(name, expected, code) { + if (typeof expected === 'string') { + expected = [[expected, code]]; + } else if (!Array.isArray(expected)) { + expected = Object.entries(expected).map(([a, b]) => [b, a]); + } else if (!(Array.isArray(expected[0]))) { + expected = [[expected[0], expected[1]]]; + } + // Deprecation codes are mandatory, everything else is not. + if (name === 'DeprecationWarning') { + expected.forEach(([_, code]) => assert(code, expected)); + } + return mustCall((warning) => { + const [ message, code ] = expected.shift(); + assert.strictEqual(warning.name, name); + if (typeof message === 'string') { + assert.strictEqual(warning.message, message); + } else { + assert.match(warning.message, message); + } + assert.strictEqual(warning.code, code); + }, expected.length); +} + +let catchWarning; + +// Accepts a warning name and description or array of descriptions or a map of +// warning names to description(s) ensures a warning is generated for each +// name/description pair. +// The expected messages have to be unique per `expectWarning()` call. +function expectWarning(nameOrMap, expected, code) { + if (catchWarning === undefined) { + catchWarning = {}; + process.on('warning', (warning) => { + if (!catchWarning[warning.name]) { + throw new TypeError( + `"${warning.name}" was triggered without being expected.\n` + + util.inspect(warning) + ); + } + catchWarning[warning.name](warning); + }); + } + if (typeof nameOrMap === 'string') { + catchWarning[nameOrMap] = _expectWarning(nameOrMap, expected, code); + } else { + Object.keys(nameOrMap).forEach((name) => { + catchWarning[name] = _expectWarning(name, nameOrMap[name]); + }); + } +} + +/** + * Useful for testing expected internal/error objects + * + * @param {Error} error + */ +function expectsError(validator, exact) { + /** + * @param {Error} error + */ + return mustCall((...args) => { + if (args.length !== 1) { + // Do not use `assert.strictEqual()` to prevent `inspect` from + // always being called. + assert.fail(`Expected one argument, got ${util.inspect(args)}`); + } + const error = args.pop(); + const descriptor = Object.getOwnPropertyDescriptor(error, 'message'); + // The error message should be non-enumerable + assert.strictEqual(descriptor.enumerable, false); + + assert.throws(() => { throw error; }, validator); + return true; + }, exact); +} + +const noop = () => {}; + +/** + * @param {Function} fn + * @param {number} exact + */ +function mustCall(fn, exact) { + return _mustCallInner(fn, exact, "exact"); +} + +function mustCallAtLeast(fn, minimum) { + return _mustCallInner(fn, minimum, 'minimum'); +} + +function mustSucceed(fn, exact) { + return mustCall(function(err, ...args) { + assert.ifError(err); + if (typeof fn === 'function') + return fn.apply(this, args); + }, exact); +} + +const mustCallChecks = []; +/** + * @param {number} exitCode + */ +function runCallChecks(exitCode) { + if (exitCode !== 0) return; + + const failed = mustCallChecks.filter(function (context) { + if ("minimum" in context) { + context.messageSegment = `at least ${context.minimum}`; + return context.actual < context.minimum; + } + context.messageSegment = `exactly ${context.exact}`; + return context.actual !== context.exact; + }); + + failed.forEach(function (context) { + console.log( + "Mismatched %s function calls. Expected %s, actual %d.", + context.name, + context.messageSegment, + context.actual, + ); + console.log(context.stack.split("\n").slice(2).join("\n")); + }); + + if (failed.length) process.exit(1); +} + +/** + * @param {Function} fn + * @param {"exact" | "minimum"} field + */ +function _mustCallInner(fn, criteria = 1, field) { + // @ts-ignore + if (process._exiting) { + throw new Error("Cannot use common.mustCall*() in process exit handler"); + } + if (typeof fn === "number") { + criteria = fn; + fn = noop; + } else if (fn === undefined) { + fn = noop; + } + + if (typeof criteria !== "number") { + throw new TypeError(`Invalid ${field} value: ${criteria}`); + } + + let context; + if (field === "exact") { + context = { + exact: criteria, + actual: 0, + stack: util.inspect(new Error()), + name: fn.name || "", + }; + } else { + context = { + minimum: criteria, + actual: 0, + stack: util.inspect(new Error()), + name: fn.name || "", + }; + } + + // Add the exit listener only once to avoid listener leak warnings + if (mustCallChecks.length === 0) process.on("exit", runCallChecks); + + mustCallChecks.push(context); + + return function () { + context.actual++; + return fn.apply(this, arguments); + }; +} + +/** + * @param {string=} msg + */ +function mustNotCall(msg) { + /** + * @param {any[]} args + */ + return function mustNotCall(...args) { + const argsInfo = args.length > 0 + ? `\ncalled with arguments: ${args.map(util.inspect).join(", ")}` + : ""; + assert.fail( + `${msg || "function should not have been called"} at unknown` + + argsInfo, + ); + }; +} + +const _mustNotMutateObjectDeepProxies = new WeakMap(); + +function mustNotMutateObjectDeep(original) { + // Return primitives and functions directly. Primitives are immutable, and + // proxied functions are impossible to compare against originals, e.g. with + // `assert.deepEqual()`. + if (original === null || typeof original !== 'object') { + return original; + } + + const cachedProxy = _mustNotMutateObjectDeepProxies.get(original); + if (cachedProxy) { + return cachedProxy; + } + + const _mustNotMutateObjectDeepHandler = { + __proto__: null, + defineProperty(target, property, descriptor) { + assert.fail(`Expected no side effects, got ${inspect(property)} ` + + 'defined'); + }, + deleteProperty(target, property) { + assert.fail(`Expected no side effects, got ${inspect(property)} ` + + 'deleted'); + }, + get(target, prop, receiver) { + return mustNotMutateObjectDeep(Reflect.get(target, prop, receiver)); + }, + preventExtensions(target) { + assert.fail('Expected no side effects, got extensions prevented on ' + + inspect(target)); + }, + set(target, property, value, receiver) { + assert.fail(`Expected no side effects, got ${inspect(value)} ` + + `assigned to ${inspect(property)}`); + }, + setPrototypeOf(target, prototype) { + assert.fail(`Expected no side effects, got set prototype to ${prototype}`); + } + }; + + const proxy = new Proxy(original, _mustNotMutateObjectDeepHandler); + _mustNotMutateObjectDeepProxies.set(original, proxy); + return proxy; +} + +// A helper function to simplify checking for ERR_INVALID_ARG_TYPE output. +function invalidArgTypeHelper(input) { + if (input == null) { + return ` Received ${input}`; + } + if (typeof input === "function" && input.name) { + return ` Received function ${input.name}`; + } + if (typeof input === "object") { + if (input.constructor && input.constructor.name) { + return ` Received an instance of ${input.constructor.name}`; + } + return ` Received ${util.inspect(input, { depth: -1 })}`; + } + let inspected = util.inspect(input, { colors: false }); + if (inspected.length > 25) { + inspected = `${inspected.slice(0, 25)}...`; + } + return ` Received type ${typeof input} (${inspected})`; +} + +const isWindows = process.platform === 'win32'; +const isAIX = process.platform === 'aix'; +const isSunOS = process.platform === 'sunos'; +const isFreeBSD = process.platform === 'freebsd'; +const isOpenBSD = process.platform === 'openbsd'; +const isLinux = process.platform === 'linux'; +const isOSX = process.platform === 'darwin'; + +const isDumbTerminal = process.env.TERM === 'dumb'; + +function skipIfDumbTerminal() { + if (isDumbTerminal) { + skip('skipping - dumb terminal'); + } +} + +function printSkipMessage(msg) { + console.log(`1..0 # Skipped: ${msg}`); +} + +function skip(msg) { + printSkipMessage(msg); + process.exit(0); +} + +const PIPE = (() => { + const localRelative = path.relative(process.cwd(), `${tmpdir.path}/`); + const pipePrefix = isWindows ? "\\\\.\\pipe\\" : localRelative; + const pipeName = `node-test.${process.pid}.sock`; + return path.join(pipePrefix, pipeName); +})(); + +function getArrayBufferViews(buf) { + const { buffer, byteOffset, byteLength } = buf; + + const out = []; + + const arrayBufferViews = [ + Int8Array, + Uint8Array, + Uint8ClampedArray, + Int16Array, + Uint16Array, + Int32Array, + Uint32Array, + Float32Array, + Float64Array, + DataView, + ]; + + for (const type of arrayBufferViews) { + const { BYTES_PER_ELEMENT = 1 } = type; + if (byteLength % BYTES_PER_ELEMENT === 0) { + out.push(new type(buffer, byteOffset, byteLength / BYTES_PER_ELEMENT)); + } + } + return out; +} + +function getBufferSources(buf) { + return [...getArrayBufferViews(buf), new Uint8Array(buf).buffer]; +} + +const pwdCommand = isWindows ? + ['cmd.exe', ['/d', '/c', 'cd']] : + ['pwd', []]; + +module.exports = { + allowGlobals, + expectsError, + expectWarning, + getArrayBufferViews, + getBufferSources, + hasCrypto: true, + hasIntl: true, + hasMultiLocalhost() { + return false; + }, + invalidArgTypeHelper, + mustCall, + mustCallAtLeast, + mustNotCall, + mustNotMutateObjectDeep, + mustSucceed, + PIPE, + platformTimeout, + printSkipMessage, + pwdCommand, + skipIfDumbTerminal, + isDumbTerminal, + isWindows, + isAIX, + isSunOS, + isFreeBSD, + isOpenBSD, + isLinux, + isOSX, + isMainThread: true, // TODO(f3n67u): replace with `worker_thread.isMainThread` when `worker_thread` implemented + skip, + get hasIPv6() { + const iFaces = require('os').networkInterfaces(); + const re = isWindows ? /Loopback Pseudo-Interface/ : /lo/; + return Object.keys(iFaces).some((name) => { + return re.test(name) && + iFaces[name].some(({ family }) => family === 'IPv6'); + }); + }, + + get localhostIPv4() { + if (localhostIPv4 !== null) return localhostIPv4; + if (localhostIPv4 === null) localhostIPv4 = '127.0.0.1'; + + return localhostIPv4; + }, + + get PORT() { + return 12346; + }, +}; diff --git a/tests/node_compat/test/common/index.mjs b/tests/node_compat/test/common/index.mjs new file mode 100644 index 000000000..25fe5cbb0 --- /dev/null +++ b/tests/node_compat/test/common/index.mjs @@ -0,0 +1,115 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +import { createRequire } from 'module'; + +const require = createRequire(import.meta.url); +const common = require('./index.js'); + +const { + isMainThread, + isWindows, + isAIX, + isIBMi, + isLinuxPPCBE, + isSunOS, + isDumbTerminal, + isFreeBSD, + isOpenBSD, + isLinux, + isOSX, + enoughTestMem, + buildType, + localIPv6Hosts, + opensslCli, + PIPE, + hasCrypto, + hasIPv6, + childShouldThrowAndAbort, + checkoutEOL, + createZeroFilledFile, + platformTimeout, + allowGlobals, + mustCall, + mustCallAtLeast, + mustSucceed, + hasMultiLocalhost, + skipIfDumbTerminal, + skipIfEslintMissing, + canCreateSymLink, + getCallSite, + mustNotCall, + mustNotMutateObjectDeep, + parseTestFlags, + printSkipMessage, + skip, + nodeProcessAborted, + isAlive, + expectWarning, + expectsError, + skipIfInspectorDisabled, + skipIf32Bits, + getArrayBufferViews, + getBufferSources, + getTTYfd, + runWithInvalidFD, + spawnPromisified, +} = common; + +const getPort = () => common.PORT; + +export { + isMainThread, + isWindows, + isAIX, + isIBMi, + isLinuxPPCBE, + isSunOS, + isDumbTerminal, + isFreeBSD, + isOpenBSD, + isLinux, + isOSX, + enoughTestMem, + buildType, + localIPv6Hosts, + opensslCli, + PIPE, + hasCrypto, + hasIPv6, + childShouldThrowAndAbort, + checkoutEOL, + createZeroFilledFile, + platformTimeout, + allowGlobals, + mustCall, + mustCallAtLeast, + mustSucceed, + hasMultiLocalhost, + skipIfDumbTerminal, + skipIfEslintMissing, + canCreateSymLink, + getCallSite, + mustNotCall, + mustNotMutateObjectDeep, + parseTestFlags, + printSkipMessage, + skip, + nodeProcessAborted, + isAlive, + expectWarning, + expectsError, + skipIfInspectorDisabled, + skipIf32Bits, + getArrayBufferViews, + getBufferSources, + getTTYfd, + runWithInvalidFD, + createRequire, + spawnPromisified, + getPort, +}; diff --git a/tests/node_compat/test/common/internet.js b/tests/node_compat/test/common/internet.js new file mode 100644 index 000000000..b42fda66c --- /dev/null +++ b/tests/node_compat/test/common/internet.js @@ -0,0 +1,68 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +'use strict'; + +// Utilities for internet-related tests + +const addresses = { + // A generic host that has registered common DNS records, + // supports both IPv4 and IPv6, and provides basic HTTP/HTTPS services + INET_HOST: 'nodejs.org', + // A host that provides IPv4 services + INET4_HOST: 'nodejs.org', + // A host that provides IPv6 services + INET6_HOST: 'nodejs.org', + // An accessible IPv4 IP, + // defaults to the Google Public DNS IPv4 address + INET4_IP: '8.8.8.8', + // An accessible IPv6 IP, + // defaults to the Google Public DNS IPv6 address + INET6_IP: '2001:4860:4860::8888', + // An invalid host that cannot be resolved + // See https://tools.ietf.org/html/rfc2606#section-2 + INVALID_HOST: 'something.invalid', + // A host with MX records registered + MX_HOST: 'nodejs.org', + // On some systems, .invalid returns a server failure/try again rather than + // record not found. Use this to guarantee record not found. + NOT_FOUND: 'come.on.fhqwhgads.test', + // A host with SRV records registered + // TODO(kt3k): Temporarily use _caldav._tcp.google.com instead of + // _jabber._tcp.google.com, which currently doesn't respond + // SRV_HOST: '_jabber._tcp.google.com', + SRV_HOST: '_caldav._tcp.google.com', + // A host with PTR records registered + PTR_HOST: '8.8.8.8.in-addr.arpa', + // A host with NAPTR records registered + NAPTR_HOST: 'sip2sip.info', + // A host with SOA records registered + SOA_HOST: 'nodejs.org', + // A host with CAA record registered + CAA_HOST: 'google.com', + // A host with CNAME records registered + CNAME_HOST: 'blog.nodejs.org', + // A host with NS records registered + NS_HOST: 'nodejs.org', + // A host with TXT records registered + TXT_HOST: 'nodejs.org', + // An accessible IPv4 DNS server + DNS4_SERVER: '8.8.8.8', + // An accessible IPv4 DNS server + DNS6_SERVER: '2001:4860:4860::8888' +}; + +for (const key of Object.keys(addresses)) { + const envName = `NODE_TEST_${key}`; + if (process.env[envName]) { + addresses[key] = process.env[envName]; + } +} + +module.exports = { + addresses +}; diff --git a/tests/node_compat/test/common/package.json b/tests/node_compat/test/common/package.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/tests/node_compat/test/common/package.json @@ -0,0 +1 @@ +{} diff --git a/tests/node_compat/test/common/tmpdir.js b/tests/node_compat/test/common/tmpdir.js new file mode 100644 index 000000000..886c4a107 --- /dev/null +++ b/tests/node_compat/test/common/tmpdir.js @@ -0,0 +1,79 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const fs = require('fs'); +const path = require('path'); +const { isMainThread } = require('worker_threads'); + +function rmSync(pathname) { + fs.rmSync(pathname, { maxRetries: 3, recursive: true, force: true }); +} + +const testRoot = process.env.NODE_TEST_DIR ? + fs.realpathSync(process.env.NODE_TEST_DIR) : path.resolve(__dirname, '..'); + +// Using a `.` prefixed name, which is the convention for "hidden" on POSIX, +// gets tools to ignore it by default or by simple rules, especially eslint. +const tmpdirName = '.tmp.' + + (process.env.TEST_SERIAL_ID || process.env.TEST_THREAD_ID || '0'); +const tmpPath = path.join(testRoot, tmpdirName); + +let firstRefresh = true; +function refresh() { + rmSync(tmpPath); + fs.mkdirSync(tmpPath); + + if (firstRefresh) { + firstRefresh = false; + // Clean only when a test uses refresh. This allows for child processes to + // use the tmpdir and only the parent will clean on exit. + process.on('exit', onexit); + } +} + +function onexit() { + // Change directory to avoid possible EBUSY + if (isMainThread) + process.chdir(testRoot); + + try { + rmSync(tmpPath); + } catch (e) { + console.error('Can\'t clean tmpdir:', tmpPath); + + const files = fs.readdirSync(tmpPath); + console.error('Files blocking:', files); + + if (files.some((f) => f.startsWith('.nfs'))) { + // Warn about NFS "silly rename" + console.error('Note: ".nfs*" might be files that were open and ' + + 'unlinked but not closed.'); + console.error('See http://nfs.sourceforge.net/#faq_d2 for details.'); + } + + console.error(); + throw e; + } +} + +function resolve(...paths) { + return path.resolve(tmpPath, ...paths); +} + +function hasEnoughSpace(size) { + const { bavail, bsize } = fs.statfsSync(tmpPath); + return bavail >= Math.ceil(size / bsize); +} + +module.exports = { + path: tmpPath, + refresh, + hasEnoughSpace, + resolve, +}; diff --git a/tests/node_compat/test/fixtures/GH-1899-output.js b/tests/node_compat/test/fixtures/GH-1899-output.js new file mode 100644 index 000000000..d647eb320 --- /dev/null +++ b/tests/node_compat/test/fixtures/GH-1899-output.js @@ -0,0 +1,30 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +console.log('hello, world!'); + diff --git a/tests/node_compat/test/fixtures/a.js b/tests/node_compat/test/fixtures/a.js new file mode 100644 index 000000000..9f5a21a06 --- /dev/null +++ b/tests/node_compat/test/fixtures/a.js @@ -0,0 +1,53 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +const c = require('./b/c'); + +console.error('load fixtures/a.js'); + +var string = 'A'; + +exports.SomeClass = c.SomeClass; + +exports.A = function() { + return string; +}; + +exports.C = function() { + return c.C(); +}; + +exports.D = function() { + return c.D(); +}; + +exports.number = 42; + +process.on('exit', function() { + string = 'A done'; +}); diff --git a/tests/node_compat/test/fixtures/child-process-spawn-node.js b/tests/node_compat/test/fixtures/child-process-spawn-node.js new file mode 100644 index 000000000..da2b557c9 --- /dev/null +++ b/tests/node_compat/test/fixtures/child-process-spawn-node.js @@ -0,0 +1,14 @@ +const assert = require("assert"); +// TODO(kt3k): Uncomment this when util.debuglog is added +// const debug = require('util').debuglog('test'); +const debug = console.log; + +function onmessage(m) { + debug("CHILD got message:", m); + assert.ok(m.hello); + process.removeListener("message", onmessage); +} + +process.on("message", onmessage); +// TODO(kt3k): Uncomment the below when the ipc features are ready +// process.send({ foo: 'bar' }); diff --git a/tests/node_compat/test/fixtures/child_process_should_emit_error.js b/tests/node_compat/test/fixtures/child_process_should_emit_error.js new file mode 100644 index 000000000..5a56c312b --- /dev/null +++ b/tests/node_compat/test/fixtures/child_process_should_emit_error.js @@ -0,0 +1,36 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +const exec = require('child_process').exec; + +[0, 1].forEach(function(i) { + exec('ls', function(err, stdout, stderr) { + console.log(i); + throw new Error('hello world'); + }); +}); diff --git a/tests/node_compat/test/fixtures/echo.js b/tests/node_compat/test/fixtures/echo.js new file mode 100644 index 000000000..893099e9b --- /dev/null +++ b/tests/node_compat/test/fixtures/echo.js @@ -0,0 +1,41 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +const common = require('../common'); +const assert = require('assert'); + +process.stdout.write('hello world\r\n'); + +// TODO(PolarETech): process.openStdin() is not yet implemented. +// Use process.stdin instead. +var stdin = process.stdin; +// var stdin = process.openStdin(); + +stdin.on('data', function(data) { + process.stdout.write(data.toString()); +}); diff --git a/tests/node_compat/test/fixtures/elipses.txt b/tests/node_compat/test/fixtures/elipses.txt new file mode 100644 index 000000000..610560050 --- /dev/null +++ b/tests/node_compat/test/fixtures/elipses.txt @@ -0,0 +1 @@ +………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………… \ No newline at end of file diff --git a/tests/node_compat/test/fixtures/empty.txt b/tests/node_compat/test/fixtures/empty.txt new file mode 100644 index 000000000..e69de29bb diff --git a/tests/node_compat/test/fixtures/exit.js b/tests/node_compat/test/fixtures/exit.js new file mode 100644 index 000000000..ca80f4828 --- /dev/null +++ b/tests/node_compat/test/fixtures/exit.js @@ -0,0 +1,31 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// TODO(PolarETech): The process.argv[3] should be argv[2]. + +process.exit(process.argv[3] || 1); diff --git a/tests/node_compat/test/fixtures/keys/agent1-cert.pem b/tests/node_compat/test/fixtures/keys/agent1-cert.pem new file mode 100644 index 000000000..bef645b0f --- /dev/null +++ b/tests/node_compat/test/fixtures/keys/agent1-cert.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID6DCCAtCgAwIBAgIUFH02wcL3Qgben6tfIibXitsApCYwDQYJKoZIhvcNAQEL +BQAwejELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQswCQYDVQQHDAJTRjEPMA0G +A1UECgwGSm95ZW50MRAwDgYDVQQLDAdOb2RlLmpzMQwwCgYDVQQDDANjYTExIDAe +BgkqhkiG9w0BCQEWEXJ5QHRpbnljbG91ZHMub3JnMCAXDTIyMDkwMzIxNDAzN1oY +DzIyOTYwNjE3MjE0MDM3WjB9MQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExCzAJ +BgNVBAcMAlNGMQ8wDQYDVQQKDAZKb3llbnQxEDAOBgNVBAsMB05vZGUuanMxDzAN +BgNVBAMMBmFnZW50MTEgMB4GCSqGSIb3DQEJARYRcnlAdGlueWNsb3Vkcy5vcmcw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDUVjIK+yDTgnCT3CxChO0E +37q9VuHdrlKeKLeQzUJW2yczSfNzX/0zfHpjY+zKWie39z3HCJqWxtiG2wxiOI8c +3WqWOvzVmdWADlh6EfkIlg+E7VC6JaKDA+zabmhPvnuu3JzogBMnsWl68lCXzuPx +deQAmEwNtqjrh74DtM+Ud0ulb//Ixjxo1q3rYKu+aaexSramuee6qJta2rjrB4l8 +B/bU+j1mDf9XQQfSjo9jRnp4hiTFdBl2k+lZzqE2L/rhu6EMjA2IhAq/7xA2MbLo +9cObVUin6lfoo5+JKRgT9Fp2xEgDOit+2EA/S6oUfPNeLSVUqmXOSWlXlwlb9Nxr +AgMBAAGjYTBfMF0GCCsGAQUFBwEBBFEwTzAjBggrBgEFBQcwAYYXaHR0cDovL29j +c3Aubm9kZWpzLm9yZy8wKAYIKwYBBQUHMAKGHGh0dHA6Ly9jYS5ub2RlanMub3Jn +L2NhLmNlcnQwDQYJKoZIhvcNAQELBQADggEBAMM0mBBjLMt9pYXePtUeNO0VTw9y +FWCM8nAcAO2kRNwkJwcsispNpkcsHZ5o8Xf5mpCotdvziEWG1hyxwU6nAWyNOLcN +G0a0KUfbMO3B6ZYe1GwPDjXaQnv75SkAdxgX5zOzca3xnhITcjUUGjQ0fbDfwFV5 +ix8mnzvfXjDONdEznVa7PFcN6QliFUMwR/h8pCRHtE5+a10OSPeJSrGG+FtrGnRW +G1IJUv6oiGF/MvWCr84REVgc1j78xomGANJIu2hN7bnD1nEMON6em8IfnDOUtynV +9wfWTqiQYD5Zifj6WcGa0aAHMuetyFG4lIfMAHmd3gaKpks7j9l26LwRPvI= +-----END CERTIFICATE----- diff --git a/tests/node_compat/test/fixtures/keys/agent1-key.pem b/tests/node_compat/test/fixtures/keys/agent1-key.pem new file mode 100644 index 000000000..1bd840716 --- /dev/null +++ b/tests/node_compat/test/fixtures/keys/agent1-key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA1FYyCvsg04Jwk9wsQoTtBN+6vVbh3a5Snii3kM1CVtsnM0nz +c1/9M3x6Y2Psylont/c9xwialsbYhtsMYjiPHN1qljr81ZnVgA5YehH5CJYPhO1Q +uiWigwPs2m5oT757rtyc6IATJ7FpevJQl87j8XXkAJhMDbao64e+A7TPlHdLpW// +yMY8aNat62CrvmmnsUq2prnnuqibWtq46weJfAf21Po9Zg3/V0EH0o6PY0Z6eIYk +xXQZdpPpWc6hNi/64buhDIwNiIQKv+8QNjGy6PXDm1VIp+pX6KOfiSkYE/RadsRI +AzorfthAP0uqFHzzXi0lVKplzklpV5cJW/TcawIDAQABAoIBAAvbtHfAhpjJVBgt +15rvaX04MWmZjIugzKRgib/gdq/7FTlcC+iJl85kSUF7tyGl30n62MxgwqFhAX6m +hQ6HMhbelrFFIhGbwbyhEHfgwROlrcAysKt0pprCgVvBhrnNXYLqdyjU3jz9P3LK +TY3s0/YMK2uNFdI+PTjKH+Z9Foqn9NZUnUonEDepGyuRO7fLeccWJPv2L4CR4a/5 +ku4VbDgVpvVSVRG3PSVzbmxobnpdpl52og+T7tPx1cLnIknPtVljXPWtZdfekh2E +eAp2KxCCHOKzzG3ItBKsVu0woeqEpy8JcoO6LbgmEoVnZpgmtQClbBgef8+i+oGE +BgW9nmECgYEA8gA63QQuZOUC56N1QXURexN2PogF4wChPaCTFbQSJXvSBkQmbqfL +qRSD8P0t7GOioPrQK6pDwFf4BJB01AvkDf8Z6DxxOJ7cqIC7LOwDupXocWX7Q0Qk +O6cwclBVsrDZK00v60uRRpl/a39GW2dx7IiQDkKQndLh3/0TbMIWHNcCgYEA4J6r +yinZbLpKw2+ezhi4B4GT1bMLoKboJwpZVyNZZCzYR6ZHv+lS7HR/02rcYMZGoYbf +n7OHwF4SrnUS7vPhG4g2ZsOhKQnMvFSQqpGmK1ZTuoKGAevyvtouhK/DgtLWzGvX +9fSahiq/UvfXs/z4M11q9Rv9ztPCmG1cwSEHlo0CgYEAogQNZJK8DMhVnYcNpXke +7uskqtCeQE/Xo06xqkIYNAgloBRYNpUYAGa/vsOBz1UVN/kzDUi8ezVp0oRz8tLT +J5u2WIi+tE2HJTiqF3UbOfvK1sCT64DfUSCpip7GAQ/tFNRkVH8PD9kMOYfILsGe +v+DdsO5Xq5HXrwHb02BNNZkCgYBsl8lt33WiPx5OBfS8pu6xkk+qjPkeHhM2bKZs +nkZlS9j0KsudWGwirN/vkkYg8zrKdK5AQ0dqFRDrDuasZ3N5IA1M+V88u+QjWK7o +B6pSYVXxYZDv9OZSpqC+vUrEQLJf+fNakXrzSk9dCT1bYv2Lt6ox/epix7XYg2bI +Z/OHMQKBgQC2FUGhlndGeugTJaoJ8nhT/0VfRUX/h6sCgSerk5qFr/hNCBV4T022 +x0NDR2yLG6MXyqApJpG6rh3QIDElQoQCNlI3/KJ6JfEfmqrLLN2OigTvA5sE4fGU +Dp/ha8OQAx95EwXuaG7LgARduvOIK3x8qi8KsZoUGJcg2ywurUbkWA== +-----END RSA PRIVATE KEY----- diff --git a/tests/node_compat/test/fixtures/keys/ca1-cert.pem b/tests/node_compat/test/fixtures/keys/ca1-cert.pem new file mode 100644 index 000000000..e1a012c6b --- /dev/null +++ b/tests/node_compat/test/fixtures/keys/ca1-cert.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDlDCCAnygAwIBAgIUSrFsjf1qfQ0t/KvfnEsOksatAikwDQYJKoZIhvcNAQEL +BQAwejELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQswCQYDVQQHDAJTRjEPMA0G +A1UECgwGSm95ZW50MRAwDgYDVQQLDAdOb2RlLmpzMQwwCgYDVQQDDANjYTExIDAe +BgkqhkiG9w0BCQEWEXJ5QHRpbnljbG91ZHMub3JnMCAXDTIyMDkwMzIxNDAzN1oY +DzIyOTYwNjE3MjE0MDM3WjB6MQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExCzAJ +BgNVBAcMAlNGMQ8wDQYDVQQKDAZKb3llbnQxEDAOBgNVBAsMB05vZGUuanMxDDAK +BgNVBAMMA2NhMTEgMB4GCSqGSIb3DQEJARYRcnlAdGlueWNsb3Vkcy5vcmcwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDNvf4OGGep+ak+4DNjbuNgy0S/ +AZPxahEFp4gpbcvsi9YLOPZ31qpilQeQf7d27scIZ02Qx1YBAzljxELB8H/ZxuYS +cQK0s+DNP22xhmgwMWznO7TezkHP5ujN2UkbfbUpfUxGFgncXeZf9wR7yFWppeHi +RWNBOgsvY7sTrS12kXjWGjqntF7xcEDHc7h+KyF6ZjVJZJCnP6pJEQ+rUjd51eCZ +Xt4WjowLnQiCS1VKzXiP83a++Ma1BKKkUitTR112/Uwd5eGoiByhmLzb/BhxnHJN +07GXjhlMItZRm/jfbZsx1mwnNOO3tx4r08l+DaqkinIadvazs+1ugCaKQn8xAgMB +AAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFqG0RXURDam +56x5accdg9sY5zEGP5VQhkK3ZDc2NyNNa25rwvrjCpO+e0OSwKAmm4aX6iIf2woY +wF2f9swWYzxn9CG4fDlUA8itwlnHxupeL4fGMTYb72vf31plUXyBySRsTwHwBloc +F7KvAZpYYKN9EMH1S/267By6H2I33BT/Ethv//n8dSfmuCurR1kYRaiOC4PVeyFk +B3sj8TtolrN0y/nToWUhmKiaVFnDx3odQ00yhmxR3t21iB7yDkko6D8Vf2dVC4j/ +YYBVprXGlTP/hiYRLDoP20xKOYznx5cvHPJ9p+lVcOZUJsJj/Iy750+2n5UiBmXt +lz88C25ucKA= +-----END CERTIFICATE----- diff --git a/tests/node_compat/test/fixtures/loop.js b/tests/node_compat/test/fixtures/loop.js new file mode 100644 index 000000000..f9bcfc66e --- /dev/null +++ b/tests/node_compat/test/fixtures/loop.js @@ -0,0 +1,17 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +var t = 1; +var k = 1; +console.log('A message', 5); +while (t > 0) { + if (t++ === 1000) { + t = 0; + console.log(`Outputted message #${k++}`); + } +} +process.exit(55); diff --git a/tests/node_compat/test/fixtures/package.json b/tests/node_compat/test/fixtures/package.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/tests/node_compat/test/fixtures/package.json @@ -0,0 +1 @@ +{} diff --git a/tests/node_compat/test/fixtures/print-chars.js b/tests/node_compat/test/fixtures/print-chars.js new file mode 100644 index 000000000..2519c77fd --- /dev/null +++ b/tests/node_compat/test/fixtures/print-chars.js @@ -0,0 +1,35 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// TODO(PolarETech): The process.argv[3] should be argv[2]. + +const assert = require('assert'); + +var n = parseInt(process.argv[3]); + +process.stdout.write('c'.repeat(n)); diff --git a/tests/node_compat/test/fixtures/x.txt b/tests/node_compat/test/fixtures/x.txt new file mode 100644 index 000000000..cd470e619 --- /dev/null +++ b/tests/node_compat/test/fixtures/x.txt @@ -0,0 +1 @@ +xyz diff --git a/tests/node_compat/test/internet/package.json b/tests/node_compat/test/internet/package.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/tests/node_compat/test/internet/package.json @@ -0,0 +1 @@ +{} diff --git a/tests/node_compat/test/internet/test-dns-any.js b/tests/node_compat/test/internet/test-dns-any.js new file mode 100644 index 000000000..b8a70b8e2 --- /dev/null +++ b/tests/node_compat/test/internet/test-dns-any.js @@ -0,0 +1,194 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// TODO(cmorten): enable remaining tests once functionality is implemented. + +'use strict'; + +const common = require('../common'); + +const assert = require('assert'); +const dns = require('dns'); +const net = require('net'); + +let running = false; +const queue = []; + +const dnsPromises = dns.promises; +const isIPv4 = net.isIPv4; +const isIPv6 = net.isIPv6; + +dns.setServers([ '8.8.8.8', '8.8.4.4' ]); + +function checkWrap(req) { + assert.ok(typeof req === 'object'); +} + +const checkers = { + checkA(r) { + assert.ok(isIPv4(r.address)); + // assert.strictEqual(typeof r.ttl, 'number'); + assert.strictEqual(r.type, 'A'); + }, + checkAAAA(r) { + assert.ok(isIPv6(r.address)); + // assert.strictEqual(typeof r.ttl, 'number'); + assert.strictEqual(r.type, 'AAAA'); + }, + checkCNAME(r) { + assert.ok(r.value); + assert.strictEqual(typeof r.value, 'string'); + assert.strictEqual(r.type, 'CNAME'); + }, + checkMX(r) { + assert.strictEqual(typeof r.exchange, 'string'); + assert.strictEqual(typeof r.priority, 'number'); + assert.strictEqual(r.type, 'MX'); + }, + checkNAPTR(r) { + assert.strictEqual(typeof r.flags, 'string'); + assert.strictEqual(typeof r.service, 'string'); + assert.strictEqual(typeof r.regexp, 'string'); + assert.strictEqual(typeof r.replacement, 'string'); + assert.strictEqual(typeof r.order, 'number'); + assert.strictEqual(typeof r.preference, 'number'); + assert.strictEqual(r.type, 'NAPTR'); + }, + checkNS(r) { + assert.strictEqual(typeof r.value, 'string'); + assert.strictEqual(r.type, 'NS'); + }, + checkPTR(r) { + assert.strictEqual(typeof r.value, 'string'); + assert.strictEqual(r.type, 'PTR'); + }, + checkTXT(r) { + assert.ok(Array.isArray(r.entries)); + assert.ok(r.entries.length > 0); + assert.strictEqual(r.type, 'TXT'); + }, + checkSOA(r) { + assert.strictEqual(typeof r.nsname, 'string'); + assert.strictEqual(typeof r.hostmaster, 'string'); + assert.strictEqual(typeof r.serial, 'number'); + assert.strictEqual(typeof r.refresh, 'number'); + assert.strictEqual(typeof r.retry, 'number'); + assert.strictEqual(typeof r.expire, 'number'); + assert.strictEqual(typeof r.minttl, 'number'); + assert.strictEqual(r.type, 'SOA'); + }, + checkSRV(r) { + assert.strictEqual(typeof r.name, 'string'); + assert.strictEqual(typeof r.port, 'number'); + assert.strictEqual(typeof r.priority, 'number'); + assert.strictEqual(typeof r.weight, 'number'); + assert.strictEqual(r.type, 'SRV'); + } +}; + +function TEST(f) { + function next() { + const f = queue.shift(); + if (f) { + running = true; + f(done); + } + } + + function done() { + running = false; + process.nextTick(next); + } + + queue.push(f); + + if (!running) { + next(); + } +} + +function processResult(res) { + assert.ok(Array.isArray(res)); + assert.ok(res.length > 0); + + const types = {}; + res.forEach((obj) => { + types[obj.type] = true; + checkers[`check${obj.type}`](obj); + }); + + return types; +} + +TEST(async function test_sip2sip_for_naptr(done) { + function validateResult(res) { + const types = processResult(res); + assert.ok( + types.A && types.NS && types.NAPTR && types.SOA, + `Missing record type, found ${Object.keys(types)}` + ); + } + + validateResult(await dnsPromises.resolve('sip2sip.info', 'ANY')); + + const req = dns.resolve( + 'sip2sip.info', + 'ANY', + common.mustSucceed((ret) => { + validateResult(ret); + done(); + })); + + checkWrap(req); +}); + +TEST(async function test_google_for_cname_and_srv(done) { + function validateResult(res) { + const types = processResult(res); + assert.ok(types.SRV); + } + + // TODO(kt3k): Temporarily use _caldav._tcp.google.com instead of + // _jabber._tcp.google.com, which currently doesn't respond + // validateResult(await dnsPromises.resolve('_jabber._tcp.google.com', 'ANY')); + validateResult(await dnsPromises.resolve('_caldav._tcp.google.com', 'ANY')); + + + // TODO(kt3k): Temporarily use _caldav._tcp.google.com instead of + // _jabber._tcp.google.com, which currently doesn't respond + const req = dns.resolve( + // '_jabber._tcp.google.com', + '_caldav._tcp.google.com', + 'ANY', + common.mustSucceed((ret) => { + validateResult(ret); + done(); + })); + + checkWrap(req); +}); + +// TODO(bartlomieju): this test started failing on CI on Dec 28th, 2023 returning +// ENOTFOUND. It's unclear what's going on, since `dig -x 8.8.8.8.in-addr.arpa` +// TEST(async function test_ptr(done) { +// function validateResult(res) { +// const types = processResult(res); +// assert.ok(types.PTR); +// } + +// validateResult(await dnsPromises.resolve('8.8.8.8.in-addr.arpa', 'ANY')); + +// const req = dns.resolve( +// '8.8.8.8.in-addr.arpa', +// 'ANY', +// common.mustSucceed((ret) => { +// validateResult(ret); +// done(); +// })); + +// checkWrap(req); +// }); diff --git a/tests/node_compat/test/internet/test-dns-idna2008.js b/tests/node_compat/test/internet/test-dns-idna2008.js new file mode 100644 index 000000000..7308f9deb --- /dev/null +++ b/tests/node_compat/test/internet/test-dns-idna2008.js @@ -0,0 +1,76 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +// Verify that non-ASCII hostnames are handled correctly as IDNA 2008. +// +// * Tests will fail with NXDOMAIN when UTF-8 leaks through to a getaddrinfo() +// that doesn't support IDNA at all. +// +// * "straße.de" will resolve to the wrong address when the resolver supports +// only IDNA 2003 (e.g., glibc until 2.28) because it encodes it wrong. + +const { mustCall } = require('../common'); +const assert = require('assert'); +const dns = require('dns'); +const { addresses } = require('../common/internet'); + +const fixture = { + hostname: 'straße.de', + expectedAddress: '81.169.145.78', + dnsServer: addresses.DNS4_SERVER, + family: 4, +}; + +// Explicitly use well-behaved DNS servers that are known to be able to resolve +// the query (which is a.k.a xn--strae-oqa.de). +dns.setServers([fixture.dnsServer]); + +dns.lookup( + fixture.hostname, + { family: fixture.family }, + mustCall((err, address) => { + if (err && err.errno === 'ESERVFAIL') { + assert.ok(err.message.includes('queryA ESERVFAIL straße.de')); + return; + } + assert.ifError(err); + assert.strictEqual(address, fixture.expectedAddress); + }), +); + +dns.promises.lookup(fixture.hostname, { family: fixture.family }) + .then(({ address }) => { + assert.strictEqual(address, fixture.expectedAddress); + }, (err) => { + if (err && err.errno === 'ESERVFAIL') { + assert.ok(err.message.includes('queryA ESERVFAIL straße.de')); + } else { + throw err; + } + }).finally(mustCall()); + +dns.resolve4(fixture.hostname, mustCall((err, addresses) => { + if (err && err.errno === 'ESERVFAIL') { + assert.ok(err.message.includes('queryA ESERVFAIL straße.de')); + return; + } + assert.ifError(err); + assert.deepStrictEqual(addresses, [fixture.expectedAddress]); +})); + +const p = new dns.promises.Resolver().resolve4(fixture.hostname); +p.then((addresses) => { + assert.deepStrictEqual(addresses, [fixture.expectedAddress]); +}, (err) => { + if (err && err.errno === 'ESERVFAIL') { + assert.ok(err.message.includes('queryA ESERVFAIL straße.de')); + } else { + throw err; + } +}).finally(mustCall()); diff --git a/tests/node_compat/test/internet/test-dns-ipv4.js b/tests/node_compat/test/internet/test-dns-ipv4.js new file mode 100644 index 000000000..43b60950a --- /dev/null +++ b/tests/node_compat/test/internet/test-dns-ipv4.js @@ -0,0 +1,257 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +'use strict'; + +// TODO: enable remaining tests once functionality is implemented. + +const common = require('../common'); +const { addresses } = require('../common/internet'); +const assert = require('assert'); +const dns = require('dns'); +const net = require('net'); +// const util = require('util'); +const isIPv4 = net.isIPv4; + +const dnsPromises = dns.promises; +let running = false; +const queue = []; + +function TEST(f) { + function next() { + const f = queue.shift(); + if (f) { + running = true; + console.log(f.name); + f(done); + } + } + + function done() { + running = false; + process.nextTick(next); + } + + queue.push(f); + + if (!running) { + next(); + } +} + +function checkWrap(req) { + assert.ok(typeof req === 'object'); +} + +TEST(async function test_resolve4(done) { + function validateResult(res) { + assert.ok(res.length > 0); + + for (let i = 0; i < res.length; i++) { + assert.ok(isIPv4(res[i])); + } + } + + validateResult(await dnsPromises.resolve4(addresses.INET4_HOST)); + + const req = dns.resolve4( + addresses.INET4_HOST, + common.mustSucceed((ips) => { + validateResult(ips); + done(); + })); + + checkWrap(req); +}); + +// TEST(async function test_reverse_ipv4(done) { +// function validateResult(res) { +// assert.ok(res.length > 0); + +// for (let i = 0; i < res.length; i++) { +// assert.ok(res[i]); +// assert.ok(typeof res[i] === 'string'); +// } +// } + +// validateResult(await dnsPromises.reverse(addresses.INET4_IP)); + +// const req = dns.reverse( +// addresses.INET4_IP, +// common.mustSucceed((domains) => { +// validateResult(domains); +// done(); +// })); + +// checkWrap(req); +// }); + +TEST(async function test_lookup_ipv4_explicit(done) { + function validateResult(res) { + assert.ok(net.isIPv4(res.address)); + assert.strictEqual(res.family, 4); + } + + validateResult(await dnsPromises.lookup(addresses.INET4_HOST, 4)); + + const req = dns.lookup( + addresses.INET4_HOST, 4, + common.mustSucceed((ip, family) => { + validateResult({ address: ip, family }); + done(); + })); + + checkWrap(req); +}); + +TEST(async function test_lookup_ipv4_implicit(done) { + function validateResult(res) { + assert.ok(net.isIPv4(res.address)); + assert.strictEqual(res.family, 4); + } + + validateResult(await dnsPromises.lookup(addresses.INET4_HOST)); + + const req = dns.lookup( + addresses.INET4_HOST, + common.mustSucceed((ip, family) => { + validateResult({ address: ip, family }); + done(); + })); + + checkWrap(req); +}); + +TEST(async function test_lookup_ipv4_explicit_object(done) { + function validateResult(res) { + assert.ok(net.isIPv4(res.address)); + assert.strictEqual(res.family, 4); + } + + validateResult(await dnsPromises.lookup(addresses.INET4_HOST, { family: 4 })); + + const req = dns.lookup(addresses.INET4_HOST, { + family: 4 + }, common.mustSucceed((ip, family) => { + validateResult({ address: ip, family }); + done(); + })); + + checkWrap(req); +}); + +TEST(async function test_lookup_ipv4_hint_addrconfig(done) { + function validateResult(res) { + assert.ok(net.isIPv4(res.address)); + assert.strictEqual(res.family, 4); + } + + validateResult(await dnsPromises.lookup(addresses.INET4_HOST, { + hints: dns.ADDRCONFIG + })); + + const req = dns.lookup(addresses.INET4_HOST, { + hints: dns.ADDRCONFIG + }, common.mustSucceed((ip, family) => { + validateResult({ address: ip, family }); + done(); + })); + + checkWrap(req); +}); + +TEST(async function test_lookup_ip_ipv4(done) { + function validateResult(res) { + assert.strictEqual(res.address, '127.0.0.1'); + assert.strictEqual(res.family, 4); + } + + validateResult(await dnsPromises.lookup('127.0.0.1')); + + const req = dns.lookup('127.0.0.1', + common.mustSucceed((ip, family) => { + validateResult({ address: ip, family }); + done(); + })); + + checkWrap(req); +}); + +TEST(async function test_lookup_localhost_ipv4(done) { + function validateResult(res) { + assert.strictEqual(res.address, '127.0.0.1'); + assert.strictEqual(res.family, 4); + } + + validateResult(await dnsPromises.lookup('localhost', 4)); + + const req = dns.lookup('localhost', 4, + common.mustSucceed((ip, family) => { + validateResult({ address: ip, family }); + done(); + })); + + checkWrap(req); +}); + +TEST(async function test_lookup_all_ipv4(done) { + function validateResult(res) { + assert.ok(Array.isArray(res)); + assert.ok(res.length > 0); + + res.forEach((ip) => { + assert.ok(isIPv4(ip.address)); + assert.strictEqual(ip.family, 4); + }); + } + + validateResult(await dnsPromises.lookup(addresses.INET4_HOST, { + all: true, + family: 4 + })); + + const req = dns.lookup( + addresses.INET4_HOST, + { all: true, family: 4 }, + common.mustSucceed((ips) => { + validateResult(ips); + done(); + }) + ); + + checkWrap(req); +}); + +// TEST(async function test_lookupservice_ip_ipv4(done) { +// function validateResult(res) { +// assert.strictEqual(typeof res.hostname, 'string'); +// assert(res.hostname); +// assert(['http', 'www', '80'].includes(res.service)); +// } + +// validateResult(await dnsPromises.lookupService('127.0.0.1', 80)); + +// const req = dns.lookupService( +// '127.0.0.1', 80, +// common.mustSucceed((hostname, service) => { +// validateResult({ hostname, service }); +// done(); +// }) +// ); + +// checkWrap(req); +// }); + +// TEST(function test_lookupservice_ip_ipv4_promise(done) { +// util.promisify(dns.lookupService)('127.0.0.1', 80) +// .then(common.mustCall(({ hostname, service }) => { +// assert.strictEqual(typeof hostname, 'string'); +// assert(hostname.length > 0); +// assert(['http', 'www', '80'].includes(service)); +// done(); +// })); +// }); diff --git a/tests/node_compat/test/internet/test-dns-ipv6.js b/tests/node_compat/test/internet/test-dns-ipv6.js new file mode 100644 index 000000000..4b94d6041 --- /dev/null +++ b/tests/node_compat/test/internet/test-dns-ipv6.js @@ -0,0 +1,250 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +'use strict'; + +// TODO: enable remaining tests once functionality is implemented. + +const common = require('../common'); +const { addresses } = require('../common/internet'); +if (!common.hasIPv6) + common.skip('this test, no IPv6 support'); + +const assert = require('assert'); +const dns = require('dns'); +const net = require('net'); +const dnsPromises = dns.promises; +const isIPv6 = net.isIPv6; + +let running = false; +const queue = []; + +function TEST(f) { + function next() { + const f = queue.shift(); + if (f) { + running = true; + console.log(f.name); + f(done); + } + } + + function done() { + running = false; + process.nextTick(next); + } + + queue.push(f); + + if (!running) { + next(); + } +} + +function checkWrap(req) { + assert.ok(typeof req === 'object'); +} + +TEST(async function test_resolve6(done) { + function validateResult(res) { + assert.ok(res.length > 0); + + for (let i = 0; i < res.length; i++) { + assert.ok(isIPv6(res[i])); + } + } + + validateResult(await dnsPromises.resolve6(addresses.INET6_HOST)); + + const req = dns.resolve6( + addresses.INET6_HOST, + common.mustSucceed((ips) => { + validateResult(ips); + done(); + })); + + checkWrap(req); +}); + +// TEST(async function test_reverse_ipv6(done) { +// function validateResult(res) { +// assert.ok(res.length > 0); + +// for (let i = 0; i < res.length; i++) { +// assert.ok(typeof res[i] === 'string'); +// } +// } + +// validateResult(await dnsPromises.reverse(addresses.INET6_IP)); + +// const req = dns.reverse( +// addresses.INET6_IP, +// common.mustSucceed((domains) => { +// validateResult(domains); +// done(); +// })); + +// checkWrap(req); +// }); + +TEST(async function test_lookup_ipv6_explicit(done) { + function validateResult(res) { + assert.ok(isIPv6(res.address)); + assert.strictEqual(res.family, 6); + } + + validateResult(await dnsPromises.lookup(addresses.INET6_HOST, 6)); + + const req = dns.lookup( + addresses.INET6_HOST, + 6, + common.mustSucceed((ip, family) => { + validateResult({ address: ip, family }); + done(); + })); + + checkWrap(req); +}); + +// This ends up just being too problematic to test +// TEST(function test_lookup_ipv6_implicit(done) { +// var req = dns.lookup(addresses.INET6_HOST, function(err, ip, family) { +// assert.ifError(err); +// assert.ok(net.isIPv6(ip)); +// assert.strictEqual(family, 6); + +// done(); +// }); + +// checkWrap(req); +// }); + +TEST(async function test_lookup_ipv6_explicit_object(done) { + function validateResult(res) { + assert.ok(isIPv6(res.address)); + assert.strictEqual(res.family, 6); + } + + validateResult(await dnsPromises.lookup(addresses.INET6_HOST, { family: 6 })); + + const req = dns.lookup(addresses.INET6_HOST, { + family: 6 + }, common.mustSucceed((ip, family) => { + validateResult({ address: ip, family }); + done(); + })); + + checkWrap(req); +}); + +TEST(function test_lookup_ipv6_hint(done) { + const req = dns.lookup(addresses.INET6_HOST, { + family: 6, + hints: dns.V4MAPPED + }, common.mustCall((err, ip, family) => { + if (err) { + // FreeBSD does not support V4MAPPED + if (common.isFreeBSD) { + assert(err instanceof Error); + assert.strictEqual(err.code, 'EAI_BADFLAGS'); + assert.strictEqual(err.hostname, addresses.INET_HOST); + assert.match(err.message, /getaddrinfo EAI_BADFLAGS/); + done(); + return; + } + + assert.ifError(err); + } + + assert.ok(isIPv6(ip)); + assert.strictEqual(family, 6); + + done(); + })); + + checkWrap(req); +}); + +TEST(async function test_lookup_ip_ipv6(done) { + function validateResult(res) { + assert.ok(isIPv6(res.address)); + assert.strictEqual(res.family, 6); + } + + validateResult(await dnsPromises.lookup('::1')); + + const req = dns.lookup( + '::1', + common.mustSucceed((ip, family) => { + validateResult({ address: ip, family }); + done(); + })); + + checkWrap(req); +}); + +TEST(async function test_lookup_all_ipv6(done) { + function validateResult(res) { + assert.ok(Array.isArray(res)); + assert.ok(res.length > 0); + + res.forEach((ip) => { + assert.ok(isIPv6(ip.address), + `Invalid IPv6: ${ip.address.toString()}`); + assert.strictEqual(ip.family, 6); + }); + } + + validateResult(await dnsPromises.lookup(addresses.INET6_HOST, { + all: true, + family: 6 + })); + + const req = dns.lookup( + addresses.INET6_HOST, + { all: true, family: 6 }, + common.mustSucceed((ips) => { + validateResult(ips); + done(); + }) + ); + + checkWrap(req); +}); + +// TEST(function test_lookupservice_ip_ipv6(done) { +// const req = dns.lookupService( +// '::1', 80, +// common.mustCall((err, host, service) => { +// if (err) { +// // Not skipping the test, rather checking an alternative result, +// // i.e. that ::1 may not be configured (e.g. in /etc/hosts) +// assert.strictEqual(err.code, 'ENOTFOUND'); +// return done(); +// } +// assert.strictEqual(typeof host, 'string'); +// assert(host); +// assert(['http', 'www', '80'].includes(service)); +// done(); +// }) +// ); + +// checkWrap(req); +// }); + +// Disabled because it appears to be not working on Linux. +// TEST(function test_lookup_localhost_ipv6(done) { +// var req = dns.lookup('localhost', 6, function(err, ip, family) { +// assert.ifError(err); +// assert.ok(net.isIPv6(ip)); +// assert.strictEqual(family, 6); +// +// done(); +// }); +// +// checkWrap(req); +// }); diff --git a/tests/node_compat/test/internet/test-dns-lookup.js b/tests/node_compat/test/internet/test-dns-lookup.js new file mode 100644 index 000000000..cfd3e758c --- /dev/null +++ b/tests/node_compat/test/internet/test-dns-lookup.js @@ -0,0 +1,61 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const common = require('../common'); +const dns = require('dns'); +const dnsPromises = dns.promises; +const { addresses } = require('../common/internet'); +const assert = require('assert'); + +assert.rejects( + dnsPromises.lookup(addresses.NOT_FOUND, { + hints: 0, + family: 0, + all: false, + }), + { + code: 'ENOTFOUND', + message: `getaddrinfo ENOTFOUND ${addresses.NOT_FOUND}`, + }, +); + +assert.rejects( + dnsPromises.lookup(addresses.NOT_FOUND, { + hints: 0, + family: 0, + all: true, + }), + { + code: 'ENOTFOUND', + message: `getaddrinfo ENOTFOUND ${addresses.NOT_FOUND}`, + }, +); + +dns.lookup(addresses.NOT_FOUND, { + hints: 0, + family: 0, + all: true, +}, common.mustCall((error) => { + assert.strictEqual(error.code, 'ENOTFOUND'); + assert.strictEqual( + error.message, + `getaddrinfo ENOTFOUND ${addresses.NOT_FOUND}`, + ); + assert.strictEqual(error.syscall, 'getaddrinfo'); + assert.strictEqual(error.hostname, addresses.NOT_FOUND); +})); + +assert.throws( + () => dnsPromises.lookup(addresses.NOT_FOUND, { + family: 'ipv4', + all: 'all', + }), + { code: 'ERR_INVALID_ARG_VALUE' }, +); diff --git a/tests/node_compat/test/internet/test-dns-promises-resolve.js b/tests/node_compat/test/internet/test-dns-promises-resolve.js new file mode 100644 index 000000000..e4ee5f782 --- /dev/null +++ b/tests/node_compat/test/internet/test-dns-promises-resolve.js @@ -0,0 +1,49 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const dnsPromises = require('dns').promises; + +// Error when rrtype is invalid. +{ + const rrtype = 'DUMMY'; + assert.throws( + () => dnsPromises.resolve('example.org', rrtype), + { + code: 'ERR_INVALID_ARG_VALUE', + name: 'TypeError', + message: `The argument 'rrtype' is invalid. Received '${rrtype}'`, + }, + ); +} + +// Error when rrtype is a number. +{ + const rrtype = 0; + assert.throws( + () => dnsPromises.resolve('example.org', rrtype), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "rrtype" argument must be of type string. ' + + `Received type ${typeof rrtype} (${rrtype})`, + }, + ); +} + +// Setting rrtype to undefined should work like resolve4. +{ + (async function() { + const rrtype = undefined; + const result = await dnsPromises.resolve('example.org', rrtype); + assert.ok(result !== undefined); + assert.ok(result.length > 0); + })().then(common.mustCall()); +} diff --git a/tests/node_compat/test/internet/test-dns-regress-6244.js b/tests/node_compat/test/internet/test-dns-regress-6244.js new file mode 100644 index 000000000..988cf21ee --- /dev/null +++ b/tests/node_compat/test/internet/test-dns-regress-6244.js @@ -0,0 +1,35 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const dns = require('dns'); + +// Should not segfault. +// Ref: https://github.com/nodejs/node-v0.x-archive/issues/6244 +dns.resolve4('127.0.0.1', common.mustCall()); diff --git a/tests/node_compat/test/internet/test-dns-setserver-in-callback-of-resolve4.js b/tests/node_compat/test/internet/test-dns-setserver-in-callback-of-resolve4.js new file mode 100644 index 000000000..b4360c205 --- /dev/null +++ b/tests/node_compat/test/internet/test-dns-setserver-in-callback-of-resolve4.js @@ -0,0 +1,25 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +// We don't care about `err` in the callback function of `dns.resolve4`. We just +// want to test whether `dns.setServers` that is run after `resolve4` will cause +// a crash or not. If it doesn't crash, the test succeeded. + +const common = require('../common'); +const { addresses } = require('../common/internet'); +const dns = require('dns'); + +dns.resolve4( + addresses.INET4_HOST, + common.mustCall(function(/* err, nameServers */) { + dns.setServers([ addresses.DNS4_SERVER ]); + })); + +// Test https://github.com/nodejs/node/issues/14734 +dns.resolve4(addresses.INET4_HOST, common.mustCall()); diff --git a/tests/node_compat/test/internet/test-dns.js b/tests/node_compat/test/internet/test-dns.js new file mode 100644 index 000000000..8aaeb728d --- /dev/null +++ b/tests/node_compat/test/internet/test-dns.js @@ -0,0 +1,766 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Flags: --expose-internals +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; + +// TODO(cmorten): enable remaining tests once functionality is implemented. + +const common = require('../common'); +const { addresses } = require('../common/internet'); +const { internalBinding } = require('internal/test/binding'); +// const { getSystemErrorName } = require('util'); +const assert = require('assert'); +const dns = require('dns'); +const net = require('net'); +const isIPv4 = net.isIPv4; +const isIPv6 = net.isIPv6; +const util = require('util'); +const dnsPromises = dns.promises; + +let expected = 0; +let completed = 0; +let running = false; +const queue = []; + + +function TEST(f) { + function next() { + const f = queue.shift(); + if (f) { + running = true; + console.log(f.name); + f(done); + } + } + + function done() { + running = false; + completed++; + process.nextTick(next); + } + + expected++; + queue.push(f); + + if (!running) { + next(); + } +} + + +function checkWrap(req) { + assert.strictEqual(typeof req, 'object'); +} + + +// TEST(function test_reverse_bogus(done) { +// dnsPromises.reverse('bogus ip') +// .then(common.mustNotCall()) +// .catch(common.mustCall((err) => { +// assert.strictEqual(err.code, 'EINVAL'); +// assert.strictEqual(getSystemErrorName(err.errno), 'EINVAL'); +// })); + +// assert.throws(() => { +// dns.reverse('bogus ip', common.mustNotCall()); +// }, /^Error: getHostByAddr EINVAL bogus ip$/); +// done(); +// }); + +// TEST(async function test_resolve4_ttl(done) { +// function validateResult(result) { +// assert.ok(result.length > 0); + +// for (const item of result) { +// assert.strictEqual(typeof item, 'object'); +// assert.strictEqual(typeof item.ttl, 'number'); +// assert.strictEqual(typeof item.address, 'string'); +// assert.ok(item.ttl >= 0); +// assert.ok(isIPv4(item.address)); +// } +// } + +// validateResult(await dnsPromises.resolve4(addresses.INET4_HOST, { +// ttl: true +// })); + +// const req = dns.resolve4(addresses.INET4_HOST, { +// ttl: true +// }, function(err, result) { +// assert.ifError(err); +// validateResult(result); +// done(); +// }); + +// checkWrap(req); +// }); + +// TEST(async function test_resolve6_ttl(done) { +// function validateResult(result) { +// assert.ok(result.length > 0); + +// for (const item of result) { +// assert.strictEqual(typeof item, 'object'); +// assert.strictEqual(typeof item.ttl, 'number'); +// assert.strictEqual(typeof item.address, 'string'); +// assert.ok(item.ttl >= 0); +// assert.ok(isIPv6(item.address)); +// } +// } + +// validateResult(await dnsPromises.resolve6(addresses.INET6_HOST, { +// ttl: true +// })); + +// const req = dns.resolve6(addresses.INET6_HOST, { +// ttl: true +// }, function(err, result) { +// assert.ifError(err); +// validateResult(result); +// done(); +// }); + +// checkWrap(req); +// }); + +TEST(async function test_resolveMx(done) { + function validateResult(result) { + assert.ok(result.length > 0); + + for (const item of result) { + assert.strictEqual(typeof item, 'object'); + assert.ok(item.exchange); + assert.strictEqual(typeof item.exchange, 'string'); + assert.strictEqual(typeof item.priority, 'number'); + } + } + + validateResult(await dnsPromises.resolveMx(addresses.MX_HOST)); + + const req = dns.resolveMx(addresses.MX_HOST, function(err, result) { + assert.ifError(err); + validateResult(result); + done(); + }); + + checkWrap(req); +}); + +// TODO(bartlomieju): this test became very flaky on CI, returning `UNKNOWN` +// instead of `ENOTFOUND`. +// TEST(function test_resolveMx_failure(done) { +// dnsPromises.resolveMx(addresses.NOT_FOUND) +// .then(common.mustNotCall()) +// .catch(common.mustCall((err) => { +// assert.strictEqual(err.code, 'ENOTFOUND'); +// })); + +// const req = dns.resolveMx(addresses.NOT_FOUND, function(err, result) { +// assert.ok(err instanceof Error); +// assert.strictEqual(err.code, 'ENOTFOUND'); + +// assert.strictEqual(result, undefined); + +// done(); +// }); + +// checkWrap(req); +// }); + +TEST(async function test_resolveNs(done) { + function validateResult(result) { + assert.ok(result.length > 0); + + for (const item of result) { + assert.ok(item); + assert.strictEqual(typeof item, 'string'); + } + } + + validateResult(await dnsPromises.resolveNs(addresses.NS_HOST)); + + const req = dns.resolveNs(addresses.NS_HOST, function(err, names) { + assert.ifError(err); + validateResult(names); + done(); + }); + + checkWrap(req); +}); + +// TODO(bartlomieju): this test became very flaky on CI, returning `UNKNOWN` +// instead of `ENOTFOUND`. +// TEST(function test_resolveNs_failure(done) { +// dnsPromises.resolveNs(addresses.NOT_FOUND) +// .then(common.mustNotCall()) +// .catch(common.mustCall((err) => { +// assert.strictEqual(err.code, 'ENOTFOUND'); +// })); + +// const req = dns.resolveNs(addresses.NOT_FOUND, function(err, result) { +// assert.ok(err instanceof Error); +// assert.strictEqual(err.code, 'ENOTFOUND'); + +// assert.strictEqual(result, undefined); + +// done(); +// }); + +// checkWrap(req); +// }); + +TEST(async function test_resolveSrv(done) { + function validateResult(result) { + assert.ok(result.length > 0); + + for (const item of result) { + assert.strictEqual(typeof item, 'object'); + assert.ok(item.name); + assert.strictEqual(typeof item.name, 'string'); + assert.strictEqual(typeof item.port, 'number'); + assert.strictEqual(typeof item.priority, 'number'); + assert.strictEqual(typeof item.weight, 'number'); + } + } + + validateResult(await dnsPromises.resolveSrv(addresses.SRV_HOST)); + + const req = dns.resolveSrv(addresses.SRV_HOST, function(err, result) { + assert.ifError(err); + validateResult(result); + done(); + }); + + checkWrap(req); +}); + +// TODO(bartlomieju): this test became very flaky on CI, returning `UNKNOWN` +// instead of `ENOTFOUND`. +// TEST(function test_resolveSrv_failure(done) { +// dnsPromises.resolveSrv(addresses.NOT_FOUND) +// .then(common.mustNotCall()) +// .catch(common.mustCall((err) => { +// assert.strictEqual(err.code, 'ENOTFOUND'); +// })); + +// const req = dns.resolveSrv(addresses.NOT_FOUND, function(err, result) { +// assert.ok(err instanceof Error); +// assert.strictEqual(err.code, 'ENOTFOUND'); + +// assert.strictEqual(result, undefined); + +// done(); +// }); + +// checkWrap(req); +// }); + +// TODO(bartlomieju): this test started failing on CI on Dec 28th, 2023 returning +// ENOTFOUND. It's unclear what's going on, since `dig -x 8.8.8.8.in-addr.arpa` +// returns correct PTR record. +// TEST(async function test_resolvePtr(done) { +// function validateResult(result) { +// assert.ok(result.length > 0); + +// for (const item of result) { +// assert.ok(item); +// assert.strictEqual(typeof item, 'string'); +// } +// } + +// validateResult(await dnsPromises.resolvePtr(addresses.PTR_HOST)); + +// const req = dns.resolvePtr(addresses.PTR_HOST, function(err, result) { +// assert.ifError(err); +// validateResult(result); +// done(); +// }); + +// checkWrap(req); +// }); + +// TODO(bartlomieju): this test became very flaky on CI, returning `UNKNOWN` +// instead of `ENOTFOUND`. +// TEST(function test_resolvePtr_failure(done) { +// dnsPromises.resolvePtr(addresses.NOT_FOUND) +// .then(common.mustNotCall()) +// .catch(common.mustCall((err) => { +// assert.strictEqual(err.code, 'ENOTFOUND'); +// })); + +// const req = dns.resolvePtr(addresses.NOT_FOUND, function(err, result) { +// assert.ok(err instanceof Error); +// assert.strictEqual(err.code, 'ENOTFOUND'); + +// assert.strictEqual(result, undefined); + +// done(); +// }); + +// checkWrap(req); +// }); + +TEST(async function test_resolveNaptr(done) { + function validateResult(result) { + assert.ok(result.length > 0); + + for (const item of result) { + assert.strictEqual(typeof item, 'object'); + assert.strictEqual(typeof item.flags, 'string'); + assert.strictEqual(typeof item.service, 'string'); + assert.strictEqual(typeof item.regexp, 'string'); + assert.strictEqual(typeof item.replacement, 'string'); + assert.strictEqual(typeof item.order, 'number'); + assert.strictEqual(typeof item.preference, 'number'); + } + } + + validateResult(await dnsPromises.resolveNaptr(addresses.NAPTR_HOST)); + + const req = dns.resolveNaptr(addresses.NAPTR_HOST, function(err, result) { + assert.ifError(err); + validateResult(result); + done(); + }); + + checkWrap(req); +}); + +// TODO(bartlomieju): this test became very flaky on CI, returning `UNKNOWN` +// instead of `ENOTFOUND`. +// TEST(function test_resolveNaptr_failure(done) { +// dnsPromises.resolveNaptr(addresses.NOT_FOUND) +// .then(common.mustNotCall()) +// .catch(common.mustCall((err) => { +// assert.strictEqual(err.code, 'ENOTFOUND'); +// })); + +// const req = dns.resolveNaptr(addresses.NOT_FOUND, function(err, result) { +// assert.ok(err instanceof Error); +// assert.strictEqual(err.code, 'ENOTFOUND'); + +// assert.strictEqual(result, undefined); + +// done(); +// }); + +// checkWrap(req); +// }); + +TEST(async function test_resolveSoa(done) { + function validateResult(result) { + assert.strictEqual(typeof result, 'object'); + assert.strictEqual(typeof result.nsname, 'string'); + assert.ok(result.nsname.length > 0); + assert.strictEqual(typeof result.hostmaster, 'string'); + assert.ok(result.hostmaster.length > 0); + assert.strictEqual(typeof result.serial, 'number'); + assert.ok((result.serial > 0) && (result.serial < 4294967295)); + assert.strictEqual(typeof result.refresh, 'number'); + assert.ok((result.refresh > 0) && (result.refresh < 2147483647)); + assert.strictEqual(typeof result.retry, 'number'); + assert.ok((result.retry > 0) && (result.retry < 2147483647)); + assert.strictEqual(typeof result.expire, 'number'); + assert.ok((result.expire > 0) && (result.expire < 2147483647)); + assert.strictEqual(typeof result.minttl, 'number'); + assert.ok((result.minttl >= 0) && (result.minttl < 2147483647)); + } + + validateResult(await dnsPromises.resolveSoa(addresses.SOA_HOST)); + + const req = dns.resolveSoa(addresses.SOA_HOST, function(err, result) { + assert.ifError(err); + validateResult(result); + done(); + }); + + checkWrap(req); +}); + +// TODO(bartlomieju): this test became very flaky on CI, returning `UNKNOWN` +// instead of `ENOTFOUND`. +// TEST(function test_resolveSoa_failure(done) { +// dnsPromises.resolveSoa(addresses.NOT_FOUND) +// .then(common.mustNotCall()) +// .catch(common.mustCall((err) => { +// assert.strictEqual(err.code, 'ENOTFOUND'); +// })); + +// const req = dns.resolveSoa(addresses.NOT_FOUND, function(err, result) { +// assert.ok(err instanceof Error); +// assert.strictEqual(err.code, 'ENOTFOUND'); + +// assert.strictEqual(result, undefined); + +// done(); +// }); + +// checkWrap(req); +// }); + +TEST(async function test_resolveCaa(done) { + function validateResult(result) { + assert.ok(Array.isArray(result), + `expected array, got ${util.inspect(result)}`); + assert.strictEqual(result.length, 1); + assert.strictEqual(typeof result[0].critical, 'number'); + assert.strictEqual(result[0].critical, 0); + assert.strictEqual(result[0].issue, 'pki.goog'); + } + + validateResult(await dnsPromises.resolveCaa(addresses.CAA_HOST)); + + const req = dns.resolveCaa(addresses.CAA_HOST, function(err, records) { + assert.ifError(err); + validateResult(records); + done(); + }); + + checkWrap(req); +}); + +// NOTE(bartlomieju): this test started failing around July 11th, 2023. +// TEST(async function test_resolveCname(done) { +// function validateResult(result) { +// assert.ok(result.length > 0); +// +// for (const item of result) { +// assert.ok(item); +// assert.strictEqual(typeof item, 'string'); +// } +// } +// +// validateResult(await dnsPromises.resolveCname(addresses.CNAME_HOST)); +// +// const req = dns.resolveCname(addresses.CNAME_HOST, function(err, names) { +// assert.ifError(err); +// validateResult(names); +// done(); +// }); +// +// checkWrap(req); +// }); + +// TODO(bartlomieju): this test became very flaky on CI, returning `UNKNOWN` +// instead of `ENOTFOUND`. +// TEST(function test_resolveCname_failure(done) { +// dnsPromises.resolveCname(addresses.NOT_FOUND) +// .then(common.mustNotCall()) +// .catch(common.mustCall((err) => { +// assert.strictEqual(err.code, 'ENOTFOUND'); +// })); + +// const req = dns.resolveCname(addresses.NOT_FOUND, function(err, result) { +// assert.ok(err instanceof Error); +// assert.strictEqual(err.code, 'ENOTFOUND'); + +// assert.strictEqual(result, undefined); + +// done(); +// }); + +// checkWrap(req); +// }); + + +TEST(async function test_resolveTxt(done) { + function validateResult(result) { + assert.ok(Array.isArray(result[0])); + assert.strictEqual(result.length, 1); + assert(result[0][0].startsWith('v=spf1')); + } + + validateResult(await dnsPromises.resolveTxt(addresses.TXT_HOST)); + + const req = dns.resolveTxt(addresses.TXT_HOST, function(err, records) { + assert.ifError(err); + validateResult(records); + done(); + }); + + checkWrap(req); +}); + +// TODO(bartlomieju): this test became very flaky on CI, returning `UNKNOWN` +// instead of `ENOTFOUND`. +// TEST(function test_resolveTxt_failure(done) { +// dnsPromises.resolveTxt(addresses.NOT_FOUND) +// .then(common.mustNotCall()) +// .catch(common.mustCall((err) => { +// assert.strictEqual(err.code, 'ENOTFOUND'); +// })); + +// const req = dns.resolveTxt(addresses.NOT_FOUND, function(err, result) { +// assert.ok(err instanceof Error); +// assert.strictEqual(err.code, 'ENOTFOUND'); + +// assert.strictEqual(result, undefined); + +// done(); +// }); + +// checkWrap(req); +// }); + + +TEST(function test_lookup_failure(done) { + dnsPromises.lookup(addresses.NOT_FOUND, 4) + .then(common.mustNotCall()) + .catch(common.expectsError({ code: dns.NOTFOUND })); + + const req = dns.lookup(addresses.NOT_FOUND, 4, (err) => { + assert.ok(err instanceof Error); + assert.strictEqual(err.code, dns.NOTFOUND); + assert.strictEqual(err.code, 'ENOTFOUND'); + assert.doesNotMatch(err.message, /ENOENT/); + assert.ok(err.message.includes(addresses.NOT_FOUND)); + + done(); + }); + + checkWrap(req); +}); + + +TEST(async function test_lookup_ip_all(done) { + function validateResult(result) { + assert.ok(Array.isArray(result)); + assert.ok(result.length > 0); + assert.strictEqual(result[0].address, '127.0.0.1'); + assert.strictEqual(result[0].family, 4); + } + + validateResult(await dnsPromises.lookup('127.0.0.1', { all: true })); + + const req = dns.lookup( + '127.0.0.1', + { all: true }, + function(err, ips, family) { + assert.ifError(err); + assert.strictEqual(family, undefined); + validateResult(ips); + done(); + } + ); + + checkWrap(req); +}); + + +TEST(function test_lookup_ip_all_promise(done) { + const req = util.promisify(dns.lookup)('127.0.0.1', { all: true }) + .then(function(ips) { + assert.ok(Array.isArray(ips)); + assert.ok(ips.length > 0); + assert.strictEqual(ips[0].address, '127.0.0.1'); + assert.strictEqual(ips[0].family, 4); + + done(); + }); + + checkWrap(req); +}); + + +TEST(function test_lookup_ip_promise(done) { + util.promisify(dns.lookup)('127.0.0.1') + .then(function({ address, family }) { + assert.strictEqual(address, '127.0.0.1'); + assert.strictEqual(family, 4); + + done(); + }); +}); + + +TEST(async function test_lookup_null_all(done) { + assert.deepStrictEqual(await dnsPromises.lookup(null, { all: true }), []); + + const req = dns.lookup(null, { all: true }, (err, ips) => { + assert.ifError(err); + assert.ok(Array.isArray(ips)); + assert.strictEqual(ips.length, 0); + + done(); + }); + + checkWrap(req); +}); + + +TEST(async function test_lookup_all_mixed(done) { + function validateResult(result) { + assert.ok(Array.isArray(result)); + assert.ok(result.length > 0); + + result.forEach(function(ip) { + if (isIPv4(ip.address)) + assert.strictEqual(ip.family, 4); + else if (isIPv6(ip.address)) + assert.strictEqual(ip.family, 6); + else + assert.fail('unexpected IP address'); + }); + } + + validateResult(await dnsPromises.lookup(addresses.INET_HOST, { all: true })); + + const req = dns.lookup(addresses.INET_HOST, { + all: true + }, function(err, ips) { + assert.ifError(err); + validateResult(ips); + done(); + }); + + checkWrap(req); +}); + + +// TEST(function test_lookupservice_invalid(done) { +// dnsPromises.lookupService('1.2.3.4', 80) +// .then(common.mustNotCall()) +// .catch(common.expectsError({ code: 'ENOTFOUND' })); + +// const req = dns.lookupService('1.2.3.4', 80, (err) => { +// assert(err instanceof Error); +// assert.strictEqual(err.code, 'ENOTFOUND'); +// assert.match(err.message, /1\.2\.3\.4/); + +// done(); +// }); + +// checkWrap(req); +// }); + + +// TEST(function test_reverse_failure(done) { +// dnsPromises.reverse('203.0.113.0') +// .then(common.mustNotCall()) +// .catch(common.expectsError({ +// code: 'ENOTFOUND', +// hostname: '203.0.113.0' +// })); + +// // 203.0.113.0/24 are addresses reserved for (RFC) documentation use only +// const req = dns.reverse('203.0.113.0', function(err) { +// assert(err instanceof Error); +// assert.strictEqual(err.code, 'ENOTFOUND'); // Silly error code... +// assert.strictEqual(err.hostname, '203.0.113.0'); +// assert.match(err.message, /203\.0\.113\.0/); + +// done(); +// }); + +// checkWrap(req); +// }); + + +// TODO(bartlomieju): this test became very flaky on CI, returning `UNKNOWN` +// instead of `ENOTFOUND`. +// TEST(function test_lookup_failure(done) { +// dnsPromises.lookup(addresses.NOT_FOUND) +// .then(common.mustNotCall()) +// .catch(common.expectsError({ +// code: 'ENOTFOUND', +// hostname: addresses.NOT_FOUND +// })); + +// const req = dns.lookup(addresses.NOT_FOUND, (err) => { +// assert(err instanceof Error); +// assert.strictEqual(err.code, 'ENOTFOUND'); // Silly error code... +// assert.strictEqual(err.hostname, addresses.NOT_FOUND); +// assert.ok(err.message.includes(addresses.NOT_FOUND)); + +// done(); +// }); + +// checkWrap(req); +// }); + + +// TODO(bartlomieju): this test became very flaky on CI, returning `UNKNOWN` +// instead of `ENOTFOUND`. +// TEST(function test_resolve_failure(done) { +// const req = dns.resolve4(addresses.NOT_FOUND, (err) => { +// assert(err instanceof Error); + +// switch (err.code) { +// case 'ENOTFOUND': +// case 'ESERVFAIL': +// break; +// default: +// assert.strictEqual(err.code, 'ENOTFOUND'); // Silly error code... +// break; +// } + +// assert.strictEqual(err.hostname, addresses.NOT_FOUND); +// assert.ok(err.message.includes(addresses.NOT_FOUND)); + +// done(); +// }); + +// checkWrap(req); +// }); + + +let getaddrinfoCallbackCalled = false; + +console.log(`looking up ${addresses.INET4_HOST}..`); + +const cares = internalBinding('cares_wrap'); +const req = new cares.GetAddrInfoReqWrap(); +cares.getaddrinfo(req, addresses.INET4_HOST, 4, + /* hints */ 0, /* verbatim */ true); + +req.oncomplete = function(err, domains) { + assert.strictEqual(err, 0); + console.log(`${addresses.INET4_HOST} = ${domains}`); + assert.ok(Array.isArray(domains)); + assert.ok(domains.length >= 1); + assert.strictEqual(typeof domains[0], 'string'); + getaddrinfoCallbackCalled = true; +}; + +process.on('exit', function() { + console.log(`${completed} tests completed`); + assert.strictEqual(running, false); + assert.strictEqual(completed, expected); + assert.ok(getaddrinfoCallbackCalled); +}); + +// Should not throw. +dns.lookup(addresses.INET6_HOST, 6, common.mustCall()); +dns.lookup(addresses.INET_HOST, {}, common.mustCall()); +// dns.lookupService('0.0.0.0', '0', common.mustCall()); +// dns.lookupService('0.0.0.0', 0, common.mustCall()); +(async function() { + await dnsPromises.lookup(addresses.INET6_HOST, 6); + await dnsPromises.lookup(addresses.INET_HOST, {}); +})().then(common.mustCall()); diff --git a/tests/node_compat/test/internet/test-http-https-default-ports.js b/tests/node_compat/test/internet/test-http-https-default-ports.js new file mode 100644 index 000000000..ef3edd2fc --- /dev/null +++ b/tests/node_compat/test/internet/test-http-https-default-ports.js @@ -0,0 +1,46 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const { addresses } = require('../common/internet'); + +if (!common.hasCrypto) + common.skip('missing crypto'); + +const https = require('https'); + +const http = require('http'); + +https.get(`https://${addresses.INET_HOST}/`, common.mustCall((res) => { + res.resume(); +})); + +http.get(`http://${addresses.INET_HOST}/`, common.mustCall((res) => { + res.resume(); +})); diff --git a/tests/node_compat/test/parallel/package.json b/tests/node_compat/test/parallel/package.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/tests/node_compat/test/parallel/package.json @@ -0,0 +1 @@ +{} diff --git a/tests/node_compat/test/parallel/test-assert-async.js b/tests/node_compat/test/parallel/test-assert-async.js new file mode 100644 index 000000000..a2a8315d8 --- /dev/null +++ b/tests/node_compat/test/parallel/test-assert-async.js @@ -0,0 +1,244 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +// Run all tests in parallel and check their outcome at the end. +const promises = []; + +// Thenable object without `catch` method, +// shouldn't be considered as a valid Thenable +const invalidThenable = { + then: (fulfill, reject) => { + fulfill(); + }, +}; + +// Function that returns a Thenable function, +// a function with `catch` and `then` methods attached, +// shouldn't be considered as a valid Thenable. +const invalidThenableFunc = () => { + function f() {} + + f.then = (fulfill, reject) => { + fulfill(); + }; + f.catch = () => {}; + + return f; +}; + +// Test assert.rejects() and assert.doesNotReject() by checking their +// expected output and by verifying that they do not work sync + +// Check `assert.rejects`. +{ + const rejectingFn = async () => assert.fail(); + const errObj = { + code: 'ERR_ASSERTION', + name: 'AssertionError', + message: 'Failed' + }; + + // `assert.rejects` accepts a function or a promise + // or a thenable as first argument. + promises.push(assert.rejects(rejectingFn, errObj)); + promises.push(assert.rejects(rejectingFn(), errObj)); + + const validRejectingThenable = { + then: (fulfill, reject) => { + reject({ code: 'FAIL' }); + }, + catch: () => {} + }; + promises.push(assert.rejects(validRejectingThenable, { code: 'FAIL' })); + + // `assert.rejects` should not accept thenables that + // use a function as `obj` and that have no `catch` handler. + promises.push(assert.rejects( + assert.rejects(invalidThenable, {}), + { + code: 'ERR_INVALID_ARG_TYPE' + }) + ); + promises.push(assert.rejects( + assert.rejects(invalidThenableFunc, {}), + { + code: 'ERR_INVALID_RETURN_VALUE' + }) + ); + + const err = new Error('foobar'); + const validate = () => { return 'baz'; }; + promises.push(assert.rejects( + () => assert.rejects(Promise.reject(err), validate), + { + message: 'The "validate" validation function is expected to ' + + "return \"true\". Received 'baz'\n\nCaught error:\n\n" + + 'Error: foobar', + code: 'ERR_ASSERTION', + actual: err, + expected: validate, + name: 'AssertionError', + operator: 'rejects', + } + )); +} + +{ + const handler = (err) => { + assert(err instanceof assert.AssertionError, + `${err.name} is not instance of AssertionError`); + assert.strictEqual(err.code, 'ERR_ASSERTION'); + assert.strictEqual(err.message, + 'Missing expected rejection (mustNotCall).'); + assert.strictEqual(err.operator, 'rejects'); + assert.ok(!err.stack.includes('at Function.rejects')); + return true; + }; + + let promise = assert.rejects(async () => {}, common.mustNotCall()); + promises.push(assert.rejects(promise, common.mustCall(handler))); + + promise = assert.rejects(() => {}, common.mustNotCall()); + promises.push(assert.rejects(promise, { + name: 'TypeError', + code: 'ERR_INVALID_RETURN_VALUE', + // FIXME(JakobJingleheimer): This should match on key words, like /Promise/ and /undefined/. + message: 'Expected instance of Promise to be returned ' + + 'from the "promiseFn" function but got undefined.' + })); + + promise = assert.rejects(Promise.resolve(), common.mustNotCall()); + promises.push(assert.rejects(promise, common.mustCall(handler))); +} + +{ + const THROWN_ERROR = new Error(); + + promises.push(assert.rejects(() => { + throw THROWN_ERROR; + }, {}).catch(common.mustCall((err) => { + assert.strictEqual(err, THROWN_ERROR); + }))); +} + +promises.push(assert.rejects( + assert.rejects('fail', {}), + { + code: 'ERR_INVALID_ARG_TYPE', + message: 'The "promiseFn" argument must be of type function or an ' + + "instance of Promise. Received type string ('fail')" + } +)); + +{ + const handler = (generated, actual, err) => { + assert.strictEqual(err.generatedMessage, generated); + assert.strictEqual(err.code, 'ERR_ASSERTION'); + assert.strictEqual(err.actual, actual); + assert.strictEqual(err.operator, 'rejects'); + assert.match(err.stack, /rejects/); + return true; + }; + const err = new Error(); + promises.push(assert.rejects( + assert.rejects(Promise.reject(null), { code: 'FOO' }), + handler.bind(null, true, null) + )); + promises.push(assert.rejects( + assert.rejects(Promise.reject(5), { code: 'FOO' }, 'AAAAA'), + handler.bind(null, false, 5) + )); + promises.push(assert.rejects( + assert.rejects(Promise.reject(err), { code: 'FOO' }, 'AAAAA'), + handler.bind(null, false, err) + )); +} + +// Check `assert.doesNotReject`. +{ + // `assert.doesNotReject` accepts a function or a promise + // or a thenable as first argument. + /* eslint-disable no-restricted-syntax */ + let promise = assert.doesNotReject(() => new Map(), common.mustNotCall()); + promises.push(assert.rejects(promise, { + message: 'Expected instance of Promise to be returned ' + + 'from the "promiseFn" function but got an instance of Map.', + code: 'ERR_INVALID_RETURN_VALUE', + name: 'TypeError' + })); + promises.push(assert.doesNotReject(async () => {})); + promises.push(assert.doesNotReject(Promise.resolve())); + + // `assert.doesNotReject` should not accept thenables that + // use a function as `obj` and that have no `catch` handler. + const validFulfillingThenable = { + then: (fulfill, reject) => { + fulfill(); + }, + catch: () => {} + }; + promises.push(assert.doesNotReject(validFulfillingThenable)); + promises.push(assert.rejects( + assert.doesNotReject(invalidThenable), + { + code: 'ERR_INVALID_ARG_TYPE' + }) + ); + promises.push(assert.rejects( + assert.doesNotReject(invalidThenableFunc), + { + code: 'ERR_INVALID_RETURN_VALUE' + }) + ); + + const handler1 = (err) => { + assert(err instanceof assert.AssertionError, + `${err.name} is not instance of AssertionError`); + assert.strictEqual(err.code, 'ERR_ASSERTION'); + assert.strictEqual(err.message, 'Failed'); + return true; + }; + const handler2 = (err) => { + assert(err instanceof assert.AssertionError, + `${err.name} is not instance of AssertionError`); + assert.strictEqual(err.code, 'ERR_ASSERTION'); + assert.strictEqual(err.message, + 'Got unwanted rejection.\nActual message: "Failed"'); + assert.strictEqual(err.operator, 'doesNotReject'); + assert.ok(err.stack); + assert.ok(!err.stack.includes('at Function.doesNotReject')); + return true; + }; + + const rejectingFn = async () => assert.fail(); + + promise = assert.doesNotReject(rejectingFn, common.mustCall(handler1)); + promises.push(assert.rejects(promise, common.mustCall(handler2))); + + promise = assert.doesNotReject(rejectingFn(), common.mustCall(handler1)); + promises.push(assert.rejects(promise, common.mustCall(handler2))); + + promise = assert.doesNotReject(() => assert.fail(), common.mustNotCall()); + promises.push(assert.rejects(promise, common.mustCall(handler1))); + + promises.push(assert.rejects( + assert.doesNotReject(123), + { + code: 'ERR_INVALID_ARG_TYPE', + message: 'The "promiseFn" argument must be of type ' + + 'function or an instance of Promise. Received type number (123)' + } + )); + /* eslint-enable no-restricted-syntax */ +} + +// Make sure all async code gets properly executed. +Promise.all(promises).then(common.mustCall()); diff --git a/tests/node_compat/test/parallel/test-assert-fail.js b/tests/node_compat/test/parallel/test-assert-fail.js new file mode 100644 index 000000000..03def3a88 --- /dev/null +++ b/tests/node_compat/test/parallel/test-assert-fail.js @@ -0,0 +1,51 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); + +// No args +assert.throws( + () => { assert.fail(); }, + { + code: 'ERR_ASSERTION', + name: 'AssertionError', + message: 'Failed', + operator: 'fail', + actual: undefined, + expected: undefined, + generatedMessage: true, + stack: /Failed/ + } +); + +// One arg = message +assert.throws(() => { + assert.fail('custom message'); +}, { + code: 'ERR_ASSERTION', + name: 'AssertionError', + message: 'custom message', + operator: 'fail', + actual: undefined, + expected: undefined, + generatedMessage: false +}); + +// One arg = Error +assert.throws(() => { + assert.fail(new TypeError('custom message')); +}, { + name: 'TypeError', + message: 'custom message' +}); + +Object.prototype.get = common.mustNotCall(); +assert.throws(() => assert.fail(''), { code: 'ERR_ASSERTION' }); +delete Object.prototype.get; diff --git a/tests/node_compat/test/parallel/test-assert-strict-exists.js b/tests/node_compat/test/parallel/test-assert-strict-exists.js new file mode 100644 index 000000000..49499c3f6 --- /dev/null +++ b/tests/node_compat/test/parallel/test-assert-strict-exists.js @@ -0,0 +1,13 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); + +assert.strictEqual(require('assert/strict'), assert.strict); diff --git a/tests/node_compat/test/parallel/test-assert.js b/tests/node_compat/test/parallel/test-assert.js new file mode 100644 index 000000000..58b95068c --- /dev/null +++ b/tests/node_compat/test/parallel/test-assert.js @@ -0,0 +1,1615 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 15.5.1 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Flags: --expose-internals +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const { inspect } = require('util'); +// TODO(kt3k): Enable these when "vm" is ready. +// const vm = require('vm'); +// TODO(kt3k): Enable these when "internal/test/binding" is ready. +// const { internalBinding } = require('internal/test/binding'); +const a = assert; + +// Disable colored output to prevent color codes from breaking assertion +// message comparisons. This should only be an issue when process.stdout +// is a TTY. +if (process.stdout.isTTY) + process.env.NODE_DISABLE_COLORS = '1'; + +const strictEqualMessageStart = 'Expected values to be strictly equal:\n'; +const start = 'Expected values to be strictly deep-equal:'; +const actExp = '+ actual - expected'; + +assert.ok(a.AssertionError.prototype instanceof Error, + 'a.AssertionError instanceof Error'); + +assert.throws(() => a(false), a.AssertionError, 'ok(false)'); +assert.throws(() => a.ok(false), a.AssertionError, 'ok(false)'); + +// Throw message if the message is instanceof Error. +{ + let threw = false; + try { + assert.ok(false, new Error('ok(false)')); + } catch (e) { + threw = true; + assert.ok(e instanceof Error); + } + assert.ok(threw, 'Error: ok(false)'); +} + + +a(true); +a('test', 'ok(\'test\')'); +a.ok(true); +a.ok('test'); + +assert.throws(() => a.equal(true, false), + a.AssertionError, 'equal(true, false)'); + +a.equal(null, null); +a.equal(undefined, undefined); +a.equal(null, undefined); +a.equal(true, true); +a.equal(2, '2'); +a.notEqual(true, false); + +assert.throws(() => a.notEqual(true, true), + a.AssertionError, 'notEqual(true, true)'); + +assert.throws(() => a.strictEqual(2, '2'), + a.AssertionError, 'strictEqual(2, \'2\')'); + +assert.throws(() => a.strictEqual(null, undefined), + a.AssertionError, 'strictEqual(null, undefined)'); + +assert.throws( + () => a.notStrictEqual(2, 2), + { + message: 'Expected "actual" to be strictly unequal to: 2\n', + name: 'AssertionError' + } +); + +assert.throws( + () => a.notStrictEqual('a '.repeat(30), 'a '.repeat(30)), + { + message: 'Expected "actual" to be strictly unequal to: ' + + `"${'a '.repeat(30)}"\n`, + name: 'AssertionError' + } +); + +assert.throws( + () => a.notEqual(1, 1), + { + message: '1 != 1', + operator: '!=' + } +); + +a.notStrictEqual(2, '2'); + +// Testing the throwing. +function thrower(errorConstructor) { + throw new errorConstructor({}); +} + +// The basic calls work. +assert.throws(() => thrower(a.AssertionError), a.AssertionError, 'message'); +assert.throws(() => thrower(a.AssertionError), a.AssertionError); +assert.throws(() => thrower(a.AssertionError)); + +// If not passing an error, catch all. +assert.throws(() => thrower(TypeError)); + +// When passing a type, only catch errors of the appropriate type. +assert.throws( + () => a.throws(() => thrower(TypeError), a.AssertionError), + { + // generatedMessage: true, + // actual: new TypeError({}), + expected: a.AssertionError, + code: 'ERR_ASSERTION', + name: 'AssertionError', + operator: 'throws', + message: 'The error is expected to be an instance of "AssertionError". ' + + 'Received "TypeError"\n\nError message:\n\n[object Object]' + } +); + +// doesNotThrow should pass through all errors. +{ + let threw = false; + try { + a.doesNotThrow(() => thrower(TypeError), a.AssertionError); + } catch (e) { + threw = true; + assert.ok(e instanceof TypeError); + } + assert(threw, 'a.doesNotThrow with an explicit error is eating extra errors'); +} + +// Key difference is that throwing our correct error makes an assertion error. +{ + let threw = false; + try { + a.doesNotThrow(() => thrower(TypeError), TypeError); + } catch (e) { + threw = true; + assert.ok(e instanceof a.AssertionError); + // Commented out the following assertion + // assert.ok(!e.stack.includes('at Function.doesNotThrow')); + } + assert.ok(threw, 'a.doesNotThrow is not catching type matching errors'); +} + +assert.throws( + () => a.doesNotThrow(() => thrower(Error), 'user message'), + { + name: 'AssertionError', + code: 'ERR_ASSERTION', + operator: 'doesNotThrow', + message: 'Got unwanted exception: user message\n' + + 'Actual message: "[object Object]"' + } +); + +assert.throws( + () => a.doesNotThrow(() => thrower(Error)), + { + code: 'ERR_ASSERTION', + message: 'Got unwanted exception.\nActual message: "[object Object]"' + } +); + +assert.throws( + () => a.doesNotThrow(() => thrower(Error), /\[[a-z]{6}\s[A-z]{6}\]/g, 'user message'), + { + name: 'AssertionError', + code: 'ERR_ASSERTION', + operator: 'doesNotThrow', + message: 'Got unwanted exception: user message\n' + + 'Actual message: "[object Object]"' + } +); + +// Make sure that validating using constructor really works. +{ + let threw = false; + try { + assert.throws( + () => { + throw ({}); + }, + Array + ); + } catch { + threw = true; + } + assert.ok(threw, 'wrong constructor validation'); +} + +// Use a RegExp to validate the error message. +{ + a.throws(() => thrower(TypeError), /\[object Object\]/); + + const symbol = Symbol('foo'); + a.throws(() => { + throw symbol; + }, /foo/); + + a.throws(() => { + a.throws(() => { + throw symbol; + }, /abc/); + }, { + message: 'The input did not match the regular expression /abc/. ' + + "Input:\n\n'Symbol(foo)'\n", + code: 'ERR_ASSERTION', + operator: 'throws', + actual: symbol, + expected: /abc/ + }); +} + +// Use a fn to validate the error object. +a.throws(() => thrower(TypeError), (err) => { + if ((err instanceof TypeError) && /\[object Object\]/.test(err)) { + return true; + } +}); + +// https://github.com/nodejs/node/issues/3188 +{ + let actual; + assert.throws( + () => { + const ES6Error = class extends Error {}; + const AnotherErrorType = class extends Error {}; + + assert.throws(() => { + actual = new AnotherErrorType('foo'); + throw actual; + }, ES6Error); + }, + (err) => { + assert.strictEqual( + err.message, + 'The error is expected to be an instance of "ES6Error". ' + + 'Received "AnotherErrorType"\n\nError message:\n\nfoo' + ); + assert.strictEqual(err.actual, actual); + return true; + } + ); +} + +// Check messages from assert.throws(). +{ + const noop = () => {}; + assert.throws( + () => { a.throws((noop)); }, + { + code: 'ERR_ASSERTION', + message: 'Missing expected exception.', + operator: 'throws', + actual: undefined, + expected: undefined + }); + + assert.throws( + () => { a.throws(noop, TypeError); }, + { + code: 'ERR_ASSERTION', + message: 'Missing expected exception (TypeError).', + actual: undefined, + expected: TypeError + }); + + assert.throws( + () => { a.throws(noop, 'fhqwhgads'); }, + { + code: 'ERR_ASSERTION', + message: 'Missing expected exception: fhqwhgads', + actual: undefined, + expected: undefined + }); + + assert.throws( + () => { a.throws(noop, TypeError, 'fhqwhgads'); }, + { + code: 'ERR_ASSERTION', + message: 'Missing expected exception (TypeError): fhqwhgads', + actual: undefined, + expected: TypeError + }); + + let threw = false; + try { + a.throws(noop); + } catch (e) { + threw = true; + assert.ok(e instanceof a.AssertionError); + // TODO(kt3k): enable this assertion + // assert.ok(!e.stack.includes('at Function.throws')); + } + assert.ok(threw); +} + +const circular = { y: 1 }; +circular.x = circular; + +function testAssertionMessage(actual, expected, msg) { + assert.throws( + () => assert.strictEqual(actual, ''), + { + generatedMessage: true, + message: msg || strictEqualMessageStart + + `+ actual - expected\n\n+ ${expected}\n- ''` + } + ); +} + +function testShortAssertionMessage(actual, expected) { + testAssertionMessage(actual, expected, strictEqualMessageStart + + `\n${inspect(actual)} !== ''\n`); +} + +// TODO(kt3k): Do we need completely simulate +// Node.js assertion error messages? +/* +testShortAssertionMessage(null, 'null'); +testShortAssertionMessage(true, 'true'); +testShortAssertionMessage(false, 'false'); +testShortAssertionMessage(100, '100'); +testShortAssertionMessage(NaN, 'NaN'); +testShortAssertionMessage(Infinity, 'Infinity'); +testShortAssertionMessage('a', '"a"'); +testShortAssertionMessage('foo', '\'foo\''); +testShortAssertionMessage(0, '0'); +testShortAssertionMessage(Symbol(), 'Symbol()'); +testShortAssertionMessage(undefined, 'undefined'); +testShortAssertionMessage(-Infinity, '-Infinity'); +testAssertionMessage([], '[]'); +testAssertionMessage(/a/, '/a/'); +testAssertionMessage(/abc/gim, '/abc/gim'); +testAssertionMessage({}, '{}'); +testAssertionMessage([1, 2, 3], '[\n+ 1,\n+ 2,\n+ 3\n+ ]'); +testAssertionMessage(function f() {}, '[Function: f]'); +testAssertionMessage(function() {}, '[Function (anonymous)]'); +testAssertionMessage(circular, + ' {\n+ x: [Circular *1],\n+ y: 1\n+ }'); +testAssertionMessage({ a: undefined, b: null }, + '{\n+ a: undefined,\n+ b: null\n+ }'); +testAssertionMessage({ a: NaN, b: Infinity, c: -Infinity }, + '{\n+ a: NaN,\n+ b: Infinity,\n+ c: -Infinity\n+ }'); +*/ + +// https://github.com/nodejs/node-v0.x-archive/issues/5292 +assert.throws( + () => assert.strictEqual(1, 2), +/* Memo: Disabled this object assertion + { + message: `${strictEqualMessageStart}\n1 !== 2\n`, + generatedMessage: true + } +*/ +); + +assert.throws( + () => assert.strictEqual(1, 2, 'oh no'), + { + message: 'oh no', + generatedMessage: false + } +); + +{ + let threw = false; + const rangeError = new RangeError('my range'); + + // Verify custom errors. + try { + assert.strictEqual(1, 2, rangeError); + } catch (e) { + assert.strictEqual(e, rangeError); + threw = true; + assert.ok(e instanceof RangeError, 'Incorrect error type thrown'); + } + assert.ok(threw); + threw = false; + + // Verify AssertionError is the result from doesNotThrow with custom Error. + try { + a.doesNotThrow(() => { + throw new TypeError('wrong type'); + }, TypeError, rangeError); + } catch (e) { + threw = true; + assert.ok(e.message.includes(rangeError.message)); + assert.ok(e instanceof assert.AssertionError); + // TODO(kt3k): Enable this assertion + // assert.ok(!e.stack.includes('doesNotThrow'), e); + } + assert.ok(threw); +} + +{ + // Verify that throws() and doesNotThrow() throw on non-functions. + const testBlockTypeError = (method, fn) => { + assert.throws( + () => method(fn), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "fn" argument must be of type function.' + + common.invalidArgTypeHelper(fn) + } + ); + }; + + testBlockTypeError(assert.throws, 'string'); + testBlockTypeError(assert.doesNotThrow, 'string'); + testBlockTypeError(assert.throws, 1); + testBlockTypeError(assert.doesNotThrow, 1); + testBlockTypeError(assert.throws, true); + testBlockTypeError(assert.doesNotThrow, true); + testBlockTypeError(assert.throws, false); + testBlockTypeError(assert.doesNotThrow, false); + testBlockTypeError(assert.throws, []); + testBlockTypeError(assert.doesNotThrow, []); + testBlockTypeError(assert.throws, {}); + testBlockTypeError(assert.doesNotThrow, {}); + testBlockTypeError(assert.throws, /foo/); + testBlockTypeError(assert.doesNotThrow, /foo/); + testBlockTypeError(assert.throws, null); + testBlockTypeError(assert.doesNotThrow, null); + testBlockTypeError(assert.throws, undefined); + testBlockTypeError(assert.doesNotThrow, undefined); +} + +// https://github.com/nodejs/node/issues/3275 +assert.throws(() => { throw 'error'; }, (err) => err === 'error'); +assert.throws(() => { throw new Error(); }, (err) => err instanceof Error); + +// Long values should be truncated for display. +assert.throws(() => { + assert.strictEqual('A'.repeat(1000), ''); +}, (err) => { + assert.strictEqual(err.code, 'ERR_ASSERTION'); + /* TODO(kt3k): Enable this assertion + assert.strictEqual(err.message, + `${strictEqualMessageStart}+ actual - expected\n\n` + + `+ '${'A'.repeat(1000)}'\n- ''`); + */ + assert.strictEqual(err.actual.length, 1000); + // TODO(kt3k): Enable this after fixing 'inspect' + // assert.ok(inspect(err).includes(`actual: '${'A'.repeat(488)}...'`)); + return true; +}); + +// Output that extends beyond 10 lines should also be truncated for display. +{ + const multilineString = 'fhqwhgads\n'.repeat(15); + assert.throws(() => { + assert.strictEqual(multilineString, ''); + }, (err) => { + assert.strictEqual(err.code, 'ERR_ASSERTION'); + // TODO(kt3k): Enable these assertion when the strictEqual message is aligned + // to Node.js API. + // assert.strictEqual(err.message.split('\n').length, 19); + assert.strictEqual(err.actual.split('\n').length, 16); + // TODO(kt3k): inspect(err) causes Maximum call stack error. + /* + assert.ok(inspect(err).includes( + "actual: 'fhqwhgads\\n' +\n" + + " 'fhqwhgads\\n' +\n".repeat(9) + + " '...'")); + */ + return true; + }); +} + +{ + // Bad args to AssertionError constructor should throw TypeError. + const args = [1, true, false, '', null, Infinity, Symbol('test'), undefined]; + args.forEach((input) => { + assert.throws( + () => new assert.AssertionError(input), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "options" argument must be of type object.' + + common.invalidArgTypeHelper(input) + }); + }); +} + +assert.throws( + () => assert.strictEqual(new Error('foo'), new Error('foobar')), + { + code: 'ERR_ASSERTION', + name: 'AssertionError', + /* TODO(kt3k): Enable this assertion when the assertion error message is fixed. + message: 'Expected "actual" to be reference-equal to "expected":\n' + + '+ actual - expected\n\n' + + '+ [Error: foo]\n- [Error: foobar]' + */ + } +); + +a.equal(NaN, NaN); +a.throws( + () => a.notEqual(NaN, NaN), + a.AssertionError +); + +// Test strict assert. +{ + const a = require('assert'); + const assert = require('assert').strict; + assert.throws(() => assert.equal(1, true), assert.AssertionError); + assert.notEqual(0, false); + assert.throws(() => assert.deepEqual(1, true), assert.AssertionError); + assert.notDeepEqual(0, false); + assert.equal(assert.strict, assert.strict.strict); + assert.equal(assert.equal, assert.strictEqual); + assert.equal(assert.deepEqual, assert.deepStrictEqual); + assert.equal(assert.notEqual, assert.notStrictEqual); + assert.equal(assert.notDeepEqual, assert.notDeepStrictEqual); + assert.equal(Object.keys(assert).length, Object.keys(a).length); + assert(7); + assert.throws( + () => assert(...[]), + { + message: 'No value argument passed to `assert.ok()`', + name: 'AssertionError', + // TODO(kt3k): Enable this + // generatedMessage: true + } + ); + assert.throws( + () => a(), + { + message: 'No value argument passed to `assert.ok()`', + name: 'AssertionError' + } + ); + + // Test setting the limit to zero and that assert.strict works properly. + const tmpLimit = Error.stackTraceLimit; + Error.stackTraceLimit = 0; + assert.throws( + () => { + assert.ok( + typeof 123 === 'string' + ); + }, + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + /* TODO(kt3k): Enable this assertion + message: 'The expression evaluated to a falsy value:\n\n ' + + "assert.ok(\n typeof 123 === 'string'\n )\n" + */ + } + ); + Error.stackTraceLimit = tmpLimit; + + // Test error diffs. + let message = [ + start, + `${actExp} ... Lines skipped`, + '', + ' [', + ' [', + ' [', + ' 1,', + ' 2,', + '+ 3', + "- '3'", + ' ]', + '...', + ' 4,', + ' 5', + ' ]'].join('\n'); + assert.throws( + () => assert.deepEqual([[[1, 2, 3]], 4, 5], [[[1, 2, '3']], 4, 5]), + /* TODO(kt3k): Enable this assertion + { message } + */ + ); + + message = [ + start, + `${actExp} ... Lines skipped`, + '', + ' [', + ' 1,', + '...', + ' 1,', + ' 0,', + '- 1,', + ' 1,', + '...', + ' 1,', + ' 1', + ' ]' + ].join('\n'); + assert.throws( + () => assert.deepEqual( + [1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1], + [1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1]), + /* TODO(kt3k): Enable this assertion + { message } + */ + ); + + message = [ + start, + `${actExp} ... Lines skipped`, + '', + ' [', + ' 1,', + '...', + ' 1,', + ' 0,', + '+ 1,', + ' 1,', + ' 1,', + ' 1', + ' ]' + ].join('\n'); + assert.throws( + () => assert.deepEqual( + [1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1], + [1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1]), + /* TODO(kt3k): Enable this assertion + { message } + */ + ); + + message = [ + start, + actExp, + '', + ' [', + ' 1,', + '+ 2,', + '- 1,', + ' 1,', + ' 1,', + ' 0,', + '+ 1,', + ' 1', + ' ]' + ].join('\n'); + assert.throws( + () => assert.deepEqual( + [1, 2, 1, 1, 0, 1, 1], + [1, 1, 1, 1, 0, 1]), + /* TODO(kt3k): Enable this assertion + { message } + */ + ); + + message = [ + start, + actExp, + '', + '+ [', + '+ 1,', + '+ 2,', + '+ 1', + '+ ]', + '- undefined', + ].join('\n'); + assert.throws( + () => assert.deepEqual([1, 2, 1], undefined), + /* TODO(kt3k): Enable this assertion + { message } + */ + ); + + message = [ + start, + actExp, + '', + ' [', + '+ 1,', + ' 2,', + ' 1', + ' ]' + ].join('\n'); + assert.throws( + () => assert.deepEqual([1, 2, 1], [2, 1]), + /* TODO(kt3k): Enable this assertion + { message } + */ + ); + + message = `${start}\n` + + `${actExp} ... Lines skipped\n` + + '\n' + + ' [\n' + + '+ 1,\n'.repeat(25) + + '...\n' + + '- 2,\n'.repeat(25) + + '...'; + assert.throws( + () => assert.deepEqual(Array(28).fill(1), Array(28).fill(2)), + /* TODO(kt3k): Enable this assertion + { message } + */ + ); + + const obj1 = {}; + const obj2 = { loop: 'forever' }; + obj2[inspect.custom] = () => '{}'; + // No infinite loop and no custom inspect. + assert.throws(() => assert.deepEqual(obj1, obj2), { + code: "ERR_ASSERTION", + /* TODO(kt3k): Enable this assertion + message: `${start}\n` + + `${actExp}\n` + + '\n' + + '+ {}\n' + + '- {\n' + + '- [Symbol(nodejs.util.inspect.custom)]: [Function (anonymous)],\n' + + "- loop: 'forever'\n" + + '- }' + */ + }); + + // notDeepEqual tests + assert.throws( + () => assert.notDeepEqual([1], [1]), + { + code: "ERR_ASSERTION", + /* TODO(kt3k): Enable this assertion + message: 'Expected "actual" not to be strictly deep-equal to:\n\n' + + '[\n 1\n]\n' + */ + } + ); + + message = 'Expected "actual" not to be strictly deep-equal to:' + + `\n\n[${'\n 1,'.repeat(45)}\n...\n`; + const data = Array(51).fill(1); + assert.throws( + () => assert.notDeepEqual(data, data), + /* TODO(kt3k): Enable this assertion + { message } + */ + ); +} + +assert.throws( + () => assert.ok(null), + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + generatedMessage: true, + /* TODO(kt3k): Enable this assertion + message: 'The expression evaluated to a falsy value:\n\n ' + + 'assert.ok(null)\n' + */ + } +); +assert.throws( + () => assert(typeof 123n === 'string'), + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + generatedMessage: true, + /* TODO(kt3k): Enable this assertion + message: 'The expression evaluated to a falsy value:\n\n ' + + "assert(typeof 123n === 'string')\n" + */ + } +); + +assert.throws( + () => assert(false, Symbol('foo')), + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + /* TODO(kt3k): Enable this assertion + generatedMessage: false, + message: 'Symbol(foo)' + */ + } +); + +// TODO(kt3k): Enable these when "internal/test/binding" is ready. +/* +{ + // Test caching. + const fs = internalBinding('fs'); + const tmp = fs.close; + fs.close = common.mustCall(tmp, 1); + function throwErr() { + assert( + (Buffer.from('test') instanceof Error) + ); + } + assert.throws( + () => throwErr(), + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + message: 'The expression evaluated to a falsy value:\n\n ' + + "assert(\n (Buffer.from('test') instanceof Error)\n )\n" + } + ); + assert.throws( + () => throwErr(), + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + message: 'The expression evaluated to a falsy value:\n\n ' + + "assert(\n (Buffer.from('test') instanceof Error)\n )\n" + } + ); + fs.close = tmp; +} +*/ + +assert.throws( + () => { + a( + (() => 'string')() + === + 123 instanceof + Buffer + ); + }, + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + /* TODO(kt3k): Enable this assertion + message: 'The expression evaluated to a falsy value:\n\n' + + ' a(\n' + + ' (() => \'string\')()\n' + + ' ===\n' + + ' 123 instanceof\n' + + ' Buffer\n' + + ' )\n' + */ + } +); + +assert.throws( + () => { + a( + (() => 'string')() + === + 123 instanceof + Buffer + ); + }, + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + /* TODO(kt3k): Enable this assertion + message: 'The expression evaluated to a falsy value:\n\n' + + ' a(\n' + + ' (() => \'string\')()\n' + + ' ===\n' + + ' 123 instanceof\n' + + ' Buffer\n' + + ' )\n' + */ + } +); + +assert.throws(() => { +a(( + () => 'string')() === +123 instanceof +Buffer +); +}, { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + /* TODO(kt3k): Enable this assertion + message: 'The expression evaluated to a falsy value:\n\n' + + ' a((\n' + + ' () => \'string\')() ===\n' + + ' 123 instanceof\n' + + ' Buffer\n' + + ' )\n' + */ + } +); + +assert.throws( + () => { + assert(true); assert(null, undefined); + }, + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + /* TODO(kt3k): Enable this assertion + message: 'The expression evaluated to a falsy value:\n\n ' + + 'assert(null, undefined)\n' + */ + } +); + +assert.throws( + () => { + assert + .ok(null, undefined); + }, + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + /* TODO(kt3k): Enable this assertion + message: 'The expression evaluated to a falsy value:\n\n ' + + 'ok(null, undefined)\n' + */ + } +); + +assert.throws( + () => assert['ok']["apply"](null, [0]), + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + /* TODO(kt3k): Enable this assertion + message: 'The expression evaluated to a falsy value:\n\n ' + + 'assert[\'ok\']["apply"](null, [0])\n' + */ + } +); + +assert.throws( + () => { + const wrapper = (fn, value) => fn(value); + wrapper(assert, false); + }, + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + /* TODO(kt3k): Enable this assertion + message: 'The expression evaluated to a falsy value:\n\n fn(value)\n' + */ + } +); + +assert.throws( + () => assert.ok.call(null, 0), + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + /* TODO(kt3k): Enable this assertion + message: 'The expression evaluated to a falsy value:\n\n ' + + 'assert.ok.call(null, 0)\n', + generatedMessage: true + */ + } +); + +assert.throws( + () => assert.ok.call(null, 0, 'test'), + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + message: 'test', + generatedMessage: false + } +); + +// Works in eval. +assert.throws( + () => new Function('assert', 'assert(1 === 2);')(assert), + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + /* TODO(kt3k): Enable this assertion + message: 'The expression evaluated to a falsy value:\n\n assert(1 === 2)\n' + */ + } +); + +assert.throws( + () => eval('console.log("FOO");\nassert.ok(1 === 2);'), + { + code: 'ERR_ASSERTION', + /* TODO(kt3k): Enable this assertion + message: 'false == true' + */ + } +); + +assert.throws( + () => assert.throws(() => {}, 'Error message', 'message'), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + /* TODO(kt3k): Enable this assertion + message: 'The "error" argument must be of type function or ' + + 'an instance of Error, RegExp, or Object. Received type string ' + + "('Error message')" + */ + } +); + +[ + 1, + false, + Symbol() +].forEach((input) => { + assert.throws( + () => assert.throws(() => {}, input), + { + code: 'ERR_INVALID_ARG_TYPE', + /* TODO(kt3k): Enable this assertion + message: 'The "error" argument must be of type function or ' + + 'an instance of Error, RegExp, or Object.' + + common.invalidArgTypeHelper(input) + */ + } + ); +}); + +{ + + assert.throws(() => { + assert.ok((() => Boolean('' === false))()); + }, { + code: "ERR_ASSERTION", + /* TODO(kt3k): Enable this assertion + message: 'The expression evaluated to a falsy value:\n\n' + + " assert.ok((() => Boolean('\\u0001' === false))())\n" + */ + }); + + const errFn = () => { + const err = new TypeError('Wrong value'); + err.code = 404; + throw err; + }; + const errObj = { + name: 'TypeError', + message: 'Wrong value' + }; + assert.throws(errFn, errObj); + + errObj.code = 404; + assert.throws(errFn, errObj); + + // Fail in case a expected property is undefined and not existent on the + // error. + errObj.foo = undefined; + assert.throws( + () => assert.throws(errFn, errObj), + { + code: 'ERR_ASSERTION', + name: 'AssertionError', + /* TODO(kt3k): Enable this assertion + message: `${start}\n${actExp}\n\n` + + ' Comparison {\n' + + ' code: 404,\n' + + '- foo: undefined,\n' + + " message: 'Wrong value',\n" + + " name: 'TypeError'\n" + + ' }' + */ + } + ); + + // Show multiple wrong properties at the same time. + errObj.code = '404'; + assert.throws( + () => assert.throws(errFn, errObj), + { + code: 'ERR_ASSERTION', + name: 'AssertionError', + /* TODO(kt3k): Enable this assertion + message: `${start}\n${actExp}\n\n` + + ' Comparison {\n' + + '+ code: 404,\n' + + "- code: '404',\n" + + '- foo: undefined,\n' + + " message: 'Wrong value',\n" + + " name: 'TypeError'\n" + + ' }' + */ + } + ); + + assert.throws( + () => assert.throws(() => { throw new Error(); }, { foo: 'bar' }, 'foobar'), + { + constructor: assert.AssertionError, + code: 'ERR_ASSERTION', + message: 'foobar' + } + ); + + assert.throws( + () => a.doesNotThrow(() => { throw new Error(); }, { foo: 'bar' }), + { + name: 'TypeError', + code: 'ERR_INVALID_ARG_TYPE', + /* TODO(kt3k): Enable this assertion + message: 'The "expected" argument must be of type function or an ' + + 'instance of RegExp. Received an instance of Object' + */ + } + ); + + assert.throws(() => { throw new Error('e'); }, new Error('e')); + assert.throws( + () => assert.throws(() => { throw new TypeError('e'); }, new Error('e')), + { + name: 'AssertionError', + code: 'ERR_ASSERTION', + /* TODO(kt3k): Enable this assertion + message: `${start}\n${actExp}\n\n` + + ' Comparison {\n' + + " message: 'e',\n" + + "+ name: 'TypeError'\n" + + "- name: 'Error'\n" + + ' }' + */ + } + ); + assert.throws( + () => assert.throws(() => { throw new Error('foo'); }, new Error('')), + { + name: 'AssertionError', + code: 'ERR_ASSERTION', + /* TODO(kt3k): Enable this assertion + generatedMessage: true, + message: `${start}\n${actExp}\n\n` + + ' Comparison {\n' + + "+ message: 'foo',\n" + + "- message: '',\n" + + " name: 'Error'\n" + + ' }' + */ + } + ); + + assert.throws(() => { throw undefined; }, /undefined/); + assert.throws( + () => a.doesNotThrow(() => { throw undefined; }), + { + name: 'AssertionError', + code: 'ERR_ASSERTION', + message: 'Got unwanted exception.\nActual message: "undefined"' + } + ); +} + +assert.throws( + () => assert.throws(() => { throw new Error(); }, {}), + { + message: "The argument 'error' may not be an empty object. Received {}", + code: 'ERR_INVALID_ARG_VALUE' + } +); + +assert.throws( + () => a.throws( + () => { throw 'foo'; }, + 'foo' + ), + { + code: 'ERR_AMBIGUOUS_ARGUMENT', + message: 'The "error/message" argument is ambiguous. ' + + 'The error "foo" is identical to the message.' + } +); + +assert.throws( + () => a.throws( + () => { throw new TypeError('foo'); }, + 'foo' + ), + { + code: 'ERR_AMBIGUOUS_ARGUMENT', + message: 'The "error/message" argument is ambiguous. ' + + 'The error message "foo" is identical to the message.' + } +); + +// Should not throw. +assert.throws(() => { throw null; }, 'foo'); + +assert.throws( + () => assert.strictEqual([], []), + { + code: 'ERR_ASSERTION', + /* TODO(kt3k): Enable this assertion + message: 'Values have same structure but are not reference-equal:\n\n[]\n' + */ + } +); + +{ + const args = (function() { return arguments; })('a'); + assert.throws( + () => assert.strictEqual(args, { 0: 'a' }), + { + code: 'ERR_ASSERTION', + /* TODO(kt3k): Enable this assertion + message: 'Expected "actual" to be reference-equal to "expected":\n' + + '+ actual - expected\n\n' + + "+ [Arguments] {\n- {\n '0': 'a'\n }" + */ + } + ); +} + +assert.throws( + () => { throw new TypeError('foobar'); }, + { + message: /foo/, + name: /^TypeError$/ + } +); + +assert.throws( + () => assert.throws( + () => { throw new TypeError('foobar'); }, + { + message: /fooa/, + name: /^TypeError$/ + } + ), + { + code: 'ERR_ASSERTION', + /* TODO(kt3k): Enable this assertion + message: `${start}\n${actExp}\n\n` + + ' Comparison {\n' + + "+ message: 'foobar',\n" + + '- message: /fooa/,\n' + + " name: 'TypeError'\n" + + ' }' + */ + } +); + +{ + let actual = null; + const expected = { message: 'foo' }; + assert.throws( + () => assert.throws( + () => { throw actual; }, + expected + ), + { + operator: 'throws', + actual, + expected, + code: 'ERR_ASSERTION', + /* TODO(kt3k): Enable this assertion + generatedMessage: true, + message: `${start}\n${actExp}\n\n` + + '+ null\n' + + '- {\n' + + "- message: 'foo'\n" + + '- }' + */ + } + ); + + actual = 'foobar'; + const message = 'message'; + assert.throws( + () => assert.throws( + () => { throw actual; }, + { message: 'foobar' }, + message + ), + { + actual, + message, + operator: 'throws', + generatedMessage: false + } + ); +} + +// Indicate where the strings diverge. +assert.throws( + () => assert.strictEqual('test test', 'test foobar'), + { + code: 'ERR_ASSERTION', + name: 'AssertionError', + /* TODO(kt3k): Enable this assertion + message: strictEqualMessageStart + + '+ actual - expected\n\n' + + "+ 'test test'\n" + + "- 'test foobar'\n" + + ' ^' + */ + } +); + +// Check for reference-equal objects in `notStrictEqual()` +assert.throws( + () => { + const obj = {}; + assert.notStrictEqual(obj, obj); + }, + { + code: 'ERR_ASSERTION', + name: 'AssertionError', + /* TODO(kt3k): Enable this assertion + message: 'Expected "actual" not to be reference-equal to "expected": {}' + */ + } +); + +assert.throws( + () => { + const obj = { a: true }; + assert.notStrictEqual(obj, obj); + }, + { + code: 'ERR_ASSERTION', + name: 'AssertionError', + /* TODO(kt3k): Enable this assertion + message: 'Expected "actual" not to be reference-equal to "expected":\n\n' + + '{\n a: true\n}\n' + */ + } +); + +{ + let threw = false; + try { + assert.deepStrictEqual(Array(100).fill(1), 'foobar'); + } catch (err) { + threw = true; + /* TODO(kt3k): Enable this assertion + assert(/actual: \[Array],\n expected: 'foobar',/.test(inspect(err))); + */ + } + assert(threw); +} + +assert.throws( + () => a.equal(1), + { code: 'ERR_MISSING_ARGS' } +); + +assert.throws( + () => a.deepEqual(/a/), + { code: 'ERR_MISSING_ARGS' } +); + +assert.throws( + () => a.notEqual(null), + { code: 'ERR_MISSING_ARGS' } +); + +assert.throws( + () => a.notDeepEqual('test'), + { code: 'ERR_MISSING_ARGS' } +); + +assert.throws( + () => a.strictEqual({}), + { code: 'ERR_MISSING_ARGS' } +); + +assert.throws( + () => a.deepStrictEqual(Symbol()), + { code: 'ERR_MISSING_ARGS' } +); + +assert.throws( + () => a.notStrictEqual(5n), + { code: 'ERR_MISSING_ARGS' } +); + +assert.throws( + () => a.notDeepStrictEqual(undefined), + { code: 'ERR_MISSING_ARGS' } +); + +assert.throws( + () => a.strictEqual(), + { code: 'ERR_MISSING_ARGS' } +); + +assert.throws( + () => a.deepStrictEqual(), + { code: 'ERR_MISSING_ARGS' } +); + +// Verify that `stackStartFunction` works as alternative to `stackStartFn`. +{ + (function hidden() { + const err = new assert.AssertionError({ + actual: 'foo', + operator: 'strictEqual', + stackStartFunction: hidden + }); + const err2 = new assert.AssertionError({ + actual: 'foo', + operator: 'strictEqual', + stackStartFn: hidden + }); + assert(!err.stack.includes('hidden')); + assert(!err2.stack.includes('hidden')); + })(); +} + +assert.throws( + () => assert.throws(() => { throw Symbol('foo'); }, RangeError), + { + code: 'ERR_ASSERTION', + /* TODO(kt3k): Enable this assertion + message: 'The error is expected to be an instance of "RangeError". ' + + 'Received "Symbol(foo)"' + */ + } +); + +assert.throws( + () => assert.throws(() => { throw [1, 2]; }, RangeError), + { + code: 'ERR_ASSERTION', + /* TODO(kt3k): Enable this assertion + message: 'The error is expected to be an instance of "RangeError". ' + + 'Received "[Array]"' + */ + } +); + +{ + const err = new TypeError('foo'); + const validate = (() => () => ({ a: true, b: [ 1, 2, 3 ] }))(); + assert.throws( + () => assert.throws(() => { throw err; }, validate), + { + message: 'The validation function is expected to ' + + `return "true". Received ${inspect(validate())}\n\nCaught ` + + `error:\n\n${err}`, + code: 'ERR_ASSERTION', + actual: err, + expected: validate, + name: 'AssertionError', + operator: 'throws', + } + ); +} + +// TODO(kt3k): Enable these when "vm" is ready. +/* +assert.throws( + () => { + const script = new vm.Script('new RangeError("foobar");'); + const context = vm.createContext(); + const err = script.runInContext(context); + assert.throws(() => { throw err; }, RangeError); + }, + { + message: 'The error is expected to be an instance of "RangeError". ' + + 'Received an error with identical name but a different ' + + 'prototype.\n\nError message:\n\nfoobar' + } +); +*/ + +// Multiple assert.match() tests. +{ + assert.throws( + () => assert.match(/abc/, 'string'), + { + code: 'ERR_INVALID_ARG_TYPE', + /* TODO(kt3k): Enable this assertion + message: 'The "regexp" argument must be an instance of RegExp. ' + + "Received type string ('string')" + */ + } + ); + assert.throws( + () => assert.match('string', /abc/), + { + actual: 'string', + expected: /abc/, + operator: 'match', + /* TODO(kt3k): Enable this assertion + message: 'The input did not match the regular expression /abc/. ' + + "Input:\n\n'string'\n", + generatedMessage: true + */ + } + ); + assert.throws( + () => assert.match('string', /abc/, 'foobar'), + { + actual: 'string', + expected: /abc/, + operator: 'match', + message: 'foobar', + generatedMessage: false + } + ); + const errorMessage = new RangeError('foobar'); + assert.throws( + () => assert.match('string', /abc/, errorMessage), + errorMessage + ); + assert.throws( + () => assert.match({ abc: 123 }, /abc/), + { + actual: { abc: 123 }, + expected: /abc/, + operator: 'match', + /* TODO(kt3k): Enable this assertion + message: 'The "string" argument must be of type string. ' + + 'Received type object ({ abc: 123 })', + generatedMessage: true + */ + } + ); + assert.match('I will pass', /pass$/); +} + +// Multiple assert.doesNotMatch() tests. +{ + assert.throws( + () => assert.doesNotMatch(/abc/, 'string'), + { + code: 'ERR_INVALID_ARG_TYPE', + /* TODO(kt3k): Enable this assertion + message: 'The "regexp" argument must be an instance of RegExp. ' + + "Received type string ('string')" + */ + } + ); + assert.throws( + () => assert.doesNotMatch('string', /string/), + { + actual: 'string', + expected: /string/, + operator: 'doesNotMatch', + /* TODO(kt3k): Enable this assertion + message: 'The input was expected to not match the regular expression ' + + "/string/. Input:\n\n'string'\n", + generatedMessage: true + */ + } + ); + assert.throws( + () => assert.doesNotMatch('string', /string/, 'foobar'), + { + actual: 'string', + expected: /string/, + operator: 'doesNotMatch', + message: 'foobar', + generatedMessage: false + } + ); + const errorMessage = new RangeError('foobar'); + assert.throws( + () => assert.doesNotMatch('string', /string/, errorMessage), + errorMessage + ); + assert.throws( + () => assert.doesNotMatch({ abc: 123 }, /abc/), + { + actual: { abc: 123 }, + expected: /abc/, + operator: 'doesNotMatch', + message: 'The "string" argument must be of type string. ' + + 'Received type object ({ abc: 123 })', + /* TODO(kt3k): Enable this assertion + generatedMessage: true + */ + } + ); + assert.doesNotMatch('I will pass', /different$/); +} + +{ + const tempColor = inspect.defaultOptions.colors; + assert.throws(() => { + inspect.defaultOptions.colors = true; + // Guarantee the position indicator is placed correctly. + assert.strictEqual(111554n, 11111115); + }, (err) => { + // TODO(kt3k): Enable this assertion + // assert.strictEqual(inspect(err).split('\n')[5], ' ^'); + inspect.defaultOptions.colors = tempColor; + return true; + }); +} diff --git a/tests/node_compat/test/parallel/test-bad-unicode.js b/tests/node_compat/test/parallel/test-bad-unicode.js new file mode 100644 index 000000000..b4188878d --- /dev/null +++ b/tests/node_compat/test/parallel/test-bad-unicode.js @@ -0,0 +1,40 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +let exception = null; + +try { + eval('"\\uc/ef"'); +} catch (e) { + exception = e; +} + +assert(exception instanceof SyntaxError); diff --git a/tests/node_compat/test/parallel/test-btoa-atob.js b/tests/node_compat/test/parallel/test-btoa-atob.js new file mode 100644 index 000000000..3fd8d323c --- /dev/null +++ b/tests/node_compat/test/parallel/test-btoa-atob.js @@ -0,0 +1,46 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); + +const { strictEqual, throws } = require('assert'); +const buffer = require('buffer'); + +// Exported on the global object +strictEqual(globalThis.atob, buffer.atob); +strictEqual(globalThis.btoa, buffer.btoa); + +// Throws type error on no argument passed +throws(() => buffer.atob(), /TypeError/); +throws(() => buffer.btoa(), /TypeError/); + +strictEqual(atob(' '), ''); +strictEqual(atob(' Y\fW\tJ\njZ A=\r= '), 'abcd'); + +strictEqual(atob(null), '\x9Eée'); +strictEqual(atob(NaN), '5£'); +strictEqual(atob(Infinity), '"wâ\x9E+r'); +strictEqual(atob(true), '¶»\x9E'); +strictEqual(atob(1234), '×mø'); +strictEqual(atob([]), ''); +strictEqual(atob({ toString: () => '' }), ''); +strictEqual(atob({ [Symbol.toPrimitive]: () => '' }), ''); + +throws(() => atob(Symbol()), /TypeError/); +[ + undefined, false, () => {}, {}, [1], + 0, 1, 0n, 1n, -Infinity, + 'a', 'a\n\n\n', '\ra\r\r', ' a ', '\t\t\ta', 'a\f\f\f', '\ta\r \n\f', +].forEach((value) => + // See #2 - https://html.spec.whatwg.org/multipage/webappapis.html#dom-atob + throws(() => atob(value), { + constructor: DOMException, + name: 'InvalidCharacterError', + code: 5, + })); diff --git a/tests/node_compat/test/parallel/test-buffer-alloc.js b/tests/node_compat/test/parallel/test-buffer-alloc.js new file mode 100644 index 000000000..bb0af6456 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-alloc.js @@ -0,0 +1,1200 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); + +const assert = require('assert'); +const vm = require('vm'); + +const SlowBuffer = require('buffer').SlowBuffer; + +// Verify the maximum Uint8Array size. +// (see https://github.com/tc39/ecma262/pull/3052). +assert.throws( + () => new Uint8Array(2 ** 53), + { message: 'Invalid typed array length: 9007199254740992' } +); + +const b = Buffer.allocUnsafe(1024); +assert.strictEqual(b.length, 1024); + +b[0] = -1; +assert.strictEqual(b[0], 255); + +for (let i = 0; i < 1024; i++) { + b[i] = i % 256; +} + +for (let i = 0; i < 1024; i++) { + assert.strictEqual(i % 256, b[i]); +} + +const c = Buffer.allocUnsafe(512); +assert.strictEqual(c.length, 512); + +const d = Buffer.from([]); +assert.strictEqual(d.length, 0); + +// Test offset properties +{ + const b = Buffer.alloc(128); + assert.strictEqual(b.length, 128); + assert.strictEqual(b.byteOffset, 0); + assert.strictEqual(b.offset, 0); +} + +// Test creating a Buffer from a Uint8Array +{ + const ui8 = new Uint8Array(4).fill(42); + const e = Buffer.from(ui8); + for (const [index, value] of e.entries()) { + assert.strictEqual(value, ui8[index]); + } +} +// Test creating a Buffer from a Uint8Array (old constructor) +{ + const ui8 = new Uint8Array(4).fill(42); + const e = Buffer(ui8); + for (const [key, value] of e.entries()) { + assert.strictEqual(value, ui8[key]); + } +} + +// Test creating a Buffer from a Uint32Array +// Note: it is implicitly interpreted as Array of integers modulo 256 +{ + const ui32 = new Uint32Array(4).fill(42); + const e = Buffer.from(ui32); + for (const [index, value] of e.entries()) { + assert.strictEqual(value, ui32[index]); + } +} +// Test creating a Buffer from a Uint32Array (old constructor) +// Note: it is implicitly interpreted as Array of integers modulo 256 +{ + const ui32 = new Uint32Array(4).fill(42); + const e = Buffer(ui32); + for (const [key, value] of e.entries()) { + assert.strictEqual(value, ui32[key]); + } +} + +// Test invalid encoding for Buffer.toString +assert.throws(() => b.toString('invalid'), + /Unknown encoding: invalid/); +// Invalid encoding for Buffer.write +assert.throws(() => b.write('test string', 0, 5, 'invalid'), + /Unknown encoding: invalid/); +// Unsupported arguments for Buffer.write +assert.throws(() => b.write('test', 'utf8', 0), + { code: 'ERR_INVALID_ARG_TYPE' }); + +// Try to create 0-length buffers. Should not throw. +Buffer.from(''); +Buffer.from('', 'ascii'); +Buffer.from('', 'latin1'); +Buffer.alloc(0); +Buffer.allocUnsafe(0); +new Buffer(''); +new Buffer('', 'ascii'); +new Buffer('', 'latin1'); +new Buffer('', 'binary'); +Buffer(0); + +const outOfRangeError = { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError' +}; + +// Try to write a 0-length string beyond the end of b +assert.throws(() => b.write('', 2048), outOfRangeError); + +// Throw when writing to negative offset +assert.throws(() => b.write('a', -1), outOfRangeError); + +// Throw when writing past bounds from the pool +assert.throws(() => b.write('a', 2048), outOfRangeError); + +// Throw when writing to negative offset +assert.throws(() => b.write('a', -1), outOfRangeError); + +// Try to copy 0 bytes worth of data into an empty buffer +b.copy(Buffer.alloc(0), 0, 0, 0); + +// Try to copy 0 bytes past the end of the target buffer +b.copy(Buffer.alloc(0), 1, 1, 1); +b.copy(Buffer.alloc(1), 1, 1, 1); + +// Try to copy 0 bytes from past the end of the source buffer +b.copy(Buffer.alloc(1), 0, 1024, 1024); + +// Testing for smart defaults and ability to pass string values as offset +{ + const writeTest = Buffer.from('abcdes'); + writeTest.write('n', 'ascii'); + assert.throws( + () => writeTest.write('o', '1', 'ascii'), + { code: 'ERR_INVALID_ARG_TYPE' } + ); + writeTest.write('o', 1, 'ascii'); + writeTest.write('d', 2, 'ascii'); + writeTest.write('e', 3, 'ascii'); + writeTest.write('j', 4, 'ascii'); + assert.strictEqual(writeTest.toString(), 'nodejs'); +} + +// Offset points to the end of the buffer and does not throw. +// (see https://github.com/nodejs/node/issues/8127). +Buffer.alloc(1).write('', 1, 0); + +// ASCII slice test +{ + const asciiString = 'hello world'; + + for (let i = 0; i < asciiString.length; i++) { + b[i] = asciiString.charCodeAt(i); + } + const asciiSlice = b.toString('ascii', 0, asciiString.length); + assert.strictEqual(asciiString, asciiSlice); +} + +{ + const asciiString = 'hello world'; + const offset = 100; + + assert.strictEqual(asciiString.length, b.write(asciiString, offset, 'ascii')); + const asciiSlice = b.toString('ascii', offset, offset + asciiString.length); + assert.strictEqual(asciiString, asciiSlice); +} + +{ + const asciiString = 'hello world'; + const offset = 100; + + const sliceA = b.slice(offset, offset + asciiString.length); + const sliceB = b.slice(offset, offset + asciiString.length); + for (let i = 0; i < asciiString.length; i++) { + assert.strictEqual(sliceA[i], sliceB[i]); + } +} + +// UTF-8 slice test +{ + const utf8String = '¡hέlló wôrld!'; + const offset = 100; + + b.write(utf8String, 0, Buffer.byteLength(utf8String), 'utf8'); + let utf8Slice = b.toString('utf8', 0, Buffer.byteLength(utf8String)); + assert.strictEqual(utf8String, utf8Slice); + + assert.strictEqual(Buffer.byteLength(utf8String), + b.write(utf8String, offset, 'utf8')); + utf8Slice = b.toString('utf8', offset, + offset + Buffer.byteLength(utf8String)); + assert.strictEqual(utf8String, utf8Slice); + + const sliceA = b.slice(offset, offset + Buffer.byteLength(utf8String)); + const sliceB = b.slice(offset, offset + Buffer.byteLength(utf8String)); + for (let i = 0; i < Buffer.byteLength(utf8String); i++) { + assert.strictEqual(sliceA[i], sliceB[i]); + } +} + +{ + const slice = b.slice(100, 150); + assert.strictEqual(slice.length, 50); + for (let i = 0; i < 50; i++) { + assert.strictEqual(b[100 + i], slice[i]); + } +} + +{ + // Make sure only top level parent propagates from allocPool + const b = Buffer.allocUnsafe(5); + const c = b.slice(0, 4); + const d = c.slice(0, 2); + assert.strictEqual(b.parent, c.parent); + assert.strictEqual(b.parent, d.parent); +} + +{ + // Also from a non-pooled instance + const b = Buffer.allocUnsafeSlow(5); + const c = b.slice(0, 4); + const d = c.slice(0, 2); + assert.strictEqual(c.parent, d.parent); +} + +{ + // Bug regression test + const testValue = '\u00F6\u65E5\u672C\u8A9E'; // ö日本語 + const buffer = Buffer.allocUnsafe(32); + const size = buffer.write(testValue, 0, 'utf8'); + const slice = buffer.toString('utf8', 0, size); + assert.strictEqual(slice, testValue); +} + +{ + // Test triple slice + const a = Buffer.allocUnsafe(8); + for (let i = 0; i < 8; i++) a[i] = i; + const b = a.slice(4, 8); + assert.strictEqual(b[0], 4); + assert.strictEqual(b[1], 5); + assert.strictEqual(b[2], 6); + assert.strictEqual(b[3], 7); + const c = b.slice(2, 4); + assert.strictEqual(c[0], 6); + assert.strictEqual(c[1], 7); +} + +{ + const d = Buffer.from([23, 42, 255]); + assert.strictEqual(d.length, 3); + assert.strictEqual(d[0], 23); + assert.strictEqual(d[1], 42); + assert.strictEqual(d[2], 255); + assert.deepStrictEqual(d, Buffer.from(d)); +} + +{ + // Test for proper UTF-8 Encoding + const e = Buffer.from('über'); + assert.deepStrictEqual(e, Buffer.from([195, 188, 98, 101, 114])); +} + +{ + // Test for proper ascii Encoding, length should be 4 + const f = Buffer.from('über', 'ascii'); + assert.deepStrictEqual(f, Buffer.from([252, 98, 101, 114])); +} + +['ucs2', 'ucs-2', 'utf16le', 'utf-16le'].forEach((encoding) => { + { + // Test for proper UTF16LE encoding, length should be 8 + const f = Buffer.from('über', encoding); + assert.deepStrictEqual(f, Buffer.from([252, 0, 98, 0, 101, 0, 114, 0])); + } + + { + // Length should be 12 + const f = Buffer.from('привет', encoding); + assert.deepStrictEqual( + f, Buffer.from([63, 4, 64, 4, 56, 4, 50, 4, 53, 4, 66, 4]) + ); + assert.strictEqual(f.toString(encoding), 'привет'); + } + + { + const f = Buffer.from([0, 0, 0, 0, 0]); + assert.strictEqual(f.length, 5); + const size = f.write('あいうえお', encoding); + assert.strictEqual(size, 4); + assert.deepStrictEqual(f, Buffer.from([0x42, 0x30, 0x44, 0x30, 0x00])); + } +}); + +{ + const f = Buffer.from('\uD83D\uDC4D', 'utf-16le'); // THUMBS UP SIGN (U+1F44D) + assert.strictEqual(f.length, 4); + assert.deepStrictEqual(f, Buffer.from('3DD84DDC', 'hex')); +} + +// Test construction from arrayish object +{ + const arrayIsh = { 0: 0, 1: 1, 2: 2, 3: 3, length: 4 }; + let g = Buffer.from(arrayIsh); + assert.deepStrictEqual(g, Buffer.from([0, 1, 2, 3])); + const strArrayIsh = { 0: '0', 1: '1', 2: '2', 3: '3', length: 4 }; + g = Buffer.from(strArrayIsh); + assert.deepStrictEqual(g, Buffer.from([0, 1, 2, 3])); +} + +// +// Test toString('base64') +// +assert.strictEqual((Buffer.from('Man')).toString('base64'), 'TWFu'); +assert.strictEqual((Buffer.from('Woman')).toString('base64'), 'V29tYW4='); + +// +// Test toString('base64url') +// +assert.strictEqual((Buffer.from('Man')).toString('base64url'), 'TWFu'); +assert.strictEqual((Buffer.from('Woman')).toString('base64url'), 'V29tYW4'); + +{ + // Test that regular and URL-safe base64 both work both ways + const expected = [0xff, 0xff, 0xbe, 0xff, 0xef, 0xbf, 0xfb, 0xef, 0xff]; + assert.deepStrictEqual(Buffer.from('//++/++/++//', 'base64'), + Buffer.from(expected)); + assert.deepStrictEqual(Buffer.from('__--_--_--__', 'base64'), + Buffer.from(expected)); + assert.deepStrictEqual(Buffer.from('//++/++/++//', 'base64url'), + Buffer.from(expected)); + assert.deepStrictEqual(Buffer.from('__--_--_--__', 'base64url'), + Buffer.from(expected)); +} + +const base64flavors = ['base64', 'base64url']; + +{ + // Test that regular and URL-safe base64 both work both ways with padding + const expected = [0xff, 0xff, 0xbe, 0xff, 0xef, 0xbf, 0xfb, 0xef, 0xff, 0xfb]; + assert.deepStrictEqual(Buffer.from('//++/++/++//+w==', 'base64'), + Buffer.from(expected)); + assert.deepStrictEqual(Buffer.from('//++/++/++//+w==', 'base64'), + Buffer.from(expected)); + assert.deepStrictEqual(Buffer.from('//++/++/++//+w==', 'base64url'), + Buffer.from(expected)); + assert.deepStrictEqual(Buffer.from('//++/++/++//+w==', 'base64url'), + Buffer.from(expected)); +} + +{ + // big example + const quote = 'Man is distinguished, not only by his reason, but by this ' + + 'singular passion from other animals, which is a lust ' + + 'of the mind, that by a perseverance of delight in the ' + + 'continued and indefatigable generation of knowledge, ' + + 'exceeds the short vehemence of any carnal pleasure.'; + const expected = 'TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb' + + '24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlci' + + 'BhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQ' + + 'gYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu' + + 'dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZ' + + 'GdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm' + + '5hbCBwbGVhc3VyZS4='; + assert.strictEqual(Buffer.from(quote).toString('base64'), expected); + assert.strictEqual( + Buffer.from(quote).toString('base64url'), + expected.replaceAll('+', '-').replaceAll('/', '_').replaceAll('=', '') + ); + + base64flavors.forEach((encoding) => { + let b = Buffer.allocUnsafe(1024); + let bytesWritten = b.write(expected, 0, encoding); + assert.strictEqual(quote.length, bytesWritten); + assert.strictEqual(quote, b.toString('ascii', 0, quote.length)); + + // Check that the base64 decoder ignores whitespace + const expectedWhite = `${expected.slice(0, 60)} \n` + + `${expected.slice(60, 120)} \n` + + `${expected.slice(120, 180)} \n` + + `${expected.slice(180, 240)} \n` + + `${expected.slice(240, 300)}\n` + + `${expected.slice(300, 360)}\n`; + b = Buffer.allocUnsafe(1024); + bytesWritten = b.write(expectedWhite, 0, encoding); + assert.strictEqual(quote.length, bytesWritten); + assert.strictEqual(quote, b.toString('ascii', 0, quote.length)); + + // Check that the base64 decoder on the constructor works + // even in the presence of whitespace. + b = Buffer.from(expectedWhite, encoding); + assert.strictEqual(quote.length, b.length); + assert.strictEqual(quote, b.toString('ascii', 0, quote.length)); + + // Check that the base64 decoder ignores illegal chars + const expectedIllegal = expected.slice(0, 60) + ' \x80' + + expected.slice(60, 120) + ' \xff' + + expected.slice(120, 180) + ' \x00' + + expected.slice(180, 240) + ' \x98' + + expected.slice(240, 300) + '\x03' + + expected.slice(300, 360); + b = Buffer.from(expectedIllegal, encoding); + assert.strictEqual(quote.length, b.length); + assert.strictEqual(quote, b.toString('ascii', 0, quote.length)); + }); +} + +base64flavors.forEach((encoding) => { + assert.strictEqual(Buffer.from('', encoding).toString(), ''); + assert.strictEqual(Buffer.from('K', encoding).toString(), ''); + + // multiple-of-4 with padding + assert.strictEqual(Buffer.from('Kg==', encoding).toString(), '*'); + assert.strictEqual(Buffer.from('Kio=', encoding).toString(), '*'.repeat(2)); + assert.strictEqual(Buffer.from('Kioq', encoding).toString(), '*'.repeat(3)); + assert.strictEqual( + Buffer.from('KioqKg==', encoding).toString(), '*'.repeat(4)); + assert.strictEqual( + Buffer.from('KioqKio=', encoding).toString(), '*'.repeat(5)); + assert.strictEqual( + Buffer.from('KioqKioq', encoding).toString(), '*'.repeat(6)); + assert.strictEqual(Buffer.from('KioqKioqKg==', encoding).toString(), + '*'.repeat(7)); + assert.strictEqual(Buffer.from('KioqKioqKio=', encoding).toString(), + '*'.repeat(8)); + assert.strictEqual(Buffer.from('KioqKioqKioq', encoding).toString(), + '*'.repeat(9)); + assert.strictEqual(Buffer.from('KioqKioqKioqKg==', encoding).toString(), + '*'.repeat(10)); + assert.strictEqual(Buffer.from('KioqKioqKioqKio=', encoding).toString(), + '*'.repeat(11)); + assert.strictEqual(Buffer.from('KioqKioqKioqKioq', encoding).toString(), + '*'.repeat(12)); + assert.strictEqual(Buffer.from('KioqKioqKioqKioqKg==', encoding).toString(), + '*'.repeat(13)); + assert.strictEqual(Buffer.from('KioqKioqKioqKioqKio=', encoding).toString(), + '*'.repeat(14)); + assert.strictEqual(Buffer.from('KioqKioqKioqKioqKioq', encoding).toString(), + '*'.repeat(15)); + assert.strictEqual( + Buffer.from('KioqKioqKioqKioqKioqKg==', encoding).toString(), + '*'.repeat(16)); + assert.strictEqual( + Buffer.from('KioqKioqKioqKioqKioqKio=', encoding).toString(), + '*'.repeat(17)); + assert.strictEqual( + Buffer.from('KioqKioqKioqKioqKioqKioq', encoding).toString(), + '*'.repeat(18)); + assert.strictEqual(Buffer.from('KioqKioqKioqKioqKioqKioqKg==', + encoding).toString(), + '*'.repeat(19)); + assert.strictEqual(Buffer.from('KioqKioqKioqKioqKioqKioqKio=', + encoding).toString(), + '*'.repeat(20)); + + // No padding, not a multiple of 4 + assert.strictEqual(Buffer.from('Kg', encoding).toString(), '*'); + assert.strictEqual(Buffer.from('Kio', encoding).toString(), '*'.repeat(2)); + assert.strictEqual(Buffer.from('KioqKg', encoding).toString(), '*'.repeat(4)); + assert.strictEqual( + Buffer.from('KioqKio', encoding).toString(), '*'.repeat(5)); + assert.strictEqual(Buffer.from('KioqKioqKg', encoding).toString(), + '*'.repeat(7)); + assert.strictEqual(Buffer.from('KioqKioqKio', encoding).toString(), + '*'.repeat(8)); + assert.strictEqual(Buffer.from('KioqKioqKioqKg', encoding).toString(), + '*'.repeat(10)); + assert.strictEqual(Buffer.from('KioqKioqKioqKio', encoding).toString(), + '*'.repeat(11)); + assert.strictEqual(Buffer.from('KioqKioqKioqKioqKg', encoding).toString(), + '*'.repeat(13)); + assert.strictEqual(Buffer.from('KioqKioqKioqKioqKio', encoding).toString(), + '*'.repeat(14)); + assert.strictEqual(Buffer.from('KioqKioqKioqKioqKioqKg', encoding).toString(), + '*'.repeat(16)); + assert.strictEqual( + Buffer.from('KioqKioqKioqKioqKioqKio', encoding).toString(), + '*'.repeat(17)); + assert.strictEqual( + Buffer.from('KioqKioqKioqKioqKioqKioqKg', encoding).toString(), + '*'.repeat(19)); + assert.strictEqual( + Buffer.from('KioqKioqKioqKioqKioqKioqKio', encoding).toString(), + '*'.repeat(20)); +}); + +// Handle padding graciously, multiple-of-4 or not +assert.strictEqual( + Buffer.from('72INjkR5fchcxk9+VgdGPFJDxUBFR5/rMFsghgxADiw==', 'base64').length, + 32 +); +assert.strictEqual( + Buffer.from('72INjkR5fchcxk9-VgdGPFJDxUBFR5_rMFsghgxADiw==', 'base64url') + .length, + 32 +); +assert.strictEqual( + Buffer.from('72INjkR5fchcxk9+VgdGPFJDxUBFR5/rMFsghgxADiw=', 'base64').length, + 32 +); +assert.strictEqual( + Buffer.from('72INjkR5fchcxk9-VgdGPFJDxUBFR5_rMFsghgxADiw=', 'base64url') + .length, + 32 +); +assert.strictEqual( + Buffer.from('72INjkR5fchcxk9+VgdGPFJDxUBFR5/rMFsghgxADiw', 'base64').length, + 32 +); +assert.strictEqual( + Buffer.from('72INjkR5fchcxk9-VgdGPFJDxUBFR5_rMFsghgxADiw', 'base64url') + .length, + 32 +); +assert.strictEqual( + Buffer.from('w69jACy6BgZmaFvv96HG6MYksWytuZu3T1FvGnulPg==', 'base64').length, + 31 +); +assert.strictEqual( + Buffer.from('w69jACy6BgZmaFvv96HG6MYksWytuZu3T1FvGnulPg==', 'base64url') + .length, + 31 +); +assert.strictEqual( + Buffer.from('w69jACy6BgZmaFvv96HG6MYksWytuZu3T1FvGnulPg=', 'base64').length, + 31 +); +assert.strictEqual( + Buffer.from('w69jACy6BgZmaFvv96HG6MYksWytuZu3T1FvGnulPg=', 'base64url') + .length, + 31 +); +assert.strictEqual( + Buffer.from('w69jACy6BgZmaFvv96HG6MYksWytuZu3T1FvGnulPg', 'base64').length, + 31 +); +assert.strictEqual( + Buffer.from('w69jACy6BgZmaFvv96HG6MYksWytuZu3T1FvGnulPg', 'base64url').length, + 31 +); + +{ +// This string encodes single '.' character in UTF-16 + const dot = Buffer.from('//4uAA==', 'base64'); + assert.strictEqual(dot[0], 0xff); + assert.strictEqual(dot[1], 0xfe); + assert.strictEqual(dot[2], 0x2e); + assert.strictEqual(dot[3], 0x00); + assert.strictEqual(dot.toString('base64'), '//4uAA=='); +} + +{ +// This string encodes single '.' character in UTF-16 + const dot = Buffer.from('//4uAA', 'base64url'); + assert.strictEqual(dot[0], 0xff); + assert.strictEqual(dot[1], 0xfe); + assert.strictEqual(dot[2], 0x2e); + assert.strictEqual(dot[3], 0x00); + assert.strictEqual(dot.toString('base64url'), '__4uAA'); +} + +{ + // Writing base64 at a position > 0 should not mangle the result. + // + // https://github.com/joyent/node/issues/402 + const segments = ['TWFkbmVzcz8h', 'IFRoaXM=', 'IGlz', 'IG5vZGUuanMh']; + const b = Buffer.allocUnsafe(64); + let pos = 0; + + for (let i = 0; i < segments.length; ++i) { + pos += b.write(segments[i], pos, 'base64'); + } + assert.strictEqual(b.toString('latin1', 0, pos), + 'Madness?! This is node.js!'); +} + +{ + // Writing base64url at a position > 0 should not mangle the result. + // + // https://github.com/joyent/node/issues/402 + const segments = ['TWFkbmVzcz8h', 'IFRoaXM', 'IGlz', 'IG5vZGUuanMh']; + const b = Buffer.allocUnsafe(64); + let pos = 0; + + for (let i = 0; i < segments.length; ++i) { + pos += b.write(segments[i], pos, 'base64url'); + } + assert.strictEqual(b.toString('latin1', 0, pos), + 'Madness?! This is node.js!'); +} + +// Regression test for https://github.com/nodejs/node/issues/3496. +assert.strictEqual(Buffer.from('=bad'.repeat(1e4), 'base64').length, 0); + +// Regression test for https://github.com/nodejs/node/issues/11987. +assert.deepStrictEqual(Buffer.from('w0 ', 'base64'), + Buffer.from('w0', 'base64')); + +// Regression test for https://github.com/nodejs/node/issues/13657. +assert.deepStrictEqual(Buffer.from(' YWJvcnVtLg', 'base64'), + Buffer.from('YWJvcnVtLg', 'base64')); + +{ + // Creating buffers larger than pool size. + const l = Buffer.poolSize + 5; + const s = 'h'.repeat(l); + const b = Buffer.from(s); + + for (let i = 0; i < l; i++) { + assert.strictEqual(b[i], 'h'.charCodeAt(0)); + } + + const sb = b.toString(); + assert.strictEqual(sb.length, s.length); + assert.strictEqual(sb, s); +} + +{ + // test hex toString + const hexb = Buffer.allocUnsafe(256); + for (let i = 0; i < 256; i++) { + hexb[i] = i; + } + const hexStr = hexb.toString('hex'); + assert.strictEqual(hexStr, + '000102030405060708090a0b0c0d0e0f' + + '101112131415161718191a1b1c1d1e1f' + + '202122232425262728292a2b2c2d2e2f' + + '303132333435363738393a3b3c3d3e3f' + + '404142434445464748494a4b4c4d4e4f' + + '505152535455565758595a5b5c5d5e5f' + + '606162636465666768696a6b6c6d6e6f' + + '707172737475767778797a7b7c7d7e7f' + + '808182838485868788898a8b8c8d8e8f' + + '909192939495969798999a9b9c9d9e9f' + + 'a0a1a2a3a4a5a6a7a8a9aaabacadaeaf' + + 'b0b1b2b3b4b5b6b7b8b9babbbcbdbebf' + + 'c0c1c2c3c4c5c6c7c8c9cacbcccdcecf' + + 'd0d1d2d3d4d5d6d7d8d9dadbdcdddedf' + + 'e0e1e2e3e4e5e6e7e8e9eaebecedeeef' + + 'f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff'); + + const hexb2 = Buffer.from(hexStr, 'hex'); + for (let i = 0; i < 256; i++) { + assert.strictEqual(hexb2[i], hexb[i]); + } +} + +// Test single hex character is discarded. +assert.strictEqual(Buffer.from('A', 'hex').length, 0); + +// Test that if a trailing character is discarded, rest of string is processed. +assert.deepStrictEqual(Buffer.from('Abx', 'hex'), Buffer.from('Ab', 'hex')); + +// Test single base64 char encodes as 0. +assert.strictEqual(Buffer.from('A', 'base64').length, 0); + + +{ + // Test an invalid slice end. + const b = Buffer.from([1, 2, 3, 4, 5]); + const b2 = b.toString('hex', 1, 10000); + const b3 = b.toString('hex', 1, 5); + const b4 = b.toString('hex', 1); + assert.strictEqual(b2, b3); + assert.strictEqual(b2, b4); +} + +function buildBuffer(data) { + if (Array.isArray(data)) { + const buffer = Buffer.allocUnsafe(data.length); + data.forEach((v, k) => buffer[k] = v); + return buffer; + } + return null; +} + +const x = buildBuffer([0x81, 0xa3, 0x66, 0x6f, 0x6f, 0xa3, 0x62, 0x61, 0x72]); + +assert.strictEqual(x.inspect(), ''); + +{ + const z = x.slice(4); + assert.strictEqual(z.length, 5); + assert.strictEqual(z[0], 0x6f); + assert.strictEqual(z[1], 0xa3); + assert.strictEqual(z[2], 0x62); + assert.strictEqual(z[3], 0x61); + assert.strictEqual(z[4], 0x72); +} + +{ + const z = x.slice(0); + assert.strictEqual(z.length, x.length); +} + +{ + const z = x.slice(0, 4); + assert.strictEqual(z.length, 4); + assert.strictEqual(z[0], 0x81); + assert.strictEqual(z[1], 0xa3); +} + +{ + const z = x.slice(0, 9); + assert.strictEqual(z.length, 9); +} + +{ + const z = x.slice(1, 4); + assert.strictEqual(z.length, 3); + assert.strictEqual(z[0], 0xa3); +} + +{ + const z = x.slice(2, 4); + assert.strictEqual(z.length, 2); + assert.strictEqual(z[0], 0x66); + assert.strictEqual(z[1], 0x6f); +} + +['ucs2', 'ucs-2', 'utf16le', 'utf-16le'].forEach((encoding) => { + const b = Buffer.allocUnsafe(10); + b.write('あいうえお', encoding); + assert.strictEqual(b.toString(encoding), 'あいうえお'); +}); + +['ucs2', 'ucs-2', 'utf16le', 'utf-16le'].forEach((encoding) => { + const b = Buffer.allocUnsafe(11); + b.write('あいうえお', 1, encoding); + assert.strictEqual(b.toString(encoding, 1), 'あいうえお'); +}); + +{ + // latin1 encoding should write only one byte per character. + const b = Buffer.from([0xde, 0xad, 0xbe, 0xef]); + let s = String.fromCharCode(0xffff); + b.write(s, 0, 'latin1'); + assert.strictEqual(b[0], 0xff); + assert.strictEqual(b[1], 0xad); + assert.strictEqual(b[2], 0xbe); + assert.strictEqual(b[3], 0xef); + s = String.fromCharCode(0xaaee); + b.write(s, 0, 'latin1'); + assert.strictEqual(b[0], 0xee); + assert.strictEqual(b[1], 0xad); + assert.strictEqual(b[2], 0xbe); + assert.strictEqual(b[3], 0xef); +} + +{ + // Binary encoding should write only one byte per character. + const b = Buffer.from([0xde, 0xad, 0xbe, 0xef]); + let s = String.fromCharCode(0xffff); + b.write(s, 0, 'latin1'); + assert.strictEqual(b[0], 0xff); + assert.strictEqual(b[1], 0xad); + assert.strictEqual(b[2], 0xbe); + assert.strictEqual(b[3], 0xef); + s = String.fromCharCode(0xaaee); + b.write(s, 0, 'latin1'); + assert.strictEqual(b[0], 0xee); + assert.strictEqual(b[1], 0xad); + assert.strictEqual(b[2], 0xbe); + assert.strictEqual(b[3], 0xef); +} + +{ + // https://github.com/nodejs/node-v0.x-archive/pull/1210 + // Test UTF-8 string includes null character + let buf = Buffer.from('\0'); + assert.strictEqual(buf.length, 1); + buf = Buffer.from('\0\0'); + assert.strictEqual(buf.length, 2); +} + +{ + const buf = Buffer.allocUnsafe(2); + assert.strictEqual(buf.write(''), 0); // 0bytes + assert.strictEqual(buf.write('\0'), 1); // 1byte (v8 adds null terminator) + assert.strictEqual(buf.write('a\0'), 2); // 1byte * 2 + assert.strictEqual(buf.write('あ'), 0); // 3bytes + assert.strictEqual(buf.write('\0あ'), 1); // 1byte + 3bytes + assert.strictEqual(buf.write('\0\0あ'), 2); // 1byte * 2 + 3bytes +} + +{ + const buf = Buffer.allocUnsafe(10); + assert.strictEqual(buf.write('あいう'), 9); // 3bytes * 3 (v8 adds null term.) + assert.strictEqual(buf.write('あいう\0'), 10); // 3bytes * 3 + 1byte +} + +{ + // https://github.com/nodejs/node-v0.x-archive/issues/243 + // Test write() with maxLength + const buf = Buffer.allocUnsafe(4); + buf.fill(0xFF); + assert.strictEqual(buf.write('abcd', 1, 2, 'utf8'), 2); + assert.strictEqual(buf[0], 0xFF); + assert.strictEqual(buf[1], 0x61); + assert.strictEqual(buf[2], 0x62); + assert.strictEqual(buf[3], 0xFF); + + buf.fill(0xFF); + assert.strictEqual(buf.write('abcd', 1, 4), 3); + assert.strictEqual(buf[0], 0xFF); + assert.strictEqual(buf[1], 0x61); + assert.strictEqual(buf[2], 0x62); + assert.strictEqual(buf[3], 0x63); + + buf.fill(0xFF); + assert.strictEqual(buf.write('abcd', 1, 2, 'utf8'), 2); + assert.strictEqual(buf[0], 0xFF); + assert.strictEqual(buf[1], 0x61); + assert.strictEqual(buf[2], 0x62); + assert.strictEqual(buf[3], 0xFF); + + buf.fill(0xFF); + assert.strictEqual(buf.write('abcdef', 1, 2, 'hex'), 2); + assert.strictEqual(buf[0], 0xFF); + assert.strictEqual(buf[1], 0xAB); + assert.strictEqual(buf[2], 0xCD); + assert.strictEqual(buf[3], 0xFF); + + ['ucs2', 'ucs-2', 'utf16le', 'utf-16le'].forEach((encoding) => { + buf.fill(0xFF); + assert.strictEqual(buf.write('abcd', 0, 2, encoding), 2); + assert.strictEqual(buf[0], 0x61); + assert.strictEqual(buf[1], 0x00); + assert.strictEqual(buf[2], 0xFF); + assert.strictEqual(buf[3], 0xFF); + }); +} + +{ + // Test offset returns are correct + const b = Buffer.allocUnsafe(16); + assert.strictEqual(b.writeUInt32LE(0, 0), 4); + assert.strictEqual(b.writeUInt16LE(0, 4), 6); + assert.strictEqual(b.writeUInt8(0, 6), 7); + assert.strictEqual(b.writeInt8(0, 7), 8); + assert.strictEqual(b.writeDoubleLE(0, 8), 16); +} + +{ + // Test unmatched surrogates not producing invalid utf8 output + // ef bf bd = utf-8 representation of unicode replacement character + // see https://codereview.chromium.org/121173009/ + const buf = Buffer.from('ab\ud800cd', 'utf8'); + assert.strictEqual(buf[0], 0x61); + assert.strictEqual(buf[1], 0x62); + assert.strictEqual(buf[2], 0xef); + assert.strictEqual(buf[3], 0xbf); + assert.strictEqual(buf[4], 0xbd); + assert.strictEqual(buf[5], 0x63); + assert.strictEqual(buf[6], 0x64); +} + +{ + // Test for buffer overrun + const buf = Buffer.from([0, 0, 0, 0, 0]); // length: 5 + const sub = buf.slice(0, 4); // length: 4 + assert.strictEqual(sub.write('12345', 'latin1'), 4); + assert.strictEqual(buf[4], 0); + assert.strictEqual(sub.write('12345', 'binary'), 4); + assert.strictEqual(buf[4], 0); +} + +{ + // Test alloc with fill option + const buf = Buffer.alloc(5, '800A', 'hex'); + assert.strictEqual(buf[0], 128); + assert.strictEqual(buf[1], 10); + assert.strictEqual(buf[2], 128); + assert.strictEqual(buf[3], 10); + assert.strictEqual(buf[4], 128); +} + + +// Check for fractional length args, junk length args, etc. +// https://github.com/joyent/node/issues/1758 + +// Call .fill() first, stops valgrind warning about uninitialized memory reads. +Buffer.allocUnsafe(3.3).fill().toString(); +// Throws bad argument error in commit 43cb4ec +Buffer.alloc(3.3).fill().toString(); +assert.strictEqual(Buffer.allocUnsafe(3.3).length, 3); +assert.strictEqual(Buffer.from({ length: 3.3 }).length, 3); +assert.strictEqual(Buffer.from({ length: 'BAM' }).length, 0); + +// Make sure that strings are not coerced to numbers. +assert.strictEqual(Buffer.from('99').length, 2); +assert.strictEqual(Buffer.from('13.37').length, 5); + +// Ensure that the length argument is respected. +['ascii', 'utf8', 'hex', 'base64', 'latin1', 'binary'].forEach((enc) => { + assert.strictEqual(Buffer.allocUnsafe(1).write('aaaaaa', 0, 1, enc), 1); +}); + +{ + // Regression test, guard against buffer overrun in the base64 decoder. + const a = Buffer.allocUnsafe(3); + const b = Buffer.from('xxx'); + a.write('aaaaaaaa', 'base64'); + assert.strictEqual(b.toString(), 'xxx'); +} + +// issue GH-3416 +Buffer.from(Buffer.allocUnsafe(0), 0, 0); + +// issue GH-5587 +assert.throws( + () => Buffer.alloc(8).writeFloatLE(0, 5), + outOfRangeError +); +assert.throws( + () => Buffer.alloc(16).writeDoubleLE(0, 9), + outOfRangeError +); + +// Attempt to overflow buffers, similar to previous bug in array buffers +assert.throws( + () => Buffer.allocUnsafe(8).writeFloatLE(0.0, 0xffffffff), + outOfRangeError +); +assert.throws( + () => Buffer.allocUnsafe(8).writeFloatLE(0.0, 0xffffffff), + outOfRangeError +); + +// Ensure negative values can't get past offset +assert.throws( + () => Buffer.allocUnsafe(8).writeFloatLE(0.0, -1), + outOfRangeError +); +assert.throws( + () => Buffer.allocUnsafe(8).writeFloatLE(0.0, -1), + outOfRangeError +); + +// Test for common write(U)IntLE/BE +{ + let buf = Buffer.allocUnsafe(3); + buf.writeUIntLE(0x123456, 0, 3); + assert.deepStrictEqual(buf.toJSON().data, [0x56, 0x34, 0x12]); + assert.strictEqual(buf.readUIntLE(0, 3), 0x123456); + + buf.fill(0xFF); + buf.writeUIntBE(0x123456, 0, 3); + assert.deepStrictEqual(buf.toJSON().data, [0x12, 0x34, 0x56]); + assert.strictEqual(buf.readUIntBE(0, 3), 0x123456); + + buf.fill(0xFF); + buf.writeIntLE(0x123456, 0, 3); + assert.deepStrictEqual(buf.toJSON().data, [0x56, 0x34, 0x12]); + assert.strictEqual(buf.readIntLE(0, 3), 0x123456); + + buf.fill(0xFF); + buf.writeIntBE(0x123456, 0, 3); + assert.deepStrictEqual(buf.toJSON().data, [0x12, 0x34, 0x56]); + assert.strictEqual(buf.readIntBE(0, 3), 0x123456); + + buf.fill(0xFF); + buf.writeIntLE(-0x123456, 0, 3); + assert.deepStrictEqual(buf.toJSON().data, [0xaa, 0xcb, 0xed]); + assert.strictEqual(buf.readIntLE(0, 3), -0x123456); + + buf.fill(0xFF); + buf.writeIntBE(-0x123456, 0, 3); + assert.deepStrictEqual(buf.toJSON().data, [0xed, 0xcb, 0xaa]); + assert.strictEqual(buf.readIntBE(0, 3), -0x123456); + + buf.fill(0xFF); + buf.writeIntLE(-0x123400, 0, 3); + assert.deepStrictEqual(buf.toJSON().data, [0x00, 0xcc, 0xed]); + assert.strictEqual(buf.readIntLE(0, 3), -0x123400); + + buf.fill(0xFF); + buf.writeIntBE(-0x123400, 0, 3); + assert.deepStrictEqual(buf.toJSON().data, [0xed, 0xcc, 0x00]); + assert.strictEqual(buf.readIntBE(0, 3), -0x123400); + + buf.fill(0xFF); + buf.writeIntLE(-0x120000, 0, 3); + assert.deepStrictEqual(buf.toJSON().data, [0x00, 0x00, 0xee]); + assert.strictEqual(buf.readIntLE(0, 3), -0x120000); + + buf.fill(0xFF); + buf.writeIntBE(-0x120000, 0, 3); + assert.deepStrictEqual(buf.toJSON().data, [0xee, 0x00, 0x00]); + assert.strictEqual(buf.readIntBE(0, 3), -0x120000); + + buf = Buffer.allocUnsafe(5); + buf.writeUIntLE(0x1234567890, 0, 5); + assert.deepStrictEqual(buf.toJSON().data, [0x90, 0x78, 0x56, 0x34, 0x12]); + assert.strictEqual(buf.readUIntLE(0, 5), 0x1234567890); + + buf.fill(0xFF); + buf.writeUIntBE(0x1234567890, 0, 5); + assert.deepStrictEqual(buf.toJSON().data, [0x12, 0x34, 0x56, 0x78, 0x90]); + assert.strictEqual(buf.readUIntBE(0, 5), 0x1234567890); + + buf.fill(0xFF); + buf.writeIntLE(0x1234567890, 0, 5); + assert.deepStrictEqual(buf.toJSON().data, [0x90, 0x78, 0x56, 0x34, 0x12]); + assert.strictEqual(buf.readIntLE(0, 5), 0x1234567890); + + buf.fill(0xFF); + buf.writeIntBE(0x1234567890, 0, 5); + assert.deepStrictEqual(buf.toJSON().data, [0x12, 0x34, 0x56, 0x78, 0x90]); + assert.strictEqual(buf.readIntBE(0, 5), 0x1234567890); + + buf.fill(0xFF); + buf.writeIntLE(-0x1234567890, 0, 5); + assert.deepStrictEqual(buf.toJSON().data, [0x70, 0x87, 0xa9, 0xcb, 0xed]); + assert.strictEqual(buf.readIntLE(0, 5), -0x1234567890); + + buf.fill(0xFF); + buf.writeIntBE(-0x1234567890, 0, 5); + assert.deepStrictEqual(buf.toJSON().data, [0xed, 0xcb, 0xa9, 0x87, 0x70]); + assert.strictEqual(buf.readIntBE(0, 5), -0x1234567890); + + buf.fill(0xFF); + buf.writeIntLE(-0x0012000000, 0, 5); + assert.deepStrictEqual(buf.toJSON().data, [0x00, 0x00, 0x00, 0xee, 0xff]); + assert.strictEqual(buf.readIntLE(0, 5), -0x0012000000); + + buf.fill(0xFF); + buf.writeIntBE(-0x0012000000, 0, 5); + assert.deepStrictEqual(buf.toJSON().data, [0xff, 0xee, 0x00, 0x00, 0x00]); + assert.strictEqual(buf.readIntBE(0, 5), -0x0012000000); +} + +// Regression test for https://github.com/nodejs/node-v0.x-archive/issues/5482: +// should throw but not assert in C++ land. +assert.throws( + () => Buffer.from('', 'buffer'), + { + code: 'ERR_UNKNOWN_ENCODING', + name: 'TypeError', + message: 'Unknown encoding: buffer' + } +); + +// Regression test for https://github.com/nodejs/node-v0.x-archive/issues/6111. +// Constructing a buffer from another buffer should a) work, and b) not corrupt +// the source buffer. +{ + const a = [...Array(128).keys()]; // [0, 1, 2, 3, ... 126, 127] + const b = Buffer.from(a); + const c = Buffer.from(b); + assert.strictEqual(b.length, a.length); + assert.strictEqual(c.length, a.length); + for (let i = 0, k = a.length; i < k; ++i) { + assert.strictEqual(a[i], i); + assert.strictEqual(b[i], i); + assert.strictEqual(c[i], i); + } +} + +if (common.hasCrypto) { // eslint-disable-line node-core/crypto-check + // Test truncation after decode + const crypto = require('crypto'); + + const b1 = Buffer.from('YW55=======', 'base64'); + const b2 = Buffer.from('YW55', 'base64'); + + assert.strictEqual( + crypto.createHash('sha1').update(b1).digest('hex'), + crypto.createHash('sha1').update(b2).digest('hex') + ); +} else { + common.printSkipMessage('missing crypto'); +} + +const ps = Buffer.poolSize; +Buffer.poolSize = 0; +assert(Buffer.allocUnsafe(1).parent instanceof ArrayBuffer); +Buffer.poolSize = ps; + +assert.throws( + () => Buffer.allocUnsafe(10).copy(), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "target" argument must be an instance of Buffer or ' + + 'Uint8Array. Received undefined' + }); + +assert.throws(() => Buffer.from(), { + name: 'TypeError', + message: 'The first argument must be of type string or an instance of ' + + 'Buffer, ArrayBuffer, or Array or an Array-like Object. Received undefined' +}); +assert.throws(() => Buffer.from(null), { + name: 'TypeError', + message: 'The first argument must be of type string or an instance of ' + + 'Buffer, ArrayBuffer, or Array or an Array-like Object. Received null' +}); + +// Test prototype getters don't throw +assert.strictEqual(Buffer.prototype.parent, undefined); +assert.strictEqual(Buffer.prototype.offset, undefined); +assert.strictEqual(SlowBuffer.prototype.parent, undefined); +assert.strictEqual(SlowBuffer.prototype.offset, undefined); + + +{ + // Test that large negative Buffer length inputs don't affect the pool offset. + // Use the fromArrayLike() variant here because it's more lenient + // about its input and passes the length directly to allocate(). + assert.deepStrictEqual(Buffer.from({ length: -Buffer.poolSize }), + Buffer.from('')); + assert.deepStrictEqual(Buffer.from({ length: -100 }), + Buffer.from('')); + + // Check pool offset after that by trying to write string into the pool. + Buffer.from('abc'); +} + + +// Test that ParseArrayIndex handles full uint32 +{ + const errMsg = common.expectsError({ + code: 'ERR_BUFFER_OUT_OF_BOUNDS', + name: 'RangeError', + message: '"offset" is outside of buffer bounds' + }); + assert.throws(() => Buffer.from(new ArrayBuffer(0), -1 >>> 0), errMsg); +} + +// ParseArrayIndex() should reject values that don't fit in a 32 bits size_t. +assert.throws(() => { + const a = Buffer.alloc(1); + const b = Buffer.alloc(1); + a.copy(b, 0, 0x100000000, 0x100000001); +}, outOfRangeError); + +// Unpooled buffer (replaces SlowBuffer) +{ + const ubuf = Buffer.allocUnsafeSlow(10); + assert(ubuf); + assert(ubuf.buffer); + assert.strictEqual(ubuf.buffer.byteLength, 10); +} + +// Regression test to verify that an empty ArrayBuffer does not throw. +Buffer.from(new ArrayBuffer()); + + +// Test that ArrayBuffer from a different context is detected correctly. +const arrayBuf = vm.runInNewContext('new ArrayBuffer()'); +Buffer.from(arrayBuf); +Buffer.from({ buffer: arrayBuf }); + +assert.throws(() => Buffer.alloc({ valueOf: () => 1 }), + /"size" argument must be of type number/); +assert.throws(() => Buffer.alloc({ valueOf: () => -1 }), + /"size" argument must be of type number/); + +assert.strictEqual(Buffer.prototype.toLocaleString, Buffer.prototype.toString); +{ + const buf = Buffer.from('test'); + assert.strictEqual(buf.toLocaleString(), buf.toString()); +} + +assert.throws(() => { + Buffer.alloc(0x1000, 'This is not correctly encoded', 'hex'); +}, { + code: 'ERR_INVALID_ARG_VALUE', + name: 'TypeError' +}); + +assert.throws(() => { + Buffer.alloc(0x1000, 'c', 'hex'); +}, { + code: 'ERR_INVALID_ARG_VALUE', + name: 'TypeError' +}); + +assert.throws(() => { + Buffer.alloc(1, Buffer.alloc(0)); +}, { + code: 'ERR_INVALID_ARG_VALUE', + name: 'TypeError' +}); + +assert.throws(() => { + Buffer.alloc(40, 'x', 20); +}, { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' +}); diff --git a/tests/node_compat/test/parallel/test-buffer-arraybuffer.js b/tests/node_compat/test/parallel/test-buffer-arraybuffer.js new file mode 100644 index 000000000..286481758 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-arraybuffer.js @@ -0,0 +1,159 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); + +const LENGTH = 16; + +const ab = new ArrayBuffer(LENGTH); +const dv = new DataView(ab); +const ui = new Uint8Array(ab); +const buf = Buffer.from(ab); + + +assert.ok(buf instanceof Buffer); +assert.strictEqual(buf.parent, buf.buffer); +assert.strictEqual(buf.buffer, ab); +assert.strictEqual(buf.length, ab.byteLength); + + +buf.fill(0xC); +for (let i = 0; i < LENGTH; i++) { + assert.strictEqual(ui[i], 0xC); + ui[i] = 0xF; + assert.strictEqual(buf[i], 0xF); +} + +buf.writeUInt32LE(0xF00, 0); +buf.writeUInt32BE(0xB47, 4); +buf.writeDoubleLE(3.1415, 8); + +assert.strictEqual(dv.getUint32(0, true), 0xF00); +assert.strictEqual(dv.getUint32(4), 0xB47); +assert.strictEqual(dv.getFloat64(8, true), 3.1415); + + +// Now test protecting users from doing stupid things + +assert.throws(function() { + function AB() { } + Object.setPrototypeOf(AB, ArrayBuffer); + Object.setPrototypeOf(AB.prototype, ArrayBuffer.prototype); + Buffer.from(new AB()); +}, { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The first argument must be of type string or an instance of ' + + 'Buffer, ArrayBuffer, or Array or an Array-like Object. Received ' + + 'an instance of AB' +}); + +// Test the byteOffset and length arguments +{ + const ab = new Uint8Array(5); + ab[0] = 1; + ab[1] = 2; + ab[2] = 3; + ab[3] = 4; + ab[4] = 5; + const buf = Buffer.from(ab.buffer, 1, 3); + assert.strictEqual(buf.length, 3); + assert.strictEqual(buf[0], 2); + assert.strictEqual(buf[1], 3); + assert.strictEqual(buf[2], 4); + buf[0] = 9; + assert.strictEqual(ab[1], 9); + + assert.throws(() => Buffer.from(ab.buffer, 6), { + code: 'ERR_BUFFER_OUT_OF_BOUNDS', + name: 'RangeError', + message: '"offset" is outside of buffer bounds' + }); + assert.throws(() => Buffer.from(ab.buffer, 3, 6), { + code: 'ERR_BUFFER_OUT_OF_BOUNDS', + name: 'RangeError', + message: '"length" is outside of buffer bounds' + }); +} + +// Test the deprecated Buffer() version also +{ + const ab = new Uint8Array(5); + ab[0] = 1; + ab[1] = 2; + ab[2] = 3; + ab[3] = 4; + ab[4] = 5; + const buf = Buffer(ab.buffer, 1, 3); + assert.strictEqual(buf.length, 3); + assert.strictEqual(buf[0], 2); + assert.strictEqual(buf[1], 3); + assert.strictEqual(buf[2], 4); + buf[0] = 9; + assert.strictEqual(ab[1], 9); + + assert.throws(() => Buffer(ab.buffer, 6), { + code: 'ERR_BUFFER_OUT_OF_BOUNDS', + name: 'RangeError', + message: '"offset" is outside of buffer bounds' + }); + assert.throws(() => Buffer(ab.buffer, 3, 6), { + code: 'ERR_BUFFER_OUT_OF_BOUNDS', + name: 'RangeError', + message: '"length" is outside of buffer bounds' + }); +} + +{ + // If byteOffset is not numeric, it defaults to 0. + const ab = new ArrayBuffer(10); + const expected = Buffer.from(ab, 0); + assert.deepStrictEqual(Buffer.from(ab, 'fhqwhgads'), expected); + assert.deepStrictEqual(Buffer.from(ab, NaN), expected); + assert.deepStrictEqual(Buffer.from(ab, {}), expected); + assert.deepStrictEqual(Buffer.from(ab, []), expected); + + // If byteOffset can be converted to a number, it will be. + assert.deepStrictEqual(Buffer.from(ab, [1]), Buffer.from(ab, 1)); + + // If byteOffset is Infinity, throw. + assert.throws(() => { + Buffer.from(ab, Infinity); + }, { + code: 'ERR_BUFFER_OUT_OF_BOUNDS', + name: 'RangeError', + message: '"offset" is outside of buffer bounds' + }); +} + +{ + // If length is not numeric, it defaults to 0. + const ab = new ArrayBuffer(10); + const expected = Buffer.from(ab, 0, 0); + assert.deepStrictEqual(Buffer.from(ab, 0, 'fhqwhgads'), expected); + assert.deepStrictEqual(Buffer.from(ab, 0, NaN), expected); + assert.deepStrictEqual(Buffer.from(ab, 0, {}), expected); + assert.deepStrictEqual(Buffer.from(ab, 0, []), expected); + + // If length can be converted to a number, it will be. + assert.deepStrictEqual(Buffer.from(ab, 0, [1]), Buffer.from(ab, 0, 1)); + + // If length is Infinity, throw. + assert.throws(() => { + Buffer.from(ab, 0, Infinity); + }, { + code: 'ERR_BUFFER_OUT_OF_BOUNDS', + name: 'RangeError', + message: '"length" is outside of buffer bounds' + }); +} + +// Test an array like entry with the length set to NaN. +assert.deepStrictEqual(Buffer.from({ length: NaN }), Buffer.alloc(0)); diff --git a/tests/node_compat/test/parallel/test-buffer-ascii.js b/tests/node_compat/test/parallel/test-buffer-ascii.js new file mode 100644 index 000000000..08e4e6543 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-ascii.js @@ -0,0 +1,53 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); + +// ASCII conversion in node.js simply masks off the high bits, +// it doesn't do transliteration. +assert.strictEqual(Buffer.from('hérité').toString('ascii'), 'hC)ritC)'); + +// 71 characters, 78 bytes. The ’ character is a triple-byte sequence. +const input = 'C’est, graphiquement, la réunion d’un accent aigu ' + + 'et d’un accent grave.'; + +const expected = 'Cb\u0000\u0019est, graphiquement, la rC)union ' + + 'db\u0000\u0019un accent aigu et db\u0000\u0019un ' + + 'accent grave.'; + +const buf = Buffer.from(input); + +for (let i = 0; i < expected.length; ++i) { + assert.strictEqual(buf.slice(i).toString('ascii'), expected.slice(i)); + + // Skip remainder of multi-byte sequence. + if (input.charCodeAt(i) > 65535) ++i; + if (input.charCodeAt(i) > 127) ++i; +} diff --git a/tests/node_compat/test/parallel/test-buffer-badhex.js b/tests/node_compat/test/parallel/test-buffer-badhex.js new file mode 100644 index 000000000..cafaa0887 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-badhex.js @@ -0,0 +1,55 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const assert = require('assert'); + +// Test hex strings and bad hex strings +{ + const buf = Buffer.alloc(4); + assert.strictEqual(buf.length, 4); + assert.deepStrictEqual(buf, Buffer.from([0, 0, 0, 0])); + assert.strictEqual(buf.write('abcdxx', 0, 'hex'), 2); + assert.deepStrictEqual(buf, Buffer.from([0xab, 0xcd, 0x00, 0x00])); + assert.strictEqual(buf.toString('hex'), 'abcd0000'); + assert.strictEqual(buf.write('abcdef01', 0, 'hex'), 4); + assert.deepStrictEqual(buf, Buffer.from([0xab, 0xcd, 0xef, 0x01])); + assert.strictEqual(buf.toString('hex'), 'abcdef01'); + + const copy = Buffer.from(buf.toString('hex'), 'hex'); + assert.strictEqual(buf.toString('hex'), copy.toString('hex')); +} + +{ + const buf = Buffer.alloc(5); + assert.strictEqual(buf.write('abcdxx', 1, 'hex'), 2); + assert.strictEqual(buf.toString('hex'), '00abcd0000'); +} + +{ + const buf = Buffer.alloc(4); + assert.deepStrictEqual(buf, Buffer.from([0, 0, 0, 0])); + assert.strictEqual(buf.write('xxabcd', 0, 'hex'), 0); + assert.deepStrictEqual(buf, Buffer.from([0, 0, 0, 0])); + assert.strictEqual(buf.write('xxab', 1, 'hex'), 0); + assert.deepStrictEqual(buf, Buffer.from([0, 0, 0, 0])); + assert.strictEqual(buf.write('cdxxab', 0, 'hex'), 1); + assert.deepStrictEqual(buf, Buffer.from([0xcd, 0, 0, 0])); +} + +{ + const buf = Buffer.alloc(256); + for (let i = 0; i < 256; i++) + buf[i] = i; + + const hex = buf.toString('hex'); + assert.deepStrictEqual(Buffer.from(hex, 'hex'), buf); + + const badHex = `${hex.slice(0, 256)}xx${hex.slice(256, 510)}`; + assert.deepStrictEqual(Buffer.from(badHex, 'hex'), buf.slice(0, 128)); +} diff --git a/tests/node_compat/test/parallel/test-buffer-bigint64.js b/tests/node_compat/test/parallel/test-buffer-bigint64.js new file mode 100644 index 000000000..7aa391f0a --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-bigint64.js @@ -0,0 +1,62 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const assert = require('assert'); + +const buf = Buffer.allocUnsafe(8); + +['LE', 'BE'].forEach(function(endianness) { + // Should allow simple BigInts to be written and read + let val = 123456789n; + buf[`writeBigInt64${endianness}`](val, 0); + let rtn = buf[`readBigInt64${endianness}`](0); + assert.strictEqual(val, rtn); + + // Should allow INT64_MAX to be written and read + val = 0x7fffffffffffffffn; + buf[`writeBigInt64${endianness}`](val, 0); + rtn = buf[`readBigInt64${endianness}`](0); + assert.strictEqual(val, rtn); + + // Should read and write a negative signed 64-bit integer + val = -123456789n; + buf[`writeBigInt64${endianness}`](val, 0); + assert.strictEqual(val, buf[`readBigInt64${endianness}`](0)); + + // Should read and write an unsigned 64-bit integer + val = 123456789n; + buf[`writeBigUInt64${endianness}`](val, 0); + assert.strictEqual(val, buf[`readBigUInt64${endianness}`](0)); + + // Should throw a RangeError upon INT64_MAX+1 being written + assert.throws(function() { + const val = 0x8000000000000000n; + buf[`writeBigInt64${endianness}`](val, 0); + }, RangeError); + + // Should throw a RangeError upon UINT64_MAX+1 being written + assert.throws(function() { + const val = 0x10000000000000000n; + buf[`writeBigUInt64${endianness}`](val, 0); + }, { + code: 'ERR_OUT_OF_RANGE', + message: 'The value of "value" is out of range. It must be ' + + '>= 0n and < 2n ** 64n. Received 18_446_744_073_709_551_616n' + }); + + // Should throw a TypeError upon invalid input + assert.throws(function() { + buf[`writeBigInt64${endianness}`]('bad', 0); + }, TypeError); + + // Should throw a TypeError upon invalid input + assert.throws(function() { + buf[`writeBigUInt64${endianness}`]('bad', 0); + }, TypeError); +}); diff --git a/tests/node_compat/test/parallel/test-buffer-bytelength.js b/tests/node_compat/test/parallel/test-buffer-bytelength.js new file mode 100644 index 000000000..4f10596a2 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-bytelength.js @@ -0,0 +1,139 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const SlowBuffer = require('buffer').SlowBuffer; +const vm = require('vm'); + +[ + [32, 'latin1'], + [NaN, 'utf8'], + [{}, 'latin1'], + [], +].forEach((args) => { + assert.throws( + () => Buffer.byteLength(...args), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "string" argument must be of type string or an instance ' + + 'of Buffer or ArrayBuffer.' + + common.invalidArgTypeHelper(args[0]) + } + ); +}); + +assert(ArrayBuffer.isView(new Buffer(10))); +assert(ArrayBuffer.isView(new SlowBuffer(10))); +assert(ArrayBuffer.isView(Buffer.alloc(10))); +assert(ArrayBuffer.isView(Buffer.allocUnsafe(10))); +assert(ArrayBuffer.isView(Buffer.allocUnsafeSlow(10))); +assert(ArrayBuffer.isView(Buffer.from(''))); + +// buffer +const incomplete = Buffer.from([0xe4, 0xb8, 0xad, 0xe6, 0x96]); +assert.strictEqual(Buffer.byteLength(incomplete), 5); +const ascii = Buffer.from('abc'); +assert.strictEqual(Buffer.byteLength(ascii), 3); + +// ArrayBuffer +const buffer = new ArrayBuffer(8); +assert.strictEqual(Buffer.byteLength(buffer), 8); + +// TypedArray +const int8 = new Int8Array(8); +assert.strictEqual(Buffer.byteLength(int8), 8); +const uint8 = new Uint8Array(8); +assert.strictEqual(Buffer.byteLength(uint8), 8); +const uintc8 = new Uint8ClampedArray(2); +assert.strictEqual(Buffer.byteLength(uintc8), 2); +const int16 = new Int16Array(8); +assert.strictEqual(Buffer.byteLength(int16), 16); +const uint16 = new Uint16Array(8); +assert.strictEqual(Buffer.byteLength(uint16), 16); +const int32 = new Int32Array(8); +assert.strictEqual(Buffer.byteLength(int32), 32); +const uint32 = new Uint32Array(8); +assert.strictEqual(Buffer.byteLength(uint32), 32); +const float32 = new Float32Array(8); +assert.strictEqual(Buffer.byteLength(float32), 32); +const float64 = new Float64Array(8); +assert.strictEqual(Buffer.byteLength(float64), 64); + +// DataView +const dv = new DataView(new ArrayBuffer(2)); +assert.strictEqual(Buffer.byteLength(dv), 2); + +// Special case: zero length string +assert.strictEqual(Buffer.byteLength('', 'ascii'), 0); +assert.strictEqual(Buffer.byteLength('', 'HeX'), 0); + +// utf8 +assert.strictEqual(Buffer.byteLength('∑éllö wørl∂!', 'utf-8'), 19); +assert.strictEqual(Buffer.byteLength('κλμνξο', 'utf8'), 12); +assert.strictEqual(Buffer.byteLength('挵挶挷挸挹', 'utf-8'), 15); +assert.strictEqual(Buffer.byteLength('𠝹𠱓𠱸', 'UTF8'), 12); +// Without an encoding, utf8 should be assumed +assert.strictEqual(Buffer.byteLength('hey there'), 9); +assert.strictEqual(Buffer.byteLength('𠱸挶νξ#xx :)'), 17); +assert.strictEqual(Buffer.byteLength('hello world', ''), 11); +// It should also be assumed with unrecognized encoding +assert.strictEqual(Buffer.byteLength('hello world', 'abc'), 11); +assert.strictEqual(Buffer.byteLength('ßœ∑≈', 'unkn0wn enc0ding'), 10); + +// base64 +assert.strictEqual(Buffer.byteLength('aGVsbG8gd29ybGQ=', 'base64'), 11); +assert.strictEqual(Buffer.byteLength('aGVsbG8gd29ybGQ=', 'BASE64'), 11); +assert.strictEqual(Buffer.byteLength('bm9kZS5qcyByb2NrcyE=', 'base64'), 14); +assert.strictEqual(Buffer.byteLength('aGkk', 'base64'), 3); +assert.strictEqual( + Buffer.byteLength('bHNrZGZsa3NqZmtsc2xrZmFqc2RsZmtqcw==', 'base64'), 25 +); +// base64url +assert.strictEqual(Buffer.byteLength('aGVsbG8gd29ybGQ', 'base64url'), 11); +assert.strictEqual(Buffer.byteLength('aGVsbG8gd29ybGQ', 'BASE64URL'), 11); +assert.strictEqual(Buffer.byteLength('bm9kZS5qcyByb2NrcyE', 'base64url'), 14); +assert.strictEqual(Buffer.byteLength('aGkk', 'base64url'), 3); +assert.strictEqual( + Buffer.byteLength('bHNrZGZsa3NqZmtsc2xrZmFqc2RsZmtqcw', 'base64url'), 25 +); +// special padding +assert.strictEqual(Buffer.byteLength('aaa=', 'base64'), 2); +assert.strictEqual(Buffer.byteLength('aaaa==', 'base64'), 3); +assert.strictEqual(Buffer.byteLength('aaa=', 'base64url'), 2); +assert.strictEqual(Buffer.byteLength('aaaa==', 'base64url'), 3); + +assert.strictEqual(Buffer.byteLength('Il était tué'), 14); +assert.strictEqual(Buffer.byteLength('Il était tué', 'utf8'), 14); + +['ascii', 'latin1', 'binary'] + .reduce((es, e) => es.concat(e, e.toUpperCase()), []) + .forEach((encoding) => { + assert.strictEqual(Buffer.byteLength('Il était tué', encoding), 12); + }); + +['ucs2', 'ucs-2', 'utf16le', 'utf-16le'] + .reduce((es, e) => es.concat(e, e.toUpperCase()), []) + .forEach((encoding) => { + assert.strictEqual(Buffer.byteLength('Il était tué', encoding), 24); + }); + +// Test that ArrayBuffer from a different context is detected correctly +const arrayBuf = vm.runInNewContext('new ArrayBuffer()'); +assert.strictEqual(Buffer.byteLength(arrayBuf), 0); + +// Verify that invalid encodings are treated as utf8 +for (let i = 1; i < 10; i++) { + const encoding = String(i).repeat(i); + + assert.ok(!Buffer.isEncoding(encoding)); + assert.strictEqual(Buffer.byteLength('foo', encoding), + Buffer.byteLength('foo', 'utf8')); +} diff --git a/tests/node_compat/test/parallel/test-buffer-compare-offset.js b/tests/node_compat/test/parallel/test-buffer-compare-offset.js new file mode 100644 index 000000000..bb7ba2998 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-compare-offset.js @@ -0,0 +1,101 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); + +const a = Buffer.from([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]); +const b = Buffer.from([5, 6, 7, 8, 9, 0, 1, 2, 3, 4]); + +assert.strictEqual(a.compare(b), -1); + +// Equivalent to a.compare(b). +assert.strictEqual(a.compare(b, 0), -1); +assert.throws(() => a.compare(b, '0'), { code: 'ERR_INVALID_ARG_TYPE' }); +assert.strictEqual(a.compare(b, undefined), -1); + +// Equivalent to a.compare(b). +assert.strictEqual(a.compare(b, 0, undefined, 0), -1); + +// Zero-length target, return 1 +assert.strictEqual(a.compare(b, 0, 0, 0), 1); +assert.throws( + () => a.compare(b, 0, '0', '0'), + { code: 'ERR_INVALID_ARG_TYPE' } +); + +// Equivalent to Buffer.compare(a, b.slice(6, 10)) +assert.strictEqual(a.compare(b, 6, 10), 1); + +// Zero-length source, return -1 +assert.strictEqual(a.compare(b, 6, 10, 0, 0), -1); + +// Zero-length source and target, return 0 +assert.strictEqual(a.compare(b, 0, 0, 0, 0), 0); +assert.strictEqual(a.compare(b, 1, 1, 2, 2), 0); + +// Equivalent to Buffer.compare(a.slice(4), b.slice(0, 5)) +assert.strictEqual(a.compare(b, 0, 5, 4), 1); + +// Equivalent to Buffer.compare(a.slice(1), b.slice(5)) +assert.strictEqual(a.compare(b, 5, undefined, 1), 1); + +// Equivalent to Buffer.compare(a.slice(2), b.slice(2, 4)) +assert.strictEqual(a.compare(b, 2, 4, 2), -1); + +// Equivalent to Buffer.compare(a.slice(4), b.slice(0, 7)) +assert.strictEqual(a.compare(b, 0, 7, 4), -1); + +// Equivalent to Buffer.compare(a.slice(4, 6), b.slice(0, 7)); +assert.strictEqual(a.compare(b, 0, 7, 4, 6), -1); + +// Null is ambiguous. +assert.throws( + () => a.compare(b, 0, null), + { code: 'ERR_INVALID_ARG_TYPE' } +); + +// Values do not get coerced. +assert.throws( + () => a.compare(b, 0, { valueOf: () => 5 }), + { code: 'ERR_INVALID_ARG_TYPE' } +); + +// Infinity should not be coerced. +assert.throws( + () => a.compare(b, Infinity, -Infinity), + { code: 'ERR_OUT_OF_RANGE' } +); + +// Zero length target because default for targetEnd <= targetSource +assert.strictEqual(a.compare(b, 0xff), 1); + +assert.throws( + () => a.compare(b, '0xff'), + { code: 'ERR_INVALID_ARG_TYPE' } +); +assert.throws( + () => a.compare(b, 0, '0xff'), + { code: 'ERR_INVALID_ARG_TYPE' } +); + +const oor = { code: 'ERR_OUT_OF_RANGE' }; + +assert.throws(() => a.compare(b, 0, 100, 0), oor); +assert.throws(() => a.compare(b, 0, 1, 0, 100), oor); +assert.throws(() => a.compare(b, -1), oor); +assert.throws(() => a.compare(b, 0, Infinity), oor); +assert.throws(() => a.compare(b, 0, 1, -1), oor); +assert.throws(() => a.compare(b, -Infinity, Infinity), oor); +assert.throws(() => a.compare(), { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "target" argument must be an instance of ' + + 'Buffer or Uint8Array. Received undefined' +}); diff --git a/tests/node_compat/test/parallel/test-buffer-concat.js b/tests/node_compat/test/parallel/test-buffer-concat.js new file mode 100644 index 000000000..5d2e2c4a5 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-concat.js @@ -0,0 +1,107 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const zero = []; +const one = [ Buffer.from('asdf') ]; +const long = []; +for (let i = 0; i < 10; i++) long.push(Buffer.from('asdf')); + +const flatZero = Buffer.concat(zero); +const flatOne = Buffer.concat(one); +const flatLong = Buffer.concat(long); +const flatLongLen = Buffer.concat(long, 40); + +assert.strictEqual(flatZero.length, 0); +assert.strictEqual(flatOne.toString(), 'asdf'); + +const check = 'asdf'.repeat(10); + +// A special case where concat used to return the first item, +// if the length is one. This check is to make sure that we don't do that. +assert.notStrictEqual(flatOne, one[0]); +assert.strictEqual(flatLong.toString(), check); +assert.strictEqual(flatLongLen.toString(), check); + +[undefined, null, Buffer.from('hello')].forEach((value) => { + assert.throws(() => { + Buffer.concat(value); + }, { + code: 'ERR_INVALID_ARG_TYPE', + message: 'The "list" argument must be an instance of Array.' + + `${common.invalidArgTypeHelper(value)}` + }); +}); + +[[42], ['hello', Buffer.from('world')]].forEach((value) => { + assert.throws(() => { + Buffer.concat(value); + }, { + code: 'ERR_INVALID_ARG_TYPE', + message: 'The "list[0]" argument must be an instance of Buffer ' + + `or Uint8Array.${common.invalidArgTypeHelper(value[0])}` + }); +}); + +assert.throws(() => { + Buffer.concat([Buffer.from('hello'), 3]); +}, { + code: 'ERR_INVALID_ARG_TYPE', + message: 'The "list[1]" argument must be an instance of Buffer ' + + 'or Uint8Array. Received type number (3)' +}); + +// eslint-disable-next-line node-core/crypto-check +const random10 = common.hasCrypto ? + require('crypto').randomBytes(10) : + Buffer.alloc(10, 1); +const empty = Buffer.alloc(0); + +assert.notDeepStrictEqual(random10, empty); +assert.notDeepStrictEqual(random10, Buffer.alloc(10)); + +assert.deepStrictEqual(Buffer.concat([], 100), empty); +assert.deepStrictEqual(Buffer.concat([random10], 0), empty); +assert.deepStrictEqual(Buffer.concat([random10], 10), random10); +assert.deepStrictEqual(Buffer.concat([random10, random10], 10), random10); +assert.deepStrictEqual(Buffer.concat([empty, random10]), random10); +assert.deepStrictEqual(Buffer.concat([random10, empty, empty]), random10); + +// The tail should be zero-filled +assert.deepStrictEqual(Buffer.concat([empty], 100), Buffer.alloc(100)); +assert.deepStrictEqual(Buffer.concat([empty], 4096), Buffer.alloc(4096)); +assert.deepStrictEqual( + Buffer.concat([random10], 40), + Buffer.concat([random10, Buffer.alloc(30)])); + +assert.deepStrictEqual(Buffer.concat([new Uint8Array([0x41, 0x42]), + new Uint8Array([0x43, 0x44])]), + Buffer.from('ABCD')); diff --git a/tests/node_compat/test/parallel/test-buffer-constants.js b/tests/node_compat/test/parallel/test-buffer-constants.js new file mode 100644 index 000000000..0c4f6e21b --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-constants.js @@ -0,0 +1,25 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const assert = require('assert'); + +const { kMaxLength, kStringMaxLength } = require('buffer'); +const { MAX_LENGTH, MAX_STRING_LENGTH } = require('buffer').constants; + +assert.strictEqual(typeof MAX_LENGTH, 'number'); +assert.strictEqual(typeof MAX_STRING_LENGTH, 'number'); +assert(MAX_STRING_LENGTH <= MAX_LENGTH); +assert.throws(() => ' '.repeat(MAX_STRING_LENGTH + 1), + /^RangeError: Invalid string length$/); + +' '.repeat(MAX_STRING_LENGTH); // Should not throw. + +// Legacy values match: +assert.strictEqual(kMaxLength, MAX_LENGTH); +assert.strictEqual(kStringMaxLength, MAX_STRING_LENGTH); diff --git a/tests/node_compat/test/parallel/test-buffer-copy.js b/tests/node_compat/test/parallel/test-buffer-copy.js new file mode 100644 index 000000000..a10bfebc5 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-copy.js @@ -0,0 +1,243 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); + +const b = Buffer.allocUnsafe(1024); +const c = Buffer.allocUnsafe(512); + +let cntr = 0; + +{ + // copy 512 bytes, from 0 to 512. + b.fill(++cntr); + c.fill(++cntr); + const copied = b.copy(c, 0, 0, 512); + assert.strictEqual(copied, 512); + for (let i = 0; i < c.length; i++) { + assert.strictEqual(c[i], b[i]); + } +} + +{ + // Current behavior is to coerce values to integers. + b.fill(++cntr); + c.fill(++cntr); + const copied = b.copy(c, '0', '0', '512'); + assert.strictEqual(copied, 512); + for (let i = 0; i < c.length; i++) { + assert.strictEqual(c[i], b[i]); + } +} + +{ + // Floats will be converted to integers via `Math.floor` + b.fill(++cntr); + c.fill(++cntr); + const copied = b.copy(c, 0, 0, 512.5); + assert.strictEqual(copied, 512); + for (let i = 0; i < c.length; i++) { + assert.strictEqual(c[i], b[i]); + } +} + +{ + // Copy c into b, without specifying sourceEnd + b.fill(++cntr); + c.fill(++cntr); + const copied = c.copy(b, 0, 0); + assert.strictEqual(copied, c.length); + for (let i = 0; i < c.length; i++) { + assert.strictEqual(b[i], c[i]); + } +} + +{ + // Copy c into b, without specifying sourceStart + b.fill(++cntr); + c.fill(++cntr); + const copied = c.copy(b, 0); + assert.strictEqual(copied, c.length); + for (let i = 0; i < c.length; i++) { + assert.strictEqual(b[i], c[i]); + } +} + +{ + // Copied source range greater than source length + b.fill(++cntr); + c.fill(++cntr); + const copied = c.copy(b, 0, 0, c.length + 1); + assert.strictEqual(copied, c.length); + for (let i = 0; i < c.length; i++) { + assert.strictEqual(b[i], c[i]); + } +} + +{ + // Copy longer buffer b to shorter c without targetStart + b.fill(++cntr); + c.fill(++cntr); + const copied = b.copy(c); + assert.strictEqual(copied, c.length); + for (let i = 0; i < c.length; i++) { + assert.strictEqual(c[i], b[i]); + } +} + +{ + // Copy starting near end of b to c + b.fill(++cntr); + c.fill(++cntr); + const copied = b.copy(c, 0, b.length - Math.floor(c.length / 2)); + assert.strictEqual(copied, Math.floor(c.length / 2)); + for (let i = 0; i < Math.floor(c.length / 2); i++) { + assert.strictEqual(c[i], b[b.length - Math.floor(c.length / 2) + i]); + } + for (let i = Math.floor(c.length / 2) + 1; i < c.length; i++) { + assert.strictEqual(c[c.length - 1], c[i]); + } +} + +{ + // Try to copy 513 bytes, and check we don't overrun c + b.fill(++cntr); + c.fill(++cntr); + const copied = b.copy(c, 0, 0, 513); + assert.strictEqual(copied, c.length); + for (let i = 0; i < c.length; i++) { + assert.strictEqual(c[i], b[i]); + } +} + +{ + // copy 768 bytes from b into b + b.fill(++cntr); + b.fill(++cntr, 256); + const copied = b.copy(b, 0, 256, 1024); + assert.strictEqual(copied, 768); + for (let i = 0; i < b.length; i++) { + assert.strictEqual(b[i], cntr); + } +} + +// Copy string longer than buffer length (failure will segfault) +const bb = Buffer.allocUnsafe(10); +bb.fill('hello crazy world'); + + +// Try to copy from before the beginning of b. Should not throw. +b.copy(c, 0, 100, 10); + +// Throw with invalid source type +assert.throws( + () => Buffer.prototype.copy.call(0), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + } +); + +// Copy throws at negative targetStart +assert.throws( + () => Buffer.allocUnsafe(5).copy(Buffer.allocUnsafe(5), -1, 0), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "targetStart" is out of range. ' + + 'It must be >= 0. Received -1' + } +); + +// Copy throws at negative sourceStart +assert.throws( + () => Buffer.allocUnsafe(5).copy(Buffer.allocUnsafe(5), 0, -1), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + } +); + +// Copy throws if sourceStart is greater than length of source +assert.throws( + () => Buffer.allocUnsafe(5).copy(Buffer.allocUnsafe(5), 0, 100), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + } +); + +{ + // Check sourceEnd resets to targetEnd if former is greater than the latter + b.fill(++cntr); + c.fill(++cntr); + b.copy(c, 0, 0, 1025); + for (let i = 0; i < c.length; i++) { + assert.strictEqual(c[i], b[i]); + } +} + +// Throw with negative sourceEnd +assert.throws( + () => b.copy(c, 0, 0, -1), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "sourceEnd" is out of range. ' + + 'It must be >= 0. Received -1' + } +); + +// When sourceStart is greater than sourceEnd, zero copied +assert.strictEqual(b.copy(c, 0, 100, 10), 0); + +// When targetStart > targetLength, zero copied +assert.strictEqual(b.copy(c, 512, 0, 10), 0); + +// Test that the `target` can be a Uint8Array. +{ + const d = new Uint8Array(c); + // copy 512 bytes, from 0 to 512. + b.fill(++cntr); + d.fill(++cntr); + const copied = b.copy(d, 0, 0, 512); + assert.strictEqual(copied, 512); + for (let i = 0; i < d.length; i++) { + assert.strictEqual(d[i], b[i]); + } +} + +// Test that the source can be a Uint8Array, too. +{ + const e = new Uint8Array(b); + // copy 512 bytes, from 0 to 512. + e.fill(++cntr); + c.fill(++cntr); + const copied = Buffer.prototype.copy.call(e, c, 0, 0, 512); + assert.strictEqual(copied, 512); + for (let i = 0; i < c.length; i++) { + assert.strictEqual(c[i], e[i]); + } +} + +// https://github.com/nodejs/node/issues/23668: Do not crash for invalid input. +c.fill('c'); +b.copy(c, 'not a valid offset'); +// Make sure this acted like a regular copy with `0` offset. +assert.deepStrictEqual(c, b.slice(0, c.length)); + +{ + c.fill('C'); + assert.throws(() => { + b.copy(c, { [Symbol.toPrimitive]() { throw new Error('foo'); } }); + }, /foo/); + // No copying took place: + assert.deepStrictEqual(c.toString(), 'C'.repeat(c.length)); +} diff --git a/tests/node_compat/test/parallel/test-buffer-equals.js b/tests/node_compat/test/parallel/test-buffer-equals.js new file mode 100644 index 000000000..3d22fae84 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-equals.js @@ -0,0 +1,32 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); + +const b = Buffer.from('abcdf'); +const c = Buffer.from('abcdf'); +const d = Buffer.from('abcde'); +const e = Buffer.from('abcdef'); + +assert.ok(b.equals(c)); +assert.ok(!c.equals(d)); +assert.ok(!d.equals(e)); +assert.ok(d.equals(d)); +assert.ok(d.equals(new Uint8Array([0x61, 0x62, 0x63, 0x64, 0x65]))); + +assert.throws( + () => Buffer.alloc(1).equals('abc'), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "otherBuffer" argument must be an instance of ' + + "Buffer or Uint8Array. Received type string ('abc')" + } +); diff --git a/tests/node_compat/test/parallel/test-buffer-failed-alloc-typed-arrays.js b/tests/node_compat/test/parallel/test-buffer-failed-alloc-typed-arrays.js new file mode 100644 index 000000000..fc822ec86 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-failed-alloc-typed-arrays.js @@ -0,0 +1,40 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); +const SlowBuffer = require('buffer').SlowBuffer; + +// Test failed or zero-sized Buffer allocations not affecting typed arrays. +// This test exists because of a regression that occurred. Because Buffer +// instances are allocated with the same underlying allocator as TypedArrays, +// but Buffer's can optional be non-zero filled, there was a regression that +// occurred when a Buffer allocated failed, the internal flag specifying +// whether or not to zero-fill was not being reset, causing TypedArrays to +// allocate incorrectly. +const zeroArray = new Uint32Array(10).fill(0); +const sizes = [1e10, 0, 0.1, -1, 'a', undefined, null, NaN]; +const allocators = [ + Buffer, + SlowBuffer, + Buffer.alloc, + Buffer.allocUnsafe, + Buffer.allocUnsafeSlow, +]; +for (const allocator of allocators) { + for (const size of sizes) { + try { + // Some of these allocations are known to fail. If they do, + // Uint32Array should still produce a zeroed out result. + allocator(size); + } catch { + assert.deepStrictEqual(zeroArray, new Uint32Array(10)); + } + } +} diff --git a/tests/node_compat/test/parallel/test-buffer-fakes.js b/tests/node_compat/test/parallel/test-buffer-fakes.js new file mode 100644 index 000000000..2e25d6219 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-fakes.js @@ -0,0 +1,61 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); + +function FakeBuffer() { } +Object.setPrototypeOf(FakeBuffer, Buffer); +Object.setPrototypeOf(FakeBuffer.prototype, Buffer.prototype); + +const fb = new FakeBuffer(); + +assert.throws(function() { + Buffer.from(fb); +}, TypeError); + +assert.throws(function() { + +Buffer.prototype; // eslint-disable-line no-unused-expressions +}, TypeError); + +assert.throws(function() { + Buffer.compare(fb, Buffer.alloc(0)); +}, TypeError); + +assert.throws(function() { + fb.write('foo'); +}, TypeError); + +assert.throws(function() { + Buffer.concat([fb, fb]); +}, TypeError); + +assert.throws(function() { + fb.toString(); +}, TypeError); + +assert.throws(function() { + fb.equals(Buffer.alloc(0)); +}, TypeError); + +assert.throws(function() { + fb.indexOf(5); +}, TypeError); + +assert.throws(function() { + fb.readFloatLE(0); +}, TypeError); + +assert.throws(function() { + fb.writeFloatLE(0); +}, TypeError); + +assert.throws(function() { + fb.fill(0); +}, TypeError); diff --git a/tests/node_compat/test/parallel/test-buffer-from.js b/tests/node_compat/test/parallel/test-buffer-from.js new file mode 100644 index 000000000..6483e2a63 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-from.js @@ -0,0 +1,73 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const { deepStrictEqual, throws } = require('assert'); +// const { runInNewContext } = require('vm'); + +const checkString = 'test'; + +const check = Buffer.from(checkString); + +class MyString extends String { + constructor() { + super(checkString); + } +} + +class MyPrimitive { + [Symbol.toPrimitive]() { + return checkString; + } +} + +class MyBadPrimitive { + [Symbol.toPrimitive]() { + return 1; + } +} + +deepStrictEqual(Buffer.from(new String(checkString)), check); +deepStrictEqual(Buffer.from(new MyString()), check); +deepStrictEqual(Buffer.from(new MyPrimitive()), check); +// TODO(Soremwar) +// Enable once again when vm works correctly +// deepStrictEqual( +// Buffer.from(runInNewContext('new String(checkString)', { checkString })), +// check +// ); + +[ + {}, + new Boolean(true), + { valueOf() { return null; } }, + { valueOf() { return undefined; } }, + { valueOf: null }, + Object.create(null), + new Number(true), + new MyBadPrimitive(), + Symbol(), + 5n, + (one, two, three) => {}, + undefined, + null, +].forEach((input) => { + const errObj = { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The first argument must be of type string or an instance of ' + + 'Buffer, ArrayBuffer, or Array or an Array-like Object.' + + common.invalidArgTypeHelper(input) + }; + throws(() => Buffer.from(input), errObj); + throws(() => Buffer.from(input, 'hex'), errObj); +}); + +Buffer.allocUnsafe(10); // Should not throw. +Buffer.from('deadbeaf', 'hex'); // Should not throw. diff --git a/tests/node_compat/test/parallel/test-buffer-includes.js b/tests/node_compat/test/parallel/test-buffer-includes.js new file mode 100644 index 000000000..797ec8246 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-includes.js @@ -0,0 +1,317 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const b = Buffer.from('abcdef'); +const buf_a = Buffer.from('a'); +const buf_bc = Buffer.from('bc'); +const buf_f = Buffer.from('f'); +const buf_z = Buffer.from('z'); +const buf_empty = Buffer.from(''); + +assert(b.includes('a')); +assert(!b.includes('a', 1)); +assert(!b.includes('a', -1)); +assert(!b.includes('a', -4)); +assert(b.includes('a', -b.length)); +assert(b.includes('a', NaN)); +assert(b.includes('a', -Infinity)); +assert(!b.includes('a', Infinity)); +assert(b.includes('bc')); +assert(!b.includes('bc', 2)); +assert(!b.includes('bc', -1)); +assert(!b.includes('bc', -3)); +assert(b.includes('bc', -5)); +assert(b.includes('bc', NaN)); +assert(b.includes('bc', -Infinity)); +assert(!b.includes('bc', Infinity)); +assert(b.includes('f'), b.length - 1); +assert(!b.includes('z')); +assert(b.includes('')); +assert(b.includes('', 1)); +assert(b.includes('', b.length + 1)); +assert(b.includes('', Infinity)); +assert(b.includes(buf_a)); +assert(!b.includes(buf_a, 1)); +assert(!b.includes(buf_a, -1)); +assert(!b.includes(buf_a, -4)); +assert(b.includes(buf_a, -b.length)); +assert(b.includes(buf_a, NaN)); +assert(b.includes(buf_a, -Infinity)); +assert(!b.includes(buf_a, Infinity)); +assert(b.includes(buf_bc)); +assert(!b.includes(buf_bc, 2)); +assert(!b.includes(buf_bc, -1)); +assert(!b.includes(buf_bc, -3)); +assert(b.includes(buf_bc, -5)); +assert(b.includes(buf_bc, NaN)); +assert(b.includes(buf_bc, -Infinity)); +assert(!b.includes(buf_bc, Infinity)); +assert(b.includes(buf_f), b.length - 1); +assert(!b.includes(buf_z)); +assert(b.includes(buf_empty)); +assert(b.includes(buf_empty, 1)); +assert(b.includes(buf_empty, b.length + 1)); +assert(b.includes(buf_empty, Infinity)); +assert(b.includes(0x61)); +assert(!b.includes(0x61, 1)); +assert(!b.includes(0x61, -1)); +assert(!b.includes(0x61, -4)); +assert(b.includes(0x61, -b.length)); +assert(b.includes(0x61, NaN)); +assert(b.includes(0x61, -Infinity)); +assert(!b.includes(0x61, Infinity)); +assert(!b.includes(0x0)); + +// test offsets +assert(b.includes('d', 2)); +assert(b.includes('f', 5)); +assert(b.includes('f', -1)); +assert(!b.includes('f', 6)); + +assert(b.includes(Buffer.from('d'), 2)); +assert(b.includes(Buffer.from('f'), 5)); +assert(b.includes(Buffer.from('f'), -1)); +assert(!b.includes(Buffer.from('f'), 6)); + +// TODO(Soremwar) +// Enable again once encoding is taking into account when evaluating indexOf +// assert(!Buffer.from('ff').includes(Buffer.from('f'), 1, 'ucs2')); + +// test hex encoding +assert.strictEqual( + Buffer.from(b.toString('hex'), 'hex') + .includes('64', 0, 'hex'), + true +); +assert.strictEqual( + Buffer.from(b.toString('hex'), 'hex') + .includes(Buffer.from('64', 'hex'), 0, 'hex'), + true +); + +// Test base64 encoding +assert.strictEqual( + Buffer.from(b.toString('base64'), 'base64') + .includes('ZA==', 0, 'base64'), + true +); +assert.strictEqual( + Buffer.from(b.toString('base64'), 'base64') + .includes(Buffer.from('ZA==', 'base64'), 0, 'base64'), + true +); + +// test ascii encoding +assert.strictEqual( + Buffer.from(b.toString('ascii'), 'ascii') + .includes('d', 0, 'ascii'), + true +); +assert.strictEqual( + Buffer.from(b.toString('ascii'), 'ascii') + .includes(Buffer.from('d', 'ascii'), 0, 'ascii'), + true +); + +// Test latin1 encoding +assert.strictEqual( + Buffer.from(b.toString('latin1'), 'latin1') + .includes('d', 0, 'latin1'), + true +); +assert.strictEqual( + Buffer.from(b.toString('latin1'), 'latin1') + .includes(Buffer.from('d', 'latin1'), 0, 'latin1'), + true +); + +// Test binary encoding +assert.strictEqual( + Buffer.from(b.toString('binary'), 'binary') + .includes('d', 0, 'binary'), + true +); +assert.strictEqual( + Buffer.from(b.toString('binary'), 'binary') + .includes(Buffer.from('d', 'binary'), 0, 'binary'), + true +); + + +// test ucs2 encoding +let twoByteString = Buffer.from('\u039a\u0391\u03a3\u03a3\u0395', 'ucs2'); + +assert(twoByteString.includes('\u0395', 4, 'ucs2')); +assert(twoByteString.includes('\u03a3', -4, 'ucs2')); +assert(twoByteString.includes('\u03a3', -6, 'ucs2')); +assert(twoByteString.includes( + Buffer.from('\u03a3', 'ucs2'), -6, 'ucs2')); +assert(!twoByteString.includes('\u03a3', -2, 'ucs2')); + +const mixedByteStringUcs2 = + Buffer.from('\u039a\u0391abc\u03a3\u03a3\u0395', 'ucs2'); +assert(mixedByteStringUcs2.includes('bc', 0, 'ucs2')); +assert(mixedByteStringUcs2.includes('\u03a3', 0, 'ucs2')); +assert(!mixedByteStringUcs2.includes('\u0396', 0, 'ucs2')); + +assert.ok( + mixedByteStringUcs2.includes(Buffer.from('bc', 'ucs2'), 0, 'ucs2')); +assert.ok( + mixedByteStringUcs2.includes(Buffer.from('\u03a3', 'ucs2'), 0, 'ucs2')); +assert.ok( + !mixedByteStringUcs2.includes(Buffer.from('\u0396', 'ucs2'), 0, 'ucs2')); + +twoByteString = Buffer.from('\u039a\u0391\u03a3\u03a3\u0395', 'ucs2'); + +// Test single char pattern +assert(twoByteString.includes('\u039a', 0, 'ucs2')); +assert(twoByteString.includes('\u0391', 0, 'ucs2'), 'Alpha'); +assert(twoByteString.includes('\u03a3', 0, 'ucs2'), 'First Sigma'); +assert(twoByteString.includes('\u03a3', 6, 'ucs2'), 'Second Sigma'); +assert(twoByteString.includes('\u0395', 0, 'ucs2'), 'Epsilon'); +assert(!twoByteString.includes('\u0392', 0, 'ucs2'), 'Not beta'); + +// Test multi-char pattern +assert(twoByteString.includes('\u039a\u0391', 0, 'ucs2'), 'Lambda Alpha'); +assert(twoByteString.includes('\u0391\u03a3', 0, 'ucs2'), 'Alpha Sigma'); +assert(twoByteString.includes('\u03a3\u03a3', 0, 'ucs2'), 'Sigma Sigma'); +assert(twoByteString.includes('\u03a3\u0395', 0, 'ucs2'), 'Sigma Epsilon'); + +const mixedByteStringUtf8 = Buffer.from('\u039a\u0391abc\u03a3\u03a3\u0395'); +assert(mixedByteStringUtf8.includes('bc')); +assert(mixedByteStringUtf8.includes('bc', 5)); +assert(mixedByteStringUtf8.includes('bc', -8)); +assert(mixedByteStringUtf8.includes('\u03a3')); +assert(!mixedByteStringUtf8.includes('\u0396')); + + +// Test complex string includes algorithms. Only trigger for long strings. +// Long string that isn't a simple repeat of a shorter string. +let longString = 'A'; +for (let i = 66; i < 76; i++) { // from 'B' to 'K' + longString = longString + String.fromCharCode(i) + longString; +} + +const longBufferString = Buffer.from(longString); + +// Pattern of 15 chars, repeated every 16 chars in long +let pattern = 'ABACABADABACABA'; +for (let i = 0; i < longBufferString.length - pattern.length; i += 7) { + const includes = longBufferString.includes(pattern, i); + assert(includes, `Long ABACABA...-string at index ${i}`); +} +assert(longBufferString.includes('AJABACA'), 'Long AJABACA, First J'); +assert(longBufferString.includes('AJABACA', 511), 'Long AJABACA, Second J'); + +pattern = 'JABACABADABACABA'; +assert(longBufferString.includes(pattern), 'Long JABACABA..., First J'); +assert(longBufferString.includes(pattern, 512), 'Long JABACABA..., Second J'); + +// Search for a non-ASCII string in a pure ASCII string. +const asciiString = Buffer.from( + 'arglebargleglopglyfarglebargleglopglyfarglebargleglopglyf'); +assert(!asciiString.includes('\x2061')); +assert(asciiString.includes('leb', 0)); + +// Search in string containing many non-ASCII chars. +const allCodePoints = []; +for (let i = 0; i < 65534; i++) allCodePoints[i] = i; +const allCharsString = String.fromCharCode.apply(String, allCodePoints) + + String.fromCharCode(65534, 65535); +const allCharsBufferUtf8 = Buffer.from(allCharsString); +const allCharsBufferUcs2 = Buffer.from(allCharsString, 'ucs2'); + +// Search for string long enough to trigger complex search with ASCII pattern +// and UC16 subject. +assert(!allCharsBufferUtf8.includes('notfound')); +assert(!allCharsBufferUcs2.includes('notfound')); + +// Find substrings in Utf8. +let lengths = [1, 3, 15]; // Single char, simple and complex. +let indices = [0x5, 0x60, 0x400, 0x680, 0x7ee, 0xFF02, 0x16610, 0x2f77b]; +for (let lengthIndex = 0; lengthIndex < lengths.length; lengthIndex++) { + for (let i = 0; i < indices.length; i++) { + const index = indices[i]; + let length = lengths[lengthIndex]; + + if (index + length > 0x7F) { + length = 2 * length; + } + + if (index + length > 0x7FF) { + length = 3 * length; + } + + if (index + length > 0xFFFF) { + length = 4 * length; + } + + const patternBufferUtf8 = allCharsBufferUtf8.slice(index, index + length); + assert(index, allCharsBufferUtf8.includes(patternBufferUtf8)); + + const patternStringUtf8 = patternBufferUtf8.toString(); + assert(index, allCharsBufferUtf8.includes(patternStringUtf8)); + } +} + +// Find substrings in Usc2. +lengths = [2, 4, 16]; // Single char, simple and complex. +indices = [0x5, 0x65, 0x105, 0x205, 0x285, 0x2005, 0x2085, 0xfff0]; +for (let lengthIndex = 0; lengthIndex < lengths.length; lengthIndex++) { + for (let i = 0; i < indices.length; i++) { + const index = indices[i] * 2; + const length = lengths[lengthIndex]; + + const patternBufferUcs2 = + allCharsBufferUcs2.slice(index, index + length); + assert.ok( + allCharsBufferUcs2.includes(patternBufferUcs2, 0, 'ucs2')); + + const patternStringUcs2 = patternBufferUcs2.toString('ucs2'); + assert.ok( + allCharsBufferUcs2.includes(patternStringUcs2, 0, 'ucs2')); + } +} + +[ + () => { }, + {}, + [], +].forEach((val) => { + assert.throws( + () => b.includes(val), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "value" argument must be one of type number or string ' + + 'or an instance of Buffer or Uint8Array.' + + common.invalidArgTypeHelper(val) + } + ); +}); + +// Test truncation of Number arguments to uint8 +// TODO(Soremwar) +// Enable once multi byte number search is available +// { +// const buf = Buffer.from('this is a test'); +// assert.ok(buf.includes(0x6973)); +// assert.ok(buf.includes(0x697320)); +// assert.ok(buf.includes(0x69732069)); +// assert.ok(buf.includes(0x697374657374)); +// assert.ok(buf.includes(0x69737374)); +// assert.ok(buf.includes(0x69737465)); +// assert.ok(buf.includes(0x69737465)); +// assert.ok(buf.includes(-140)); +// assert.ok(buf.includes(-152)); +// assert.ok(!buf.includes(0xff)); +// assert.ok(!buf.includes(0xffff)); +// } diff --git a/tests/node_compat/test/parallel/test-buffer-indexof.js b/tests/node_compat/test/parallel/test-buffer-indexof.js new file mode 100644 index 000000000..802e0208b --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-indexof.js @@ -0,0 +1,646 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const b = Buffer.from('abcdef'); +const buf_a = Buffer.from('a'); +const buf_bc = Buffer.from('bc'); +const buf_f = Buffer.from('f'); +const buf_z = Buffer.from('z'); +const buf_empty = Buffer.from(''); + +const s = 'abcdef'; + +assert.strictEqual(b.indexOf('a'), 0); +assert.strictEqual(b.indexOf('a', 1), -1); +assert.strictEqual(b.indexOf('a', -1), -1); +assert.strictEqual(b.indexOf('a', -4), -1); +assert.strictEqual(b.indexOf('a', -b.length), 0); +assert.strictEqual(b.indexOf('a', NaN), 0); +assert.strictEqual(b.indexOf('a', -Infinity), 0); +assert.strictEqual(b.indexOf('a', Infinity), -1); +assert.strictEqual(b.indexOf('bc'), 1); +assert.strictEqual(b.indexOf('bc', 2), -1); +assert.strictEqual(b.indexOf('bc', -1), -1); +assert.strictEqual(b.indexOf('bc', -3), -1); +assert.strictEqual(b.indexOf('bc', -5), 1); +assert.strictEqual(b.indexOf('bc', NaN), 1); +assert.strictEqual(b.indexOf('bc', -Infinity), 1); +assert.strictEqual(b.indexOf('bc', Infinity), -1); +assert.strictEqual(b.indexOf('f'), b.length - 1); +assert.strictEqual(b.indexOf('z'), -1); +assert.strictEqual(b.indexOf(''), 0); +assert.strictEqual(b.indexOf('', 1), 1); +assert.strictEqual(b.indexOf('', b.length + 1), b.length); +assert.strictEqual(b.indexOf('', Infinity), b.length); +assert.strictEqual(b.indexOf(buf_a), 0); +assert.strictEqual(b.indexOf(buf_a, 1), -1); +assert.strictEqual(b.indexOf(buf_a, -1), -1); +assert.strictEqual(b.indexOf(buf_a, -4), -1); +assert.strictEqual(b.indexOf(buf_a, -b.length), 0); +assert.strictEqual(b.indexOf(buf_a, NaN), 0); +assert.strictEqual(b.indexOf(buf_a, -Infinity), 0); +assert.strictEqual(b.indexOf(buf_a, Infinity), -1); +assert.strictEqual(b.indexOf(buf_bc), 1); +assert.strictEqual(b.indexOf(buf_bc, 2), -1); +assert.strictEqual(b.indexOf(buf_bc, -1), -1); +assert.strictEqual(b.indexOf(buf_bc, -3), -1); +assert.strictEqual(b.indexOf(buf_bc, -5), 1); +assert.strictEqual(b.indexOf(buf_bc, NaN), 1); +assert.strictEqual(b.indexOf(buf_bc, -Infinity), 1); +assert.strictEqual(b.indexOf(buf_bc, Infinity), -1); +assert.strictEqual(b.indexOf(buf_f), b.length - 1); +assert.strictEqual(b.indexOf(buf_z), -1); +assert.strictEqual(b.indexOf(buf_empty), 0); +assert.strictEqual(b.indexOf(buf_empty, 1), 1); +assert.strictEqual(b.indexOf(buf_empty, b.length + 1), b.length); +assert.strictEqual(b.indexOf(buf_empty, Infinity), b.length); +assert.strictEqual(b.indexOf(0x61), 0); +assert.strictEqual(b.indexOf(0x61, 1), -1); +assert.strictEqual(b.indexOf(0x61, -1), -1); +assert.strictEqual(b.indexOf(0x61, -4), -1); +assert.strictEqual(b.indexOf(0x61, -b.length), 0); +assert.strictEqual(b.indexOf(0x61, NaN), 0); +assert.strictEqual(b.indexOf(0x61, -Infinity), 0); +assert.strictEqual(b.indexOf(0x61, Infinity), -1); +assert.strictEqual(b.indexOf(0x0), -1); + +// test offsets +assert.strictEqual(b.indexOf('d', 2), 3); +assert.strictEqual(b.indexOf('f', 5), 5); +assert.strictEqual(b.indexOf('f', -1), 5); +assert.strictEqual(b.indexOf('f', 6), -1); + +assert.strictEqual(b.indexOf(Buffer.from('d'), 2), 3); +assert.strictEqual(b.indexOf(Buffer.from('f'), 5), 5); +assert.strictEqual(b.indexOf(Buffer.from('f'), -1), 5); +assert.strictEqual(b.indexOf(Buffer.from('f'), 6), -1); + +// TODO(Soremwar) +// Enable again once encoding is taking into account when evaluating indexOf +// assert.strictEqual(Buffer.from('ff').indexOf(Buffer.from('f'), 1, 'ucs2'), -1); + +// Test invalid and uppercase encoding +assert.strictEqual(b.indexOf('b', 'utf8'), 1); +assert.strictEqual(b.indexOf('b', 'UTF8'), 1); +assert.strictEqual(b.indexOf('62', 'HEX'), 1); +assert.throws(() => b.indexOf('bad', 'enc'), /Unknown encoding: enc/); + +// test hex encoding +assert.strictEqual( + Buffer.from(b.toString('hex'), 'hex') + .indexOf('64', 0, 'hex'), + 3 +); +assert.strictEqual( + Buffer.from(b.toString('hex'), 'hex') + .indexOf(Buffer.from('64', 'hex'), 0, 'hex'), + 3 +); + +// Test base64 encoding +assert.strictEqual( + Buffer.from(b.toString('base64'), 'base64') + .indexOf('ZA==', 0, 'base64'), + 3 +); +assert.strictEqual( + Buffer.from(b.toString('base64'), 'base64') + .indexOf(Buffer.from('ZA==', 'base64'), 0, 'base64'), + 3 +); + +// Test base64url encoding +assert.strictEqual( + Buffer.from(b.toString('base64url'), 'base64url') + .indexOf('ZA==', 0, 'base64url'), + 3 +); + +// test ascii encoding +assert.strictEqual( + Buffer.from(b.toString('ascii'), 'ascii') + .indexOf('d', 0, 'ascii'), + 3 +); +assert.strictEqual( + Buffer.from(b.toString('ascii'), 'ascii') + .indexOf(Buffer.from('d', 'ascii'), 0, 'ascii'), + 3 +); + +// Test latin1 encoding +assert.strictEqual( + Buffer.from(b.toString('latin1'), 'latin1') + .indexOf('d', 0, 'latin1'), + 3 +); +assert.strictEqual( + Buffer.from(b.toString('latin1'), 'latin1') + .indexOf(Buffer.from('d', 'latin1'), 0, 'latin1'), + 3 +); +assert.strictEqual( + Buffer.from('aa\u00e8aa', 'latin1') + .indexOf('\u00e8', 'latin1'), + 2 +); +assert.strictEqual( + Buffer.from('\u00e8', 'latin1') + .indexOf('\u00e8', 'latin1'), + 0 +); +assert.strictEqual( + Buffer.from('\u00e8', 'latin1') + .indexOf(Buffer.from('\u00e8', 'latin1'), 'latin1'), + 0 +); + +// Test binary encoding +assert.strictEqual( + Buffer.from(b.toString('binary'), 'binary') + .indexOf('d', 0, 'binary'), + 3 +); +assert.strictEqual( + Buffer.from(b.toString('binary'), 'binary') + .indexOf(Buffer.from('d', 'binary'), 0, 'binary'), + 3 +); +assert.strictEqual( + Buffer.from('aa\u00e8aa', 'binary') + .indexOf('\u00e8', 'binary'), + 2 +); +assert.strictEqual( + Buffer.from('\u00e8', 'binary') + .indexOf('\u00e8', 'binary'), + 0 +); +assert.strictEqual( + Buffer.from('\u00e8', 'binary') + .indexOf(Buffer.from('\u00e8', 'binary'), 'binary'), + 0 +); + + +// Test optional offset with passed encoding +assert.strictEqual(Buffer.from('aaaa0').indexOf('30', 'hex'), 4); +assert.strictEqual(Buffer.from('aaaa00a').indexOf('3030', 'hex'), 4); + +{ + // Test usc2 and utf16le encoding + ['ucs2', 'utf16le'].forEach((encoding) => { + const twoByteString = Buffer.from( + '\u039a\u0391\u03a3\u03a3\u0395', encoding); + + assert.strictEqual(twoByteString.indexOf('\u0395', 4, encoding), 8); + assert.strictEqual(twoByteString.indexOf('\u03a3', -4, encoding), 6); + assert.strictEqual(twoByteString.indexOf('\u03a3', -6, encoding), 4); + assert.strictEqual(twoByteString.indexOf( + Buffer.from('\u03a3', encoding), -6, encoding), 4); + assert.strictEqual(-1, twoByteString.indexOf('\u03a3', -2, encoding)); + }); +} + +const mixedByteStringUcs2 = + Buffer.from('\u039a\u0391abc\u03a3\u03a3\u0395', 'ucs2'); +assert.strictEqual(mixedByteStringUcs2.indexOf('bc', 0, 'ucs2'), 6); +assert.strictEqual(mixedByteStringUcs2.indexOf('\u03a3', 0, 'ucs2'), 10); +assert.strictEqual(-1, mixedByteStringUcs2.indexOf('\u0396', 0, 'ucs2')); + +assert.strictEqual( + mixedByteStringUcs2.indexOf(Buffer.from('bc', 'ucs2'), 0, 'ucs2'), 6); +assert.strictEqual( + mixedByteStringUcs2.indexOf(Buffer.from('\u03a3', 'ucs2'), 0, 'ucs2'), 10); +assert.strictEqual( + -1, mixedByteStringUcs2.indexOf(Buffer.from('\u0396', 'ucs2'), 0, 'ucs2')); + +{ + const twoByteString = Buffer.from('\u039a\u0391\u03a3\u03a3\u0395', 'ucs2'); + + // Test single char pattern + assert.strictEqual(twoByteString.indexOf('\u039a', 0, 'ucs2'), 0); + let index = twoByteString.indexOf('\u0391', 0, 'ucs2'); + assert.strictEqual(index, 2, `Alpha - at index ${index}`); + index = twoByteString.indexOf('\u03a3', 0, 'ucs2'); + assert.strictEqual(index, 4, `First Sigma - at index ${index}`); + index = twoByteString.indexOf('\u03a3', 6, 'ucs2'); + assert.strictEqual(index, 6, `Second Sigma - at index ${index}`); + index = twoByteString.indexOf('\u0395', 0, 'ucs2'); + assert.strictEqual(index, 8, `Epsilon - at index ${index}`); + index = twoByteString.indexOf('\u0392', 0, 'ucs2'); + assert.strictEqual(-1, index, `Not beta - at index ${index}`); + + // Test multi-char pattern + index = twoByteString.indexOf('\u039a\u0391', 0, 'ucs2'); + assert.strictEqual(index, 0, `Lambda Alpha - at index ${index}`); + index = twoByteString.indexOf('\u0391\u03a3', 0, 'ucs2'); + assert.strictEqual(index, 2, `Alpha Sigma - at index ${index}`); + index = twoByteString.indexOf('\u03a3\u03a3', 0, 'ucs2'); + assert.strictEqual(index, 4, `Sigma Sigma - at index ${index}`); + index = twoByteString.indexOf('\u03a3\u0395', 0, 'ucs2'); + assert.strictEqual(index, 6, `Sigma Epsilon - at index ${index}`); +} + +const mixedByteStringUtf8 = Buffer.from('\u039a\u0391abc\u03a3\u03a3\u0395'); +assert.strictEqual(mixedByteStringUtf8.indexOf('bc'), 5); +assert.strictEqual(mixedByteStringUtf8.indexOf('bc', 5), 5); +assert.strictEqual(mixedByteStringUtf8.indexOf('bc', -8), 5); +assert.strictEqual(mixedByteStringUtf8.indexOf('\u03a3'), 7); +assert.strictEqual(mixedByteStringUtf8.indexOf('\u0396'), -1); + + +// Test complex string indexOf algorithms. Only trigger for long strings. +// Long string that isn't a simple repeat of a shorter string. +let longString = 'A'; +for (let i = 66; i < 76; i++) { // from 'B' to 'K' + longString = longString + String.fromCharCode(i) + longString; +} + +const longBufferString = Buffer.from(longString); + +// Pattern of 15 chars, repeated every 16 chars in long +let pattern = 'ABACABADABACABA'; +for (let i = 0; i < longBufferString.length - pattern.length; i += 7) { + const index = longBufferString.indexOf(pattern, i); + assert.strictEqual((i + 15) & ~0xf, index, + `Long ABACABA...-string at index ${i}`); +} + +let index = longBufferString.indexOf('AJABACA'); +assert.strictEqual(index, 510, `Long AJABACA, First J - at index ${index}`); +index = longBufferString.indexOf('AJABACA', 511); +assert.strictEqual(index, 1534, `Long AJABACA, Second J - at index ${index}`); + +pattern = 'JABACABADABACABA'; +index = longBufferString.indexOf(pattern); +assert.strictEqual(index, 511, `Long JABACABA..., First J - at index ${index}`); +index = longBufferString.indexOf(pattern, 512); +assert.strictEqual( + index, 1535, `Long JABACABA..., Second J - at index ${index}`); + +// Search for a non-ASCII string in a pure ASCII string. +const asciiString = Buffer.from( + 'arglebargleglopglyfarglebargleglopglyfarglebargleglopglyf'); +assert.strictEqual(-1, asciiString.indexOf('\x2061')); +assert.strictEqual(asciiString.indexOf('leb', 0), 3); + +// Search in string containing many non-ASCII chars. +const allCodePoints = []; +for (let i = 0; i < 65534; i++) allCodePoints[i] = i; +const allCharsString = String.fromCharCode.apply(String, allCodePoints) + + String.fromCharCode(65534, 65535); +const allCharsBufferUtf8 = Buffer.from(allCharsString); +const allCharsBufferUcs2 = Buffer.from(allCharsString, 'ucs2'); + +// Search for string long enough to trigger complex search with ASCII pattern +// and UC16 subject. +assert.strictEqual(-1, allCharsBufferUtf8.indexOf('notfound')); +assert.strictEqual(-1, allCharsBufferUcs2.indexOf('notfound')); + +// Needle is longer than haystack, but only because it's encoded as UTF-16 +assert.strictEqual(Buffer.from('aaaa').indexOf('a'.repeat(4), 'ucs2'), -1); + +assert.strictEqual(Buffer.from('aaaa').indexOf('a'.repeat(4), 'utf8'), 0); +assert.strictEqual(Buffer.from('aaaa').indexOf('你好', 'ucs2'), -1); + +// Haystack has odd length, but the needle is UCS2. +assert.strictEqual(Buffer.from('aaaaa').indexOf('b', 'ucs2'), -1); + +{ + // Find substrings in Utf8. + const lengths = [1, 3, 15]; // Single char, simple and complex. + const indices = [0x5, 0x60, 0x400, 0x680, 0x7ee, 0xFF02, 0x16610, 0x2f77b]; + for (let lengthIndex = 0; lengthIndex < lengths.length; lengthIndex++) { + for (let i = 0; i < indices.length; i++) { + const index = indices[i]; + let length = lengths[lengthIndex]; + + if (index + length > 0x7F) { + length = 2 * length; + } + + if (index + length > 0x7FF) { + length = 3 * length; + } + + if (index + length > 0xFFFF) { + length = 4 * length; + } + + const patternBufferUtf8 = allCharsBufferUtf8.slice(index, index + length); + assert.strictEqual(index, allCharsBufferUtf8.indexOf(patternBufferUtf8)); + + const patternStringUtf8 = patternBufferUtf8.toString(); + assert.strictEqual(index, allCharsBufferUtf8.indexOf(patternStringUtf8)); + } + } +} + +// TODO(Soremwar) +// Enable again once encoding is taking into account when evaluating indexOf +// { +// // Find substrings in Usc2. +// const lengths = [2, 4, 16]; // Single char, simple and complex. +// const indices = [0x5, 0x65, 0x105, 0x205, 0x285, 0x2005, 0x2085, 0xfff0]; +// for (let lengthIndex = 0; lengthIndex < lengths.length; lengthIndex++) { +// for (let i = 0; i < indices.length; i++) { +// const index = indices[i] * 2; +// const length = lengths[lengthIndex]; + +// const patternBufferUcs2 = +// allCharsBufferUcs2.slice(index, index + length); +// assert.strictEqual( +// index, allCharsBufferUcs2.indexOf(patternBufferUcs2, 0, 'ucs2')); + +// const patternStringUcs2 = patternBufferUcs2.toString('ucs2'); +// assert.strictEqual( +// index, allCharsBufferUcs2.indexOf(patternStringUcs2, 0, 'ucs2')); +// } +// } +// } + +[ + () => {}, + {}, + [], +].forEach((val) => { + assert.throws( + () => b.indexOf(val), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "value" argument must be one of type number or string ' + + 'or an instance of Buffer or Uint8Array.' + + common.invalidArgTypeHelper(val) + } + ); +}); + +// Test weird offset arguments. +// The following offsets coerce to NaN or 0, searching the whole Buffer +assert.strictEqual(b.indexOf('b', undefined), 1); +assert.strictEqual(b.indexOf('b', {}), 1); +assert.strictEqual(b.indexOf('b', 0), 1); +assert.strictEqual(b.indexOf('b', null), 1); +assert.strictEqual(b.indexOf('b', []), 1); + +// The following offset coerces to 2, in other words +[2] === 2 +assert.strictEqual(b.indexOf('b', [2]), -1); + +// Behavior should match String.indexOf() +assert.strictEqual( + b.indexOf('b', undefined), + s.indexOf('b', undefined)); +assert.strictEqual( + b.indexOf('b', {}), + s.indexOf('b', {})); +assert.strictEqual( + b.indexOf('b', 0), + s.indexOf('b', 0)); +assert.strictEqual( + b.indexOf('b', null), + s.indexOf('b', null)); +assert.strictEqual( + b.indexOf('b', []), + s.indexOf('b', [])); +assert.strictEqual( + b.indexOf('b', [2]), + s.indexOf('b', [2])); + +// All code for handling encodings is shared between Buffer.indexOf and +// Buffer.lastIndexOf, so only testing the separate lastIndexOf semantics. + +// Test lastIndexOf basic functionality; Buffer b contains 'abcdef'. +// lastIndexOf string: +assert.strictEqual(b.lastIndexOf('a'), 0); +assert.strictEqual(b.lastIndexOf('a', 1), 0); +assert.strictEqual(b.lastIndexOf('b', 1), 1); +assert.strictEqual(b.lastIndexOf('c', 1), -1); +assert.strictEqual(b.lastIndexOf('a', -1), 0); +assert.strictEqual(b.lastIndexOf('a', -4), 0); +assert.strictEqual(b.lastIndexOf('a', -b.length), 0); +assert.strictEqual(b.lastIndexOf('a', -b.length - 1), -1); +assert.strictEqual(b.lastIndexOf('a', NaN), 0); +assert.strictEqual(b.lastIndexOf('a', -Infinity), -1); +assert.strictEqual(b.lastIndexOf('a', Infinity), 0); +// lastIndexOf Buffer: +assert.strictEqual(b.lastIndexOf(buf_a), 0); +assert.strictEqual(b.lastIndexOf(buf_a, 1), 0); +assert.strictEqual(b.lastIndexOf(buf_a, -1), 0); +assert.strictEqual(b.lastIndexOf(buf_a, -4), 0); +assert.strictEqual(b.lastIndexOf(buf_a, -b.length), 0); +assert.strictEqual(b.lastIndexOf(buf_a, -b.length - 1), -1); +assert.strictEqual(b.lastIndexOf(buf_a, NaN), 0); +assert.strictEqual(b.lastIndexOf(buf_a, -Infinity), -1); +assert.strictEqual(b.lastIndexOf(buf_a, Infinity), 0); +assert.strictEqual(b.lastIndexOf(buf_bc), 1); +assert.strictEqual(b.lastIndexOf(buf_bc, 2), 1); +assert.strictEqual(b.lastIndexOf(buf_bc, -1), 1); +assert.strictEqual(b.lastIndexOf(buf_bc, -3), 1); +assert.strictEqual(b.lastIndexOf(buf_bc, -5), 1); +assert.strictEqual(b.lastIndexOf(buf_bc, -6), -1); +assert.strictEqual(b.lastIndexOf(buf_bc, NaN), 1); +assert.strictEqual(b.lastIndexOf(buf_bc, -Infinity), -1); +assert.strictEqual(b.lastIndexOf(buf_bc, Infinity), 1); +assert.strictEqual(b.lastIndexOf(buf_f), b.length - 1); +assert.strictEqual(b.lastIndexOf(buf_z), -1); +assert.strictEqual(b.lastIndexOf(buf_empty), b.length); +assert.strictEqual(b.lastIndexOf(buf_empty, 1), 1); +assert.strictEqual(b.lastIndexOf(buf_empty, b.length + 1), b.length); +assert.strictEqual(b.lastIndexOf(buf_empty, Infinity), b.length); +// lastIndexOf number: +assert.strictEqual(b.lastIndexOf(0x61), 0); +assert.strictEqual(b.lastIndexOf(0x61, 1), 0); +assert.strictEqual(b.lastIndexOf(0x61, -1), 0); +assert.strictEqual(b.lastIndexOf(0x61, -4), 0); +assert.strictEqual(b.lastIndexOf(0x61, -b.length), 0); +assert.strictEqual(b.lastIndexOf(0x61, -b.length - 1), -1); +assert.strictEqual(b.lastIndexOf(0x61, NaN), 0); +assert.strictEqual(b.lastIndexOf(0x61, -Infinity), -1); +assert.strictEqual(b.lastIndexOf(0x61, Infinity), 0); +assert.strictEqual(b.lastIndexOf(0x0), -1); + +// Test weird offset arguments. +// The following offsets coerce to NaN, searching the whole Buffer +assert.strictEqual(b.lastIndexOf('b', undefined), 1); +assert.strictEqual(b.lastIndexOf('b', {}), 1); + +// The following offsets coerce to 0 +assert.strictEqual(b.lastIndexOf('b', 0), -1); +assert.strictEqual(b.lastIndexOf('b', null), -1); +assert.strictEqual(b.lastIndexOf('b', []), -1); + +// The following offset coerces to 2, in other words +[2] === 2 +assert.strictEqual(b.lastIndexOf('b', [2]), 1); + +// Behavior should match String.lastIndexOf() +assert.strictEqual( + b.lastIndexOf('b', undefined), + s.lastIndexOf('b', undefined)); +assert.strictEqual( + b.lastIndexOf('b', {}), + s.lastIndexOf('b', {})); +assert.strictEqual( + b.lastIndexOf('b', 0), + s.lastIndexOf('b', 0)); +assert.strictEqual( + b.lastIndexOf('b', null), + s.lastIndexOf('b', null)); +assert.strictEqual( + b.lastIndexOf('b', []), + s.lastIndexOf('b', [])); +assert.strictEqual( + b.lastIndexOf('b', [2]), + s.lastIndexOf('b', [2])); + +// Test needles longer than the haystack. +assert.strictEqual(b.lastIndexOf('aaaaaaaaaaaaaaa', 'ucs2'), -1); +assert.strictEqual(b.lastIndexOf('aaaaaaaaaaaaaaa', 'utf8'), -1); +assert.strictEqual(b.lastIndexOf('aaaaaaaaaaaaaaa', 'latin1'), -1); +assert.strictEqual(b.lastIndexOf('aaaaaaaaaaaaaaa', 'binary'), -1); +assert.strictEqual(b.lastIndexOf(Buffer.from('aaaaaaaaaaaaaaa')), -1); +assert.strictEqual(b.lastIndexOf('aaaaaaaaaaaaaaa', 2, 'ucs2'), -1); +assert.strictEqual(b.lastIndexOf('aaaaaaaaaaaaaaa', 3, 'utf8'), -1); +assert.strictEqual(b.lastIndexOf('aaaaaaaaaaaaaaa', 5, 'latin1'), -1); +assert.strictEqual(b.lastIndexOf('aaaaaaaaaaaaaaa', 5, 'binary'), -1); +assert.strictEqual(b.lastIndexOf(Buffer.from('aaaaaaaaaaaaaaa'), 7), -1); + +// 你好 expands to a total of 6 bytes using UTF-8 and 4 bytes using UTF-16 +assert.strictEqual(buf_bc.lastIndexOf('你好', 'ucs2'), -1); +assert.strictEqual(buf_bc.lastIndexOf('你好', 'utf8'), -1); +assert.strictEqual(buf_bc.lastIndexOf('你好', 'latin1'), -1); +assert.strictEqual(buf_bc.lastIndexOf('你好', 'binary'), -1); +assert.strictEqual(buf_bc.lastIndexOf(Buffer.from('你好')), -1); +assert.strictEqual(buf_bc.lastIndexOf('你好', 2, 'ucs2'), -1); +assert.strictEqual(buf_bc.lastIndexOf('你好', 3, 'utf8'), -1); +assert.strictEqual(buf_bc.lastIndexOf('你好', 5, 'latin1'), -1); +assert.strictEqual(buf_bc.lastIndexOf('你好', 5, 'binary'), -1); +assert.strictEqual(buf_bc.lastIndexOf(Buffer.from('你好'), 7), -1); + +// Test lastIndexOf on a longer buffer: +const bufferString = Buffer.from('a man a plan a canal panama'); +assert.strictEqual(bufferString.lastIndexOf('canal'), 15); +assert.strictEqual(bufferString.lastIndexOf('panama'), 21); +assert.strictEqual(bufferString.lastIndexOf('a man a plan a canal panama'), 0); +assert.strictEqual(-1, bufferString.lastIndexOf('a man a plan a canal mexico')); +assert.strictEqual(-1, bufferString + .lastIndexOf('a man a plan a canal mexico city')); +assert.strictEqual(-1, bufferString.lastIndexOf(Buffer.from('a'.repeat(1000)))); +assert.strictEqual(bufferString.lastIndexOf('a man a plan', 4), 0); +assert.strictEqual(bufferString.lastIndexOf('a '), 13); +assert.strictEqual(bufferString.lastIndexOf('a ', 13), 13); +assert.strictEqual(bufferString.lastIndexOf('a ', 12), 6); +assert.strictEqual(bufferString.lastIndexOf('a ', 5), 0); +assert.strictEqual(bufferString.lastIndexOf('a ', -1), 13); +assert.strictEqual(bufferString.lastIndexOf('a ', -27), 0); +assert.strictEqual(-1, bufferString.lastIndexOf('a ', -28)); + +// Test lastIndexOf for the case that the first character can be found, +// but in a part of the buffer that does not make search to search +// due do length constraints. +const abInUCS2 = Buffer.from('ab', 'ucs2'); +assert.strictEqual(-1, Buffer.from('µaaaa¶bbbb', 'latin1').lastIndexOf('µ')); +assert.strictEqual(-1, Buffer.from('µaaaa¶bbbb', 'binary').lastIndexOf('µ')); +assert.strictEqual(-1, Buffer.from('bc').lastIndexOf('ab')); +assert.strictEqual(-1, Buffer.from('abc').lastIndexOf('qa')); +assert.strictEqual(-1, Buffer.from('abcdef').lastIndexOf('qabc')); +assert.strictEqual(-1, Buffer.from('bc').lastIndexOf(Buffer.from('ab'))); +assert.strictEqual(-1, Buffer.from('bc', 'ucs2').lastIndexOf('ab', 'ucs2')); +assert.strictEqual(-1, Buffer.from('bc', 'ucs2').lastIndexOf(abInUCS2)); + +assert.strictEqual(Buffer.from('abc').lastIndexOf('ab'), 0); +assert.strictEqual(Buffer.from('abc').lastIndexOf('ab', 1), 0); +assert.strictEqual(Buffer.from('abc').lastIndexOf('ab', 2), 0); +assert.strictEqual(Buffer.from('abc').lastIndexOf('ab', 3), 0); + +// The above tests test the LINEAR and SINGLE-CHAR strategies. +// Now, we test the BOYER-MOORE-HORSPOOL strategy. +// Test lastIndexOf on a long buffer w multiple matches: +pattern = 'JABACABADABACABA'; +assert.strictEqual(longBufferString.lastIndexOf(pattern), 1535); +assert.strictEqual(longBufferString.lastIndexOf(pattern, 1535), 1535); +assert.strictEqual(longBufferString.lastIndexOf(pattern, 1534), 511); + +// Finally, give it a really long input to trigger fallback from BMH to +// regular BOYER-MOORE (which has better worst-case complexity). + +// Generate a really long Thue-Morse sequence of 'yolo' and 'swag', +// "yolo swag swag yolo swag yolo yolo swag" ..., goes on for about 5MB. +// This is hard to search because it all looks similar, but never repeats. + +// countBits returns the number of bits in the binary representation of n. +function countBits(n) { + let count; + for (count = 0; n > 0; count++) { + n = n & (n - 1); // remove top bit + } + return count; +} +const parts = []; +for (let i = 0; i < 1000000; i++) { + parts.push((countBits(i) % 2 === 0) ? 'yolo' : 'swag'); +} +const reallyLong = Buffer.from(parts.join(' ')); +assert.strictEqual(reallyLong.slice(0, 19).toString(), 'yolo swag swag yolo'); + +// Expensive reverse searches. Stress test lastIndexOf: +pattern = reallyLong.slice(0, 100000); // First 1/50th of the pattern. +assert.strictEqual(reallyLong.lastIndexOf(pattern), 4751360); +assert.strictEqual(reallyLong.lastIndexOf(pattern, 4000000), 3932160); +assert.strictEqual(reallyLong.lastIndexOf(pattern, 3000000), 2949120); +pattern = reallyLong.slice(100000, 200000); // Second 1/50th. +assert.strictEqual(reallyLong.lastIndexOf(pattern), 4728480); +pattern = reallyLong.slice(0, 1000000); // First 1/5th. +assert.strictEqual(reallyLong.lastIndexOf(pattern), 3932160); +pattern = reallyLong.slice(0, 2000000); // first 2/5ths. +assert.strictEqual(reallyLong.lastIndexOf(pattern), 0); + +// Test truncation of Number arguments to uint8 +// TODO(Soremwar) +// Enable once multi byte number search is available +// { +// const buf = Buffer.from('this is a test'); +// assert.strictEqual(buf.indexOf(0x6973), 3); +// assert.strictEqual(buf.indexOf(0x697320), 4); +// assert.strictEqual(buf.indexOf(0x69732069), 2); +// assert.strictEqual(buf.indexOf(0x697374657374), 0); +// assert.strictEqual(buf.indexOf(0x69737374), 0); +// assert.strictEqual(buf.indexOf(0x69737465), 11); +// assert.strictEqual(buf.indexOf(0x69737465), 11); +// assert.strictEqual(buf.indexOf(-140), 0); +// assert.strictEqual(buf.indexOf(-152), 1); +// assert.strictEqual(buf.indexOf(0xff), -1); +// assert.strictEqual(buf.indexOf(0xffff), -1); +// } + +// Test that Uint8Array arguments are okay. +{ + const needle = new Uint8Array([ 0x66, 0x6f, 0x6f ]); + const haystack = Buffer.from('a foo b foo'); + assert.strictEqual(haystack.indexOf(needle), 2); + assert.strictEqual(haystack.lastIndexOf(needle), haystack.length - 3); +} + +// Avoid abort because of invalid usage +// see https://github.com/nodejs/node/issues/32753 +{ + assert.throws(() => { + const buffer = require('buffer'); + new buffer.Buffer.prototype.lastIndexOf(1, 'str'); + }, { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "buffer" argument must be an instance of Buffer, ' + + 'TypedArray, or DataView. ' + + 'Received an instance of lastIndexOf' + }); +} diff --git a/tests/node_compat/test/parallel/test-buffer-inheritance.js b/tests/node_compat/test/parallel/test-buffer-inheritance.js new file mode 100644 index 000000000..6440a84cb --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-inheritance.js @@ -0,0 +1,46 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); + + +function T(n) { + const ui8 = new Uint8Array(n); + Object.setPrototypeOf(ui8, T.prototype); + return ui8; +} +Object.setPrototypeOf(T.prototype, Buffer.prototype); +Object.setPrototypeOf(T, Buffer); + +T.prototype.sum = function sum() { + let cntr = 0; + for (let i = 0; i < this.length; i++) + cntr += this[i]; + return cntr; +}; + + +const vals = [new T(4), T(4)]; + +vals.forEach(function(t) { + assert.strictEqual(t.constructor, T); + assert.strictEqual(Object.getPrototypeOf(t), T.prototype); + assert.strictEqual(Object.getPrototypeOf(Object.getPrototypeOf(t)), + Buffer.prototype); + + t.fill(5); + let cntr = 0; + for (let i = 0; i < t.length; i++) + cntr += t[i]; + assert.strictEqual(cntr, t.length * 5); + + // Check this does not throw + t.toString(); +}); diff --git a/tests/node_compat/test/parallel/test-buffer-isencoding.js b/tests/node_compat/test/parallel/test-buffer-isencoding.js new file mode 100644 index 000000000..439e6860a --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-isencoding.js @@ -0,0 +1,45 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); + +[ + 'hex', + 'utf8', + 'utf-8', + 'ascii', + 'latin1', + 'binary', + 'base64', + 'base64url', + 'ucs2', + 'ucs-2', + 'utf16le', + 'utf-16le', +].forEach((enc) => { + assert.strictEqual(Buffer.isEncoding(enc), true); +}); + +[ + 'utf9', + 'utf-7', + 'Unicode-FTW', + 'new gnu gun', + false, + NaN, + {}, + Infinity, + [], + 1, + 0, + -1, +].forEach((enc) => { + assert.strictEqual(Buffer.isEncoding(enc), false); +}); diff --git a/tests/node_compat/test/parallel/test-buffer-iterator.js b/tests/node_compat/test/parallel/test-buffer-iterator.js new file mode 100644 index 000000000..8ac97e259 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-iterator.js @@ -0,0 +1,69 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const assert = require('assert'); + +const buffer = Buffer.from([1, 2, 3, 4, 5]); +let arr; +let b; + +// Buffers should be iterable + +arr = []; + +for (b of buffer) + arr.push(b); + +assert.deepStrictEqual(arr, [1, 2, 3, 4, 5]); + + +// Buffer iterators should be iterable + +arr = []; + +for (b of buffer[Symbol.iterator]()) + arr.push(b); + +assert.deepStrictEqual(arr, [1, 2, 3, 4, 5]); + + +// buffer#values() should return iterator for values + +arr = []; + +for (b of buffer.values()) + arr.push(b); + +assert.deepStrictEqual(arr, [1, 2, 3, 4, 5]); + + +// buffer#keys() should return iterator for keys + +arr = []; + +for (b of buffer.keys()) + arr.push(b); + +assert.deepStrictEqual(arr, [0, 1, 2, 3, 4]); + + +// buffer#entries() should return iterator for entries + +arr = []; + +for (b of buffer.entries()) + arr.push(b); + +assert.deepStrictEqual(arr, [ + [0, 1], + [1, 2], + [2, 3], + [3, 4], + [4, 5], +]); diff --git a/tests/node_compat/test/parallel/test-buffer-new.js b/tests/node_compat/test/parallel/test-buffer-new.js new file mode 100644 index 000000000..d15138327 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-new.js @@ -0,0 +1,18 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); + +assert.throws(() => new Buffer(42, 'utf8'), { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "string" argument must be of type string. Received type ' + + 'number (42)' +}); diff --git a/tests/node_compat/test/parallel/test-buffer-no-negative-allocation.js b/tests/node_compat/test/parallel/test-buffer-no-negative-allocation.js new file mode 100644 index 000000000..df4a6cb52 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-no-negative-allocation.js @@ -0,0 +1,45 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); +const { SlowBuffer } = require('buffer'); + +const msg = { + code: 'ERR_INVALID_ARG_VALUE', + name: 'RangeError', + message: /^The argument 'size' is invalid\. Received [^"]*$/ +}; + +// Test that negative Buffer length inputs throw errors. + +assert.throws(() => Buffer(-Buffer.poolSize), msg); +assert.throws(() => Buffer(-100), msg); +assert.throws(() => Buffer(-1), msg); +assert.throws(() => Buffer(NaN), msg); + +assert.throws(() => Buffer.alloc(-Buffer.poolSize), msg); +assert.throws(() => Buffer.alloc(-100), msg); +assert.throws(() => Buffer.alloc(-1), msg); +assert.throws(() => Buffer.alloc(NaN), msg); + +assert.throws(() => Buffer.allocUnsafe(-Buffer.poolSize), msg); +assert.throws(() => Buffer.allocUnsafe(-100), msg); +assert.throws(() => Buffer.allocUnsafe(-1), msg); +assert.throws(() => Buffer.allocUnsafe(NaN), msg); + +assert.throws(() => Buffer.allocUnsafeSlow(-Buffer.poolSize), msg); +assert.throws(() => Buffer.allocUnsafeSlow(-100), msg); +assert.throws(() => Buffer.allocUnsafeSlow(-1), msg); +assert.throws(() => Buffer.allocUnsafeSlow(NaN), msg); + +assert.throws(() => SlowBuffer(-Buffer.poolSize), msg); +assert.throws(() => SlowBuffer(-100), msg); +assert.throws(() => SlowBuffer(-1), msg); +assert.throws(() => SlowBuffer(NaN), msg); diff --git a/tests/node_compat/test/parallel/test-buffer-nopendingdep-map.js b/tests/node_compat/test/parallel/test-buffer-nopendingdep-map.js new file mode 100644 index 000000000..a6320d0b0 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-nopendingdep-map.js @@ -0,0 +1,20 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Flags: --no-warnings --pending-deprecation +'use strict'; + +const common = require('../common'); + +process.on('warning', common.mustNotCall('A warning should not be emitted')); + +// With the --pending-deprecation flag, the deprecation warning for +// new Buffer() should not be emitted when Uint8Array methods are called. + +Buffer.from('abc').map((i) => i); +Buffer.from('abc').filter((i) => i); +Buffer.from('abc').slice(1, 2); diff --git a/tests/node_compat/test/parallel/test-buffer-of-no-deprecation.js b/tests/node_compat/test/parallel/test-buffer-of-no-deprecation.js new file mode 100644 index 000000000..b2b48d51d --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-of-no-deprecation.js @@ -0,0 +1,14 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); + +process.on('warning', common.mustNotCall()); + +Buffer.of(0, 1); diff --git a/tests/node_compat/test/parallel/test-buffer-over-max-length.js b/tests/node_compat/test/parallel/test-buffer-over-max-length.js new file mode 100644 index 000000000..c10c1e9d1 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-over-max-length.js @@ -0,0 +1,37 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); + +const assert = require('assert'); + +const buffer = require('buffer'); +const SlowBuffer = buffer.SlowBuffer; + +const kMaxLength = buffer.kMaxLength; +const bufferMaxSizeMsg = { + code: 'ERR_INVALID_ARG_VALUE', + name: 'RangeError', + message: /^The argument 'size' is invalid\. Received [^"]*$/ +}; + +assert.throws(() => Buffer((-1 >>> 0) + 2), bufferMaxSizeMsg); +assert.throws(() => SlowBuffer((-1 >>> 0) + 2), bufferMaxSizeMsg); +assert.throws(() => Buffer.alloc((-1 >>> 0) + 2), bufferMaxSizeMsg); +assert.throws(() => Buffer.allocUnsafe((-1 >>> 0) + 2), bufferMaxSizeMsg); +assert.throws(() => Buffer.allocUnsafeSlow((-1 >>> 0) + 2), bufferMaxSizeMsg); + +assert.throws(() => Buffer(kMaxLength + 1), bufferMaxSizeMsg); +assert.throws(() => SlowBuffer(kMaxLength + 1), bufferMaxSizeMsg); +assert.throws(() => Buffer.alloc(kMaxLength + 1), bufferMaxSizeMsg); +assert.throws(() => Buffer.allocUnsafe(kMaxLength + 1), bufferMaxSizeMsg); +assert.throws(() => Buffer.allocUnsafeSlow(kMaxLength + 1), bufferMaxSizeMsg); + +// issue GH-4331 +assert.throws(() => Buffer.allocUnsafe(0x100000001), bufferMaxSizeMsg); +assert.throws(() => Buffer.allocUnsafe(0xFFFFFFFFF), bufferMaxSizeMsg); diff --git a/tests/node_compat/test/parallel/test-buffer-parent-property.js b/tests/node_compat/test/parallel/test-buffer-parent-property.js new file mode 100644 index 000000000..6efc42d06 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-parent-property.js @@ -0,0 +1,28 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +// Fix for https://github.com/nodejs/node/issues/8266 +// +// Zero length Buffer objects should expose the `buffer` property of the +// TypedArrays, via the `parent` property. +require('../common'); +const assert = require('assert'); + +// If the length of the buffer object is zero +assert((new Buffer(0)).parent instanceof ArrayBuffer); + +// If the length of the buffer object is equal to the underlying ArrayBuffer +assert((new Buffer(Buffer.poolSize)).parent instanceof ArrayBuffer); + +// Same as the previous test, but with user created buffer +const arrayBuffer = new ArrayBuffer(0); +assert.strictEqual(new Buffer(arrayBuffer).parent, arrayBuffer); +assert.strictEqual(new Buffer(arrayBuffer).buffer, arrayBuffer); +assert.strictEqual(Buffer.from(arrayBuffer).parent, arrayBuffer); +assert.strictEqual(Buffer.from(arrayBuffer).buffer, arrayBuffer); diff --git a/tests/node_compat/test/parallel/test-buffer-read.js b/tests/node_compat/test/parallel/test-buffer-read.js new file mode 100644 index 000000000..391b309a8 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-read.js @@ -0,0 +1,113 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const assert = require('assert'); + +// Testing basic buffer read functions +const buf = Buffer.from([0xa4, 0xfd, 0x48, 0xea, 0xcf, 0xff, 0xd9, 0x01, 0xde]); + +function read(buff, funx, args, expected) { + assert.strictEqual(buff[funx](...args), expected); + assert.throws( + () => buff[funx](-1, args[1]), + { code: 'ERR_OUT_OF_RANGE' } + ); +} + +// Testing basic functionality of readDoubleBE() and readDoubleLE() +read(buf, 'readDoubleBE', [1], -3.1827727774563287e+295); +read(buf, 'readDoubleLE', [1], -6.966010051009108e+144); + +// Testing basic functionality of readFloatBE() and readFloatLE() +read(buf, 'readFloatBE', [1], -1.6691549692541768e+37); +read(buf, 'readFloatLE', [1], -7861303808); + +// Testing basic functionality of readInt8() +read(buf, 'readInt8', [1], -3); + +// Testing basic functionality of readInt16BE() and readInt16LE() +read(buf, 'readInt16BE', [1], -696); +read(buf, 'readInt16LE', [1], 0x48fd); + +// Testing basic functionality of readInt32BE() and readInt32LE() +read(buf, 'readInt32BE', [1], -45552945); +read(buf, 'readInt32LE', [1], -806729475); + +// Testing basic functionality of readIntBE() and readIntLE() +read(buf, 'readIntBE', [1, 1], -3); +read(buf, 'readIntLE', [2, 1], 0x48); + +// Testing basic functionality of readUInt8() +read(buf, 'readUInt8', [1], 0xfd); + +// Testing basic functionality of readUInt16BE() and readUInt16LE() +read(buf, 'readUInt16BE', [2], 0x48ea); +read(buf, 'readUInt16LE', [2], 0xea48); + +// Testing basic functionality of readUInt32BE() and readUInt32LE() +read(buf, 'readUInt32BE', [1], 0xfd48eacf); +read(buf, 'readUInt32LE', [1], 0xcfea48fd); + +// Testing basic functionality of readUIntBE() and readUIntLE() +read(buf, 'readUIntBE', [2, 2], 0x48ea); +read(buf, 'readUIntLE', [2, 2], 0xea48); + +// Error name and message +const OOR_ERROR = +{ + name: 'RangeError' +}; + +const OOB_ERROR = +{ + name: 'RangeError', + message: 'Attempt to access memory outside buffer bounds' +}; + +// Attempt to overflow buffers, similar to previous bug in array buffers +assert.throws( + () => Buffer.allocUnsafe(8).readFloatBE(0xffffffff), OOR_ERROR); + +assert.throws( + () => Buffer.allocUnsafe(8).readFloatLE(0xffffffff), OOR_ERROR); + +// Ensure negative values can't get past offset +assert.throws( + () => Buffer.allocUnsafe(8).readFloatBE(-1), OOR_ERROR); +assert.throws( + () => Buffer.allocUnsafe(8).readFloatLE(-1), OOR_ERROR); + +// Offset checks +{ + const buf = Buffer.allocUnsafe(0); + + assert.throws( + () => buf.readUInt8(0), OOB_ERROR); + assert.throws( + () => buf.readInt8(0), OOB_ERROR); +} + +[16, 32].forEach((bit) => { + const buf = Buffer.allocUnsafe(bit / 8 - 1); + [`Int${bit}B`, `Int${bit}L`, `UInt${bit}B`, `UInt${bit}L`].forEach((fn) => { + assert.throws( + () => buf[`read${fn}E`](0), OOB_ERROR); + }); +}); + +[16, 32].forEach((bits) => { + const buf = Buffer.from([0xFF, 0xFF, 0xFF, 0xFF]); + ['LE', 'BE'].forEach((endian) => { + assert.strictEqual(buf[`readUInt${bits}${endian}`](0), + (0xFFFFFFFF >>> (32 - bits))); + + assert.strictEqual(buf[`readInt${bits}${endian}`](0), + (0xFFFFFFFF >> (32 - bits))); + }); +}); diff --git a/tests/node_compat/test/parallel/test-buffer-readdouble.js b/tests/node_compat/test/parallel/test-buffer-readdouble.js new file mode 100644 index 000000000..f4ab9ba88 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-readdouble.js @@ -0,0 +1,151 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); + +// Test (64 bit) double +const buffer = Buffer.allocUnsafe(8); + +buffer[0] = 0x55; +buffer[1] = 0x55; +buffer[2] = 0x55; +buffer[3] = 0x55; +buffer[4] = 0x55; +buffer[5] = 0x55; +buffer[6] = 0xd5; +buffer[7] = 0x3f; +assert.strictEqual(buffer.readDoubleBE(0), 1.1945305291680097e+103); +assert.strictEqual(buffer.readDoubleLE(0), 0.3333333333333333); + +buffer[0] = 1; +buffer[1] = 0; +buffer[2] = 0; +buffer[3] = 0; +buffer[4] = 0; +buffer[5] = 0; +buffer[6] = 0xf0; +buffer[7] = 0x3f; +assert.strictEqual(buffer.readDoubleBE(0), 7.291122019655968e-304); +assert.strictEqual(buffer.readDoubleLE(0), 1.0000000000000002); + +buffer[0] = 2; +assert.strictEqual(buffer.readDoubleBE(0), 4.778309726801735e-299); +assert.strictEqual(buffer.readDoubleLE(0), 1.0000000000000004); + +buffer[0] = 1; +buffer[6] = 0; +buffer[7] = 0; +// eslint-disable-next-line no-loss-of-precision +assert.strictEqual(buffer.readDoubleBE(0), 7.291122019556398e-304); +assert.strictEqual(buffer.readDoubleLE(0), 5e-324); + +buffer[0] = 0xff; +buffer[1] = 0xff; +buffer[2] = 0xff; +buffer[3] = 0xff; +buffer[4] = 0xff; +buffer[5] = 0xff; +buffer[6] = 0x0f; +buffer[7] = 0x00; +assert.ok(Number.isNaN(buffer.readDoubleBE(0))); +assert.strictEqual(buffer.readDoubleLE(0), 2.225073858507201e-308); + +buffer[6] = 0xef; +buffer[7] = 0x7f; +assert.ok(Number.isNaN(buffer.readDoubleBE(0))); +assert.strictEqual(buffer.readDoubleLE(0), 1.7976931348623157e+308); + +buffer[0] = 0; +buffer[1] = 0; +buffer[2] = 0; +buffer[3] = 0; +buffer[4] = 0; +buffer[5] = 0; +buffer[6] = 0xf0; +buffer[7] = 0x3f; +assert.strictEqual(buffer.readDoubleBE(0), 3.03865e-319); +assert.strictEqual(buffer.readDoubleLE(0), 1); + +buffer[6] = 0; +buffer[7] = 0x40; +assert.strictEqual(buffer.readDoubleBE(0), 3.16e-322); +assert.strictEqual(buffer.readDoubleLE(0), 2); + +buffer[7] = 0xc0; +assert.strictEqual(buffer.readDoubleBE(0), 9.5e-322); +assert.strictEqual(buffer.readDoubleLE(0), -2); + +buffer[6] = 0x10; +buffer[7] = 0; +assert.strictEqual(buffer.readDoubleBE(0), 2.0237e-320); +assert.strictEqual(buffer.readDoubleLE(0), 2.2250738585072014e-308); + +buffer[6] = 0; +assert.strictEqual(buffer.readDoubleBE(0), 0); +assert.strictEqual(buffer.readDoubleLE(0), 0); +assert.ok(1 / buffer.readDoubleLE(0) >= 0); + +buffer[7] = 0x80; +assert.strictEqual(buffer.readDoubleBE(0), 6.3e-322); +assert.strictEqual(buffer.readDoubleLE(0), -0); +assert.ok(1 / buffer.readDoubleLE(0) < 0); + +buffer[6] = 0xf0; +buffer[7] = 0x7f; +assert.strictEqual(buffer.readDoubleBE(0), 3.0418e-319); +assert.strictEqual(buffer.readDoubleLE(0), Infinity); + +buffer[7] = 0xff; +assert.strictEqual(buffer.readDoubleBE(0), 3.04814e-319); +assert.strictEqual(buffer.readDoubleLE(0), -Infinity); + +['readDoubleLE', 'readDoubleBE'].forEach((fn) => { + + // Verify that default offset works fine. + buffer[fn](undefined); + buffer[fn](); + + ['', '0', null, {}, [], () => {}, true, false].forEach((off) => { + assert.throws( + () => buffer[fn](off), + { code: 'ERR_INVALID_ARG_TYPE' } + ); + }); + + [Infinity, -1, 1].forEach((offset) => { + assert.throws( + () => buffer[fn](offset), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "offset" is out of range. ' + + `It must be >= 0 and <= 0. Received ${offset}` + }); + }); + + assert.throws( + () => Buffer.alloc(1)[fn](1), + { + code: 'ERR_BUFFER_OUT_OF_BOUNDS', + name: 'RangeError', + message: 'Attempt to access memory outside buffer bounds' + }); + + [NaN, 1.01].forEach((offset) => { + assert.throws( + () => buffer[fn](offset), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "offset" is out of range. ' + + `It must be an integer. Received ${offset}` + }); + }); +}); diff --git a/tests/node_compat/test/parallel/test-buffer-readfloat.js b/tests/node_compat/test/parallel/test-buffer-readfloat.js new file mode 100644 index 000000000..780d3a6ac --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-readfloat.js @@ -0,0 +1,113 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); + +// Test 32 bit float +const buffer = Buffer.alloc(4); + +buffer[0] = 0; +buffer[1] = 0; +buffer[2] = 0x80; +buffer[3] = 0x3f; +assert.strictEqual(buffer.readFloatBE(0), 4.600602988224807e-41); +assert.strictEqual(buffer.readFloatLE(0), 1); + +buffer[0] = 0; +buffer[1] = 0; +buffer[2] = 0; +buffer[3] = 0xc0; +assert.strictEqual(buffer.readFloatBE(0), 2.6904930515036488e-43); +assert.strictEqual(buffer.readFloatLE(0), -2); + +buffer[0] = 0xff; +buffer[1] = 0xff; +buffer[2] = 0x7f; +buffer[3] = 0x7f; +assert.ok(Number.isNaN(buffer.readFloatBE(0))); +assert.strictEqual(buffer.readFloatLE(0), 3.4028234663852886e+38); + +buffer[0] = 0xab; +buffer[1] = 0xaa; +buffer[2] = 0xaa; +buffer[3] = 0x3e; +assert.strictEqual(buffer.readFloatBE(0), -1.2126478207002966e-12); +assert.strictEqual(buffer.readFloatLE(0), 0.3333333432674408); + +buffer[0] = 0; +buffer[1] = 0; +buffer[2] = 0; +buffer[3] = 0; +assert.strictEqual(buffer.readFloatBE(0), 0); +assert.strictEqual(buffer.readFloatLE(0), 0); +assert.ok(1 / buffer.readFloatLE(0) >= 0); + +buffer[3] = 0x80; +assert.strictEqual(buffer.readFloatBE(0), 1.793662034335766e-43); +assert.strictEqual(buffer.readFloatLE(0), -0); +assert.ok(1 / buffer.readFloatLE(0) < 0); + +buffer[0] = 0; +buffer[1] = 0; +buffer[2] = 0x80; +buffer[3] = 0x7f; +assert.strictEqual(buffer.readFloatBE(0), 4.609571298396486e-41); +assert.strictEqual(buffer.readFloatLE(0), Infinity); + +buffer[0] = 0; +buffer[1] = 0; +buffer[2] = 0x80; +buffer[3] = 0xff; +assert.strictEqual(buffer.readFloatBE(0), 4.627507918739843e-41); +assert.strictEqual(buffer.readFloatLE(0), -Infinity); + +['readFloatLE', 'readFloatBE'].forEach((fn) => { + + // Verify that default offset works fine. + buffer[fn](undefined); + buffer[fn](); + + ['', '0', null, {}, [], () => {}, true, false].forEach((off) => { + assert.throws( + () => buffer[fn](off), + { code: 'ERR_INVALID_ARG_TYPE' } + ); + }); + + [Infinity, -1, 1].forEach((offset) => { + assert.throws( + () => buffer[fn](offset), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "offset" is out of range. ' + + `It must be >= 0 and <= 0. Received ${offset}` + }); + }); + + assert.throws( + () => Buffer.alloc(1)[fn](1), + { + code: 'ERR_BUFFER_OUT_OF_BOUNDS', + name: 'RangeError', + message: 'Attempt to access memory outside buffer bounds' + }); + + [NaN, 1.01].forEach((offset) => { + assert.throws( + () => buffer[fn](offset), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "offset" is out of range. ' + + `It must be an integer. Received ${offset}` + }); + }); +}); diff --git a/tests/node_compat/test/parallel/test-buffer-readint.js b/tests/node_compat/test/parallel/test-buffer-readint.js new file mode 100644 index 000000000..0c865eb92 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-readint.js @@ -0,0 +1,204 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); + +// Test OOB +{ + const buffer = Buffer.alloc(4); + + ['Int8', 'Int16BE', 'Int16LE', 'Int32BE', 'Int32LE'].forEach((fn) => { + + // Verify that default offset works fine. + buffer[`read${fn}`](undefined); + buffer[`read${fn}`](); + + ['', '0', null, {}, [], () => {}, true, false].forEach((o) => { + assert.throws( + () => buffer[`read${fn}`](o), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + }); + }); + + [Infinity, -1, -4294967295].forEach((offset) => { + assert.throws( + () => buffer[`read${fn}`](offset), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError' + }); + }); + + [NaN, 1.01].forEach((offset) => { + assert.throws( + () => buffer[`read${fn}`](offset), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "offset" is out of range. ' + + `It must be an integer. Received ${offset}` + }); + }); + }); +} + +// Test 8 bit signed integers +{ + const data = Buffer.from([0x23, 0xab, 0x7c, 0xef]); + + assert.strictEqual(data.readInt8(0), 0x23); + + data[0] = 0xff; + assert.strictEqual(data.readInt8(0), -1); + + data[0] = 0x87; + assert.strictEqual(data.readInt8(0), -121); + assert.strictEqual(data.readInt8(1), -85); + assert.strictEqual(data.readInt8(2), 124); + assert.strictEqual(data.readInt8(3), -17); +} + +// Test 16 bit integers +{ + const buffer = Buffer.from([0x16, 0x79, 0x65, 0x6e, 0x69, 0x78]); + + assert.strictEqual(buffer.readInt16BE(0), 0x1679); + assert.strictEqual(buffer.readInt16LE(0), 0x7916); + + buffer[0] = 0xff; + buffer[1] = 0x80; + assert.strictEqual(buffer.readInt16BE(0), -128); + assert.strictEqual(buffer.readInt16LE(0), -32513); + + buffer[0] = 0x77; + buffer[1] = 0x65; + assert.strictEqual(buffer.readInt16BE(0), 0x7765); + assert.strictEqual(buffer.readInt16BE(1), 0x6565); + assert.strictEqual(buffer.readInt16BE(2), 0x656e); + assert.strictEqual(buffer.readInt16BE(3), 0x6e69); + assert.strictEqual(buffer.readInt16BE(4), 0x6978); + assert.strictEqual(buffer.readInt16LE(0), 0x6577); + assert.strictEqual(buffer.readInt16LE(1), 0x6565); + assert.strictEqual(buffer.readInt16LE(2), 0x6e65); + assert.strictEqual(buffer.readInt16LE(3), 0x696e); + assert.strictEqual(buffer.readInt16LE(4), 0x7869); +} + +// Test 32 bit integers +{ + const buffer = Buffer.from([0x43, 0x53, 0x16, 0x79, 0x36, 0x17]); + + assert.strictEqual(buffer.readInt32BE(0), 0x43531679); + assert.strictEqual(buffer.readInt32LE(0), 0x79165343); + + buffer[0] = 0xff; + buffer[1] = 0xfe; + buffer[2] = 0xef; + buffer[3] = 0xfa; + assert.strictEqual(buffer.readInt32BE(0), -69638); + assert.strictEqual(buffer.readInt32LE(0), -84934913); + + buffer[0] = 0x42; + buffer[1] = 0xc3; + buffer[2] = 0x95; + buffer[3] = 0xa9; + assert.strictEqual(buffer.readInt32BE(0), 0x42c395a9); + assert.strictEqual(buffer.readInt32BE(1), -1013601994); + assert.strictEqual(buffer.readInt32BE(2), -1784072681); + assert.strictEqual(buffer.readInt32LE(0), -1449802942); + assert.strictEqual(buffer.readInt32LE(1), 917083587); + assert.strictEqual(buffer.readInt32LE(2), 389458325); +} + +// Test Int +{ + const buffer = Buffer.from([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]); + + assert.strictEqual(buffer.readIntLE(0, 1), 0x01); + assert.strictEqual(buffer.readIntBE(0, 1), 0x01); + assert.strictEqual(buffer.readIntLE(0, 3), 0x030201); + assert.strictEqual(buffer.readIntBE(0, 3), 0x010203); + assert.strictEqual(buffer.readIntLE(0, 5), 0x0504030201); + assert.strictEqual(buffer.readIntBE(0, 5), 0x0102030405); + assert.strictEqual(buffer.readIntLE(0, 6), 0x060504030201); + assert.strictEqual(buffer.readIntBE(0, 6), 0x010203040506); + assert.strictEqual(buffer.readIntLE(1, 6), 0x070605040302); + assert.strictEqual(buffer.readIntBE(1, 6), 0x020304050607); + assert.strictEqual(buffer.readIntLE(2, 6), 0x080706050403); + assert.strictEqual(buffer.readIntBE(2, 6), 0x030405060708); + + // Check byteLength. + ['readIntBE', 'readIntLE'].forEach((fn) => { + ['', '0', null, {}, [], () => {}, true, false, undefined].forEach((len) => { + assert.throws( + () => buffer[fn](0, len), + { code: 'ERR_INVALID_ARG_TYPE' }); + }); + + [Infinity, -1].forEach((byteLength) => { + assert.throws( + () => buffer[fn](0, byteLength), + { + code: 'ERR_OUT_OF_RANGE', + message: 'The value of "byteLength" is out of range. ' + + `It must be >= 1 and <= 6. Received ${byteLength}` + }); + }); + + [NaN, 1.01].forEach((byteLength) => { + assert.throws( + () => buffer[fn](0, byteLength), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "byteLength" is out of range. ' + + `It must be an integer. Received ${byteLength}` + }); + }); + }); + + // Test 1 to 6 bytes. + for (let i = 1; i <= 6; i++) { + ['readIntBE', 'readIntLE'].forEach((fn) => { + ['', '0', null, {}, [], () => {}, true, false, undefined].forEach((o) => { + assert.throws( + () => buffer[fn](o, i), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + }); + }); + + [Infinity, -1, -4294967295].forEach((offset) => { + assert.throws( + () => buffer[fn](offset, i), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "offset" is out of range. ' + + `It must be >= 0 and <= ${8 - i}. Received ${offset}` + }); + }); + + [NaN, 1.01].forEach((offset) => { + assert.throws( + () => buffer[fn](offset, i), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "offset" is out of range. ' + + `It must be an integer. Received ${offset}` + }); + }); + }); + } +} diff --git a/tests/node_compat/test/parallel/test-buffer-readuint.js b/tests/node_compat/test/parallel/test-buffer-readuint.js new file mode 100644 index 000000000..bbef6f49a --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-readuint.js @@ -0,0 +1,172 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); + +// Test OOB +{ + const buffer = Buffer.alloc(4); + + ['UInt8', 'UInt16BE', 'UInt16LE', 'UInt32BE', 'UInt32LE'].forEach((fn) => { + + // Verify that default offset works fine. + buffer[`read${fn}`](undefined); + buffer[`read${fn}`](); + + ['', '0', null, {}, [], () => {}, true, false].forEach((o) => { + assert.throws( + () => buffer[`read${fn}`](o), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + }); + }); + + [Infinity, -1, -4294967295].forEach((offset) => { + assert.throws( + () => buffer[`read${fn}`](offset), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError' + }); + }); + + [NaN, 1.01].forEach((offset) => { + assert.throws( + () => buffer[`read${fn}`](offset), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "offset" is out of range. ' + + `It must be an integer. Received ${offset}` + }); + }); + }); +} + +// Test 8 bit unsigned integers +{ + const data = Buffer.from([0xff, 0x2a, 0x2a, 0x2a]); + assert.strictEqual(data.readUInt8(0), 255); + assert.strictEqual(data.readUInt8(1), 42); + assert.strictEqual(data.readUInt8(2), 42); + assert.strictEqual(data.readUInt8(3), 42); +} + +// Test 16 bit unsigned integers +{ + const data = Buffer.from([0x00, 0x2a, 0x42, 0x3f]); + assert.strictEqual(data.readUInt16BE(0), 0x2a); + assert.strictEqual(data.readUInt16BE(1), 0x2a42); + assert.strictEqual(data.readUInt16BE(2), 0x423f); + assert.strictEqual(data.readUInt16LE(0), 0x2a00); + assert.strictEqual(data.readUInt16LE(1), 0x422a); + assert.strictEqual(data.readUInt16LE(2), 0x3f42); + + data[0] = 0xfe; + data[1] = 0xfe; + assert.strictEqual(data.readUInt16BE(0), 0xfefe); + assert.strictEqual(data.readUInt16LE(0), 0xfefe); +} + +// Test 32 bit unsigned integers +{ + const data = Buffer.from([0x32, 0x65, 0x42, 0x56, 0x23, 0xff]); + assert.strictEqual(data.readUInt32BE(0), 0x32654256); + assert.strictEqual(data.readUInt32BE(1), 0x65425623); + assert.strictEqual(data.readUInt32BE(2), 0x425623ff); + assert.strictEqual(data.readUInt32LE(0), 0x56426532); + assert.strictEqual(data.readUInt32LE(1), 0x23564265); + assert.strictEqual(data.readUInt32LE(2), 0xff235642); +} + +// Test UInt +{ + const buffer = Buffer.from([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]); + + assert.strictEqual(buffer.readUIntLE(0, 1), 0x01); + assert.strictEqual(buffer.readUIntBE(0, 1), 0x01); + assert.strictEqual(buffer.readUIntLE(0, 3), 0x030201); + assert.strictEqual(buffer.readUIntBE(0, 3), 0x010203); + assert.strictEqual(buffer.readUIntLE(0, 5), 0x0504030201); + assert.strictEqual(buffer.readUIntBE(0, 5), 0x0102030405); + assert.strictEqual(buffer.readUIntLE(0, 6), 0x060504030201); + assert.strictEqual(buffer.readUIntBE(0, 6), 0x010203040506); + assert.strictEqual(buffer.readUIntLE(1, 6), 0x070605040302); + assert.strictEqual(buffer.readUIntBE(1, 6), 0x020304050607); + assert.strictEqual(buffer.readUIntLE(2, 6), 0x080706050403); + assert.strictEqual(buffer.readUIntBE(2, 6), 0x030405060708); + + // Check byteLength. + ['readUIntBE', 'readUIntLE'].forEach((fn) => { + ['', '0', null, {}, [], () => {}, true, false, undefined].forEach((len) => { + assert.throws( + () => buffer[fn](0, len), + { code: 'ERR_INVALID_ARG_TYPE' }); + }); + + [Infinity, -1].forEach((byteLength) => { + assert.throws( + () => buffer[fn](0, byteLength), + { + code: 'ERR_OUT_OF_RANGE', + message: 'The value of "byteLength" is out of range. ' + + `It must be >= 1 and <= 6. Received ${byteLength}` + }); + }); + + [NaN, 1.01].forEach((byteLength) => { + assert.throws( + () => buffer[fn](0, byteLength), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "byteLength" is out of range. ' + + `It must be an integer. Received ${byteLength}` + }); + }); + }); + + // Test 1 to 6 bytes. + for (let i = 1; i <= 6; i++) { + ['readUIntBE', 'readUIntLE'].forEach((fn) => { + ['', '0', null, {}, [], () => {}, true, false, undefined].forEach((o) => { + assert.throws( + () => buffer[fn](o, i), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + }); + }); + + [Infinity, -1, -4294967295].forEach((offset) => { + assert.throws( + () => buffer[fn](offset, i), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "offset" is out of range. ' + + `It must be >= 0 and <= ${8 - i}. Received ${offset}` + }); + }); + + [NaN, 1.01].forEach((offset) => { + assert.throws( + () => buffer[fn](offset, i), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "offset" is out of range. ' + + `It must be an integer. Received ${offset}` + }); + }); + }); + } +} diff --git a/tests/node_compat/test/parallel/test-buffer-safe-unsafe.js b/tests/node_compat/test/parallel/test-buffer-safe-unsafe.js new file mode 100644 index 000000000..180af8993 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-safe-unsafe.js @@ -0,0 +1,31 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); + +const safe = Buffer.alloc(10); + +function isZeroFilled(buf) { + for (let n = 0; n < buf.length; n++) + if (buf[n] !== 0) return false; + return true; +} + +assert(isZeroFilled(safe)); + +// Test that unsafe allocations doesn't affect subsequent safe allocations +Buffer.allocUnsafe(10); +assert(isZeroFilled(new Float64Array(10))); + +new Buffer(10); +assert(isZeroFilled(new Float64Array(10))); + +Buffer.allocUnsafe(10); +assert(isZeroFilled(Buffer.alloc(10))); diff --git a/tests/node_compat/test/parallel/test-buffer-slice.js b/tests/node_compat/test/parallel/test-buffer-slice.js new file mode 100644 index 000000000..518618d8d --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-slice.js @@ -0,0 +1,136 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; + +require('../common'); +const assert = require('assert'); + +assert.strictEqual(Buffer.from('hello', 'utf8').slice(0, 0).length, 0); +assert.strictEqual(Buffer('hello', 'utf8').slice(0, 0).length, 0); + +const buf = Buffer.from('0123456789', 'utf8'); +const expectedSameBufs = [ + [buf.slice(-10, 10), Buffer.from('0123456789', 'utf8')], + [buf.slice(-20, 10), Buffer.from('0123456789', 'utf8')], + [buf.slice(-20, -10), Buffer.from('', 'utf8')], + [buf.slice(), Buffer.from('0123456789', 'utf8')], + [buf.slice(0), Buffer.from('0123456789', 'utf8')], + [buf.slice(0, 0), Buffer.from('', 'utf8')], + [buf.slice(undefined), Buffer.from('0123456789', 'utf8')], + [buf.slice('foobar'), Buffer.from('0123456789', 'utf8')], + [buf.slice(undefined, undefined), Buffer.from('0123456789', 'utf8')], + [buf.slice(2), Buffer.from('23456789', 'utf8')], + [buf.slice(5), Buffer.from('56789', 'utf8')], + [buf.slice(10), Buffer.from('', 'utf8')], + [buf.slice(5, 8), Buffer.from('567', 'utf8')], + [buf.slice(8, -1), Buffer.from('8', 'utf8')], + [buf.slice(-10), Buffer.from('0123456789', 'utf8')], + [buf.slice(0, -9), Buffer.from('0', 'utf8')], + [buf.slice(0, -10), Buffer.from('', 'utf8')], + [buf.slice(0, -1), Buffer.from('012345678', 'utf8')], + [buf.slice(2, -2), Buffer.from('234567', 'utf8')], + [buf.slice(0, 65536), Buffer.from('0123456789', 'utf8')], + [buf.slice(65536, 0), Buffer.from('', 'utf8')], + [buf.slice(-5, -8), Buffer.from('', 'utf8')], + [buf.slice(-5, -3), Buffer.from('56', 'utf8')], + [buf.slice(-10, 10), Buffer.from('0123456789', 'utf8')], + [buf.slice('0', '1'), Buffer.from('0', 'utf8')], + [buf.slice('-5', '10'), Buffer.from('56789', 'utf8')], + [buf.slice('-10', '10'), Buffer.from('0123456789', 'utf8')], + [buf.slice('-10', '-5'), Buffer.from('01234', 'utf8')], + [buf.slice('-10', '-0'), Buffer.from('', 'utf8')], + [buf.slice('111'), Buffer.from('', 'utf8')], + [buf.slice('0', '-111'), Buffer.from('', 'utf8')], +]; + +for (let i = 0, s = buf.toString(); i < buf.length; ++i) { + expectedSameBufs.push( + [buf.slice(i), Buffer.from(s.slice(i))], + [buf.slice(0, i), Buffer.from(s.slice(0, i))], + [buf.slice(-i), Buffer.from(s.slice(-i))], + [buf.slice(0, -i), Buffer.from(s.slice(0, -i))] + ); +} + +expectedSameBufs.forEach(([buf1, buf2]) => { + assert.strictEqual(Buffer.compare(buf1, buf2), 0); +}); + +const utf16Buf = Buffer.from('0123456789', 'utf16le'); +assert.deepStrictEqual(utf16Buf.slice(0, 6), Buffer.from('012', 'utf16le')); +// Try to slice a zero length Buffer. +// See https://github.com/joyent/node/issues/5881 +assert.strictEqual(Buffer.alloc(0).slice(0, 1).length, 0); + +{ + // Single argument slice + assert.strictEqual(Buffer.from('abcde', 'utf8').slice(1).toString('utf8'), + 'bcde'); +} + +// slice(0,0).length === 0 +assert.strictEqual(Buffer.from('hello', 'utf8').slice(0, 0).length, 0); + +{ + // Regression tests for https://github.com/nodejs/node/issues/9096 + const buf = Buffer.from('abcd', 'utf8'); + assert.strictEqual(buf.slice(buf.length / 3).toString('utf8'), 'bcd'); + assert.strictEqual( + buf.slice(buf.length / 3, buf.length).toString(), + 'bcd' + ); +} + +{ + const buf = Buffer.from('abcdefg', 'utf8'); + assert.strictEqual(buf.slice(-(-1 >>> 0) - 1).toString('utf8'), + buf.toString('utf8')); +} + +{ + const buf = Buffer.from('abc', 'utf8'); + assert.strictEqual(buf.slice(-0.5).toString('utf8'), buf.toString('utf8')); +} + +{ + const buf = Buffer.from([ + 1, 29, 0, 0, 1, 143, 216, 162, 92, 254, 248, 63, 0, + 0, 0, 18, 184, 6, 0, 175, 29, 0, 8, 11, 1, 0, 0, + ]); + const chunk1 = Buffer.from([ + 1, 29, 0, 0, 1, 143, 216, 162, 92, 254, 248, 63, 0, + ]); + const chunk2 = Buffer.from([ + 0, 0, 18, 184, 6, 0, 175, 29, 0, 8, 11, 1, 0, 0, + ]); + const middle = buf.length / 2; + + assert.deepStrictEqual(buf.slice(0, middle), chunk1); + assert.deepStrictEqual(buf.slice(middle), chunk2); +} diff --git a/tests/node_compat/test/parallel/test-buffer-slow.js b/tests/node_compat/test/parallel/test-buffer-slow.js new file mode 100644 index 000000000..eed2898c5 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-slow.js @@ -0,0 +1,69 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); +const buffer = require('buffer'); +const SlowBuffer = buffer.SlowBuffer; + +const ones = [1, 1, 1, 1]; + +// Should create a Buffer +let sb = SlowBuffer(4); +assert(sb instanceof Buffer); +assert.strictEqual(sb.length, 4); +sb.fill(1); +for (const [key, value] of sb.entries()) { + assert.deepStrictEqual(value, ones[key]); +} + +// underlying ArrayBuffer should have the same length +assert.strictEqual(sb.buffer.byteLength, 4); + +// Should work without new +sb = SlowBuffer(4); +assert(sb instanceof Buffer); +assert.strictEqual(sb.length, 4); +sb.fill(1); +for (const [key, value] of sb.entries()) { + assert.deepStrictEqual(value, ones[key]); +} + +// Should work with edge cases +assert.strictEqual(SlowBuffer(0).length, 0); +try { + assert.strictEqual( + SlowBuffer(buffer.kMaxLength).length, buffer.kMaxLength); +} catch (e) { + // Don't match on message as it is from the JavaScript engine. V8 and + // ChakraCore provide different messages. + assert.strictEqual(e.name, 'RangeError'); +} + +// Should throw with invalid length type +const bufferInvalidTypeMsg = { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: /^The "size" argument must be of type number/, +}; +assert.throws(() => SlowBuffer(), bufferInvalidTypeMsg); +assert.throws(() => SlowBuffer({}), bufferInvalidTypeMsg); +assert.throws(() => SlowBuffer('6'), bufferInvalidTypeMsg); +assert.throws(() => SlowBuffer(true), bufferInvalidTypeMsg); + +// Should throw with invalid length value +const bufferMaxSizeMsg = { + code: 'ERR_INVALID_ARG_VALUE', + name: 'RangeError', + message: /^The argument 'size' is invalid\. Received [^"]*$/ +}; +assert.throws(() => SlowBuffer(NaN), bufferMaxSizeMsg); +assert.throws(() => SlowBuffer(Infinity), bufferMaxSizeMsg); +assert.throws(() => SlowBuffer(-1), bufferMaxSizeMsg); +assert.throws(() => SlowBuffer(buffer.kMaxLength + 1), bufferMaxSizeMsg); diff --git a/tests/node_compat/test/parallel/test-buffer-swap.js b/tests/node_compat/test/parallel/test-buffer-swap.js new file mode 100644 index 000000000..8e1315601 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-swap.js @@ -0,0 +1,159 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); + +// Test buffers small enough to use the JS implementation +{ + const buf = Buffer.from([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10]); + + assert.strictEqual(buf, buf.swap16()); + assert.deepStrictEqual(buf, Buffer.from([0x02, 0x01, 0x04, 0x03, 0x06, 0x05, + 0x08, 0x07, 0x0a, 0x09, 0x0c, 0x0b, + 0x0e, 0x0d, 0x10, 0x0f])); + buf.swap16(); // restore + + assert.strictEqual(buf, buf.swap32()); + assert.deepStrictEqual(buf, Buffer.from([0x04, 0x03, 0x02, 0x01, 0x08, 0x07, + 0x06, 0x05, 0x0c, 0x0b, 0x0a, 0x09, + 0x10, 0x0f, 0x0e, 0x0d])); + buf.swap32(); // restore + + assert.strictEqual(buf, buf.swap64()); + assert.deepStrictEqual(buf, Buffer.from([0x08, 0x07, 0x06, 0x05, 0x04, 0x03, + 0x02, 0x01, 0x10, 0x0f, 0x0e, 0x0d, + 0x0c, 0x0b, 0x0a, 0x09])); +} + +// Operates in-place +{ + const buf = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7]); + buf.slice(1, 5).swap32(); + assert.deepStrictEqual(buf, Buffer.from([0x1, 0x5, 0x4, 0x3, 0x2, 0x6, 0x7])); + buf.slice(1, 5).swap16(); + assert.deepStrictEqual(buf, Buffer.from([0x1, 0x4, 0x5, 0x2, 0x3, 0x6, 0x7])); + + // Length assertions + const re16 = /Buffer size must be a multiple of 16-bits/; + const re32 = /Buffer size must be a multiple of 32-bits/; + const re64 = /Buffer size must be a multiple of 64-bits/; + + assert.throws(() => Buffer.from(buf).swap16(), re16); + assert.throws(() => Buffer.alloc(1025).swap16(), re16); + assert.throws(() => Buffer.from(buf).swap32(), re32); + assert.throws(() => buf.slice(1, 3).swap32(), re32); + assert.throws(() => Buffer.alloc(1025).swap32(), re32); + assert.throws(() => buf.slice(1, 3).swap64(), re64); + assert.throws(() => Buffer.alloc(1025).swap64(), re64); +} + +{ + const buf = Buffer.from([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10]); + + buf.slice(2, 18).swap64(); + + assert.deepStrictEqual(buf, Buffer.from([0x01, 0x02, 0x0a, 0x09, 0x08, 0x07, + 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, + 0x10, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, + 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10])); +} + +// Force use of native code (Buffer size above threshold limit for js impl) +{ + const bufData = new Uint32Array(256).fill(0x04030201); + const buf = Buffer.from(bufData.buffer, bufData.byteOffset); + const otherBufData = new Uint32Array(256).fill(0x03040102); + const otherBuf = Buffer.from(otherBufData.buffer, otherBufData.byteOffset); + buf.swap16(); + assert.deepStrictEqual(buf, otherBuf); +} + +{ + const bufData = new Uint32Array(256).fill(0x04030201); + const buf = Buffer.from(bufData.buffer); + const otherBufData = new Uint32Array(256).fill(0x01020304); + const otherBuf = Buffer.from(otherBufData.buffer, otherBufData.byteOffset); + buf.swap32(); + assert.deepStrictEqual(buf, otherBuf); +} + +{ + const bufData = new Uint8Array(256 * 8); + const otherBufData = new Uint8Array(256 * 8); + for (let i = 0; i < bufData.length; i++) { + bufData[i] = i % 8; + otherBufData[otherBufData.length - i - 1] = i % 8; + } + const buf = Buffer.from(bufData.buffer, bufData.byteOffset); + const otherBuf = Buffer.from(otherBufData.buffer, otherBufData.byteOffset); + buf.swap64(); + assert.deepStrictEqual(buf, otherBuf); +} + +// Test native code with buffers that are not memory-aligned +{ + const bufData = new Uint8Array(256 * 8); + const otherBufData = new Uint8Array(256 * 8 - 2); + for (let i = 0; i < bufData.length; i++) { + bufData[i] = i % 2; + } + for (let i = 1; i < otherBufData.length; i++) { + otherBufData[otherBufData.length - i] = (i + 1) % 2; + } + const buf = Buffer.from(bufData.buffer, bufData.byteOffset); + // 0|1 0|1 0|1... + const otherBuf = Buffer.from(otherBufData.buffer, otherBufData.byteOffset); + // 0|0 1|0 1|0... + + buf.slice(1, buf.length - 1).swap16(); + assert.deepStrictEqual(buf.slice(0, otherBuf.length), otherBuf); +} + +{ + const bufData = new Uint8Array(256 * 8); + const otherBufData = new Uint8Array(256 * 8 - 4); + for (let i = 0; i < bufData.length; i++) { + bufData[i] = i % 4; + } + for (let i = 1; i < otherBufData.length; i++) { + otherBufData[otherBufData.length - i] = (i + 1) % 4; + } + const buf = Buffer.from(bufData.buffer, bufData.byteOffset); + // 0|1 2 3 0|1 2 3... + const otherBuf = Buffer.from(otherBufData.buffer, otherBufData.byteOffset); + // 0|0 3 2 1|0 3 2... + + buf.slice(1, buf.length - 3).swap32(); + assert.deepStrictEqual(buf.slice(0, otherBuf.length), otherBuf); +} + +{ + const bufData = new Uint8Array(256 * 8); + const otherBufData = new Uint8Array(256 * 8 - 8); + for (let i = 0; i < bufData.length; i++) { + bufData[i] = i % 8; + } + for (let i = 1; i < otherBufData.length; i++) { + otherBufData[otherBufData.length - i] = (i + 1) % 8; + } + const buf = Buffer.from(bufData.buffer, bufData.byteOffset); + // 0|1 2 3 4 5 6 7 0|1 2 3 4... + const otherBuf = Buffer.from(otherBufData.buffer, otherBufData.byteOffset); + // 0|0 7 6 5 4 3 2 1|0 7 6 5... + + buf.slice(1, buf.length - 7).swap64(); + assert.deepStrictEqual(buf.slice(0, otherBuf.length), otherBuf); +} diff --git a/tests/node_compat/test/parallel/test-buffer-tojson.js b/tests/node_compat/test/parallel/test-buffer-tojson.js new file mode 100644 index 000000000..d21786c37 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-tojson.js @@ -0,0 +1,42 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); + +{ + assert.strictEqual(JSON.stringify(Buffer.alloc(0)), + '{"type":"Buffer","data":[]}'); + assert.strictEqual(JSON.stringify(Buffer.from([1, 2, 3, 4])), + '{"type":"Buffer","data":[1,2,3,4]}'); +} + +// issue GH-7849 +{ + const buf = Buffer.from('test'); + const json = JSON.stringify(buf); + const obj = JSON.parse(json); + const copy = Buffer.from(obj); + + assert.deepStrictEqual(buf, copy); +} + +// GH-5110 +{ + const buffer = Buffer.from('test'); + const string = JSON.stringify(buffer); + + assert.strictEqual(string, '{"type":"Buffer","data":[116,101,115,116]}'); + + function receiver(key, value) { + return value && value.type === 'Buffer' ? Buffer.from(value.data) : value; + } + + assert.deepStrictEqual(buffer, JSON.parse(string, receiver)); +} diff --git a/tests/node_compat/test/parallel/test-buffer-tostring-range.js b/tests/node_compat/test/parallel/test-buffer-tostring-range.js new file mode 100644 index 000000000..9fa199bd5 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-tostring-range.js @@ -0,0 +1,107 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); + +const rangeBuffer = Buffer.from('abc'); + +// If start >= buffer's length, empty string will be returned +assert.strictEqual(rangeBuffer.toString('ascii', 3), ''); +assert.strictEqual(rangeBuffer.toString('ascii', +Infinity), ''); +assert.strictEqual(rangeBuffer.toString('ascii', 3.14, 3), ''); +assert.strictEqual(rangeBuffer.toString('ascii', 'Infinity', 3), ''); + +// If end <= 0, empty string will be returned +assert.strictEqual(rangeBuffer.toString('ascii', 1, 0), ''); +assert.strictEqual(rangeBuffer.toString('ascii', 1, -1.2), ''); +assert.strictEqual(rangeBuffer.toString('ascii', 1, -100), ''); +assert.strictEqual(rangeBuffer.toString('ascii', 1, -Infinity), ''); + +// If start < 0, start will be taken as zero +assert.strictEqual(rangeBuffer.toString('ascii', -1, 3), 'abc'); +assert.strictEqual(rangeBuffer.toString('ascii', -1.99, 3), 'abc'); +assert.strictEqual(rangeBuffer.toString('ascii', -Infinity, 3), 'abc'); +assert.strictEqual(rangeBuffer.toString('ascii', '-1', 3), 'abc'); +assert.strictEqual(rangeBuffer.toString('ascii', '-1.99', 3), 'abc'); +assert.strictEqual(rangeBuffer.toString('ascii', '-Infinity', 3), 'abc'); + +// If start is an invalid integer, start will be taken as zero +assert.strictEqual(rangeBuffer.toString('ascii', 'node.js', 3), 'abc'); +assert.strictEqual(rangeBuffer.toString('ascii', {}, 3), 'abc'); +assert.strictEqual(rangeBuffer.toString('ascii', [], 3), 'abc'); +assert.strictEqual(rangeBuffer.toString('ascii', NaN, 3), 'abc'); +assert.strictEqual(rangeBuffer.toString('ascii', null, 3), 'abc'); +assert.strictEqual(rangeBuffer.toString('ascii', undefined, 3), 'abc'); +assert.strictEqual(rangeBuffer.toString('ascii', false, 3), 'abc'); +assert.strictEqual(rangeBuffer.toString('ascii', '', 3), 'abc'); + +// But, if start is an integer when coerced, then it will be coerced and used. +assert.strictEqual(rangeBuffer.toString('ascii', '-1', 3), 'abc'); +assert.strictEqual(rangeBuffer.toString('ascii', '1', 3), 'bc'); +assert.strictEqual(rangeBuffer.toString('ascii', '-Infinity', 3), 'abc'); +assert.strictEqual(rangeBuffer.toString('ascii', '3', 3), ''); +assert.strictEqual(rangeBuffer.toString('ascii', Number(3), 3), ''); +assert.strictEqual(rangeBuffer.toString('ascii', '3.14', 3), ''); +assert.strictEqual(rangeBuffer.toString('ascii', '1.99', 3), 'bc'); +assert.strictEqual(rangeBuffer.toString('ascii', '-1.99', 3), 'abc'); +assert.strictEqual(rangeBuffer.toString('ascii', 1.99, 3), 'bc'); +assert.strictEqual(rangeBuffer.toString('ascii', true, 3), 'bc'); + +// If end > buffer's length, end will be taken as buffer's length +assert.strictEqual(rangeBuffer.toString('ascii', 0, 5), 'abc'); +assert.strictEqual(rangeBuffer.toString('ascii', 0, 6.99), 'abc'); +assert.strictEqual(rangeBuffer.toString('ascii', 0, Infinity), 'abc'); +assert.strictEqual(rangeBuffer.toString('ascii', 0, '5'), 'abc'); +assert.strictEqual(rangeBuffer.toString('ascii', 0, '6.99'), 'abc'); +assert.strictEqual(rangeBuffer.toString('ascii', 0, 'Infinity'), 'abc'); + +// If end is an invalid integer, end will be taken as buffer's length +assert.strictEqual(rangeBuffer.toString('ascii', 0, 'node.js'), ''); +assert.strictEqual(rangeBuffer.toString('ascii', 0, {}), ''); +assert.strictEqual(rangeBuffer.toString('ascii', 0, NaN), ''); +assert.strictEqual(rangeBuffer.toString('ascii', 0, undefined), 'abc'); +assert.strictEqual(rangeBuffer.toString('ascii', 0), 'abc'); +assert.strictEqual(rangeBuffer.toString('ascii', 0, null), ''); +assert.strictEqual(rangeBuffer.toString('ascii', 0, []), ''); +assert.strictEqual(rangeBuffer.toString('ascii', 0, false), ''); +assert.strictEqual(rangeBuffer.toString('ascii', 0, ''), ''); + +// But, if end is an integer when coerced, then it will be coerced and used. +assert.strictEqual(rangeBuffer.toString('ascii', 0, '-1'), ''); +assert.strictEqual(rangeBuffer.toString('ascii', 0, '1'), 'a'); +assert.strictEqual(rangeBuffer.toString('ascii', 0, '-Infinity'), ''); +assert.strictEqual(rangeBuffer.toString('ascii', 0, '3'), 'abc'); +assert.strictEqual(rangeBuffer.toString('ascii', 0, Number(3)), 'abc'); +assert.strictEqual(rangeBuffer.toString('ascii', 0, '3.14'), 'abc'); +assert.strictEqual(rangeBuffer.toString('ascii', 0, '1.99'), 'a'); +assert.strictEqual(rangeBuffer.toString('ascii', 0, '-1.99'), ''); +assert.strictEqual(rangeBuffer.toString('ascii', 0, 1.99), 'a'); +assert.strictEqual(rangeBuffer.toString('ascii', 0, true), 'a'); + +// Try toString() with an object as an encoding +assert.strictEqual(rangeBuffer.toString({ toString: function() { + return 'ascii'; +} }), 'abc'); + +// Try toString() with 0 and null as the encoding +assert.throws(() => { + rangeBuffer.toString(0, 1, 2); +}, { + code: 'ERR_UNKNOWN_ENCODING', + name: 'TypeError', + message: 'Unknown encoding: 0' +}); +assert.throws(() => { + rangeBuffer.toString(null, 1, 2); +}, { + code: 'ERR_UNKNOWN_ENCODING', + name: 'TypeError', + message: 'Unknown encoding: null' +}); diff --git a/tests/node_compat/test/parallel/test-buffer-tostring-rangeerror.js b/tests/node_compat/test/parallel/test-buffer-tostring-rangeerror.js new file mode 100644 index 000000000..793d2d891 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-tostring-rangeerror.js @@ -0,0 +1,28 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); + +// This test ensures that Node.js throws a RangeError when trying to convert a +// gigantic buffer into a string. +// Regression test for https://github.com/nodejs/node/issues/649. + +const assert = require('assert'); +const SlowBuffer = require('buffer').SlowBuffer; + +const len = 1422561062959; +const message = { + code: 'ERR_INVALID_ARG_VALUE', + name: 'RangeError', + message: /^The argument 'size' is invalid\. Received [^"]*$/ +}; +assert.throws(() => Buffer(len).toString('utf8'), message); +assert.throws(() => SlowBuffer(len).toString('utf8'), message); +assert.throws(() => Buffer.alloc(len).toString('utf8'), message); +assert.throws(() => Buffer.allocUnsafe(len).toString('utf8'), message); +assert.throws(() => Buffer.allocUnsafeSlow(len).toString('utf8'), message); diff --git a/tests/node_compat/test/parallel/test-buffer-tostring.js b/tests/node_compat/test/parallel/test-buffer-tostring.js new file mode 100644 index 000000000..a6f5cabe0 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-tostring.js @@ -0,0 +1,44 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); + +// utf8, ucs2, ascii, latin1, utf16le +const encodings = ['utf8', 'utf-8', 'ucs2', 'ucs-2', 'ascii', 'latin1', + 'binary', 'utf16le', 'utf-16le']; + +encodings + .reduce((es, e) => es.concat(e, e.toUpperCase()), []) + .forEach((encoding) => { + assert.strictEqual(Buffer.from('foo', encoding).toString(encoding), 'foo'); + }); + +// base64 +['base64', 'BASE64'].forEach((encoding) => { + assert.strictEqual(Buffer.from('Zm9v', encoding).toString(encoding), 'Zm9v'); +}); + +// hex +['hex', 'HEX'].forEach((encoding) => { + assert.strictEqual(Buffer.from('666f6f', encoding).toString(encoding), + '666f6f'); +}); + +// Invalid encodings +for (let i = 1; i < 10; i++) { + const encoding = String(i).repeat(i); + const error = common.expectsError({ + code: 'ERR_UNKNOWN_ENCODING', + name: 'TypeError', + message: `Unknown encoding: ${encoding}` + }); + assert.ok(!Buffer.isEncoding(encoding)); + assert.throws(() => Buffer.from('foo').toString(encoding), error); +} diff --git a/tests/node_compat/test/parallel/test-buffer-writedouble.js b/tests/node_compat/test/parallel/test-buffer-writedouble.js new file mode 100644 index 000000000..3e4d4e676 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-writedouble.js @@ -0,0 +1,140 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +// Tests to verify doubles are correctly written + +require('../common'); +const assert = require('assert'); + +const buffer = Buffer.allocUnsafe(16); + +buffer.writeDoubleBE(2.225073858507201e-308, 0); +buffer.writeDoubleLE(2.225073858507201e-308, 8); +assert.ok(buffer.equals(new Uint8Array([ + 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, +]))); + +buffer.writeDoubleBE(1.0000000000000004, 0); +buffer.writeDoubleLE(1.0000000000000004, 8); +assert.ok(buffer.equals(new Uint8Array([ + 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, +]))); + +buffer.writeDoubleBE(-2, 0); +buffer.writeDoubleLE(-2, 8); +assert.ok(buffer.equals(new Uint8Array([ + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, +]))); + +buffer.writeDoubleBE(1.7976931348623157e+308, 0); +buffer.writeDoubleLE(1.7976931348623157e+308, 8); +assert.ok(buffer.equals(new Uint8Array([ + 0x7f, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0x7f, +]))); + +buffer.writeDoubleBE(0 * -1, 0); +buffer.writeDoubleLE(0 * -1, 8); +assert.ok(buffer.equals(new Uint8Array([ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, +]))); + +buffer.writeDoubleBE(Infinity, 0); +buffer.writeDoubleLE(Infinity, 8); + +assert.ok(buffer.equals(new Uint8Array([ + 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x7F, +]))); + +assert.strictEqual(buffer.readDoubleBE(0), Infinity); +assert.strictEqual(buffer.readDoubleLE(8), Infinity); + +buffer.writeDoubleBE(-Infinity, 0); +buffer.writeDoubleLE(-Infinity, 8); + +assert.ok(buffer.equals(new Uint8Array([ + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, +]))); + +assert.strictEqual(buffer.readDoubleBE(0), -Infinity); +assert.strictEqual(buffer.readDoubleLE(8), -Infinity); + +buffer.writeDoubleBE(NaN, 0); +buffer.writeDoubleLE(NaN, 8); + +// JS only knows a single NaN but there exist two platform specific +// implementations. Therefore, allow both quiet and signalling NaNs. +if (buffer[1] === 0xF7) { + assert.ok(buffer.equals(new Uint8Array([ + 0x7F, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x7F, + ]))); +} else { + assert.ok(buffer.equals(new Uint8Array([ + 0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x7F, + ]))); +} + +assert.ok(Number.isNaN(buffer.readDoubleBE(0))); +assert.ok(Number.isNaN(buffer.readDoubleLE(8))); + +// OOB in writeDouble{LE,BE} should throw. +{ + const small = Buffer.allocUnsafe(1); + + ['writeDoubleLE', 'writeDoubleBE'].forEach((fn) => { + + // Verify that default offset works fine. + buffer[fn](23, undefined); + buffer[fn](23); + + assert.throws( + () => small[fn](11.11, 0), + { + code: 'ERR_BUFFER_OUT_OF_BOUNDS', + name: 'RangeError', + message: 'Attempt to access memory outside buffer bounds' + }); + + ['', '0', null, {}, [], () => {}, true, false].forEach((off) => { + assert.throws( + () => small[fn](23, off), + { code: 'ERR_INVALID_ARG_TYPE' }); + }); + + [Infinity, -1, 9].forEach((offset) => { + assert.throws( + () => buffer[fn](23, offset), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "offset" is out of range. ' + + `It must be >= 0 and <= 8. Received ${offset}` + }); + }); + + [NaN, 1.01].forEach((offset) => { + assert.throws( + () => buffer[fn](42, offset), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "offset" is out of range. ' + + `It must be an integer. Received ${offset}` + }); + }); + }); +} diff --git a/tests/node_compat/test/parallel/test-buffer-writefloat.js b/tests/node_compat/test/parallel/test-buffer-writefloat.js new file mode 100644 index 000000000..4dd75f83e --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-writefloat.js @@ -0,0 +1,124 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +// Tests to verify floats are correctly written + +require('../common'); +const assert = require('assert'); + +const buffer = Buffer.allocUnsafe(8); + +buffer.writeFloatBE(1, 0); +buffer.writeFloatLE(1, 4); +assert.ok(buffer.equals( + new Uint8Array([ 0x3f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f ]))); + +buffer.writeFloatBE(1 / 3, 0); +buffer.writeFloatLE(1 / 3, 4); +assert.ok(buffer.equals( + new Uint8Array([ 0x3e, 0xaa, 0xaa, 0xab, 0xab, 0xaa, 0xaa, 0x3e ]))); + +buffer.writeFloatBE(3.4028234663852886e+38, 0); +buffer.writeFloatLE(3.4028234663852886e+38, 4); +assert.ok(buffer.equals( + new Uint8Array([ 0x7f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f ]))); + +buffer.writeFloatLE(1.1754943508222875e-38, 0); +buffer.writeFloatBE(1.1754943508222875e-38, 4); +assert.ok(buffer.equals( + new Uint8Array([ 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00 ]))); + +buffer.writeFloatBE(0 * -1, 0); +buffer.writeFloatLE(0 * -1, 4); +assert.ok(buffer.equals( + new Uint8Array([ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 ]))); + +buffer.writeFloatBE(Infinity, 0); +buffer.writeFloatLE(Infinity, 4); +assert.ok(buffer.equals( + new Uint8Array([ 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x7F ]))); + +assert.strictEqual(buffer.readFloatBE(0), Infinity); +assert.strictEqual(buffer.readFloatLE(4), Infinity); + +buffer.writeFloatBE(-Infinity, 0); +buffer.writeFloatLE(-Infinity, 4); +assert.ok(buffer.equals( + new Uint8Array([ 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF ]))); + +assert.strictEqual(buffer.readFloatBE(0), -Infinity); +assert.strictEqual(buffer.readFloatLE(4), -Infinity); + +buffer.writeFloatBE(NaN, 0); +buffer.writeFloatLE(NaN, 4); + +// JS only knows a single NaN but there exist two platform specific +// implementations. Therefore, allow both quiet and signalling NaNs. +if (buffer[1] === 0xBF) { + assert.ok( + buffer.equals(new Uint8Array( + [ 0x7F, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x7F ]))); +} else { + assert.ok( + buffer.equals(new Uint8Array( + [ 0x7F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x7F ]))); +} + +assert.ok(Number.isNaN(buffer.readFloatBE(0))); +assert.ok(Number.isNaN(buffer.readFloatLE(4))); + +// OOB in writeFloat{LE,BE} should throw. +{ + const small = Buffer.allocUnsafe(1); + + ['writeFloatLE', 'writeFloatBE'].forEach((fn) => { + + // Verify that default offset works fine. + buffer[fn](23, undefined); + buffer[fn](23); + + assert.throws( + () => small[fn](11.11, 0), + { + code: 'ERR_BUFFER_OUT_OF_BOUNDS', + name: 'RangeError', + message: 'Attempt to access memory outside buffer bounds' + }); + + ['', '0', null, {}, [], () => {}, true, false].forEach((off) => { + assert.throws( + () => small[fn](23, off), + { code: 'ERR_INVALID_ARG_TYPE' } + ); + }); + + [Infinity, -1, 5].forEach((offset) => { + assert.throws( + () => buffer[fn](23, offset), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "offset" is out of range. ' + + `It must be >= 0 and <= 4. Received ${offset}` + } + ); + }); + + [NaN, 1.01].forEach((offset) => { + assert.throws( + () => buffer[fn](42, offset), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "offset" is out of range. ' + + `It must be an integer. Received ${offset}` + }); + }); + }); +} diff --git a/tests/node_compat/test/parallel/test-buffer-writeint.js b/tests/node_compat/test/parallel/test-buffer-writeint.js new file mode 100644 index 000000000..117ba47c0 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-writeint.js @@ -0,0 +1,277 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +// Tests to verify signed integers are correctly written + +require('../common'); +const assert = require('assert'); +const errorOutOfBounds = { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: new RegExp('^The value of "value" is out of range\\. ' + + 'It must be >= -\\d+ and <= \\d+\\. Received .+$') +}; + +// Test 8 bit +{ + const buffer = Buffer.alloc(2); + + buffer.writeInt8(0x23, 0); + buffer.writeInt8(-5, 1); + assert.ok(buffer.equals(new Uint8Array([ 0x23, 0xfb ]))); + + /* Make sure we handle min/max correctly */ + buffer.writeInt8(0x7f, 0); + buffer.writeInt8(-0x80, 1); + assert.ok(buffer.equals(new Uint8Array([ 0x7f, 0x80 ]))); + + assert.throws(() => { + buffer.writeInt8(0x7f + 1, 0); + }, errorOutOfBounds); + assert.throws(() => { + buffer.writeInt8(-0x80 - 1, 0); + }, errorOutOfBounds); + + // Verify that default offset works fine. + buffer.writeInt8(23, undefined); + buffer.writeInt8(23); + + ['', '0', null, {}, [], () => {}, true, false].forEach((off) => { + assert.throws( + () => buffer.writeInt8(23, off), + { code: 'ERR_INVALID_ARG_TYPE' }); + }); + + [NaN, Infinity, -1, 1.01].forEach((off) => { + assert.throws( + () => buffer.writeInt8(23, off), + { code: 'ERR_OUT_OF_RANGE' }); + }); +} + +// Test 16 bit +{ + const buffer = Buffer.alloc(4); + + buffer.writeInt16BE(0x0023, 0); + buffer.writeInt16LE(0x0023, 2); + assert.ok(buffer.equals(new Uint8Array([ 0x00, 0x23, 0x23, 0x00 ]))); + + buffer.writeInt16BE(-5, 0); + buffer.writeInt16LE(-5, 2); + assert.ok(buffer.equals(new Uint8Array([ 0xff, 0xfb, 0xfb, 0xff ]))); + + buffer.writeInt16BE(-1679, 0); + buffer.writeInt16LE(-1679, 2); + assert.ok(buffer.equals(new Uint8Array([ 0xf9, 0x71, 0x71, 0xf9 ]))); + + /* Make sure we handle min/max correctly */ + buffer.writeInt16BE(0x7fff, 0); + buffer.writeInt16BE(-0x8000, 2); + assert.ok(buffer.equals(new Uint8Array([ 0x7f, 0xff, 0x80, 0x00 ]))); + + buffer.writeInt16LE(0x7fff, 0); + buffer.writeInt16LE(-0x8000, 2); + assert.ok(buffer.equals(new Uint8Array([ 0xff, 0x7f, 0x00, 0x80 ]))); + + ['writeInt16BE', 'writeInt16LE'].forEach((fn) => { + + // Verify that default offset works fine. + buffer[fn](23, undefined); + buffer[fn](23); + + assert.throws(() => { + buffer[fn](0x7fff + 1, 0); + }, errorOutOfBounds); + assert.throws(() => { + buffer[fn](-0x8000 - 1, 0); + }, errorOutOfBounds); + + ['', '0', null, {}, [], () => {}, true, false].forEach((off) => { + assert.throws( + () => buffer[fn](23, off), + { code: 'ERR_INVALID_ARG_TYPE' }); + }); + + [NaN, Infinity, -1, 1.01].forEach((off) => { + assert.throws( + () => buffer[fn](23, off), + { code: 'ERR_OUT_OF_RANGE' }); + }); + }); +} + +// Test 32 bit +{ + const buffer = Buffer.alloc(8); + + buffer.writeInt32BE(0x23, 0); + buffer.writeInt32LE(0x23, 4); + assert.ok(buffer.equals(new Uint8Array([ + 0x00, 0x00, 0x00, 0x23, 0x23, 0x00, 0x00, 0x00, + ]))); + + buffer.writeInt32BE(-5, 0); + buffer.writeInt32LE(-5, 4); + assert.ok(buffer.equals(new Uint8Array([ + 0xff, 0xff, 0xff, 0xfb, 0xfb, 0xff, 0xff, 0xff, + ]))); + + buffer.writeInt32BE(-805306713, 0); + buffer.writeInt32LE(-805306713, 4); + assert.ok(buffer.equals(new Uint8Array([ + 0xcf, 0xff, 0xfe, 0xa7, 0xa7, 0xfe, 0xff, 0xcf, + ]))); + + /* Make sure we handle min/max correctly */ + buffer.writeInt32BE(0x7fffffff, 0); + buffer.writeInt32BE(-0x80000000, 4); + assert.ok(buffer.equals(new Uint8Array([ + 0x7f, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, + ]))); + + buffer.writeInt32LE(0x7fffffff, 0); + buffer.writeInt32LE(-0x80000000, 4); + assert.ok(buffer.equals(new Uint8Array([ + 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x80, + ]))); + + ['writeInt32BE', 'writeInt32LE'].forEach((fn) => { + + // Verify that default offset works fine. + buffer[fn](23, undefined); + buffer[fn](23); + + assert.throws(() => { + buffer[fn](0x7fffffff + 1, 0); + }, errorOutOfBounds); + assert.throws(() => { + buffer[fn](-0x80000000 - 1, 0); + }, errorOutOfBounds); + + ['', '0', null, {}, [], () => {}, true, false].forEach((off) => { + assert.throws( + () => buffer[fn](23, off), + { code: 'ERR_INVALID_ARG_TYPE' }); + }); + + [NaN, Infinity, -1, 1.01].forEach((off) => { + assert.throws( + () => buffer[fn](23, off), + { code: 'ERR_OUT_OF_RANGE' }); + }); + }); +} + +// Test 48 bit +{ + const value = 0x1234567890ab; + const buffer = Buffer.allocUnsafe(6); + buffer.writeIntBE(value, 0, 6); + assert.ok(buffer.equals(new Uint8Array([ + 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, + ]))); + + buffer.writeIntLE(value, 0, 6); + assert.ok(buffer.equals(new Uint8Array([ + 0xab, 0x90, 0x78, 0x56, 0x34, 0x12, + ]))); +} + +// Test Int +{ + const data = Buffer.alloc(8); + + // Check byteLength. + ['writeIntBE', 'writeIntLE'].forEach((fn) => { + ['', '0', null, {}, [], () => {}, true, false, undefined].forEach((bl) => { + assert.throws( + () => data[fn](23, 0, bl), + { code: 'ERR_INVALID_ARG_TYPE' }); + }); + + [Infinity, -1].forEach((byteLength) => { + assert.throws( + () => data[fn](23, 0, byteLength), + { + code: 'ERR_OUT_OF_RANGE', + message: 'The value of "byteLength" is out of range. ' + + `It must be >= 1 and <= 6. Received ${byteLength}` + } + ); + }); + + [NaN, 1.01].forEach((byteLength) => { + assert.throws( + () => data[fn](42, 0, byteLength), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "byteLength" is out of range. ' + + `It must be an integer. Received ${byteLength}` + }); + }); + }); + + // Test 1 to 6 bytes. + for (let i = 1; i <= 6; i++) { + ['writeIntBE', 'writeIntLE'].forEach((fn) => { + const min = -(2 ** (i * 8 - 1)); + const max = 2 ** (i * 8 - 1) - 1; + let range = `>= ${min} and <= ${max}`; + if (i > 4) { + range = `>= -(2 ** ${i * 8 - 1}) and < 2 ** ${i * 8 - 1}`; + } + [min - 1, max + 1].forEach((val) => { + const received = i > 4 ? + String(val).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1_') : + val; + assert.throws(() => { + data[fn](val, 0, i); + }, { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "value" is out of range. ' + + `It must be ${range}. Received ${received}` + }); + }); + + ['', '0', null, {}, [], () => {}, true, false, undefined].forEach((o) => { + assert.throws( + () => data[fn](min, o, i), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + }); + }); + + [Infinity, -1, -4294967295].forEach((offset) => { + assert.throws( + () => data[fn](min, offset, i), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "offset" is out of range. ' + + `It must be >= 0 and <= ${8 - i}. Received ${offset}` + }); + }); + + [NaN, 1.01].forEach((offset) => { + assert.throws( + () => data[fn](max, offset, i), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "offset" is out of range. ' + + `It must be an integer. Received ${offset}` + }); + }); + }); + } +} diff --git a/tests/node_compat/test/parallel/test-buffer-writeuint.js b/tests/node_compat/test/parallel/test-buffer-writeuint.js new file mode 100644 index 000000000..1c954bb9f --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-writeuint.js @@ -0,0 +1,237 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); + +// We need to check the following things: +// - We are correctly resolving big endian (doesn't mean anything for 8 bit) +// - Correctly resolving little endian (doesn't mean anything for 8 bit) +// - Correctly using the offsets +// - Correctly interpreting values that are beyond the signed range as unsigned + +{ // OOB + const data = Buffer.alloc(8); + ['UInt8', 'UInt16BE', 'UInt16LE', 'UInt32BE', 'UInt32LE'].forEach((fn) => { + + // Verify that default offset works fine. + data[`write${fn}`](23, undefined); + data[`write${fn}`](23); + + ['', '0', null, {}, [], () => {}, true, false].forEach((o) => { + assert.throws( + () => data[`write${fn}`](23, o), + { code: 'ERR_INVALID_ARG_TYPE' }); + }); + + [NaN, Infinity, -1, 1.01].forEach((o) => { + assert.throws( + () => data[`write${fn}`](23, o), + { code: 'ERR_OUT_OF_RANGE' }); + }); + }); +} + +{ // Test 8 bit + const data = Buffer.alloc(4); + + data.writeUInt8(23, 0); + data.writeUInt8(23, 1); + data.writeUInt8(23, 2); + data.writeUInt8(23, 3); + assert.ok(data.equals(new Uint8Array([23, 23, 23, 23]))); + + data.writeUInt8(23, 0); + data.writeUInt8(23, 1); + data.writeUInt8(23, 2); + data.writeUInt8(23, 3); + assert.ok(data.equals(new Uint8Array([23, 23, 23, 23]))); + + data.writeUInt8(255, 0); + assert.strictEqual(data[0], 255); + + data.writeUInt8(255, 0); + assert.strictEqual(data[0], 255); +} + +// Test 16 bit +{ + let value = 0x2343; + const data = Buffer.alloc(4); + + data.writeUInt16BE(value, 0); + assert.ok(data.equals(new Uint8Array([0x23, 0x43, 0, 0]))); + + data.writeUInt16BE(value, 1); + assert.ok(data.equals(new Uint8Array([0x23, 0x23, 0x43, 0]))); + + data.writeUInt16BE(value, 2); + assert.ok(data.equals(new Uint8Array([0x23, 0x23, 0x23, 0x43]))); + + data.writeUInt16LE(value, 0); + assert.ok(data.equals(new Uint8Array([0x43, 0x23, 0x23, 0x43]))); + + data.writeUInt16LE(value, 1); + assert.ok(data.equals(new Uint8Array([0x43, 0x43, 0x23, 0x43]))); + + data.writeUInt16LE(value, 2); + assert.ok(data.equals(new Uint8Array([0x43, 0x43, 0x43, 0x23]))); + + value = 0xff80; + data.writeUInt16LE(value, 0); + assert.ok(data.equals(new Uint8Array([0x80, 0xff, 0x43, 0x23]))); + + data.writeUInt16BE(value, 0); + assert.ok(data.equals(new Uint8Array([0xff, 0x80, 0x43, 0x23]))); + + value = 0xfffff; + ['writeUInt16BE', 'writeUInt16LE'].forEach((fn) => { + assert.throws( + () => data[fn](value, 0), + { + code: 'ERR_OUT_OF_RANGE', + message: 'The value of "value" is out of range. ' + + `It must be >= 0 and <= 65535. Received ${value}` + } + ); + }); +} + +// Test 32 bit +{ + const data = Buffer.alloc(6); + const value = 0xe7f90a6d; + + data.writeUInt32BE(value, 0); + assert.ok(data.equals(new Uint8Array([0xe7, 0xf9, 0x0a, 0x6d, 0, 0]))); + + data.writeUInt32BE(value, 1); + assert.ok(data.equals(new Uint8Array([0xe7, 0xe7, 0xf9, 0x0a, 0x6d, 0]))); + + data.writeUInt32BE(value, 2); + assert.ok(data.equals(new Uint8Array([0xe7, 0xe7, 0xe7, 0xf9, 0x0a, 0x6d]))); + + data.writeUInt32LE(value, 0); + assert.ok(data.equals(new Uint8Array([0x6d, 0x0a, 0xf9, 0xe7, 0x0a, 0x6d]))); + + data.writeUInt32LE(value, 1); + assert.ok(data.equals(new Uint8Array([0x6d, 0x6d, 0x0a, 0xf9, 0xe7, 0x6d]))); + + data.writeUInt32LE(value, 2); + assert.ok(data.equals(new Uint8Array([0x6d, 0x6d, 0x6d, 0x0a, 0xf9, 0xe7]))); +} + +// Test 48 bit +{ + const value = 0x1234567890ab; + const data = Buffer.allocUnsafe(6); + data.writeUIntBE(value, 0, 6); + assert.ok(data.equals(new Uint8Array([0x12, 0x34, 0x56, 0x78, 0x90, 0xab]))); + + data.writeUIntLE(value, 0, 6); + assert.ok(data.equals(new Uint8Array([0xab, 0x90, 0x78, 0x56, 0x34, 0x12]))); +} + +// Test UInt +{ + const data = Buffer.alloc(8); + let val = 0x100; + + // Check byteLength. + ['writeUIntBE', 'writeUIntLE'].forEach((fn) => { + ['', '0', null, {}, [], () => {}, true, false, undefined].forEach((bl) => { + assert.throws( + () => data[fn](23, 0, bl), + { code: 'ERR_INVALID_ARG_TYPE' }); + }); + + [Infinity, -1].forEach((byteLength) => { + assert.throws( + () => data[fn](23, 0, byteLength), + { + code: 'ERR_OUT_OF_RANGE', + message: 'The value of "byteLength" is out of range. ' + + `It must be >= 1 and <= 6. Received ${byteLength}` + } + ); + }); + + [NaN, 1.01].forEach((byteLength) => { + assert.throws( + () => data[fn](42, 0, byteLength), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "byteLength" is out of range. ' + + `It must be an integer. Received ${byteLength}` + }); + }); + }); + + // Test 1 to 6 bytes. + for (let i = 1; i <= 6; i++) { + const range = i < 5 ? `= ${val - 1}` : ` 2 ** ${i * 8}`; + const received = i > 4 ? + String(val).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1_') : + val; + ['writeUIntBE', 'writeUIntLE'].forEach((fn) => { + assert.throws(() => { + data[fn](val, 0, i); + }, { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "value" is out of range. ' + + `It must be >= 0 and <${range}. Received ${received}` + }); + + ['', '0', null, {}, [], () => {}, true, false].forEach((o) => { + assert.throws( + () => data[fn](23, o, i), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + }); + }); + + [Infinity, -1, -4294967295].forEach((offset) => { + assert.throws( + () => data[fn](val - 1, offset, i), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "offset" is out of range. ' + + `It must be >= 0 and <= ${8 - i}. Received ${offset}` + }); + }); + + [NaN, 1.01].forEach((offset) => { + assert.throws( + () => data[fn](val - 1, offset, i), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "offset" is out of range. ' + + `It must be an integer. Received ${offset}` + }); + }); + }); + + val *= 0x100; + } +} + +for (const fn of [ + 'UInt8', 'UInt16LE', 'UInt16BE', 'UInt32LE', 'UInt32BE', 'UIntLE', 'UIntBE', + 'BigUInt64LE', 'BigUInt64BE', +]) { + const p = Buffer.prototype; + const lowerFn = fn.replace(/UInt/, 'Uint'); + assert.strictEqual(p[`write${fn}`], p[`write${lowerFn}`]); + assert.strictEqual(p[`read${fn}`], p[`read${lowerFn}`]); +} diff --git a/tests/node_compat/test/parallel/test-buffer-zero-fill-cli.js b/tests/node_compat/test/parallel/test-buffer-zero-fill-cli.js new file mode 100644 index 000000000..c3250b870 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-zero-fill-cli.js @@ -0,0 +1,39 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +// Flags: --zero-fill-buffers + +// when using --zero-fill-buffers, every Buffer and SlowBuffer +// instance must be zero filled upon creation + +require('../common'); +const SlowBuffer = require('buffer').SlowBuffer; +const assert = require('assert'); + +function isZeroFilled(buf) { + for (const n of buf) + if (n > 0) return false; + return true; +} + +// This can be somewhat unreliable because the +// allocated memory might just already happen to +// contain all zeroes. The test is run multiple +// times to improve the reliability. +for (let i = 0; i < 50; i++) { + const bufs = [ + Buffer.alloc(20), + Buffer.allocUnsafe(20), + SlowBuffer(20), + Buffer(20), + new SlowBuffer(20), + ]; + for (const buf of bufs) { + assert(isZeroFilled(buf)); + } +} diff --git a/tests/node_compat/test/parallel/test-buffer-zero-fill-reset.js b/tests/node_compat/test/parallel/test-buffer-zero-fill-reset.js new file mode 100644 index 000000000..1f1baed66 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-zero-fill-reset.js @@ -0,0 +1,26 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); + + +function testUint8Array(ui) { + const length = ui.length; + for (let i = 0; i < length; i++) + if (ui[i] !== 0) return false; + return true; +} + + +for (let i = 0; i < 100; i++) { + Buffer.alloc(0); + const ui = new Uint8Array(65); + assert.ok(testUint8Array(ui), `Uint8Array is not zero-filled: ${ui}`); +} diff --git a/tests/node_compat/test/parallel/test-buffer-zero-fill.js b/tests/node_compat/test/parallel/test-buffer-zero-fill.js new file mode 100644 index 000000000..be8ce1412 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-zero-fill.js @@ -0,0 +1,21 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); + +// Tests deprecated Buffer API on purpose +const buf1 = Buffer(100); +const buf2 = new Buffer(100); + +for (let n = 0; n < buf1.length; n++) + assert.strictEqual(buf1[n], 0); + +for (let n = 0; n < buf2.length; n++) + assert.strictEqual(buf2[n], 0); diff --git a/tests/node_compat/test/parallel/test-child-process-default-options.js b/tests/node_compat/test/parallel/test-child-process-default-options.js new file mode 100644 index 000000000..265cfe22f --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-default-options.js @@ -0,0 +1,58 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const { isWindows } = require('../common'); +const assert = require('assert'); + +const spawn = require('child_process').spawn; +const debug = require('util').debuglog('test'); + +process.env.HELLO = 'WORLD'; + +let child; +if (isWindows) { + child = spawn('cmd.exe', ['/c', 'set'], {}); +} else { + child = spawn('/usr/bin/env', [], {}); +} + +let response = ''; + +child.stdout.setEncoding('utf8'); + +child.stdout.on('data', function(chunk) { + debug(`stdout: ${chunk}`); + response += chunk; +}); + +process.on('exit', function() { + assert.ok(response.includes('HELLO=WORLD'), + 'spawn did not use process.env as default ' + + `(process.env.HELLO = ${process.env.HELLO})`); +}); diff --git a/tests/node_compat/test/parallel/test-child-process-double-pipe.js b/tests/node_compat/test/parallel/test-child-process-double-pipe.js new file mode 100644 index 000000000..bd31d1038 --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-double-pipe.js @@ -0,0 +1,129 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const { + isWindows, + mustCall, + mustCallAtLeast, +} = require('../common'); +const assert = require('assert'); +const os = require('os'); +const spawn = require('child_process').spawn; +const debug = require('util').debuglog('test'); + +// We're trying to reproduce: +// $ echo "hello\nnode\nand\nworld" | grep o | sed s/o/a/ + +let grep, sed, echo; + +if (isWindows) { + grep = spawn('grep', ['--binary', 'o']); + sed = spawn('sed', ['--binary', 's/o/O/']); + echo = spawn('cmd.exe', + ['/c', 'echo', 'hello&&', 'echo', + 'node&&', 'echo', 'and&&', 'echo', 'world']); +} else { + grep = spawn('grep', ['o']); + sed = spawn('sed', ['s/o/O/']); + echo = spawn('echo', ['hello\nnode\nand\nworld\n']); +} + +// If the spawn function leaks file descriptors to subprocesses, grep and sed +// hang. +// This happens when calling pipe(2) and then forgetting to set the +// FD_CLOEXEC flag on the resulting file descriptors. +// +// This test checks child processes exit, meaning they don't hang like +// explained above. + + +// pipe echo | grep +echo.stdout.on('data', mustCallAtLeast((data) => { + debug(`grep stdin write ${data.length}`); + if (!grep.stdin.write(data)) { + echo.stdout.pause(); + } +})); + +// TODO(@jasnell): This does not appear to ever be +// emitted. It's not clear if it is necessary. +grep.stdin.on('drain', (data) => { + echo.stdout.resume(); +}); + +// Propagate end from echo to grep +echo.stdout.on('end', mustCall((code) => { + grep.stdin.end(); +})); + +echo.on('exit', mustCall(() => { + debug('echo exit'); +})); + +grep.on('exit', mustCall(() => { + debug('grep exit'); +})); + +sed.on('exit', mustCall(() => { + debug('sed exit'); +})); + + +// pipe grep | sed +grep.stdout.on('data', mustCallAtLeast((data) => { + debug(`grep stdout ${data.length}`); + if (!sed.stdin.write(data)) { + grep.stdout.pause(); + } +})); + +// TODO(@jasnell): This does not appear to ever be +// emitted. It's not clear if it is necessary. +sed.stdin.on('drain', (data) => { + grep.stdout.resume(); +}); + +// Propagate end from grep to sed +grep.stdout.on('end', mustCall((code) => { + debug('grep stdout end'); + sed.stdin.end(); +})); + + +let result = ''; + +// print sed's output +sed.stdout.on('data', mustCallAtLeast((data) => { + result += data.toString('utf8', 0, data.length); + debug(data); +})); + +sed.stdout.on('end', mustCall((code) => { + assert.strictEqual(result, `hellO${os.EOL}nOde${os.EOL}wOrld${os.EOL}`); +})); diff --git a/tests/node_compat/test/parallel/test-child-process-exec-abortcontroller-promisified.js b/tests/node_compat/test/parallel/test-child-process-exec-abortcontroller-promisified.js new file mode 100644 index 000000000..4ba699ba4 --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-exec-abortcontroller-promisified.js @@ -0,0 +1,54 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.8.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// TODO(PolarETech): The "eval" subcommand passed to execPromisifed() should be the "-e" option. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const exec = require('child_process').exec; +const { promisify } = require('util'); + +const execPromisifed = promisify(exec); +const invalidArgTypeError = { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' +}; + +const waitCommand = common.isLinux ? + 'sleep 2m' : + `${process.execPath} eval "setInterval(()=>{}, 99)"`; + +{ + const ac = new AbortController(); + const signal = ac.signal; + const promise = execPromisifed(waitCommand, { signal }); + assert.rejects(promise, /AbortError/, 'post aborted sync signal failed') + .then(common.mustCall()); + ac.abort(); +} + +{ + assert.throws(() => { + execPromisifed(waitCommand, { signal: {} }); + }, invalidArgTypeError); +} + +{ + function signal() {} + assert.throws(() => { + execPromisifed(waitCommand, { signal }); + }, invalidArgTypeError); +} + +{ + const signal = AbortSignal.abort(); // Abort in advance + const promise = execPromisifed(waitCommand, { signal }); + + assert.rejects(promise, /AbortError/, 'pre aborted signal failed') + .then(common.mustCall()); +} diff --git a/tests/node_compat/test/parallel/test-child-process-exec-cwd.js b/tests/node_compat/test/parallel/test-child-process-exec-cwd.js new file mode 100644 index 000000000..4bd394cca --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-exec-cwd.js @@ -0,0 +1,46 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const exec = require('child_process').exec; + +let pwdcommand, dir; + +if (common.isWindows) { + pwdcommand = 'echo %cd%'; + dir = 'c:\\windows'; +} else { + pwdcommand = 'pwd'; + dir = '/dev'; +} + +exec(pwdcommand, { cwd: dir }, common.mustSucceed((stdout, stderr) => { + assert(stdout.toLowerCase().startsWith(dir)); +})); diff --git a/tests/node_compat/test/parallel/test-child-process-exec-encoding.js b/tests/node_compat/test/parallel/test-child-process-exec-encoding.js new file mode 100644 index 000000000..fe03e98d0 --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-exec-encoding.js @@ -0,0 +1,59 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.8.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// TODO(PolarETech): The process.argv[3] check should be argv[2], and the +// command passed to exec() should not need to include "run", "-A", +// and "require.ts". + +'use strict'; +const common = require('../common'); +const stdoutData = 'foo'; +const stderrData = 'bar'; + +if (process.argv[3] === 'child') { + // The following console calls are part of the test. + console.log(stdoutData); + console.error(stderrData); +} else { + const assert = require('assert'); + const cp = require('child_process'); + const expectedStdout = `${stdoutData}\n`; + const expectedStderr = `${stderrData}\n`; + function run(options, callback) { + const cmd = `"${process.execPath}" run -A require.ts "${__filename}" child`; + + cp.exec(cmd, options, common.mustSucceed((stdout, stderr) => { + callback(stdout, stderr); + })); + } + + // Test default encoding, which should be utf8. + run({}, (stdout, stderr) => { + assert.strictEqual(typeof stdout, 'string'); + assert.strictEqual(typeof stderr, 'string'); + assert.strictEqual(stdout, expectedStdout); + assert.strictEqual(stderr, expectedStderr); + }); + + // Test explicit utf8 encoding. + run({ encoding: 'utf8' }, (stdout, stderr) => { + assert.strictEqual(typeof stdout, 'string'); + assert.strictEqual(typeof stderr, 'string'); + assert.strictEqual(stdout, expectedStdout); + assert.strictEqual(stderr, expectedStderr); + }); + + // Test cases that result in buffer encodings. + [undefined, null, 'buffer', 'invalid'].forEach((encoding) => { + run({ encoding }, (stdout, stderr) => { + assert(stdout instanceof Buffer); + assert(stdout instanceof Buffer); + assert.strictEqual(stdout.toString(), expectedStdout); + assert.strictEqual(stderr.toString(), expectedStderr); + }); + }); +} diff --git a/tests/node_compat/test/parallel/test-child-process-exec-env.js b/tests/node_compat/test/parallel/test-child-process-exec-env.js new file mode 100644 index 000000000..2797b8761 --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-exec-env.js @@ -0,0 +1,71 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const { isWindows } = require('../common'); +const assert = require('assert'); +const exec = require('child_process').exec; +const debug = require('util').debuglog('test'); + +let success_count = 0; +let error_count = 0; +let response = ''; +let child; + +function after(err, stdout, stderr) { + if (err) { + error_count++; + debug(`error!: ${err.code}`); + debug(`stdout: ${JSON.stringify(stdout)}`); + debug(`stderr: ${JSON.stringify(stderr)}`); + assert.strictEqual(err.killed, false); + } else { + success_count++; + assert.notStrictEqual(stdout, ''); + } +} + +if (!isWindows) { + child = exec('/usr/bin/env', { env: { 'HELLO': 'WORLD' } }, after); +} else { + child = exec('set', + { env: { ...process.env, 'HELLO': 'WORLD' } }, + after); +} + +child.stdout.setEncoding('utf8'); +child.stdout.on('data', function(chunk) { + response += chunk; +}); + +process.on('exit', function() { + debug('response: ', response); + assert.strictEqual(success_count, 1); + assert.strictEqual(error_count, 0); + assert.ok(response.includes('HELLO=WORLD')); +}); diff --git a/tests/node_compat/test/parallel/test-child-process-exec-error.js b/tests/node_compat/test/parallel/test-child-process-exec-error.js new file mode 100644 index 000000000..3f809ed18 --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-exec-error.js @@ -0,0 +1,51 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const child_process = require('child_process'); + +function test(fn, code, expectPidType = 'number') { + const child = fn('does-not-exist', common.mustCall(function(err) { + assert.strictEqual(err.code, code); + assert(err.cmd.includes('does-not-exist')); + })); + + assert.strictEqual(typeof child.pid, expectPidType); +} + +// With `shell: true`, expect pid (of the shell) +if (common.isWindows) { + test(child_process.exec, 1, 'number'); // Exit code of cmd.exe +} else { + test(child_process.exec, 127, 'number'); // Exit code of /bin/sh +} + +// With `shell: false`, expect no pid +test(child_process.execFile, 'ENOENT', 'undefined'); diff --git a/tests/node_compat/test/parallel/test-child-process-exec-kill-throws.js b/tests/node_compat/test/parallel/test-child-process-exec-kill-throws.js new file mode 100644 index 000000000..6a28c2a18 --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-exec-kill-throws.js @@ -0,0 +1,42 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.8.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// TODO(PolarETech): The process.argv[3] check should be argv[2], and the +// command passed to exec() should not need to include "run", "-A", +// and "require.ts". + +'use strict'; +// Flags: --expose-internals +const common = require('../common'); +const assert = require('assert'); +const cp = require('child_process'); + +if (process.argv[3] === 'child') { + // Since maxBuffer is 0, this should trigger an error. + console.log('foo'); +} else { + const internalCp = require('internal/child_process'); + + // Monkey patch ChildProcess#kill() to kill the process and then throw. + const kill = internalCp.ChildProcess.prototype.kill; + + internalCp.ChildProcess.prototype.kill = function() { + kill.apply(this, arguments); + throw new Error('mock error'); + }; + + const cmd = `"${process.execPath}" run -A require.ts "${__filename}" child`; + const options = { maxBuffer: 0, killSignal: 'SIGKILL' }; + + const child = cp.exec(cmd, options, common.mustCall((err, stdout, stderr) => { + // Verify that if ChildProcess#kill() throws, the error is reported. + assert.strictEqual(err.message, 'mock error', err); + assert.strictEqual(stdout, ''); + assert.strictEqual(stderr, ''); + assert.strictEqual(child.killed, true); + })); +} diff --git a/tests/node_compat/test/parallel/test-child-process-exec-maxbuf.js b/tests/node_compat/test/parallel/test-child-process-exec-maxbuf.js new file mode 100644 index 000000000..2e99855c0 --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-exec-maxbuf.js @@ -0,0 +1,161 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.8.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// TODO(PolarETech): The "eval" subcommand passed to exec() should be the "-e" option. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const cp = require('child_process'); + +function runChecks(err, stdio, streamName, expected) { + assert.strictEqual(err.message, `${streamName} maxBuffer length exceeded`); + assert(err instanceof RangeError); + assert.strictEqual(err.code, 'ERR_CHILD_PROCESS_STDIO_MAXBUFFER'); + assert.deepStrictEqual(stdio[streamName], expected); +} + +// default value +{ + const cmd = + `"${process.execPath}" eval "console.log('a'.repeat(1024 * 1024))"`; + + cp.exec(cmd, common.mustCall((err) => { + assert(err instanceof RangeError); + assert.strictEqual(err.message, 'stdout maxBuffer length exceeded'); + assert.strictEqual(err.code, 'ERR_CHILD_PROCESS_STDIO_MAXBUFFER'); + })); +} + +// default value +{ + const cmd = + `${process.execPath} eval "console.log('a'.repeat(1024 * 1024 - 1))"`; + + cp.exec(cmd, common.mustSucceed((stdout, stderr) => { + assert.strictEqual(stdout.trim(), 'a'.repeat(1024 * 1024 - 1)); + assert.strictEqual(stderr, ''); + })); +} + +{ + const cmd = `"${process.execPath}" eval "console.log('hello world');"`; + const options = { maxBuffer: Infinity }; + + cp.exec(cmd, options, common.mustSucceed((stdout, stderr) => { + assert.strictEqual(stdout.trim(), 'hello world'); + assert.strictEqual(stderr, ''); + })); +} + +{ + const cmd = 'echo hello world'; + + cp.exec( + cmd, + { maxBuffer: 5 }, + common.mustCall((err, stdout, stderr) => { + runChecks(err, { stdout, stderr }, 'stdout', 'hello'); + }) + ); +} + +// default value +{ + const cmd = + `"${process.execPath}" eval "console.log('a'.repeat(1024 * 1024))"`; + + cp.exec( + cmd, + common.mustCall((err, stdout, stderr) => { + runChecks( + err, + { stdout, stderr }, + 'stdout', + 'a'.repeat(1024 * 1024) + ); + }) + ); +} + +// default value +{ + const cmd = + `"${process.execPath}" eval "console.log('a'.repeat(1024 * 1024 - 1))"`; + + cp.exec(cmd, common.mustSucceed((stdout, stderr) => { + assert.strictEqual(stdout.trim(), 'a'.repeat(1024 * 1024 - 1)); + assert.strictEqual(stderr, ''); + })); +} + +const unicode = '中文测试'; // length = 4, byte length = 12 + +{ + const cmd = `"${process.execPath}" eval "console.log('${unicode}');"`; + + cp.exec( + cmd, + { maxBuffer: 10 }, + common.mustCall((err, stdout, stderr) => { + runChecks(err, { stdout, stderr }, 'stdout', '中文测试\n'); + }) + ); +} + +{ + const cmd = `"${process.execPath}" eval "console.error('${unicode}');"`; + + cp.exec( + cmd, + { maxBuffer: 3 }, + common.mustCall((err, stdout, stderr) => { + runChecks(err, { stdout, stderr }, 'stderr', '中文测'); + }) + ); +} + +{ + const cmd = `"${process.execPath}" eval "console.log('${unicode}');"`; + + const child = cp.exec( + cmd, + { encoding: null, maxBuffer: 10 }, + common.mustCall((err, stdout, stderr) => { + runChecks(err, { stdout, stderr }, 'stdout', '中文测试\n'); + }) + ); + + child.stdout.setEncoding('utf-8'); +} + +{ + const cmd = `"${process.execPath}" eval "console.error('${unicode}');"`; + + const child = cp.exec( + cmd, + { encoding: null, maxBuffer: 3 }, + common.mustCall((err, stdout, stderr) => { + runChecks(err, { stdout, stderr }, 'stderr', '中文测'); + }) + ); + + child.stderr.setEncoding('utf-8'); +} + +{ + const cmd = `"${process.execPath}" eval "console.error('${unicode}');"`; + + cp.exec( + cmd, + { encoding: null, maxBuffer: 5 }, + common.mustCall((err, stdout, stderr) => { + const buf = Buffer.from(unicode).slice(0, 5); + runChecks(err, { stdout, stderr }, 'stderr', buf); + }) + ); +} diff --git a/tests/node_compat/test/parallel/test-child-process-exec-std-encoding.js b/tests/node_compat/test/parallel/test-child-process-exec-std-encoding.js new file mode 100644 index 000000000..85f3ec2bf --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-exec-std-encoding.js @@ -0,0 +1,33 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.8.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// TODO(PolarETech): The process.argv[3] check should be argv[2], and the +// command passed to exec() should not need to include "run", "-A", +// and "require.ts". + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const cp = require('child_process'); +const stdoutData = 'foo'; +const stderrData = 'bar'; +const expectedStdout = `${stdoutData}\n`; +const expectedStderr = `${stderrData}\n`; + +if (process.argv[3] === 'child') { + // The following console calls are part of the test. + console.log(stdoutData); + console.error(stderrData); +} else { + const cmd = `"${process.execPath}" run -A require.ts "${__filename}" child`; + const child = cp.exec(cmd, common.mustSucceed((stdout, stderr) => { + assert.strictEqual(stdout, expectedStdout); + assert.strictEqual(stderr, expectedStderr); + })); + child.stdout.setEncoding('utf-8'); + child.stderr.setEncoding('utf-8'); +} diff --git a/tests/node_compat/test/parallel/test-child-process-exec-stdout-stderr-data-string.js b/tests/node_compat/test/parallel/test-child-process-exec-stdout-stderr-data-string.js new file mode 100644 index 000000000..0e5453926 --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-exec-stdout-stderr-data-string.js @@ -0,0 +1,20 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +// Refs: https://github.com/nodejs/node/issues/7342 +const common = require('../common'); +const assert = require('assert'); +const exec = require('child_process').exec; + +const command = common.isWindows ? 'dir' : 'ls'; + +exec(command).stdout.on('data', common.mustCallAtLeast()); + +exec('fhqwhgads').stderr.on('data', common.mustCallAtLeast((data) => { + assert.strictEqual(typeof data, 'string'); +})); diff --git a/tests/node_compat/test/parallel/test-child-process-exec-timeout-not-expired.js b/tests/node_compat/test/parallel/test-child-process-exec-timeout-not-expired.js new file mode 100644 index 000000000..31fa1f725 --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-exec-timeout-not-expired.js @@ -0,0 +1,45 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// TODO(PolarETech): The process.argv[3] check should be argv[2], and the +// command passed to exec() should not need to include "run", "-A", +// and "require.ts". + +'use strict'; + +// Test exec() when a timeout is set, but not expired. + +const common = require('../common'); +const assert = require('assert'); +const cp = require('child_process'); + +const { + cleanupStaleProcess, + logAfterTime +} = require('../common/child_process'); + +const kTimeoutNotSupposedToExpire = 2 ** 30; +const childRunTime = common.platformTimeout(100); + +// The time spent in the child should be smaller than the timeout below. +assert(childRunTime < kTimeoutNotSupposedToExpire); + +if (process.argv[3] === 'child') { + logAfterTime(childRunTime); + return; +} + +const cmd = `"${process.execPath}" run -A require.ts "${__filename}" child`; + +cp.exec(cmd, { + timeout: kTimeoutNotSupposedToExpire +}, common.mustSucceed((stdout, stderr) => { + assert.strictEqual(stdout.trim(), 'child stdout'); + assert.strictEqual(stderr.trim(), 'child stderr'); +})); + +cleanupStaleProcess(__filename); diff --git a/tests/node_compat/test/parallel/test-child-process-execfile-maxbuf.js b/tests/node_compat/test/parallel/test-child-process-execfile-maxbuf.js new file mode 100644 index 000000000..729929c78 --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-execfile-maxbuf.js @@ -0,0 +1,99 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const { execFile } = require('child_process'); + +function checkFactory(streamName) { + return common.mustCall((err) => { + assert(err instanceof RangeError); + assert.strictEqual(err.message, `${streamName} maxBuffer length exceeded`); + assert.strictEqual(err.code, 'ERR_CHILD_PROCESS_STDIO_MAXBUFFER'); + }); +} + +// default value +{ + execFile( + process.execPath, + ['-e', 'console.log("a".repeat(1024 * 1024))'], + checkFactory('stdout') + ); +} + +// default value +{ + execFile( + process.execPath, + ['-e', 'console.log("a".repeat(1024 * 1024 - 1))'], + common.mustSucceed((stdout, stderr) => { + assert.strictEqual(stdout.trim(), 'a'.repeat(1024 * 1024 - 1)); + assert.strictEqual(stderr, ''); + }) + ); +} + +{ + const options = { maxBuffer: Infinity }; + + execFile( + process.execPath, + ['-e', 'console.log("hello world");'], + options, + common.mustSucceed((stdout, stderr) => { + assert.strictEqual(stdout.trim(), 'hello world'); + assert.strictEqual(stderr, ''); + }) + ); +} + +{ + execFile('echo', ['hello world'], { maxBuffer: 5 }, checkFactory('stdout')); +} + +const unicode = '中文测试'; // length = 4, byte length = 12 + +{ + execFile( + process.execPath, + ['-e', `console.log('${unicode}');`], + { maxBuffer: 10 }, + checkFactory('stdout')); +} + +{ + execFile( + process.execPath, + ['-e', `console.error('${unicode}');`], + { maxBuffer: 10 }, + checkFactory('stderr') + ); +} + +{ + const child = execFile( + process.execPath, + ['-e', `console.log('${unicode}');`], + { encoding: null, maxBuffer: 10 }, + checkFactory('stdout') + ); + + child.stdout.setEncoding('utf-8'); +} + +{ + const child = execFile( + process.execPath, + ['-e', `console.error('${unicode}');`], + { encoding: null, maxBuffer: 10 }, + checkFactory('stderr') + ); + + child.stderr.setEncoding('utf-8'); +} diff --git a/tests/node_compat/test/parallel/test-child-process-execfile.js b/tests/node_compat/test/parallel/test-child-process-execfile.js new file mode 100644 index 000000000..9f9268407 --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-execfile.js @@ -0,0 +1,135 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.8.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// TODO(PolarETech): The args passed to execFile() should not need to +// include "require.ts". + +// TODO(cjihrig): See inline TODO comments below. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const { execFile, execFileSync } = require('child_process'); +const { getSystemErrorName } = require('util'); +const fixtures = require('../common/fixtures'); +const os = require('os'); + +const fixture = fixtures.path('exit.js'); +const echoFixture = fixtures.path('echo.js'); +const execOpts = { encoding: 'utf8', shell: true }; + +{ + execFile( + process.execPath, + ['require.ts', fixture, 42], + common.mustCall((e) => { + // Check that arguments are included in message + assert.strictEqual(e.message.trim(), + `Command failed: ${process.execPath} require.ts ${fixture} 42`); + assert.strictEqual(e.code, 42); + }) + ); +} + +{ + // Verify that negative exit codes can be translated to UV error names. + const errorString = `Error: Command failed: ${process.execPath}`; + const code = -1; + const callback = common.mustCall((err, stdout, stderr) => { + assert.strictEqual(err.toString().trim(), errorString); + assert.strictEqual(err.code, getSystemErrorName(code)); + assert.strictEqual(err.killed, true); + assert.strictEqual(err.signal, null); + assert.strictEqual(err.cmd, process.execPath); + assert.strictEqual(stdout.trim(), ''); + assert.strictEqual(stderr.trim(), ''); + }); + const child = execFile(process.execPath, callback); + + child.kill(); + child.emit('close', code, null); +} + +{ + // Verify the shell option works properly + execFile(process.execPath, ['require.ts', fixture, 0], execOpts, common.mustSucceed()); +} + +{ + // Verify that the signal option works properly + const ac = new AbortController(); + const { signal } = ac; + + const test = () => { + const check = common.mustCall((err) => { + assert.strictEqual(err.code, 'ABORT_ERR'); + assert.strictEqual(err.name, 'AbortError'); + assert.strictEqual(err.signal, undefined); + }); + execFile(process.execPath, ['require.ts', echoFixture, 0], { signal }, check); + }; + + // Verify that it still works the same way now that the signal is aborted. + test(); + ac.abort(); +} + +{ + // Verify that does not spawn a child if already aborted + const signal = AbortSignal.abort(); + + const check = common.mustCall((err) => { + assert.strictEqual(err.code, 'ABORT_ERR'); + assert.strictEqual(err.name, 'AbortError'); + assert.strictEqual(err.signal, undefined); + }); + execFile(process.execPath, ['require.ts', echoFixture, 0], { signal }, check); +} + +{ + // Verify that if something different than Abortcontroller.signal + // is passed, ERR_INVALID_ARG_TYPE is thrown + assert.throws(() => { + const callback = common.mustNotCall(() => {}); + + execFile(process.execPath, ['require.ts', echoFixture, 0], { signal: 'hello' }, callback); + }, { code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' }); +} +{ + // Verify that the process completing removes the abort listener + const ac = new AbortController(); + const { signal } = ac; + + const callback = common.mustCall((err) => { + // TODO(cjihrig): The assertion on the next line currently fails because + // kEvents is not defined. See TODO comment in _events.mjs. + // assert.strictEqual(getEventListeners(ac.signal).length, 0); + assert.strictEqual(err, null); + }); + execFile(process.execPath, ['require.ts', fixture, 0], { signal }, callback); +} + +// Verify the execFile() stdout is the same as execFileSync(). +{ + const file = 'echo'; + const args = ['foo', 'bar']; + + // Test with and without `{ shell: true }` + [ + // Skipping shell-less test on Windows because its echo command is a shell built-in command. + ...(common.isWindows ? [] : [{ encoding: 'utf8' }]), + { shell: true, encoding: 'utf8' }, + ].forEach((options) => { + const execFileSyncStdout = execFileSync(file, args, options); + assert.strictEqual(execFileSyncStdout, `foo bar${os.EOL}`); + + execFile(file, args, options, common.mustCall((_, stdout) => { + assert.strictEqual(stdout, execFileSyncStdout); + })); + }); +} diff --git a/tests/node_compat/test/parallel/test-child-process-execfilesync-maxbuf.js b/tests/node_compat/test/parallel/test-child-process-execfilesync-maxbuf.js new file mode 100644 index 000000000..7ad857a18 --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-execfilesync-maxbuf.js @@ -0,0 +1,60 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); + +// This test checks that the maxBuffer option for child_process.execFileSync() +// works as expected. + +const assert = require('assert'); +const { getSystemErrorName } = require('util'); +const { execFileSync } = require('child_process'); +const msgOut = 'this is stdout'; +const msgOutBuf = Buffer.from(`${msgOut}\n`); + +const args = [ + '-e', + `console.log("${msgOut}");`, +]; + +// Verify that an error is returned if maxBuffer is surpassed. +{ + assert.throws(() => { + execFileSync(process.execPath, args, { maxBuffer: 1 }); + }, (e) => { + assert.ok(e, 'maxBuffer should error'); + assert.strictEqual(e.code, 'ENOBUFS'); + assert.strictEqual(getSystemErrorName(e.errno), 'ENOBUFS'); + // We can have buffers larger than maxBuffer because underneath we alloc 64k + // that matches our read sizes. + assert.deepStrictEqual(e.stdout, msgOutBuf); + return true; + }); +} + +// Verify that a maxBuffer size of Infinity works. +{ + const ret = execFileSync(process.execPath, args, { maxBuffer: Infinity }); + + assert.deepStrictEqual(ret, msgOutBuf); +} + +// Default maxBuffer size is 1024 * 1024. +{ + assert.throws(() => { + execFileSync( + process.execPath, + ['-e', "console.log('a'.repeat(1024 * 1024))"] + ); + }, (e) => { + assert.ok(e, 'maxBuffer should error'); + assert.strictEqual(e.code, 'ENOBUFS'); + assert.strictEqual(getSystemErrorName(e.errno), 'ENOBUFS'); + return true; + }); +} diff --git a/tests/node_compat/test/parallel/test-child-process-execsync-maxbuf.js b/tests/node_compat/test/parallel/test-child-process-execsync-maxbuf.js new file mode 100644 index 000000000..703896ef1 --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-execsync-maxbuf.js @@ -0,0 +1,76 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.8.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// TODO(cjihrig): This should use Node's -e instead of Deno's eval CLI arg. + +'use strict'; +require('../common'); + +// This test checks that the maxBuffer option for child_process.spawnSync() +// works as expected. + +const assert = require('assert'); +const { getSystemErrorName } = require('util'); +const { execSync } = require('child_process'); +const msgOut = 'this is stdout'; +const msgOutBuf = Buffer.from(`${msgOut}\n`); + +const args = [ + 'eval', + `"console.log('${msgOut}')";`, +]; + +// Verify that an error is returned if maxBuffer is surpassed. +{ + assert.throws(() => { + execSync(`"${process.execPath}" ${args.join(' ')}`, { maxBuffer: 1 }); + }, (e) => { + assert.ok(e, 'maxBuffer should error'); + assert.strictEqual(e.code, 'ENOBUFS'); + assert.strictEqual(getSystemErrorName(e.errno), 'ENOBUFS'); + // We can have buffers larger than maxBuffer because underneath we alloc 64k + // that matches our read sizes. + assert.deepStrictEqual(e.stdout, msgOutBuf); + return true; + }); +} + +// Verify that a maxBuffer size of Infinity works. +{ + const ret = execSync( + `"${process.execPath}" ${args.join(' ')}`, + { maxBuffer: Infinity } + ); + + assert.deepStrictEqual(ret, msgOutBuf); +} + +// Default maxBuffer size is 1024 * 1024. +{ + assert.throws(() => { + execSync( + `"${process.execPath}" eval "console.log('a'.repeat(1024 * 1024))"` + ); + }, (e) => { + assert.ok(e, 'maxBuffer should error'); + assert.strictEqual(e.code, 'ENOBUFS'); + assert.strictEqual(getSystemErrorName(e.errno), 'ENOBUFS'); + return true; + }); +} + +// Default maxBuffer size is 1024 * 1024. +{ + const ret = execSync( + `"${process.execPath}" eval "console.log('a'.repeat(1024 * 1024 - 1))"` + ); + + assert.deepStrictEqual( + ret.toString().trim(), + 'a'.repeat(1024 * 1024 - 1) + ); +} diff --git a/tests/node_compat/test/parallel/test-child-process-exit-code.js b/tests/node_compat/test/parallel/test-child-process-exit-code.js new file mode 100644 index 000000000..caa57986b --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-exit-code.js @@ -0,0 +1,51 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// TODO(PolarETech): The args passed to spawn() should not need to +// include "require.ts". + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const spawn = require('child_process').spawn; +const fixtures = require('../common/fixtures'); + +const exitScript = fixtures.path('exit.js'); +const exitChild = spawn(process.argv[0], ['require.ts', exitScript, 23]); +exitChild.on('exit', common.mustCall(function(code, signal) { + assert.strictEqual(code, 23); + assert.strictEqual(signal, null); +})); + + +const errorScript = fixtures.path('child_process_should_emit_error.js'); +const errorChild = spawn(process.argv[0], ['require.ts', errorScript]); +errorChild.on('exit', common.mustCall(function(code, signal) { + assert.ok(code !== 0); + assert.strictEqual(signal, null); +})); diff --git a/tests/node_compat/test/parallel/test-child-process-flush-stdio.js b/tests/node_compat/test/parallel/test-child-process-flush-stdio.js new file mode 100644 index 000000000..c39bcbdbe --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-flush-stdio.js @@ -0,0 +1,40 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const cp = require('child_process'); +const assert = require('assert'); + +// Windows' `echo` command is a built-in shell command and not an external +// executable like on *nix +const opts = { shell: common.isWindows }; + +const p = cp.spawn('echo', [], opts); + +p.on('close', common.mustCall((code, signal) => { + assert.strictEqual(code, 0); + assert.strictEqual(signal, null); + spawnWithReadable(); +})); + +p.stdout.read(); + +const spawnWithReadable = () => { + const buffer = []; + const p = cp.spawn('echo', ['123'], opts); + p.on('close', common.mustCall((code, signal) => { + assert.strictEqual(code, 0); + assert.strictEqual(signal, null); + assert.strictEqual(Buffer.concat(buffer).toString().trim(), '123'); + })); + p.stdout.on('readable', () => { + let buf; + while ((buf = p.stdout.read()) !== null) + buffer.push(buf); + }); +}; diff --git a/tests/node_compat/test/parallel/test-child-process-fork-ref.js b/tests/node_compat/test/parallel/test-child-process-fork-ref.js new file mode 100644 index 000000000..37c186af8 --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-fork-ref.js @@ -0,0 +1,72 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; + +// Ignore on Windows. +if (process.platform === 'win32') { + process.exit(0); +} + +require('../common'); +const assert = require('assert'); +const fork = require('child_process').fork; + +if (process.argv[2] === 'child') { + process.send('1'); + + // Check that child don't instantly die + setTimeout(function() { + process.send('2'); + }, 200); + + process.on('disconnect', function() { + process.stdout.write('3'); + }); + +} else { + const child = fork(__filename, ['child'], { silent: true }); + + const ipc = []; + let stdout = ''; + + child.on('message', function(msg) { + ipc.push(msg); + + if (msg === '2') child.disconnect(); + }); + + child.stdout.on('data', function(chunk) { + stdout += chunk; + }); + + child.once('exit', function() { + assert.deepStrictEqual(ipc, ['1', '2']); + assert.strictEqual(stdout, '3'); + }); +} diff --git a/tests/node_compat/test/parallel/test-child-process-fork-ref2.js b/tests/node_compat/test/parallel/test-child-process-fork-ref2.js new file mode 100644 index 000000000..da59d9378 --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-fork-ref2.js @@ -0,0 +1,63 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; + +// Ignore on Windows. +if (process.platform === 'win32') { + process.exit(0); +} + +const { + mustCall, + mustNotCall, + platformTimeout, +} = require('../common'); +const fork = require('child_process').fork; +const debug = require('util').debuglog('test'); + +if (process.argv[2] === 'child') { + debug('child -> call disconnect'); + process.disconnect(); + + setTimeout(() => { + debug('child -> will this keep it alive?'); + process.on('message', mustNotCall()); + }, platformTimeout(400)); + +} else { + const child = fork(__filename, ['child']); + + child.on('disconnect', mustCall(() => { + debug('parent -> disconnect'); + })); + + child.once('exit', mustCall(() => { + debug('parent -> exit'); + })); +} diff --git a/tests/node_compat/test/parallel/test-child-process-ipc-next-tick.js b/tests/node_compat/test/parallel/test-child-process-ipc-next-tick.js new file mode 100644 index 000000000..d255a0a64 --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-ipc-next-tick.js @@ -0,0 +1,52 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +// Ignore on Windows. +if (process.platform === 'win32') { + process.exit(0); +} + +const common = require('../common'); +const assert = require('assert'); +const cp = require('child_process'); +const NUM_MESSAGES = 10; +const values = []; + +for (let i = 0; i < NUM_MESSAGES; ++i) { + values[i] = i; +} + +if (process.argv[2] === 'child') { + const received = values.map(() => { return false; }); + + process.on('uncaughtException', common.mustCall((err) => { + received[err] = true; + const done = received.every((element) => { return element === true; }); + + if (done) + process.disconnect(); + }, NUM_MESSAGES)); + + process.on('message', (msg) => { + // If messages are handled synchronously, throwing should break the IPC + // message processing. + throw msg; + }); + + process.send('ready'); +} else { + const child = cp.fork(__filename, ['child']); + + child.on('message', common.mustCall((msg) => { + assert.strictEqual(msg, 'ready'); + values.forEach((value) => { + child.send(value); + }); + })); +} diff --git a/tests/node_compat/test/parallel/test-child-process-ipc.js b/tests/node_compat/test/parallel/test-child-process-ipc.js new file mode 100644 index 000000000..c1d7bc2b6 --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-ipc.js @@ -0,0 +1,73 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// TODO(PolarETech): The args passed to spawn() should not need to +// include "require.ts". + +'use strict'; + +const { + mustCall, + mustNotCall, +} = require('../common'); +const assert = require('assert'); +const debug = require('util').debuglog('test'); + +const { spawn } = require('child_process'); +const fixtures = require('../common/fixtures'); + +const sub = fixtures.path('echo.js'); + +const child = spawn(process.argv[0], ['require.ts', sub]); + +child.stderr.on('data', mustNotCall()); + +child.stdout.setEncoding('utf8'); + +const messages = [ + 'hello world\r\n', + 'echo me\r\n', +]; + +child.stdout.on('data', mustCall((data) => { + debug(`child said: ${JSON.stringify(data)}`); + const test = messages.shift(); + debug(`testing for '${test}'`); + assert.strictEqual(data, test); + if (messages.length) { + debug(`writing '${messages[0]}'`); + child.stdin.write(messages[0]); + } else { + assert.strictEqual(messages.length, 0); + child.stdin.end(); + } +}, messages.length)); + +child.stdout.on('end', mustCall((data) => { + debug('child end'); +})); diff --git a/tests/node_compat/test/parallel/test-child-process-kill.js b/tests/node_compat/test/parallel/test-child-process-kill.js new file mode 100644 index 000000000..4d4ac3033 --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-kill.js @@ -0,0 +1,48 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const spawn = require('child_process').spawn; +const cat = spawn(common.isWindows ? 'cmd' : 'cat'); + +cat.stdout.on('end', common.mustCall()); +cat.stderr.on('data', common.mustNotCall()); +cat.stderr.on('end', common.mustCall()); + +cat.on('exit', common.mustCall((code, signal) => { + assert.strictEqual(code, null); + assert.strictEqual(signal, 'SIGTERM'); + assert.strictEqual(cat.signalCode, 'SIGTERM'); +})); + +assert.strictEqual(cat.signalCode, null); +assert.strictEqual(cat.killed, false); +cat.kill(); +assert.strictEqual(cat.killed, true); diff --git a/tests/node_compat/test/parallel/test-child-process-set-blocking.js b/tests/node_compat/test/parallel/test-child-process-set-blocking.js new file mode 100644 index 000000000..b43d9ba9c --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-set-blocking.js @@ -0,0 +1,43 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const ch = require('child_process'); + +const SIZE = 100000; +const python = process.env.PYTHON || (common.isWindows ? 'python' : 'python3'); + +const cp = ch.spawn(python, ['-c', `print(${SIZE} * "C")`], { + stdio: 'inherit' +}); + +cp.on('exit', common.mustCall(function(code) { + assert.strictEqual(code, 0); +})); diff --git a/tests/node_compat/test/parallel/test-child-process-spawn-args.js b/tests/node_compat/test/parallel/test-child-process-spawn-args.js new file mode 100644 index 000000000..e2597c921 --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-spawn-args.js @@ -0,0 +1,62 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +// This test confirms that `undefined`, `null`, and `[]` +// can be used as a placeholder for the second argument (`args`) of `spawn()`. +// Previously, there was a bug where using `undefined` for the second argument +// caused the third argument (`options`) to be ignored. +// See https://github.com/nodejs/node/issues/24912. + +const common = require('../common'); +const tmpdir = require('../common/tmpdir'); + +const assert = require('assert'); +const { spawn } = require('child_process'); + +tmpdir.refresh(); + +const command = common.isWindows ? 'cd' : 'pwd'; +const options = { cwd: tmpdir.path }; + +if (common.isWindows) { + // This test is not the case for Windows based systems + // unless the `shell` options equals to `true` + + options.shell = true; +} + +const testCases = [ + undefined, + null, + [], +]; + +const expectedResult = tmpdir.path.trim().toLowerCase(); + +(async () => { + const results = await Promise.all( + testCases.map((testCase) => { + return new Promise((resolve) => { + const subprocess = spawn(command, testCase, options); + + let accumulatedData = Buffer.alloc(0); + + subprocess.stdout.on('data', common.mustCall((data) => { + accumulatedData = Buffer.concat([accumulatedData, data]); + })); + + subprocess.stdout.on('end', () => { + resolve(accumulatedData.toString().trim().toLowerCase()); + }); + }); + }) + ); + + assert.deepStrictEqual([...new Set(results)], [expectedResult]); +})().then(common.mustCall()); diff --git a/tests/node_compat/test/parallel/test-child-process-spawn-event.js b/tests/node_compat/test/parallel/test-child-process-spawn-event.js new file mode 100644 index 000000000..315644fd1 --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-spawn-event.js @@ -0,0 +1,34 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const spawn = require('child_process').spawn; +const assert = require('assert'); + +const subprocess = spawn('echo', ['ok']); + +let didSpawn = false; +subprocess.on('spawn', function() { + didSpawn = true; +}); +function mustCallAfterSpawn() { + return common.mustCall(function() { + assert.ok(didSpawn); + }); +} + +subprocess.on('error', common.mustNotCall()); +subprocess.on('spawn', common.mustCall()); +subprocess.stdout.on('data', mustCallAfterSpawn()); +subprocess.stdout.on('end', mustCallAfterSpawn()); +subprocess.stdout.on('close', mustCallAfterSpawn()); +subprocess.stderr.on('data', common.mustNotCall()); +subprocess.stderr.on('end', mustCallAfterSpawn()); +subprocess.stderr.on('close', mustCallAfterSpawn()); +subprocess.on('exit', mustCallAfterSpawn()); +subprocess.on('close', mustCallAfterSpawn()); diff --git a/tests/node_compat/test/parallel/test-child-process-spawnsync-args.js b/tests/node_compat/test/parallel/test-child-process-spawnsync-args.js new file mode 100644 index 000000000..05e04a92e --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-spawnsync-args.js @@ -0,0 +1,55 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +// This test confirms that `undefined`, `null`, and `[]` can be used +// as a placeholder for the second argument (`args`) of `spawnSync()`. +// Previously, there was a bug where using `undefined` for the second argument +// caused the third argument (`options`) to be ignored. +// See https://github.com/nodejs/node/issues/24912. + +const common = require('../common'); +const tmpdir = require('../common/tmpdir'); + +const assert = require('assert'); +const { spawnSync } = require('child_process'); + +const command = common.isWindows ? 'cd' : 'pwd'; +const options = { cwd: tmpdir.path }; + +tmpdir.refresh(); + +if (common.isWindows) { + // This test is not the case for Windows based systems + // unless the `shell` options equals to `true` + + options.shell = true; +} + +const testCases = [ + undefined, + null, + [], +]; + +const expectedResult = tmpdir.path.trim().toLowerCase(); + +const results = testCases.map((testCase) => { + const { stdout, stderr, error } = spawnSync( + command, + testCase, + options + ); + + assert.ifError(error); + assert.deepStrictEqual(stderr, Buffer.alloc(0)); + + return stdout.toString().trim().toLowerCase(); +}); + +assert.deepStrictEqual([...new Set(results)], [expectedResult]); diff --git a/tests/node_compat/test/parallel/test-child-process-spawnsync-env.js b/tests/node_compat/test/parallel/test-child-process-spawnsync-env.js new file mode 100644 index 000000000..d08ed48d9 --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-spawnsync-env.js @@ -0,0 +1,47 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.8.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// TODO(cjihrig): The process.argv[3] check should be argv[2], and the +// arguments array passed to spawnSync() should not need to include +// "require.ts". + +'use strict'; +require('../common'); +const assert = require('assert'); +const cp = require('child_process'); + +if (process.argv[3] === 'child') { + console.log(process.env.foo); +} else { + const expected = 'bar'; + const child = cp.spawnSync(process.execPath, ["require.ts", __filename, 'child'], { + env: Object.assign(process.env, { foo: expected }) + }); + + assert.strictEqual(child.stdout.toString().trim(), expected); +} diff --git a/tests/node_compat/test/parallel/test-child-process-spawnsync-maxbuf.js b/tests/node_compat/test/parallel/test-child-process-spawnsync-maxbuf.js new file mode 100644 index 000000000..62b71c729 --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-spawnsync-maxbuf.js @@ -0,0 +1,65 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); + +// This test checks that the maxBuffer option for child_process.spawnSync() +// works as expected. + +const assert = require('assert'); +const spawnSync = require('child_process').spawnSync; +const { getSystemErrorName } = require('util'); +const msgOut = 'this is stdout'; +const msgOutBuf = Buffer.from(`${msgOut}\n`); + +const args = [ + '-e', + `console.log("${msgOut}");`, +]; + +// Verify that an error is returned if maxBuffer is surpassed. +{ + const ret = spawnSync(process.execPath, args, { maxBuffer: 1 }); + + assert.ok(ret.error, 'maxBuffer should error'); + assert.strictEqual(ret.error.code, 'ENOBUFS'); + assert.strictEqual(getSystemErrorName(ret.error.errno), 'ENOBUFS'); + // We can have buffers larger than maxBuffer because underneath we alloc 64k + // that matches our read sizes. + assert.deepStrictEqual(ret.stdout, msgOutBuf); +} + +// Verify that a maxBuffer size of Infinity works. +{ + const ret = spawnSync(process.execPath, args, { maxBuffer: Infinity }); + + assert.ifError(ret.error); + assert.deepStrictEqual(ret.stdout, msgOutBuf); +} + +// Default maxBuffer size is 1024 * 1024. +{ + const args = ['-e', "console.log('a'.repeat(1024 * 1024))"]; + const ret = spawnSync(process.execPath, args); + + assert.ok(ret.error, 'maxBuffer should error'); + assert.strictEqual(ret.error.code, 'ENOBUFS'); + assert.strictEqual(getSystemErrorName(ret.error.errno), 'ENOBUFS'); +} + +// Default maxBuffer size is 1024 * 1024. +{ + const args = ['-e', "console.log('a'.repeat(1024 * 1024 - 1))"]; + const ret = spawnSync(process.execPath, args); + + assert.ifError(ret.error); + assert.deepStrictEqual( + ret.stdout.toString().trim(), + 'a'.repeat(1024 * 1024 - 1) + ); +} diff --git a/tests/node_compat/test/parallel/test-child-process-spawnsync-validation-errors.js b/tests/node_compat/test/parallel/test-child-process-spawnsync-validation-errors.js new file mode 100644 index 000000000..89ff02260 --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-spawnsync-validation-errors.js @@ -0,0 +1,223 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const spawnSync = require('child_process').spawnSync; +const signals = require('os').constants.signals; +const rootUser = common.isWindows ? false : + common.isIBMi ? true : process.getuid() === 0; + +const invalidArgTypeError = { code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' }; +const invalidRangeError = { code: 'ERR_OUT_OF_RANGE', name: 'RangeError' }; + +function pass(option, value) { + // Run the command with the specified option. Since it's not a real command, + // spawnSync() should run successfully but return an ENOENT error. + const child = spawnSync('not_a_real_command', { [option]: value }); + + assert.strictEqual(child.error.code, 'ENOENT'); +} + +function fail(option, value, message) { + assert.throws(() => { + spawnSync('not_a_real_command', { [option]: value }); + }, message); +} + +{ + // Validate the cwd option + pass('cwd', undefined); + pass('cwd', null); + pass('cwd', __dirname); + fail('cwd', 0, invalidArgTypeError); + fail('cwd', 1, invalidArgTypeError); + fail('cwd', true, invalidArgTypeError); + fail('cwd', false, invalidArgTypeError); + fail('cwd', [], invalidArgTypeError); + fail('cwd', {}, invalidArgTypeError); + fail('cwd', common.mustNotCall(), invalidArgTypeError); +} + +{ + // Validate the detached option + pass('detached', undefined); + pass('detached', null); + pass('detached', true); + pass('detached', false); + fail('detached', 0, invalidArgTypeError); + fail('detached', 1, invalidArgTypeError); + fail('detached', __dirname, invalidArgTypeError); + fail('detached', [], invalidArgTypeError); + fail('detached', {}, invalidArgTypeError); + fail('detached', common.mustNotCall(), invalidArgTypeError); +} + +if (!common.isWindows) { + { + // Validate the uid option + if (!rootUser) { + pass('uid', undefined); + pass('uid', null); + pass('uid', process.getuid()); + fail('uid', __dirname, invalidArgTypeError); + fail('uid', true, invalidArgTypeError); + fail('uid', false, invalidArgTypeError); + fail('uid', [], invalidArgTypeError); + fail('uid', {}, invalidArgTypeError); + fail('uid', common.mustNotCall(), invalidArgTypeError); + fail('uid', NaN, invalidArgTypeError); + fail('uid', Infinity, invalidArgTypeError); + fail('uid', 3.1, invalidArgTypeError); + fail('uid', -3.1, invalidArgTypeError); + } + } + + { + // Validate the gid option + if (process.getgid() !== 0) { + pass('gid', undefined); + pass('gid', null); + pass('gid', process.getgid()); + fail('gid', __dirname, invalidArgTypeError); + fail('gid', true, invalidArgTypeError); + fail('gid', false, invalidArgTypeError); + fail('gid', [], invalidArgTypeError); + fail('gid', {}, invalidArgTypeError); + fail('gid', common.mustNotCall(), invalidArgTypeError); + fail('gid', NaN, invalidArgTypeError); + fail('gid', Infinity, invalidArgTypeError); + fail('gid', 3.1, invalidArgTypeError); + fail('gid', -3.1, invalidArgTypeError); + } + } +} + +{ + // Validate the shell option + pass('shell', undefined); + pass('shell', null); + pass('shell', false); + fail('shell', 0, invalidArgTypeError); + fail('shell', 1, invalidArgTypeError); + fail('shell', [], invalidArgTypeError); + fail('shell', {}, invalidArgTypeError); + fail('shell', common.mustNotCall(), invalidArgTypeError); +} + +{ + // Validate the argv0 option + pass('argv0', undefined); + pass('argv0', null); + pass('argv0', 'myArgv0'); + fail('argv0', 0, invalidArgTypeError); + fail('argv0', 1, invalidArgTypeError); + fail('argv0', true, invalidArgTypeError); + fail('argv0', false, invalidArgTypeError); + fail('argv0', [], invalidArgTypeError); + fail('argv0', {}, invalidArgTypeError); + fail('argv0', common.mustNotCall(), invalidArgTypeError); +} + +{ + // Validate the windowsHide option + pass('windowsHide', undefined); + pass('windowsHide', null); + pass('windowsHide', true); + pass('windowsHide', false); + fail('windowsHide', 0, invalidArgTypeError); + fail('windowsHide', 1, invalidArgTypeError); + fail('windowsHide', __dirname, invalidArgTypeError); + fail('windowsHide', [], invalidArgTypeError); + fail('windowsHide', {}, invalidArgTypeError); + fail('windowsHide', common.mustNotCall(), invalidArgTypeError); +} + +{ + // Validate the windowsVerbatimArguments option + pass('windowsVerbatimArguments', undefined); + pass('windowsVerbatimArguments', null); + pass('windowsVerbatimArguments', true); + pass('windowsVerbatimArguments', false); + fail('windowsVerbatimArguments', 0, invalidArgTypeError); + fail('windowsVerbatimArguments', 1, invalidArgTypeError); + fail('windowsVerbatimArguments', __dirname, invalidArgTypeError); + fail('windowsVerbatimArguments', [], invalidArgTypeError); + fail('windowsVerbatimArguments', {}, invalidArgTypeError); + fail('windowsVerbatimArguments', common.mustNotCall(), invalidArgTypeError); +} + +{ + // Validate the timeout option + pass('timeout', undefined); + pass('timeout', null); + pass('timeout', 1); + pass('timeout', 0); + fail('timeout', -1, invalidRangeError); + fail('timeout', true, invalidRangeError); + fail('timeout', false, invalidRangeError); + fail('timeout', __dirname, invalidRangeError); + fail('timeout', [], invalidRangeError); + fail('timeout', {}, invalidRangeError); + fail('timeout', common.mustNotCall(), invalidRangeError); + fail('timeout', NaN, invalidRangeError); + fail('timeout', Infinity, invalidRangeError); + fail('timeout', 3.1, invalidRangeError); + fail('timeout', -3.1, invalidRangeError); +} + +{ + // Validate the maxBuffer option + pass('maxBuffer', undefined); + pass('maxBuffer', null); + pass('maxBuffer', 1); + pass('maxBuffer', 0); + pass('maxBuffer', Infinity); + pass('maxBuffer', 3.14); + fail('maxBuffer', -1, invalidRangeError); + fail('maxBuffer', NaN, invalidRangeError); + fail('maxBuffer', -Infinity, invalidRangeError); + fail('maxBuffer', true, invalidRangeError); + fail('maxBuffer', false, invalidRangeError); + fail('maxBuffer', __dirname, invalidRangeError); + fail('maxBuffer', [], invalidRangeError); + fail('maxBuffer', {}, invalidRangeError); + fail('maxBuffer', common.mustNotCall(), invalidRangeError); +} + +{ + // Validate the killSignal option + const unknownSignalErr = { code: 'ERR_UNKNOWN_SIGNAL', name: 'TypeError' }; + + pass('killSignal', undefined); + pass('killSignal', null); + pass('killSignal', 'SIGKILL'); + fail('killSignal', 'SIGNOTAVALIDSIGNALNAME', unknownSignalErr); + fail('killSignal', true, invalidArgTypeError); + fail('killSignal', false, invalidArgTypeError); + fail('killSignal', [], invalidArgTypeError); + fail('killSignal', {}, invalidArgTypeError); + fail('killSignal', common.mustNotCall(), invalidArgTypeError); + + // Invalid signal names and numbers should fail + fail('killSignal', 500, unknownSignalErr); + fail('killSignal', 0, unknownSignalErr); + fail('killSignal', -200, unknownSignalErr); + fail('killSignal', 3.14, unknownSignalErr); + + Object.getOwnPropertyNames(Object.prototype).forEach((property) => { + fail('killSignal', property, unknownSignalErr); + }); + + // Valid signal names and numbers should pass + for (const signalName in signals) { + pass('killSignal', signals[signalName]); + pass('killSignal', signalName); + pass('killSignal', signalName.toLowerCase()); + } +} diff --git a/tests/node_compat/test/parallel/test-child-process-spawnsync.js b/tests/node_compat/test/parallel/test-child-process-spawnsync.js new file mode 100644 index 000000000..bb60f3bef --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-spawnsync.js @@ -0,0 +1,74 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +const assert = require('assert'); +const { spawnSync } = require('child_process'); +const { getSystemErrorName } = require('util'); + +// `sleep` does different things on Windows and Unix, but in both cases, it does +// more-or-less nothing if there are no parameters +const ret = spawnSync('sleep', ['0']); +assert.strictEqual(ret.status, 0); + +// Error test when command does not exist +const ret_err = spawnSync('command_does_not_exist', ['bar']).error; + +assert.strictEqual(ret_err.code, 'ENOENT'); +assert.strictEqual(getSystemErrorName(ret_err.errno), 'ENOENT'); +assert.strictEqual(ret_err.syscall, 'spawnSync command_does_not_exist'); +assert.strictEqual(ret_err.path, 'command_does_not_exist'); +assert.deepStrictEqual(ret_err.spawnargs, ['bar']); + +{ + // Test the cwd option + const cwd = tmpdir.path; + const response = spawnSync(...common.pwdCommand, { cwd }); + + assert.strictEqual(response.stdout.toString().trim(), cwd); +} + + +{ + // Assert Buffer is the default encoding + const retDefault = spawnSync(...common.pwdCommand); + const retBuffer = spawnSync(...common.pwdCommand, { encoding: 'buffer' }); + assert.deepStrictEqual(retDefault.output, retBuffer.output); + + const retUTF8 = spawnSync(...common.pwdCommand, { encoding: 'utf8' }); + const stringifiedDefault = [ + null, + retDefault.stdout.toString(), + retDefault.stderr.toString(), + ]; + assert.deepStrictEqual(retUTF8.output, stringifiedDefault); +} diff --git a/tests/node_compat/test/parallel/test-child-process-stdio-inherit.js b/tests/node_compat/test/parallel/test-child-process-stdio-inherit.js new file mode 100644 index 000000000..e213dd6b8 --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-stdio-inherit.js @@ -0,0 +1,66 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// TODO(PolarETech): The process.argv[3] check should be argv[2], and +// the args passed to spawn() should not need to include "require.ts". + +'use strict'; +require('../common'); +const assert = require('assert'); +const spawn = require('child_process').spawn; + +if (process.argv[3] === 'parent') + parent(); +else + grandparent(); + +function grandparent() { + const child = spawn(process.execPath, ['require.ts', __filename, 'parent']); + child.stderr.pipe(process.stderr); + let output = ''; + const input = 'asdfasdf'; + + child.stdout.on('data', function(chunk) { + output += chunk; + }); + child.stdout.setEncoding('utf8'); + + child.stdin.end(input); + + child.on('close', function(code, signal) { + assert.strictEqual(code, 0); + assert.strictEqual(signal, null); + // 'cat' on windows adds a \r\n at the end. + assert.strictEqual(output.trim(), input.trim()); + }); +} + +function parent() { + // Should not immediately exit. + spawn('cat', [], { stdio: 'inherit' }); +} diff --git a/tests/node_compat/test/parallel/test-child-process-stdout-flush-exit.js b/tests/node_compat/test/parallel/test-child-process-stdout-flush-exit.js new file mode 100644 index 000000000..585cc6084 --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-stdout-flush-exit.js @@ -0,0 +1,67 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// TODO(PolarETech): The process.argv[3] check should be argv[2], +// the args passed to spawn() should not need to include "require.ts", +// and the process.argv[2] passed to spawn() should be argv[1]. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +// If child process output to console and exit +// The console.log statements here are part of the test. +if (process.argv[3] === 'child') { + console.log('hello'); + for (let i = 0; i < 200; i++) { + console.log('filler'); + } + console.log('goodbye'); + process.exit(0); +} else { + // parent process + const spawn = require('child_process').spawn; + + // spawn self as child + const child = spawn(process.argv[0], ['require.ts', process.argv[2], 'child']); + + let stdout = ''; + + child.stderr.on('data', common.mustNotCall()); + + // Check if we receive both 'hello' at start and 'goodbye' at end + child.stdout.setEncoding('utf8'); + child.stdout.on('data', common.mustCallAtLeast((data) => { + stdout += data; + })); + + child.on('close', common.mustCall(() => { + assert.strictEqual(stdout.slice(0, 6), 'hello\n'); + assert.strictEqual(stdout.slice(stdout.length - 8), 'goodbye\n'); + })); +} diff --git a/tests/node_compat/test/parallel/test-child-process-stdout-flush.js b/tests/node_compat/test/parallel/test-child-process-stdout-flush.js new file mode 100644 index 000000000..4054d2189 --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-stdout-flush.js @@ -0,0 +1,58 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// TODO(PolarETech): The args passed to spawn() should not need to +// include "require.ts". + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const spawn = require('child_process').spawn; +const fixtures = require('../common/fixtures'); + +const sub = fixtures.path('print-chars.js'); + +const n = 500000; + +const child = spawn(process.argv[0], ['require.ts', sub, n]); + +let count = 0; + +child.stderr.setEncoding('utf8'); +child.stderr.on('data', common.mustNotCall()); + +child.stdout.setEncoding('utf8'); +child.stdout.on('data', (data) => { + count += data.length; +}); + +child.on('close', common.mustCall((code, signal) => { + assert.strictEqual(code, 0); + assert.strictEqual(signal, null); + assert.strictEqual(n, count); +})); diff --git a/tests/node_compat/test/parallel/test-console-async-write-error.js b/tests/node_compat/test/parallel/test-console-async-write-error.js new file mode 100644 index 000000000..e7591cb9b --- /dev/null +++ b/tests/node_compat/test/parallel/test-console-async-write-error.js @@ -0,0 +1,22 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const { Console } = require('console'); +const { Writable } = require('stream'); + +for (const method of ['dir', 'log', 'warn']) { + const out = new Writable({ + write: common.mustCall((chunk, enc, callback) => { + process.nextTick(callback, new Error('foobar')); + }) + }); + + const c = new Console(out, out, true); + c[method]('abc'); // Should not throw. +} diff --git a/tests/node_compat/test/parallel/test-console-group.js b/tests/node_compat/test/parallel/test-console-group.js new file mode 100644 index 000000000..f07107cec --- /dev/null +++ b/tests/node_compat/test/parallel/test-console-group.js @@ -0,0 +1,248 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const { + hijackStdout, + hijackStderr, + restoreStdout, + restoreStderr +} = require('../common/hijackstdio'); + +const assert = require('assert'); +const Console = require('console').Console; + +let c, stdout, stderr; + +function setup(groupIndentation) { + stdout = ''; + hijackStdout(function(data) { + stdout += data; + }); + + stderr = ''; + hijackStderr(function(data) { + stderr += data; + }); + + c = new Console({ stdout: process.stdout, + stderr: process.stderr, + colorMode: false, + groupIndentation: groupIndentation }); +} + +function teardown() { + restoreStdout(); + restoreStderr(); +} + +// Basic group() functionality +{ + setup(); + const expectedOut = 'This is the outer level\n' + + ' Level 2\n' + + ' Level 3\n' + + ' Back to level 2\n' + + 'Back to the outer level\n' + + 'Still at the outer level\n'; + + + const expectedErr = ' More of level 3\n'; + + c.log('This is the outer level'); + c.group(); + c.log('Level 2'); + c.group(); + c.log('Level 3'); + c.warn('More of level 3'); + c.groupEnd(); + c.log('Back to level 2'); + c.groupEnd(); + c.log('Back to the outer level'); + c.groupEnd(); + c.log('Still at the outer level'); + + assert.strictEqual(stdout, expectedOut); + assert.strictEqual(stderr, expectedErr); + teardown(); +} + +// Group indentation is tracked per Console instance. +{ + setup(); + const expectedOut = 'No indentation\n' + + 'None here either\n' + + ' Now the first console is indenting\n' + + 'But the second one does not\n'; + const expectedErr = ''; + + const c2 = new Console(process.stdout, process.stderr); + c.log('No indentation'); + c2.log('None here either'); + c.group(); + c.log('Now the first console is indenting'); + c2.log('But the second one does not'); + + assert.strictEqual(stdout, expectedOut); + assert.strictEqual(stderr, expectedErr); + teardown(); +} + +// Make sure labels work. +{ + setup(); + const expectedOut = 'This is a label\n' + + ' And this is the data for that label\n'; + const expectedErr = ''; + + c.group('This is a label'); + c.log('And this is the data for that label'); + + assert.strictEqual(stdout, expectedOut); + assert.strictEqual(stderr, expectedErr); + teardown(); +} + +// Check that console.groupCollapsed() is an alias of console.group() +{ + setup(); + const expectedOut = 'Label\n' + + ' Level 2\n' + + ' Level 3\n'; + const expectedErr = ''; + + c.groupCollapsed('Label'); + c.log('Level 2'); + c.groupCollapsed(); + c.log('Level 3'); + + assert.strictEqual(stdout, expectedOut); + assert.strictEqual(stderr, expectedErr); + teardown(); +} + +// Check that multiline strings and object output are indented properly. +{ + setup(); + const expectedOut = 'not indented\n' + + ' indented\n' + + ' also indented\n' + + ' {\n' + + " also: 'a',\n" + + " multiline: 'object',\n" + + " should: 'be',\n" + + " indented: 'properly',\n" + + " kthx: 'bai'\n" + + ' }\n'; + const expectedErr = ''; + + c.log('not indented'); + c.group(); + c.log('indented\nalso indented'); + c.log({ also: 'a', + multiline: 'object', + should: 'be', + indented: 'properly', + kthx: 'bai' }); + + assert.strictEqual(stdout, expectedOut); + assert.strictEqual(stderr, expectedErr); + teardown(); +} + +// Check that the kGroupIndent symbol property is not enumerable +{ + const keys = Reflect.ownKeys(console) + .filter((val) => Object.prototype.propertyIsEnumerable.call(console, val)) + .map((val) => val.toString()); + assert(!keys.includes('Symbol(groupIndent)'), + 'groupIndent should not be enumerable'); +} + +// Check custom groupIndentation. +{ + setup(3); + const expectedOut = 'Set the groupIndentation parameter to 3\n' + + 'This is the outer level\n' + + ' Level 2\n' + + ' Level 3\n' + + ' Back to level 2\n' + + 'Back to the outer level\n' + + 'Still at the outer level\n'; + + + const expectedErr = ' More of level 3\n'; + + c.log('Set the groupIndentation parameter to 3'); + c.log('This is the outer level'); + c.group(); + c.log('Level 2'); + c.group(); + c.log('Level 3'); + c.warn('More of level 3'); + c.groupEnd(); + c.log('Back to level 2'); + c.groupEnd(); + c.log('Back to the outer level'); + c.groupEnd(); + c.log('Still at the outer level'); + + assert.strictEqual(stdout, expectedOut); + assert.strictEqual(stderr, expectedErr); + teardown(); +} + +// Check the correctness of the groupIndentation parameter. +{ + // TypeError + [null, 'str', [], false, true, {}].forEach((e) => { + assert.throws( + () => { + new Console({ stdout: process.stdout, + stderr: process.stderr, + groupIndentation: e }); + }, + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + } + ); + }); + + // RangeError for integer + [NaN, 1.01].forEach((e) => { + assert.throws( + () => { + new Console({ stdout: process.stdout, + stderr: process.stderr, + groupIndentation: e }); + }, + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: /an integer/, + } + ); + }); + + // RangeError + [-1, 1001].forEach((e) => { + assert.throws( + () => { + new Console({ stdout: process.stdout, + stderr: process.stderr, + groupIndentation: e }); + }, + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: />= 0 && <= 1000/, + } + ); + }); +} diff --git a/tests/node_compat/test/parallel/test-console-instance.js b/tests/node_compat/test/parallel/test-console-instance.js new file mode 100644 index 000000000..ee561564f --- /dev/null +++ b/tests/node_compat/test/parallel/test-console-instance.js @@ -0,0 +1,156 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const Stream = require('stream'); +const requiredConsole = require('console'); +const Console = requiredConsole.Console; + +const out = new Stream(); +const err = new Stream(); + +// Ensure the Console instance doesn't write to the +// process' "stdout" or "stderr" streams. +process.stdout.write = process.stderr.write = common.mustNotCall(); + +// Make sure that the "Console" function exists. +assert.strictEqual(typeof Console, 'function'); + +// Note: We don't replace global console with node.js console +// assert.strictEqual(requiredConsole, global.console); +// Make sure the custom instanceof of Console works +assert.ok(global.console instanceof Console); +assert.ok(!({} instanceof Console)); + +// Make sure that the Console constructor throws +// when not given a writable stream instance. +assert.throws( + () => { new Console(); }, + { + code: 'ERR_CONSOLE_WRITABLE_STREAM', + name: 'TypeError', + message: /stdout/ + } +); + +// Console constructor should throw if stderr exists but is not writable. +assert.throws( + () => { + out.write = () => {}; + err.write = undefined; + new Console(out, err); + }, + { + code: 'ERR_CONSOLE_WRITABLE_STREAM', + name: 'TypeError', + message: /stderr/ + } +); + +out.write = err.write = (d) => {}; + +{ + const c = new Console(out, err); + assert.ok(c instanceof Console); + + out.write = err.write = common.mustCall((d) => { + assert.strictEqual(d, 'test\n'); + }, 2); + + c.log('test'); + c.error('test'); + + out.write = common.mustCall((d) => { + assert.strictEqual(d, '{ foo: 1 }\n'); + }); + + c.dir({ foo: 1 }); + + // Ensure that the console functions are bound to the console instance. + let called = 0; + out.write = common.mustCall((d) => { + called++; + assert.strictEqual(d, `${called} ${called - 1} [ 1, 2, 3 ]\n`); + }, 3); + + [1, 2, 3].forEach(c.log); +} + +// Test calling Console without the `new` keyword. +{ + const withoutNew = Console(out, err); + assert.ok(withoutNew instanceof Console); +} + +// Test extending Console +{ + class MyConsole extends Console { + hello() {} + // See if the methods on Console.prototype are overridable. + log() { return 'overridden'; } + } + const myConsole = new MyConsole(process.stdout); + assert.strictEqual(typeof myConsole.hello, 'function'); + assert.ok(myConsole instanceof Console); + assert.strictEqual(myConsole.log(), 'overridden'); + + const log = myConsole.log; + assert.strictEqual(log(), 'overridden'); +} + +// Instance that does not ignore the stream errors. +{ + const c2 = new Console(out, err, false); + + out.write = () => { throw new Error('out'); }; + err.write = () => { throw new Error('err'); }; + + assert.throws(() => c2.log('foo'), /^Error: out$/); + assert.throws(() => c2.warn('foo'), /^Error: err$/); + assert.throws(() => c2.dir('foo'), /^Error: out$/); +} + +// Console constructor throws if inspectOptions is not an object. +[null, true, false, 'foo', 5, Symbol()].forEach((inspectOptions) => { + assert.throws( + () => { + new Console({ + stdout: out, + stderr: err, + inspectOptions + }); + }, + { + message: 'The "options.inspectOptions" property must be of type object.' + + common.invalidArgTypeHelper(inspectOptions), + code: 'ERR_INVALID_ARG_TYPE' + } + ); +}); diff --git a/tests/node_compat/test/parallel/test-console-log-stdio-broken-dest.js b/tests/node_compat/test/parallel/test-console-log-stdio-broken-dest.js new file mode 100644 index 000000000..832e1a510 --- /dev/null +++ b/tests/node_compat/test/parallel/test-console-log-stdio-broken-dest.js @@ -0,0 +1,31 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const { Writable } = require('stream'); +const { Console } = require('console'); +const { EventEmitter } = require('events'); + +const stream = new Writable({ + write(chunk, enc, cb) { + cb(); + }, + writev(chunks, cb) { + setTimeout(cb, 10, new Error('kaboom')); + } +}); +const myConsole = new Console(stream, stream); + +process.on('warning', common.mustNotCall()); + +stream.cork(); +for (let i = 0; i < EventEmitter.defaultMaxListeners + 1; i++) { + myConsole.log('a message'); +} +stream.uncork(); diff --git a/tests/node_compat/test/parallel/test-console-log-throw-primitive.js b/tests/node_compat/test/parallel/test-console-log-throw-primitive.js new file mode 100644 index 000000000..760c96399 --- /dev/null +++ b/tests/node_compat/test/parallel/test-console-log-throw-primitive.js @@ -0,0 +1,21 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const { Writable } = require('stream'); +const { Console } = require('console'); + +const stream = new Writable({ + write() { + throw null; // eslint-disable-line no-throw-literal + } +}); + +const console = new Console({ stdout: stream }); + +console.log('test'); // Should not throw diff --git a/tests/node_compat/test/parallel/test-console-no-swallow-stack-overflow.js b/tests/node_compat/test/parallel/test-console-no-swallow-stack-overflow.js new file mode 100644 index 000000000..98621b3ce --- /dev/null +++ b/tests/node_compat/test/parallel/test-console-no-swallow-stack-overflow.js @@ -0,0 +1,26 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const { Console } = require('console'); +const { Writable } = require('stream'); + +for (const method of ['dir', 'log', 'warn']) { + assert.throws(() => { + const out = new Writable({ + write: common.mustCall(function write(...args) { + // Exceeds call stack. + return write(...args); + }), + }); + const c = new Console(out, out, true); + + c[method]('Hello, world!'); + }, { name: 'RangeError' }); +} diff --git a/tests/node_compat/test/parallel/test-console-sync-write-error.js b/tests/node_compat/test/parallel/test-console-sync-write-error.js new file mode 100644 index 000000000..1018a3b54 --- /dev/null +++ b/tests/node_compat/test/parallel/test-console-sync-write-error.js @@ -0,0 +1,46 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const { Console } = require('console'); +const { Writable } = require('stream'); + +for (const method of ['dir', 'log', 'warn']) { + { + const out = new Writable({ + write: common.mustCall((chunk, enc, callback) => { + callback(new Error('foobar')); + }) + }); + + const c = new Console(out, out, true); + c[method]('abc'); // Should not throw. + } + + { + const out = new Writable({ + write: common.mustCall((chunk, enc, callback) => { + throw new Error('foobar'); + }) + }); + + const c = new Console(out, out, true); + c[method]('abc'); // Should not throw. + } + + { + const out = new Writable({ + write: common.mustCall((chunk, enc, callback) => { + setImmediate(() => callback(new Error('foobar'))); + }) + }); + + const c = new Console(out, out, true); + c[method]('abc'); // Should not throw. + } +} diff --git a/tests/node_compat/test/parallel/test-console-table.js b/tests/node_compat/test/parallel/test-console-table.js new file mode 100644 index 000000000..a7fddac1e --- /dev/null +++ b/tests/node_compat/test/parallel/test-console-table.js @@ -0,0 +1,300 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); + +const assert = require('assert'); +const { Console } = require('console'); + +const queue = []; + +const console = new Console({ write: (x) => { + queue.push(x); +}, removeListener: () => {} }, process.stderr, false); + +function test(data, only, expected) { + if (arguments.length === 2) { + expected = only; + only = undefined; + } + console.table(data, only); + assert.deepStrictEqual( + queue.shift().split('\n'), + expected.trimLeft().split('\n') + ); +} + +assert.throws(() => console.table([], false), { + code: 'ERR_INVALID_ARG_TYPE', +}); + +test(null, 'null\n'); +test(undefined, 'undefined\n'); +test(false, 'false\n'); +test('hi', 'hi\n'); +test(Symbol(), 'Symbol()\n'); +test(function() {}, '[Function (anonymous)]\n'); + +test([1, 2, 3], ` +┌─────────┬────────┐ +│ (index) │ Values │ +├─────────┼────────┤ +│ 0 │ 1 │ +│ 1 │ 2 │ +│ 2 │ 3 │ +└─────────┴────────┘ +`); + +test([Symbol(), 5, [10]], ` +┌─────────┬────┬──────────┐ +│ (index) │ 0 │ Values │ +├─────────┼────┼──────────┤ +│ 0 │ │ Symbol() │ +│ 1 │ │ 5 │ +│ 2 │ 10 │ │ +└─────────┴────┴──────────┘ +`); + +test([null, 5], ` +┌─────────┬────────┐ +│ (index) │ Values │ +├─────────┼────────┤ +│ 0 │ null │ +│ 1 │ 5 │ +└─────────┴────────┘ +`); + +test([undefined, 5], ` +┌─────────┬───────────┐ +│ (index) │ Values │ +├─────────┼───────────┤ +│ 0 │ undefined │ +│ 1 │ 5 │ +└─────────┴───────────┘ +`); + +test({ a: 1, b: Symbol(), c: [10] }, ` +┌─────────┬────┬──────────┐ +│ (index) │ 0 │ Values │ +├─────────┼────┼──────────┤ +│ a │ │ 1 │ +│ b │ │ Symbol() │ +│ c │ 10 │ │ +└─────────┴────┴──────────┘ +`); + +test(new Map([ ['a', 1], [Symbol(), [2]] ]), ` +┌───────────────────┬──────────┬────────┐ +│ (iteration index) │ Key │ Values │ +├───────────────────┼──────────┼────────┤ +│ 0 │ 'a' │ 1 │ +│ 1 │ Symbol() │ [ 2 ] │ +└───────────────────┴──────────┴────────┘ +`); + +test(new Set([1, 2, Symbol()]), ` +┌───────────────────┬──────────┐ +│ (iteration index) │ Values │ +├───────────────────┼──────────┤ +│ 0 │ 1 │ +│ 1 │ 2 │ +│ 2 │ Symbol() │ +└───────────────────┴──────────┘ +`); + +test({ a: 1, b: 2 }, ['a'], ` +┌─────────┬───┐ +│ (index) │ a │ +├─────────┼───┤ +│ a │ │ +│ b │ │ +└─────────┴───┘ +`); + +test([{ a: 1, b: 2 }, { a: 3, c: 4 }], ['a'], ` +┌─────────┬───┐ +│ (index) │ a │ +├─────────┼───┤ +│ 0 │ 1 │ +│ 1 │ 3 │ +└─────────┴───┘ +`); + +test(new Map([[1, 1], [2, 2], [3, 3]]).entries(), ` +┌───────────────────┬─────┬────────┐ +│ (iteration index) │ Key │ Values │ +├───────────────────┼─────┼────────┤ +│ 0 │ 1 │ 1 │ +│ 1 │ 2 │ 2 │ +│ 2 │ 3 │ 3 │ +└───────────────────┴─────┴────────┘ +`); + +test(new Map([[1, 1], [2, 2], [3, 3]]).values(), ` +┌───────────────────┬────────┐ +│ (iteration index) │ Values │ +├───────────────────┼────────┤ +│ 0 │ 1 │ +│ 1 │ 2 │ +│ 2 │ 3 │ +└───────────────────┴────────┘ +`); + +test(new Map([[1, 1], [2, 2], [3, 3]]).keys(), ` +┌───────────────────┬────────┐ +│ (iteration index) │ Values │ +├───────────────────┼────────┤ +│ 0 │ 1 │ +│ 1 │ 2 │ +│ 2 │ 3 │ +└───────────────────┴────────┘ +`); + +test(new Set([1, 2, 3]).values(), ` +┌───────────────────┬────────┐ +│ (iteration index) │ Values │ +├───────────────────┼────────┤ +│ 0 │ 1 │ +│ 1 │ 2 │ +│ 2 │ 3 │ +└───────────────────┴────────┘ +`); + + +test({ a: { a: 1, b: 2, c: 3 } }, ` +┌─────────┬───┬───┬───┐ +│ (index) │ a │ b │ c │ +├─────────┼───┼───┼───┤ +│ a │ 1 │ 2 │ 3 │ +└─────────┴───┴───┴───┘ +`); + +test({ a: { a: { a: 1, b: 2, c: 3 } } }, ` +┌─────────┬──────────┐ +│ (index) │ a │ +├─────────┼──────────┤ +│ a │ [Object] │ +└─────────┴──────────┘ +`); + +test({ a: [1, 2] }, ` +┌─────────┬───┬───┐ +│ (index) │ 0 │ 1 │ +├─────────┼───┼───┤ +│ a │ 1 │ 2 │ +└─────────┴───┴───┘ +`); + +test({ a: [1, 2, 3, 4, 5], b: 5, c: { e: 5 } }, ` +┌─────────┬───┬───┬───┬───┬───┬───┬────────┐ +│ (index) │ 0 │ 1 │ 2 │ 3 │ 4 │ e │ Values │ +├─────────┼───┼───┼───┼───┼───┼───┼────────┤ +│ a │ 1 │ 2 │ 3 │ 4 │ 5 │ │ │ +│ b │ │ │ │ │ │ │ 5 │ +│ c │ │ │ │ │ │ 5 │ │ +└─────────┴───┴───┴───┴───┴───┴───┴────────┘ +`); + +test(new Uint8Array([1, 2, 3]), ` +┌─────────┬────────┐ +│ (index) │ Values │ +├─────────┼────────┤ +│ 0 │ 1 │ +│ 1 │ 2 │ +│ 2 │ 3 │ +└─────────┴────────┘ +`); + +test(Buffer.from([1, 2, 3]), ` +┌─────────┬────────┐ +│ (index) │ Values │ +├─────────┼────────┤ +│ 0 │ 1 │ +│ 1 │ 2 │ +│ 2 │ 3 │ +└─────────┴────────┘ +`); + +test({ a: undefined }, ['x'], ` +┌─────────┬───┐ +│ (index) │ x │ +├─────────┼───┤ +│ a │ │ +└─────────┴───┘ +`); + +test([], ` +┌─────────┐ +│ (index) │ +├─────────┤ +└─────────┘ +`); + +test(new Map(), ` +┌───────────────────┬─────┬────────┐ +│ (iteration index) │ Key │ Values │ +├───────────────────┼─────┼────────┤ +└───────────────────┴─────┴────────┘ +`); + +test([{ a: 1, b: 'Y' }, { a: 'Z', b: 2 }], ` +┌─────────┬─────┬─────┐ +│ (index) │ a │ b │ +├─────────┼─────┼─────┤ +│ 0 │ 1 │ 'Y' │ +│ 1 │ 'Z' │ 2 │ +└─────────┴─────┴─────┘ +`); + +{ + const line = '─'.repeat(79); + const header = `${' '.repeat(37)}name${' '.repeat(40)}`; + const name = 'very long long long long long long long long long long long ' + + 'long long long long'; + test([{ name }], ` +┌─────────┬──${line}──┐ +│ (index) │ ${header}│ +├─────────┼──${line}──┤ +│ 0 │ '${name}' │ +└─────────┴──${line}──┘ +`); +} + +test({ foo: '¥', bar: '¥' }, ` +┌─────────┬────────┐ +│ (index) │ Values │ +├─────────┼────────┤ +│ foo │ '¥' │ +│ bar │ '¥' │ +└─────────┴────────┘ +`); + +test({ foo: '你好', bar: 'hello' }, ` +┌─────────┬─────────┐ +│ (index) │ Values │ +├─────────┼─────────┤ +│ foo │ '你好' │ +│ bar │ 'hello' │ +└─────────┴─────────┘ +`); + +// Regression test for prototype pollution via console.table. Earlier versions +// of Node.js created an object with a non-null prototype within console.table +// and then wrote to object[column][index], which lead to an error as well as +// modifications to Object.prototype. +test([{ foo: 10 }, { foo: 20 }], ['__proto__'], ` +┌─────────┬───────────┐ +│ (index) │ __proto__ │ +├─────────┼───────────┤ +│ 0 │ │ +│ 1 │ │ +└─────────┴───────────┘ +`); +assert.strictEqual('0' in Object.prototype, false); +assert.strictEqual('1' in Object.prototype, false); diff --git a/tests/node_compat/test/parallel/test-console-tty-colors.js b/tests/node_compat/test/parallel/test-console-tty-colors.js new file mode 100644 index 000000000..6b6886d1f --- /dev/null +++ b/tests/node_compat/test/parallel/test-console-tty-colors.js @@ -0,0 +1,102 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const util = require('util'); +const { Writable } = require('stream'); +const { Console } = require('console'); + +function check(isTTY, colorMode, expectedColorMode, inspectOptions) { + const items = [ + 1, + { a: 2 }, + [ 'foo' ], + { '\\a': '\\bar' }, + ]; + + let i = 0; + const stream = new Writable({ + write: common.mustCall((chunk, enc, cb) => { + assert.strictEqual(chunk.trim(), + util.inspect(items[i++], { + colors: expectedColorMode, + ...inspectOptions + })); + cb(); + }, items.length), + decodeStrings: false + }); + stream.isTTY = isTTY; + + // Set ignoreErrors to `false` here so that we see assertion failures + // from the `write()` call happen. + const testConsole = new Console({ + stdout: stream, + ignoreErrors: false, + colorMode, + inspectOptions + }); + for (const item of items) { + testConsole.log(item); + } +} + +check(true, 'auto', true); +check(false, 'auto', false); +check(false, undefined, true, { colors: true, compact: false }); +check(true, 'auto', true, { compact: false }); +check(true, undefined, false, { colors: false }); +check(true, true, true); +check(false, true, true); +check(true, false, false); +check(false, false, false); + +// Check invalid options. +{ + const stream = new Writable({ + write: common.mustNotCall() + }); + + [0, 'true', null, {}, [], () => {}].forEach((colorMode) => { + const received = util.inspect(colorMode); + assert.throws( + () => { + new Console({ + stdout: stream, + ignoreErrors: false, + colorMode: colorMode + }); + }, + { + message: `The argument 'colorMode' is invalid. Received ${received}`, + code: 'ERR_INVALID_ARG_VALUE' + } + ); + }); + + [true, false, 'auto'].forEach((colorMode) => { + assert.throws( + () => { + new Console({ + stdout: stream, + ignoreErrors: false, + colorMode: colorMode, + inspectOptions: { + colors: false + } + }); + }, + { + message: 'Option "options.inspectOptions.color" cannot be used in ' + + 'combination with option "colorMode"', + code: 'ERR_INCOMPATIBLE_OPTION_PAIR' + } + ); + }); +} diff --git a/tests/node_compat/test/parallel/test-crypto-dh-shared.js b/tests/node_compat/test/parallel/test-crypto-dh-shared.js new file mode 100644 index 000000000..7266b00b9 --- /dev/null +++ b/tests/node_compat/test/parallel/test-crypto-dh-shared.js @@ -0,0 +1,22 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const crypto = require('crypto'); + +const alice = crypto.createDiffieHellmanGroup('modp5'); +const bob = crypto.createDiffieHellmanGroup('modp5'); +alice.generateKeys(); +bob.generateKeys(); +const aSecret = alice.computeSecret(bob.getPublicKey()).toString('hex'); +const bSecret = bob.computeSecret(alice.getPublicKey()).toString('hex'); +assert.strictEqual(aSecret, bSecret); diff --git a/tests/node_compat/test/parallel/test-crypto-dh.js b/tests/node_compat/test/parallel/test-crypto-dh.js new file mode 100644 index 000000000..bcf0c6764 --- /dev/null +++ b/tests/node_compat/test/parallel/test-crypto-dh.js @@ -0,0 +1,214 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const crypto = require('crypto'); + +const size = common.hasFipsCrypto || common.hasOpenSSL3 ? 1024 : 256; +const dh1 = crypto.createDiffieHellman(size); +const p1 = dh1.getPrime('buffer'); +const dh2 = crypto.createDiffieHellman(p1, 'buffer'); +const key1 = dh1.generateKeys(); +const key2 = dh2.generateKeys('hex'); +const secret1 = dh1.computeSecret(key2, 'hex', 'base64'); +const secret2 = dh2.computeSecret(key1, 'latin1', 'buffer'); + +// Test Diffie-Hellman with two parties sharing a secret, +// using various encodings as we go along +assert.strictEqual(secret2.toString('base64'), secret1); +assert.strictEqual(dh1.verifyError, 0); +assert.strictEqual(dh2.verifyError, 0); + +// https://github.com/nodejs/node/issues/32738 +// XXX(bnoordhuis) validateInt32() throwing ERR_OUT_OF_RANGE and RangeError +// instead of ERR_INVALID_ARG_TYPE and TypeError is questionable, IMO. +assert.throws(() => crypto.createDiffieHellman(13.37), { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "sizeOrKey" is out of range. ' + + 'It must be an integer. Received 13.37', +}); + +assert.throws(() => crypto.createDiffieHellman('abcdef', 13.37), { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "generator" is out of range. ' + + 'It must be an integer. Received 13.37', +}); + +for (const bits of [-1, 0, 1]) { + if (common.hasOpenSSL3) { + assert.throws(() => crypto.createDiffieHellman(bits), { + code: 'ERR_OSSL_DH_MODULUS_TOO_SMALL', + name: 'Error', + message: /modulus too small/, + }); + } else { + assert.throws(() => crypto.createDiffieHellman(bits), { + code: 'ERR_OSSL_BN_BITS_TOO_SMALL', + name: 'Error', + message: /bits too small/, + }); + } +} + +// Through a fluke of history, g=0 defaults to DH_GENERATOR (2). +{ + const g = 0; + crypto.createDiffieHellman('abcdef', g); + crypto.createDiffieHellman('abcdef', 'hex', g); +} + +for (const g of [-1, 1]) { + const ex = { + code: 'ERR_OSSL_DH_BAD_GENERATOR', + name: 'Error', + message: /bad generator/, + }; + assert.throws(() => crypto.createDiffieHellman('abcdef', g), ex); + assert.throws(() => crypto.createDiffieHellman('abcdef', 'hex', g), ex); +} + +crypto.createDiffieHellman('abcdef', Buffer.from([2])); // OK + +for (const g of [Buffer.from([]), + Buffer.from([0]), + Buffer.from([1])]) { + const ex = { + code: 'ERR_OSSL_DH_BAD_GENERATOR', + name: 'Error', + message: /bad generator/, + }; + assert.throws(() => crypto.createDiffieHellman('abcdef', g), ex); + assert.throws(() => crypto.createDiffieHellman('abcdef', 'hex', g), ex); +} + +[ + [0x1, 0x2], + () => { }, + /abc/, + {}, +].forEach((input) => { + assert.throws( + () => crypto.createDiffieHellman(input), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + } + ); +}); + +// Create "another dh1" using generated keys from dh1, +// and compute secret again +const dh3 = crypto.createDiffieHellman(p1, 'buffer'); +const privkey1 = dh1.getPrivateKey(); +dh3.setPublicKey(key1); +dh3.setPrivateKey(privkey1); + +assert.deepStrictEqual(dh1.getPrime(), dh3.getPrime()); +assert.deepStrictEqual(dh1.getGenerator(), dh3.getGenerator()); +assert.deepStrictEqual(dh1.getPublicKey(), dh3.getPublicKey()); +assert.deepStrictEqual(dh1.getPrivateKey(), dh3.getPrivateKey()); +assert.strictEqual(dh3.verifyError, 0); + +const secret3 = dh3.computeSecret(key2, 'hex', 'base64'); + +assert.strictEqual(secret1, secret3); + +// computeSecret works without a public key set at all. +const dh4 = crypto.createDiffieHellman(p1, 'buffer'); +dh4.setPrivateKey(privkey1); + +assert.deepStrictEqual(dh1.getPrime(), dh4.getPrime()); +assert.deepStrictEqual(dh1.getGenerator(), dh4.getGenerator()); +assert.deepStrictEqual(dh1.getPrivateKey(), dh4.getPrivateKey()); +assert.strictEqual(dh4.verifyError, 0); + +const secret4 = dh4.computeSecret(key2, 'hex', 'base64'); + +assert.strictEqual(secret1, secret4); + + +if (false) { + let wrongBlockLength; + if (common.hasOpenSSL3) { + wrongBlockLength = { + message: 'error:1C80006B:Provider routines::wrong final block length', + code: 'ERR_OSSL_WRONG_FINAL_BLOCK_LENGTH', + library: 'Provider routines', + reason: 'wrong final block length' + }; + } else { + wrongBlockLength = { + message: 'error:0606506D:digital envelope' + + ' routines:EVP_DecryptFinal_ex:wrong final block length', + code: 'ERR_OSSL_EVP_WRONG_FINAL_BLOCK_LENGTH', + library: 'digital envelope routines', + reason: 'wrong final block length' + }; + } + + // Run this one twice to make sure that the dh3 clears its error properly + { + const c = crypto.createDecipheriv('aes-128-ecb', crypto.randomBytes(16), ''); + assert.throws(() => { + c.final('utf8'); + }, wrongBlockLength); + } + + { + const c = crypto.createDecipheriv('aes-128-ecb', crypto.randomBytes(16), ''); + assert.throws(() => { + c.final('utf8'); + }, wrongBlockLength); + } + + assert.throws(() => { + dh3.computeSecret(''); + }, { message: common.hasOpenSSL3 ? + 'error:02800080:Diffie-Hellman routines::invalid secret' : + 'Supplied key is too small' }); + + // Invalid test: curve argument is undefined + assert.throws( + () => crypto.createECDH(), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "curve" argument must be of type string. ' + + 'Received undefined' + }); +} + +assert.throws( + function() { + crypto.getDiffieHellman('unknown-group'); + }, + { + name: 'Error', + code: 'ERR_CRYPTO_UNKNOWN_DH_GROUP', + message: 'Unknown DH group' + }, + 'crypto.getDiffieHellman(\'unknown-group\') ' + + 'failed to throw the expected error.' +); + +assert.throws( + () => crypto.createDiffieHellman('', true), + { + code: 'ERR_INVALID_ARG_TYPE' + } +); +[true, Symbol(), {}, () => {}, []].forEach((generator) => assert.throws( + () => crypto.createDiffieHellman('', 'base64', generator), + { code: 'ERR_INVALID_ARG_TYPE' } +)); diff --git a/tests/node_compat/test/parallel/test-crypto-hkdf.js b/tests/node_compat/test/parallel/test-crypto-hkdf.js new file mode 100644 index 000000000..b5b35e3ce --- /dev/null +++ b/tests/node_compat/test/parallel/test-crypto-hkdf.js @@ -0,0 +1,203 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. + +'use strict'; + +const common = require('../common'); + +if (!common.hasCrypto) + common.skip('missing crypto'); + +const { kMaxLength } = require('buffer'); +const assert = require('assert'); +const { + createSecretKey, + hkdf, + hkdfSync +} = require('crypto'); + +{ + assert.throws(() => hkdf(), { + code: 'ERR_INVALID_ARG_TYPE', + message: /The "digest" argument must be of type string/ + }); + + [1, {}, [], false, Infinity].forEach((i) => { + assert.throws(() => hkdf(i, 'a'), { + code: 'ERR_INVALID_ARG_TYPE', + message: /^The "digest" argument must be of type string/ + }); + assert.throws(() => hkdfSync(i, 'a'), { + code: 'ERR_INVALID_ARG_TYPE', + message: /^The "digest" argument must be of type string/ + }); + }); + + [1, {}, [], false, Infinity].forEach((i) => { + assert.throws(() => hkdf('sha256', i), { + code: 'ERR_INVALID_ARG_TYPE', + message: /^The "ikm" argument must be / + }); + assert.throws(() => hkdfSync('sha256', i), { + code: 'ERR_INVALID_ARG_TYPE', + message: /^The "ikm" argument must be / + }); + }); + + [1, {}, [], false, Infinity].forEach((i) => { + assert.throws(() => hkdf('sha256', 'secret', i), { + code: 'ERR_INVALID_ARG_TYPE', + message: /^The "salt" argument must be / + }); + assert.throws(() => hkdfSync('sha256', 'secret', i), { + code: 'ERR_INVALID_ARG_TYPE', + message: /^The "salt" argument must be / + }); + }); + + [1, {}, [], false, Infinity].forEach((i) => { + assert.throws(() => hkdf('sha256', 'secret', 'salt', i), { + code: 'ERR_INVALID_ARG_TYPE', + message: /^The "info" argument must be / + }); + assert.throws(() => hkdfSync('sha256', 'secret', 'salt', i), { + code: 'ERR_INVALID_ARG_TYPE', + message: /^The "info" argument must be / + }); + }); + + ['test', {}, [], false].forEach((i) => { + assert.throws(() => hkdf('sha256', 'secret', 'salt', 'info', i), { + code: 'ERR_INVALID_ARG_TYPE', + message: /^The "length" argument must be of type number/ + }); + assert.throws(() => hkdfSync('sha256', 'secret', 'salt', 'info', i), { + code: 'ERR_INVALID_ARG_TYPE', + message: /^The "length" argument must be of type number/ + }); + }); + + assert.throws(() => hkdf('sha256', 'secret', 'salt', 'info', -1), { + code: 'ERR_OUT_OF_RANGE' + }); + assert.throws(() => hkdfSync('sha256', 'secret', 'salt', 'info', -1), { + code: 'ERR_OUT_OF_RANGE' + }); + assert.throws(() => hkdf('sha256', 'secret', 'salt', 'info', + kMaxLength + 1), { + code: 'ERR_OUT_OF_RANGE' + }); + assert.throws(() => hkdfSync('sha256', 'secret', 'salt', 'info', + kMaxLength + 1), { + code: 'ERR_OUT_OF_RANGE' + }); + + assert.throws(() => hkdfSync('unknown', 'a', '', '', 10), { + code: 'ERR_CRYPTO_INVALID_DIGEST' + }); + + assert.throws(() => hkdf('unknown', 'a', '', Buffer.alloc(1025), 10, + common.mustNotCall()), { + code: 'ERR_OUT_OF_RANGE' + }); + + assert.throws(() => hkdfSync('unknown', 'a', '', Buffer.alloc(1025), 10), { + code: 'ERR_OUT_OF_RANGE' + }); +} + +const algorithms = [ + ['sha256', 'secret', 'salt', 'info', 10], + ['sha256', '', '', '', 10], + ['sha256', '', 'salt', '', 10], + ['sha512', 'secret', 'salt', '', 15], +]; + +algorithms.forEach(([ hash, secret, salt, info, length ]) => { + { + const syncResult = hkdfSync(hash, secret, salt, info, length); + assert(syncResult instanceof ArrayBuffer); + let is_async = false; + hkdf(hash, secret, salt, info, length, + common.mustSucceed((asyncResult) => { + assert(is_async); + assert(asyncResult instanceof ArrayBuffer); + assert.deepStrictEqual(syncResult, asyncResult); + })); + // Keep this after the hkdf call above. This verifies + // that the callback is invoked asynchronously. + is_async = true; + } + + { + const buf_secret = Buffer.from(secret); + const buf_salt = Buffer.from(salt); + const buf_info = Buffer.from(info); + + const syncResult = hkdfSync(hash, buf_secret, buf_salt, buf_info, length); + hkdf(hash, buf_secret, buf_salt, buf_info, length, + common.mustSucceed((asyncResult) => { + assert.deepStrictEqual(syncResult, asyncResult); + })); + } + + { + const key_secret = createSecretKey(Buffer.from(secret)); + const buf_salt = Buffer.from(salt); + const buf_info = Buffer.from(info); + + const syncResult = hkdfSync(hash, key_secret, buf_salt, buf_info, length); + hkdf(hash, key_secret, buf_salt, buf_info, length, + common.mustSucceed((asyncResult) => { + assert.deepStrictEqual(syncResult, asyncResult); + })); + } + + { + const ta_secret = new Uint8Array(Buffer.from(secret)); + const ta_salt = new Uint16Array(Buffer.from(salt)); + const ta_info = new Uint32Array(Buffer.from(info)); + + const syncResult = hkdfSync(hash, ta_secret, ta_salt, ta_info, length); + hkdf(hash, ta_secret, ta_salt, ta_info, length, + common.mustSucceed((asyncResult) => { + assert.deepStrictEqual(syncResult, asyncResult); + })); + } + + { + const ta_secret = new Uint8Array(Buffer.from(secret)); + const ta_salt = new Uint16Array(Buffer.from(salt)); + const ta_info = new Uint32Array(Buffer.from(info)); + + const syncResult = hkdfSync( + hash, + ta_secret.buffer, + ta_salt.buffer, + ta_info.buffer, + length); + hkdf(hash, ta_secret, ta_salt, ta_info, length, + common.mustSucceed((asyncResult) => { + assert.deepStrictEqual(syncResult, asyncResult); + })); + } + + { + const ta_secret = new Uint8Array(Buffer.from(secret)); + const sa_salt = new ArrayBuffer(0); + const sa_info = new ArrayBuffer(1); + + const syncResult = hkdfSync( + hash, + ta_secret.buffer, + sa_salt, + sa_info, + length); + hkdf(hash, ta_secret, sa_salt, sa_info, length, + common.mustSucceed((asyncResult) => { + assert.deepStrictEqual(syncResult, asyncResult); + })); + } +}); diff --git a/tests/node_compat/test/parallel/test-crypto-hmac.js b/tests/node_compat/test/parallel/test-crypto-hmac.js new file mode 100644 index 000000000..174457a63 --- /dev/null +++ b/tests/node_compat/test/parallel/test-crypto-hmac.js @@ -0,0 +1,483 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const crypto = require('crypto'); + +{ + const Hmac = crypto.Hmac; + const instance = crypto.Hmac('sha256', 'Node'); + assert(instance instanceof Hmac, 'Hmac is expected to return a new instance' + + ' when called without `new`'); +} + +assert.throws( + () => crypto.createHmac(null), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "hmac" argument must be of type string. Received null' + }); + +// This used to segfault. See: https://github.com/nodejs/node/issues/9819 +assert.throws( + () => crypto.createHmac('sha256', 'key').digest({ + toString: () => { throw new Error('boom'); }, + }), + { + name: 'Error', + message: 'boom' + }); + +assert.throws( + () => crypto.createHmac('sha1', null), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + }); + +function testHmac(algo, key, data, expected) { + // TODO(kt3k): Skip non-string key for now. + // Enable this when we implement crypto.createSecretKey + if (typeof key !== "string") { + return; + } + // FIPS does not support MD5. + if (common.hasFipsCrypto && algo === 'md5') + return; + + if (!Array.isArray(data)) + data = [data]; + + // If the key is a Buffer, test Hmac with a key object as well. + const keyWrappers = [ + (key) => key, + ...(typeof key === 'string' ? [] : [crypto.createSecretKey]), + ]; + + for (const keyWrapper of keyWrappers) { + const hmac = crypto.createHmac(algo, keyWrapper(key)); + for (const chunk of data) + hmac.update(chunk); + const actual = hmac.digest('hex'); + assert.strictEqual(actual, expected); + } +} + +{ + // Test HMAC with multiple updates. + testHmac('sha1', 'Node', ['some data', 'to hmac'], + '19fd6e1ba73d9ed2224dd5094a71babe85d9a892'); +} + +// Test HMAC (Wikipedia Test Cases) +const wikipedia = [ + { + key: 'key', data: 'The quick brown fox jumps over the lazy dog', + hmac: { // HMACs lifted from Wikipedia. + md5: '80070713463e7749b90c2dc24911e275', + sha1: 'de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9', + sha256: + 'f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc' + + '2d1a3cd8' + } + }, + { + key: 'key', data: '', + hmac: { // Intermediate test to help debugging. + md5: '63530468a04e386459855da0063b6596', + sha1: 'f42bb0eeb018ebbd4597ae7213711ec60760843f', + sha256: + '5d5d139563c95b5967b9bd9a8c9b233a9dedb45072794cd232dc1b74' + + '832607d0' + } + }, + { + key: '', data: 'The quick brown fox jumps over the lazy dog', + hmac: { // Intermediate test to help debugging. + md5: 'ad262969c53bc16032f160081c4a07a0', + sha1: '2ba7f707ad5f187c412de3106583c3111d668de8', + sha256: + 'fb011e6154a19b9a4c767373c305275a5a69e8b68b0b4c9200c383dc' + + 'ed19a416' + } + }, + { + key: '', data: '', + hmac: { // HMACs lifted from Wikipedia. + md5: '74e6f7298a9c2d168935f58c001bad88', + sha1: 'fbdb1d1b18aa6c08324b7d64b71fb76370690e1d', + sha256: + 'b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c71214' + + '4292c5ad' + } + }, +]; + +for (const { key, data, hmac } of wikipedia) { + for (const hash in hmac) + testHmac(hash, key, data, hmac[hash]); +} + +// Test HMAC-SHA-* (rfc 4231 Test Cases) +const rfc4231 = [ + { + key: Buffer.from('0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b', 'hex'), + data: Buffer.from('4869205468657265', 'hex'), // 'Hi There' + hmac: { + sha224: '896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22', + sha256: + 'b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c' + + '2e32cff7', + sha384: + 'afd03944d84895626b0825f4ab46907f15f9dadbe4101ec682aa034c' + + '7cebc59cfaea9ea9076ede7f4af152e8b2fa9cb6', + sha512: + '87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b305' + + '45e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f170' + + '2e696c203a126854' + } + }, + { + key: Buffer.from('4a656665', 'hex'), // 'Jefe' + data: Buffer.from('7768617420646f2079612077616e7420666f72206e6f74686' + + '96e673f', 'hex'), // 'what do ya want for nothing?' + hmac: { + sha224: 'a30e01098bc6dbbf45690f3a7e9e6d0f8bbea2a39e6148008fd05e44', + sha256: + '5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b9' + + '64ec3843', + sha384: + 'af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec373' + + '6322445e8e2240ca5e69e2c78b3239ecfab21649', + sha512: + '164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7' + + 'ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b' + + '636e070a38bce737' + } + }, + { + key: Buffer.from('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'), + data: Buffer.from('ddddddddddddddddddddddddddddddddddddddddddddddddd' + + 'ddddddddddddddddddddddddddddddddddddddddddddddddddd', + 'hex'), + hmac: { + sha224: '7fb3cb3588c6c1f6ffa9694d7d6ad2649365b0c1f65d69d1ec8333ea', + sha256: + '773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514' + + 'ced565fe', + sha384: + '88062608d3e6ad8a0aa2ace014c8a86f0aa635d947ac9febe83ef4e5' + + '5966144b2a5ab39dc13814b94e3ab6e101a34f27', + sha512: + 'fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33' + + 'b2279d39bf3e848279a722c806b485a47e67c807b946a337bee89426' + + '74278859e13292fb' + } + }, + { + key: Buffer.from('0102030405060708090a0b0c0d0e0f10111213141516171819', + 'hex'), + data: Buffer.from('cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdc' + + 'dcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd', + 'hex'), + hmac: { + sha224: '6c11506874013cac6a2abc1bb382627cec6a90d86efc012de7afec5a', + sha256: + '82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff4' + + '6729665b', + sha384: + '3e8a69b7783c25851933ab6290af6ca77a9981480850009cc5577c6e' + + '1f573b4e6801dd23c4a7d679ccf8a386c674cffb', + sha512: + 'b0ba465637458c6990e5a8c5f61d4af7e576d97ff94b872de76f8050' + + '361ee3dba91ca5c11aa25eb4d679275cc5788063a5f19741120c4f2d' + + 'e2adebeb10a298dd' + } + }, + + { + key: Buffer.from('0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c', 'hex'), + // 'Test With Truncation' + data: Buffer.from('546573742057697468205472756e636174696f6e', 'hex'), + hmac: { + sha224: '0e2aea68a90c8d37c988bcdb9fca6fa8', + sha256: 'a3b6167473100ee06e0c796c2955552b', + sha384: '3abf34c3503b2a23a46efc619baef897', + sha512: '415fad6271580a531d4179bc891d87a6' + }, + truncate: true + }, + { + key: Buffer.from('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + + 'aaaaaaaaaaaa', 'hex'), + // 'Test Using Larger Than Block-Size Key - Hash Key First' + data: Buffer.from('54657374205573696e67204c6172676572205468616e20426' + + 'c6f636b2d53697a65204b6579202d2048617368204b657920' + + '4669727374', 'hex'), + hmac: { + sha224: '95e9a0db962095adaebe9b2d6f0dbce2d499f112f2d2b7273fa6870e', + sha256: + '60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f' + + '0ee37f54', + sha384: + '4ece084485813e9088d2c63a041bc5b44f9ef1012a2b588f3cd11f05' + + '033ac4c60c2ef6ab4030fe8296248df163f44952', + sha512: + '80b24263c7c1a3ebb71493c1dd7be8b49b46d1f41b4aeec1121b0137' + + '83f8f3526b56d037e05f2598bd0fd2215d6a1e5295e64f73f63f0aec' + + '8b915a985d786598' + } + }, + { + key: Buffer.from('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + + 'aaaaaaaaaaaa', 'hex'), + // 'This is a test using a larger than block-size key and a larger ' + + // 'than block-size data. The key needs to be hashed before being ' + + // 'used by the HMAC algorithm.' + data: Buffer.from('5468697320697320612074657374207573696e672061206c6' + + '172676572207468616e20626c6f636b2d73697a65206b6579' + + '20616e642061206c6172676572207468616e20626c6f636b2' + + 'd73697a6520646174612e20546865206b6579206e65656473' + + '20746f20626520686173686564206265666f7265206265696' + + 'e6720757365642062792074686520484d414320616c676f72' + + '6974686d2e', 'hex'), + hmac: { + sha224: '3a854166ac5d9f023f54d517d0b39dbd946770db9c2b95c9f6f565d1', + sha256: + '9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f5153' + + '5c3a35e2', + sha384: + '6617178e941f020d351e2f254e8fd32c602420feb0b8fb9adccebb82' + + '461e99c5a678cc31e799176d3860e6110c46523e', + sha512: + 'e37b6a775dc87dbaa4dfa9f96e5e3ffddebd71f8867289865df5a32d' + + '20cdc944b6022cac3c4982b10d5eeb55c3e4de15134676fb6de04460' + + '65c97440fa8c6a58' + } + }, +]; + +for (let i = 0, l = rfc4231.length; i < l; i++) { + for (const hash in rfc4231[i].hmac) { + const str = crypto.createHmac(hash, rfc4231[i].key); + str.end(rfc4231[i].data); + let strRes = str.read().toString('hex'); + let actual = crypto.createHmac(hash, rfc4231[i].key) + .update(rfc4231[i].data) + .digest('hex'); + if (rfc4231[i].truncate) { + actual = actual.slice(0, 32); // first 128 bits == 32 hex chars + strRes = strRes.slice(0, 32); + } + const expected = rfc4231[i].hmac[hash]; + assert.strictEqual( + actual, + expected, + `Test HMAC-${hash} rfc 4231 case ${i + 1}: ${actual} must be ${expected}` + ); + assert.strictEqual( + actual, + strRes, + `Should get same result from stream (hash: ${hash} and case: ${i + 1})` + + ` => ${actual} must be ${strRes}` + ); + } +} + +// Test HMAC-MD5/SHA1 (rfc 2202 Test Cases) +const rfc2202_md5 = [ + { + key: Buffer.from('0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b', 'hex'), + data: 'Hi There', + hmac: '9294727a3638bb1c13f48ef8158bfc9d' + }, + { + key: 'Jefe', + data: 'what do ya want for nothing?', + hmac: '750c783e6ab0b503eaa86e310a5db738' + }, + { + key: Buffer.from('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'), + data: Buffer.from('ddddddddddddddddddddddddddddddddddddddddddddddddd' + + 'ddddddddddddddddddddddddddddddddddddddddddddddddddd', + 'hex'), + hmac: '56be34521d144c88dbb8c733f0e8b3f6' + }, + { + key: Buffer.from('0102030405060708090a0b0c0d0e0f10111213141516171819', + 'hex'), + data: Buffer.from('cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdc' + + 'dcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd' + + 'cdcdcdcdcd', + 'hex'), + hmac: '697eaf0aca3a3aea3a75164746ffaa79' + }, + { + key: Buffer.from('0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c', 'hex'), + data: 'Test With Truncation', + hmac: '56461ef2342edc00f9bab995690efd4c' + }, + { + key: Buffer.from('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + + 'aaaaaaaaaaaaaaaaaaaaaa', + 'hex'), + data: 'Test Using Larger Than Block-Size Key - Hash Key First', + hmac: '6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd' + }, + { + key: Buffer.from('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + + 'aaaaaaaaaaaaaaaaaaaaaa', + 'hex'), + data: + 'Test Using Larger Than Block-Size Key and Larger Than One ' + + 'Block-Size Data', + hmac: '6f630fad67cda0ee1fb1f562db3aa53e' + }, +]; + +for (const { key, data, hmac } of rfc2202_md5) + testHmac('md5', key, data, hmac); + +const rfc2202_sha1 = [ + { + key: Buffer.from('0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b', 'hex'), + data: 'Hi There', + hmac: 'b617318655057264e28bc0b6fb378c8ef146be00' + }, + { + key: 'Jefe', + data: 'what do ya want for nothing?', + hmac: 'effcdf6ae5eb2fa2d27416d5f184df9c259a7c79' + }, + { + key: Buffer.from('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'), + data: Buffer.from('ddddddddddddddddddddddddddddddddddddddddddddd' + + 'ddddddddddddddddddddddddddddddddddddddddddddd' + + 'dddddddddd', + 'hex'), + hmac: '125d7342b9ac11cd91a39af48aa17b4f63f175d3' + }, + { + key: Buffer.from('0102030405060708090a0b0c0d0e0f10111213141516171819', + 'hex'), + data: Buffer.from('cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdc' + + 'dcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd' + + 'cdcdcdcdcd', + 'hex'), + hmac: '4c9007f4026250c6bc8414f9bf50c86c2d7235da' + }, + { + key: Buffer.from('0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c', 'hex'), + data: 'Test With Truncation', + hmac: '4c1a03424b55e07fe7f27be1d58bb9324a9a5a04' + }, + { + key: Buffer.from('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + + 'aaaaaaaaaaaaaaaaaaaaaa', + 'hex'), + data: 'Test Using Larger Than Block-Size Key - Hash Key First', + hmac: 'aa4ae5e15272d00e95705637ce8a3b55ed402112' + }, + { + key: Buffer.from('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + + 'aaaaaaaaaaaaaaaaaaaaaa', + 'hex'), + data: + 'Test Using Larger Than Block-Size Key and Larger Than One ' + + 'Block-Size Data', + hmac: 'e8e99d0f45237d786d6bbaa7965c7808bbff1a91' + }, +]; + +for (const { key, data, hmac } of rfc2202_sha1) + testHmac('sha1', key, data, hmac); + +assert.strictEqual( + crypto.createHmac('sha256', 'w00t').digest('ucs2'), + crypto.createHmac('sha256', 'w00t').digest().toString('ucs2')); + +// Check initialized -> uninitialized state transition after calling digest(). +{ + const expected = + '\u0010\u0041\u0052\u00c5\u00bf\u00dc\u00a0\u007b\u00c6\u0033' + + '\u00ee\u00bd\u0046\u0019\u009f\u0002\u0055\u00c9\u00f4\u009d'; + { + const h = crypto.createHmac('sha1', 'key').update('data'); + assert.deepStrictEqual(h.digest('buffer'), Buffer.from(expected, 'latin1')); + // TODO(kt3k): Enable this assertion + // assert.deepStrictEqual(h.digest('buffer'), Buffer.from('')); + } + { + const h = crypto.createHmac('sha1', 'key').update('data'); + assert.strictEqual(h.digest('latin1'), expected); + // TODO(kt3k): Enable this assertion + // assert.strictEqual(h.digest('latin1'), ''); + } +} + +// Check initialized -> uninitialized state transition after calling digest(). +// Calls to update() omitted intentionally. +{ + const expected = + '\u00f4\u002b\u00b0\u00ee\u00b0\u0018\u00eb\u00bd\u0045\u0097' + + '\u00ae\u0072\u0013\u0071\u001e\u00c6\u0007\u0060\u0084\u003f'; + { + const h = crypto.createHmac('sha1', 'key'); + assert.deepStrictEqual(h.digest('buffer'), Buffer.from(expected, 'latin1')); + // TODO(kt3k): Enable this assertion + // assert.deepStrictEqual(h.digest('buffer'), Buffer.from('')); + } + { + const h = crypto.createHmac('sha1', 'key'); + assert.strictEqual(h.digest('latin1'), expected); + // TODO(kt3k): Enable this assertion + // assert.strictEqual(h.digest('latin1'), ''); + } +} + +/* +TODO(kt3k): Enable this test. +{ + assert.throws( + () => crypto.createHmac('sha7', 'key'), + /Invalid digest/); +} +*/ + +/* + TODO(kt3k): enable this case when we implemented crypto.createSecretKey +{ + const buf = Buffer.alloc(0); + const keyObject = crypto.createSecretKey(Buffer.alloc(0)); + assert.deepStrictEqual( + crypto.createHmac('sha256', buf).update('foo').digest(), + crypto.createHmac('sha256', keyObject).update('foo').digest(), + ); +} +*/ diff --git a/tests/node_compat/test/parallel/test-crypto-prime.js b/tests/node_compat/test/parallel/test-crypto-prime.js new file mode 100644 index 000000000..fc2218c2a --- /dev/null +++ b/tests/node_compat/test/parallel/test-crypto-prime.js @@ -0,0 +1,302 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. + +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); + +const { + generatePrime, + generatePrimeSync, + checkPrime, + checkPrimeSync, +} = require('crypto'); + +const { promisify } = require('util'); +const pgeneratePrime = promisify(generatePrime); +const pCheckPrime = promisify(checkPrime); + +assert(!checkPrimeSync(Buffer.from([0x1]))); +assert(checkPrimeSync(Buffer.from([0x2]))); +assert(checkPrimeSync(Buffer.from([0x3]))); +assert(!checkPrimeSync(Buffer.from([0x4]))); + +assert( + !checkPrimeSync( + Buffer.from([0x1]), + { + fast: true, + trialDivision: true, + checks: 10 + })); + +(async function() { + const prime = await pgeneratePrime(36); + assert(await pCheckPrime(prime)); +})().then(common.mustCall()); + +assert.throws(() => { + generatePrimeSync(32, { bigint: '' }); +}, { code: 'ERR_INVALID_ARG_TYPE' }); + +assert.throws(() => { + generatePrime(32, { bigint: '' }, common.mustNotCall()); +}, { code: 'ERR_INVALID_ARG_TYPE' }); + +{ + const prime = generatePrimeSync(3, { bigint: true }); + assert.strictEqual(typeof prime, 'bigint'); + assert.strictEqual(prime, 7n); + assert(checkPrimeSync(prime)); + checkPrime(prime, common.mustSucceed(assert)); +} + +{ + generatePrime(3, { bigint: true }, common.mustSucceed((prime) => { + assert.strictEqual(typeof prime, 'bigint'); + assert.strictEqual(prime, 7n); + assert(checkPrimeSync(prime)); + checkPrime(prime, common.mustSucceed(assert)); + })); +} + + +['hello', false, {}, []].forEach((i) => { + assert.throws(() => generatePrime(i), { + code: 'ERR_INVALID_ARG_TYPE' + }); + assert.throws(() => generatePrimeSync(i), { + code: 'ERR_INVALID_ARG_TYPE' + }); +}); + +['hello', false, 123].forEach((i) => { + assert.throws(() => generatePrime(80, i, common.mustNotCall()), { + code: 'ERR_INVALID_ARG_TYPE' + }); + assert.throws(() => generatePrimeSync(80, i), { + code: 'ERR_INVALID_ARG_TYPE' + }); +}); + +['hello', false, 123].forEach((i) => { + assert.throws(() => generatePrime(80, {}), { + code: 'ERR_INVALID_ARG_TYPE' + }); +}); + +[-1, 0, 2 ** 31, 2 ** 31 + 1, 2 ** 32 - 1, 2 ** 32].forEach((size) => { + assert.throws(() => generatePrime(size, common.mustNotCall()), { + code: 'ERR_OUT_OF_RANGE', + message: />= 1 && <= 2147483647/ + }); + assert.throws(() => generatePrimeSync(size), { + code: 'ERR_OUT_OF_RANGE', + message: />= 1 && <= 2147483647/ + }); +}); + +['test', -1, {}, []].forEach((i) => { + assert.throws(() => generatePrime(8, { safe: i }, common.mustNotCall()), { + code: 'ERR_INVALID_ARG_TYPE' + }); + assert.throws(() => generatePrime(8, { rem: i }, common.mustNotCall()), { + code: 'ERR_INVALID_ARG_TYPE' + }); + assert.throws(() => generatePrime(8, { add: i }, common.mustNotCall()), { + code: 'ERR_INVALID_ARG_TYPE' + }); + assert.throws(() => generatePrimeSync(8, { safe: i }), { + code: 'ERR_INVALID_ARG_TYPE' + }); + assert.throws(() => generatePrimeSync(8, { rem: i }), { + code: 'ERR_INVALID_ARG_TYPE' + }); + assert.throws(() => generatePrimeSync(8, { add: i }), { + code: 'ERR_INVALID_ARG_TYPE' + }); +}); + +{ + // Negative BigInts should not be converted to 0 silently. + + assert.throws(() => generatePrime(20, { add: -1n }, common.mustNotCall()), { + code: 'ERR_OUT_OF_RANGE', + message: 'The value of "options.add" is out of range. It must be >= 0. ' + + 'Received -1n' + }); + + assert.throws(() => generatePrime(20, { rem: -1n }, common.mustNotCall()), { + code: 'ERR_OUT_OF_RANGE', + message: 'The value of "options.rem" is out of range. It must be >= 0. ' + + 'Received -1n' + }); + + // assert.throws(() => checkPrime(-1n, common.mustNotCall()), { + // code: 'ERR_OUT_OF_RANGE', + // message: 'The value of "candidate" is out of range. It must be >= 0. ' + + // 'Received -1n' + // }); +} + +generatePrime(80, common.mustSucceed((prime) => { + assert(checkPrimeSync(prime)); + checkPrime(prime, common.mustSucceed((result) => { + assert(result); + })); +})); + +assert(checkPrimeSync(generatePrimeSync(80))); + +generatePrime(80, {}, common.mustSucceed((prime) => { + assert(checkPrimeSync(prime)); +})); + +assert(checkPrimeSync(generatePrimeSync(80, {}))); + +// generatePrime(32, { safe: true }, common.mustSucceed((prime) => { +// assert(checkPrimeSync(prime)); +// const buf = Buffer.from(prime); +// const val = buf.readUInt32BE(); +// const check = (val - 1) / 2; +// buf.writeUInt32BE(check); +// assert(checkPrimeSync(buf)); +// })); + +// { +// const prime = generatePrimeSync(32, { safe: true }); +// assert(checkPrimeSync(prime)); +// const buf = Buffer.from(prime); +// const val = buf.readUInt32BE(); +// const check = (val - 1) / 2; +// buf.writeUInt32BE(check); +// assert(checkPrimeSync(buf)); +// } + +// const add = 12; +// const rem = 11; +// const add_buf = Buffer.from([add]); +// const rem_buf = Buffer.from([rem]); +// generatePrime( +// 32, +// { add: add_buf, rem: rem_buf }, +// common.mustSucceed((prime) => { +// assert(checkPrimeSync(prime)); +// const buf = Buffer.from(prime); +// const val = buf.readUInt32BE(); +// assert.strictEqual(val % add, rem); +// })); + +// { +// const prime = generatePrimeSync(32, { add: add_buf, rem: rem_buf }); +// assert(checkPrimeSync(prime)); +// const buf = Buffer.from(prime); +// const val = buf.readUInt32BE(); +// assert.strictEqual(val % add, rem); +// } + +// { +// const prime = generatePrimeSync(32, { add: BigInt(add), rem: BigInt(rem) }); +// assert(checkPrimeSync(prime)); +// const buf = Buffer.from(prime); +// const val = buf.readUInt32BE(); +// assert.strictEqual(val % add, rem); +// } + +// { +// // The behavior when specifying only add without rem should depend on the +// // safe option. + +// if (process.versions.openssl >= '1.1.1f') { +// generatePrime(128, { +// bigint: true, +// add: 5n +// }, common.mustSucceed((prime) => { +// assert(checkPrimeSync(prime)); +// assert.strictEqual(prime % 5n, 1n); +// })); + +// generatePrime(128, { +// bigint: true, +// safe: true, +// add: 5n +// }, common.mustSucceed((prime) => { +// assert(checkPrimeSync(prime)); +// assert.strictEqual(prime % 5n, 3n); +// })); +// } +// } + +// { +// // This is impossible because it implies (prime % 2**64) == 1 and +// // prime < 2**64, meaning prime = 1, but 1 is not prime. +// for (const add of [2n ** 64n, 2n ** 65n]) { +// assert.throws(() => { +// generatePrimeSync(64, { add }); +// }, { +// code: 'ERR_OUT_OF_RANGE', +// message: 'invalid options.add' +// }); +// } + +// // Any parameters with rem >= add lead to an impossible condition. +// for (const rem of [7n, 8n, 3000n]) { +// assert.throws(() => { +// generatePrimeSync(64, { add: 7n, rem }); +// }, { +// code: 'ERR_OUT_OF_RANGE', +// message: 'invalid options.rem' +// }); +// } + +// // This is possible, but not allowed. It implies prime == 7, which means that +// // we did not actually generate a random prime. +// assert.throws(() => { +// generatePrimeSync(3, { add: 8n, rem: 7n }); +// }, { +// code: 'ERR_OUT_OF_RANGE' +// }); + +// if (process.versions.openssl >= '1.1.1f') { +// // This is possible and allowed (but makes little sense). +// assert.strictEqual(generatePrimeSync(4, { +// add: 15n, +// rem: 13n, +// bigint: true +// }), 13n); +// } +// } + +[1, 'hello', {}, []].forEach((i) => { + assert.throws(() => checkPrime(i), { + code: 'ERR_INVALID_ARG_TYPE' + }); +}); + +for (const checks of ['hello', {}, []]) { + assert.throws(() => checkPrime(2n, { checks }, common.mustNotCall()), { + code: 'ERR_INVALID_ARG_TYPE', + message: /checks/ + }); + assert.throws(() => checkPrimeSync(2n, { checks }), { + code: 'ERR_INVALID_ARG_TYPE', + message: /checks/ + }); +} + +for (const checks of [-(2 ** 31), -1, 2 ** 31, 2 ** 32 - 1, 2 ** 32, 2 ** 50]) { + assert.throws(() => checkPrime(2n, { checks }, common.mustNotCall()), { + code: 'ERR_OUT_OF_RANGE', + message: /<= 2147483647/ + }); + assert.throws(() => checkPrimeSync(2n, { checks }), { + code: 'ERR_OUT_OF_RANGE', + message: /<= 2147483647/ + }); +} diff --git a/tests/node_compat/test/parallel/test-crypto-secret-keygen.js b/tests/node_compat/test/parallel/test-crypto-secret-keygen.js new file mode 100644 index 000000000..b108269d3 --- /dev/null +++ b/tests/node_compat/test/parallel/test-crypto-secret-keygen.js @@ -0,0 +1,144 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); + +const { + generateKey, + generateKeySync +} = require('crypto'); + +[1, true, [], {}, Infinity, null, undefined].forEach((i) => { + assert.throws(() => generateKey(i, 1, common.mustNotCall()), { + code: 'ERR_INVALID_ARG_TYPE', + message: /The "type" argument must be / + }); + assert.throws(() => generateKeySync(i, 1), { + code: 'ERR_INVALID_ARG_TYPE', + message: /The "type" argument must be / + }); +}); + +['', true, [], null, undefined].forEach((i) => { + assert.throws(() => generateKey('aes', i, common.mustNotCall()), { + code: 'ERR_INVALID_ARG_TYPE', + message: /The "options" argument must be / + }); + assert.throws(() => generateKeySync('aes', i), { + code: 'ERR_INVALID_ARG_TYPE', + message: /The "options" argument must be / + }); +}); + +['', true, {}, [], null, undefined].forEach((length) => { + assert.throws(() => generateKey('hmac', { length }, common.mustNotCall()), { + code: 'ERR_INVALID_ARG_TYPE', + message: /The "options\.length" property must be / + }); + assert.throws(() => generateKeySync('hmac', { length }), { + code: 'ERR_INVALID_ARG_TYPE', + message: /The "options\.length" property must be / + }); +}); + +assert.throws(() => generateKey('aes', { length: 256 }), { + code: 'ERR_INVALID_ARG_TYPE' +}); + +assert.throws(() => generateKey('hmac', { length: -1 }, common.mustNotCall()), { + code: 'ERR_OUT_OF_RANGE' +}); + +assert.throws(() => generateKey('hmac', { length: 4 }, common.mustNotCall()), { + code: 'ERR_OUT_OF_RANGE' +}); + +assert.throws(() => generateKey('hmac', { length: 7 }, common.mustNotCall()), { + code: 'ERR_OUT_OF_RANGE' +}); + +assert.throws( + () => generateKey('hmac', { length: 2 ** 31 }, common.mustNotCall()), { + code: 'ERR_OUT_OF_RANGE' + }); + +assert.throws(() => generateKeySync('hmac', { length: -1 }), { + code: 'ERR_OUT_OF_RANGE' +}); + +assert.throws(() => generateKeySync('hmac', { length: 4 }), { + code: 'ERR_OUT_OF_RANGE' +}); + +assert.throws(() => generateKeySync('hmac', { length: 7 }), { + code: 'ERR_OUT_OF_RANGE' +}); + +assert.throws( + () => generateKeySync('hmac', { length: 2 ** 31 }), { + code: 'ERR_OUT_OF_RANGE' + }); + +assert.throws(() => generateKeySync('aes', { length: 123 }), { + code: 'ERR_INVALID_ARG_VALUE', + message: /The property 'options\.length' must be one of: 128, 192, 256/ +}); + +{ + const key = generateKeySync('aes', { length: 128 }); + assert(key); + const keybuf = key.export(); + assert.strictEqual(keybuf.byteLength, 128 / 8); + + generateKey('aes', { length: 128 }, common.mustSucceed((key) => { + assert(key); + const keybuf = key.export(); + assert.strictEqual(keybuf.byteLength, 128 / 8); + })); +} + +{ + const key = generateKeySync('aes', { length: 256 }); + assert(key); + const keybuf = key.export(); + assert.strictEqual(keybuf.byteLength, 256 / 8); + + generateKey('aes', { length: 256 }, common.mustSucceed((key) => { + assert(key); + const keybuf = key.export(); + assert.strictEqual(keybuf.byteLength, 256 / 8); + })); +} + +{ + const key = generateKeySync('hmac', { length: 123 }); + assert(key); + const keybuf = key.export(); + assert.strictEqual(keybuf.byteLength, Math.floor(123 / 8)); + + generateKey('hmac', { length: 123 }, common.mustSucceed((key) => { + assert(key); + const keybuf = key.export(); + assert.strictEqual(keybuf.byteLength, Math.floor(123 / 8)); + })); +} + +assert.throws( + () => generateKey('unknown', { length: 123 }, common.mustNotCall()), { + code: 'ERR_INVALID_ARG_VALUE', + message: /The argument 'type' must be a supported key type/ + }); + +assert.throws(() => generateKeySync('unknown', { length: 123 }), { + code: 'ERR_INVALID_ARG_VALUE', + message: /The argument 'type' must be a supported key type/ +}); diff --git a/tests/node_compat/test/parallel/test-crypto-stream.js b/tests/node_compat/test/parallel/test-crypto-stream.js new file mode 100644 index 000000000..07d3c5c6d --- /dev/null +++ b/tests/node_compat/test/parallel/test-crypto-stream.js @@ -0,0 +1,96 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const stream = require('stream'); +const crypto = require('crypto'); + +if (!common.hasFipsCrypto) { + // Small stream to buffer converter + class Stream2buffer extends stream.Writable { + constructor(callback) { + super(); + + this._buffers = []; + this.once('finish', function() { + callback(null, Buffer.concat(this._buffers)); + }); + } + + _write(data, encoding, done) { + this._buffers.push(data); + return done(null); + } + } + + // Create an md5 hash of "Hallo world" + const hasher1 = crypto.createHash('md5'); + hasher1.pipe(new Stream2buffer(common.mustCall(function end(err, hash) { + assert.strictEqual(err, null); + assert.strictEqual( + hash.toString('hex'), '06460dadb35d3d503047ce750ceb2d07' + ); + }))); + hasher1.end('Hallo world'); + + // Simpler check for unpipe, setEncoding, pause and resume + crypto.createHash('md5').unpipe({}); + crypto.createHash('md5').setEncoding('utf8'); + crypto.createHash('md5').pause(); + crypto.createHash('md5').resume(); +} + +// Decipher._flush() should emit an error event, not an exception. +const key = Buffer.from('48fb56eb10ffeb13fc0ef551bbca3b1b', 'hex'); +const badkey = Buffer.from('12341234123412341234123412341234', 'hex'); +const iv = Buffer.from('6d358219d1f488f5f4eb12820a66d146', 'hex'); +const cipher = crypto.createCipheriv('aes-128-cbc', key, iv); +const decipher = crypto.createDecipheriv('aes-128-cbc', badkey, iv); + +// TODO(kt3k): Align error message of decipher with wrong padding and +// enable the below test case. +/* +cipher.pipe(decipher) + .on('error', common.expectsError(common.hasOpenSSL3 ? { + message: /bad decrypt/, + library: 'Provider routines', + reason: 'bad decrypt', + } : { + message: /bad decrypt/, + function: 'EVP_DecryptFinal_ex', + library: 'digital envelope routines', + reason: 'bad decrypt', + })); +*/ + +cipher.end('Papaya!'); // Should not cause an unhandled exception. diff --git a/tests/node_compat/test/parallel/test-crypto-update-encoding.js b/tests/node_compat/test/parallel/test-crypto-update-encoding.js new file mode 100644 index 000000000..deb3c17c3 --- /dev/null +++ b/tests/node_compat/test/parallel/test-crypto-update-encoding.js @@ -0,0 +1,29 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); + +if (!common.hasCrypto) + common.skip('missing crypto'); + +const crypto = require('crypto'); + +const zeros = Buffer.alloc; +const key = zeros(16); +const iv = zeros(16); + +const cipher = () => crypto.createCipheriv('aes-128-cbc', key, iv); +const decipher = () => crypto.createDecipheriv('aes-128-cbc', key, iv); +const hash = () => crypto.createSign('sha256'); +const hmac = () => crypto.createHmac('sha256', key); +const sign = () => crypto.createSign('sha256'); +const verify = () => crypto.createVerify('sha256'); + +for (const f of [cipher, decipher, hash, hmac, sign, verify]) + for (const n of [15, 16]) + f().update(zeros(n), 'hex'); // Should ignore inputEncoding. diff --git a/tests/node_compat/test/parallel/test-crypto-x509.js b/tests/node_compat/test/parallel/test-crypto-x509.js new file mode 100644 index 000000000..eeee2f7d7 --- /dev/null +++ b/tests/node_compat/test/parallel/test-crypto-x509.js @@ -0,0 +1,109 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. + +'use strict'; +const common = require('../common'); + +if (!common.hasCrypto) + common.skip('missing crypto'); + +const { + X509Certificate, +} = require('crypto'); + +const assert = require('assert'); +const fixtures = require('../common/fixtures'); +const { readFileSync } = require('fs'); + +const cert = readFileSync(fixtures.path('keys', 'agent1-cert.pem')); +const ca = readFileSync(fixtures.path('keys', 'ca1-cert.pem')); + +[1, {}, false, null].forEach((i) => { + assert.throws(() => new X509Certificate(i), { + code: 'ERR_INVALID_ARG_TYPE' + }); +}); + +const subjectCheck = `C=US +ST=CA +L=SF +O=Joyent +OU=Node.js +CN=agent1 +Email=ry@tinyclouds.org`; + +const issuerCheck = `C=US +ST=CA +L=SF +O=Joyent +OU=Node.js +CN=ca1 +Email=ry@tinyclouds.org`; + +let infoAccessCheck = `OCSP - URI:http://ocsp.nodejs.org/ +CA Issuers - URI:http://ca.nodejs.org/ca.cert`; +if (!common.hasOpenSSL3) + infoAccessCheck += '\n'; + +const der = Buffer.from( + '308203e8308202d0a0030201020214147d36c1c2f74206de9fab5f2226d78adb00a42630' + + '0d06092a864886f70d01010b0500307a310b3009060355040613025553310b3009060355' + + '04080c024341310b300906035504070c025346310f300d060355040a0c064a6f79656e74' + + '3110300e060355040b0c074e6f64652e6a73310c300a06035504030c036361313120301e' + + '06092a864886f70d010901161172794074696e79636c6f7564732e6f72673020170d3232' + + '303930333231343033375a180f32323936303631373231343033375a307d310b30090603' + + '55040613025553310b300906035504080c024341310b300906035504070c025346310f30' + + '0d060355040a0c064a6f79656e743110300e060355040b0c074e6f64652e6a73310f300d' + + '06035504030c066167656e74313120301e06092a864886f70d010901161172794074696e' + + '79636c6f7564732e6f726730820122300d06092a864886f70d01010105000382010f0030' + + '82010a0282010100d456320afb20d3827093dc2c4284ed04dfbabd56e1ddae529e28b790' + + 'cd4256db273349f3735ffd337c7a6363ecca5a27b7f73dc7089a96c6d886db0c62388f1c' + + 'dd6a963afcd599d5800e587a11f908960f84ed50ba25a28303ecda6e684fbe7baedc9ce8' + + '801327b1697af25097cee3f175e400984c0db6a8eb87be03b4cf94774ba56fffc8c63c68' + + 'd6adeb60abbe69a7b14ab6a6b9e7baa89b5adab8eb07897c07f6d4fa3d660dff574107d2' + + '8e8f63467a788624c574197693e959cea1362ffae1bba10c8c0d88840abfef103631b2e8' + + 'f5c39b5548a7ea57e8a39f89291813f45a76c448033a2b7ed8403f4baa147cf35e2d2554' + + 'aa65ce49695797095bf4dc6b0203010001a361305f305d06082b06010505070101045130' + + '4f302306082b060105050730018617687474703a2f2f6f6373702e6e6f64656a732e6f72' + + '672f302806082b06010505073002861c687474703a2f2f63612e6e6f64656a732e6f7267' + + '2f63612e63657274300d06092a864886f70d01010b05000382010100c3349810632ccb7d' + + 'a585de3ed51e34ed154f0f7215608cf2701c00eda444dc2427072c8aca4da6472c1d9e68' + + 'f177f99a90a8b5dbf3884586d61cb1c14ea7016c8d38b70d1b46b42947db30edc1e9961e' + + 'd46c0f0e35da427bfbe52900771817e733b371adf19e12137235141a34347db0dfc05579' + + '8b1f269f3bdf5e30ce35d1339d56bb3c570de9096215433047f87ca42447b44e7e6b5d0e' + + '48f7894ab186f85b6b1a74561b520952fea888617f32f582afce1111581cd63efcc68986' + + '00d248bb684dedb9c3d6710c38de9e9bc21f9c3394b729d5f707d64ea890603e5989f8fa' + + '59c19ad1a00732e7adc851b89487cc00799dde068aa64b3b8fd976e8bc113ef2', + 'hex'); + +{ + const x509 = new X509Certificate(cert); + + assert(!x509.ca); + assert.strictEqual(x509.subject, subjectCheck); + assert.strictEqual(x509.subjectAltName, undefined); + assert.strictEqual(x509.issuer, issuerCheck); + assert.strictEqual(x509.validFrom, 'Sep 3 21:40:37 2022 +00:00'); + assert.strictEqual(x509.validTo, 'Jun 17 21:40:37 2296 +00:00'); + assert.strictEqual( + x509.fingerprint, + '8B:89:16:C4:99:87:D2:13:1A:64:94:36:38:A5:32:01:F0:95:3B:53'); + assert.strictEqual( + x509.fingerprint256, + '2C:62:59:16:91:89:AB:90:6A:3E:98:88:A6:D3:C5:58:58:6C:AE:FF:9C:33:' + + '22:7C:B6:77:D3:34:E7:53:4B:05' + ); + assert.strictEqual( + x509.fingerprint512, + '0B:6F:D0:4D:6B:22:53:99:66:62:51:2D:2C:96:F2:58:3F:95:1C:CC:4C:44:' + + '9D:B5:59:AA:AD:A8:F6:2A:24:8A:BB:06:A5:26:42:52:30:A3:37:61:30:A9:' + + '5A:42:63:E0:21:2F:D6:70:63:07:96:6F:27:A7:78:12:08:02:7A:8B' + ); + assert.strictEqual(x509.keyUsage, undefined); + assert.strictEqual(x509.serialNumber, '147D36C1C2F74206DE9FAB5F2226D78ADB00A426'); + + assert.strictEqual(x509.checkEmail('ry@tinyclouds.org'), 'ry@tinyclouds.org'); + assert.strictEqual(x509.checkEmail('sally@example.com'), undefined); +} \ No newline at end of file diff --git a/tests/node_compat/test/parallel/test-dgram-close-during-bind.js b/tests/node_compat/test/parallel/test-dgram-close-during-bind.js new file mode 100644 index 000000000..fd1fe523e --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-close-during-bind.js @@ -0,0 +1,26 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Flags: --expose-internals +'use strict'; +const common = require('../common'); +const dgram = require('dgram'); +const { kStateSymbol } = require('internal/dgram'); +const socket = dgram.createSocket('udp4'); +const { handle } = socket[kStateSymbol]; +const lookup = handle.lookup; + +// Test the scenario where the socket is closed during a bind operation. +handle.bind = common.mustNotCall('bind() should not be called.'); + +handle.lookup = common.mustCall(function(address, callback) { + socket.close(common.mustCall(() => { + lookup.call(this, address, callback); + })); +}); + +socket.bind(common.mustNotCall('Socket should not bind.')); diff --git a/tests/node_compat/test/parallel/test-dgram-close-signal.js b/tests/node_compat/test/parallel/test-dgram-close-signal.js new file mode 100644 index 000000000..ef6ac3a32 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-close-signal.js @@ -0,0 +1,38 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const dgram = require('dgram'); + +{ + // Test bad signal. + assert.throws( + () => dgram.createSocket({ type: 'udp4', signal: {} }), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + }); +} + +{ + // Test close. + const controller = new AbortController(); + const { signal } = controller; + const server = dgram.createSocket({ type: 'udp4', signal }); + server.on('close', common.mustCall()); + controller.abort(); +} + +{ + // Test close with pre-aborted signal. + const signal = AbortSignal.abort(); + const server = dgram.createSocket({ type: 'udp4', signal }); + server.on('close', common.mustCall()); +} diff --git a/tests/node_compat/test/parallel/test-dgram-custom-lookup.js b/tests/node_compat/test/parallel/test-dgram-custom-lookup.js new file mode 100644 index 000000000..ca3bd3df3 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-custom-lookup.js @@ -0,0 +1,56 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const dgram = require('dgram'); +const dns = require('dns'); + +{ + // Verify that the provided lookup function is called. + const lookup = common.mustCall((host, family, callback) => { + dns.lookup(host, family, callback); + }); + + const socket = dgram.createSocket({ type: 'udp4', lookup }); + + socket.bind(common.mustCall(() => { + socket.close(); + })); +} + +// TODO: unable to overwrite imports with spies +// { +// // Verify that lookup defaults to dns.lookup(). +// const originalLookup = dns.lookup; + +// dns.lookup = common.mustCall((host, family, callback) => { +// dns.lookup = originalLookup; +// originalLookup(host, family, callback); +// }); + +// const socket = dgram.createSocket({ type: 'udp4' }); + +// socket.bind(common.mustCall(() => { +// socket.close(); +// })); +// } + +{ + // Verify that non-functions throw. + [null, true, false, 0, 1, NaN, '', 'foo', {}, Symbol()].forEach((value) => { + assert.throws(() => { + dgram.createSocket({ type: 'udp4', lookup: value }); + }, { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "lookup" argument must be of type function.' + + common.invalidArgTypeHelper(value) + }); + }); +} diff --git a/tests/node_compat/test/parallel/test-dgram-ipv6only.js b/tests/node_compat/test/parallel/test-dgram-ipv6only.js new file mode 100644 index 000000000..31f4e1fd9 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-ipv6only.js @@ -0,0 +1,44 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// TODO(cmorten): Deno.listenDatagram is currently `0.0.0.0` when you listen to `::`. + +'use strict'; + +const common = require('../common'); +if (!common.hasIPv6) + common.skip('no IPv6 support'); + +const dgram = require('dgram'); + +// This test ensures that dual-stack support is disabled when +// we specify the `ipv6Only` option in `dgram.createSocket()`. +const socket = dgram.createSocket({ + type: 'udp6', + ipv6Only: true, +}); + +socket.bind({ + port: 0, + address: '::', +}, common.mustCall(() => { + const { port } = socket.address(); + const client = dgram.createSocket('udp4'); + + // We can still bind to '0.0.0.0'. + // TODO: uncomment out when Deno allows IPv4 and IPv6 to be bound + // independently + // client.bind({ + // port, + // address: '0.0.0.0', + // }, common.mustCall(() => { + client.close(); + socket.close(); + // })); + + client.on('error', common.mustNotCall()); +})); diff --git a/tests/node_compat/test/parallel/test-dgram-send-cb-quelches-error.js b/tests/node_compat/test/parallel/test-dgram-send-cb-quelches-error.js new file mode 100644 index 000000000..d2fd5af50 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-send-cb-quelches-error.js @@ -0,0 +1,47 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// TODO(cmorten): uncomment dns module code once dns.setServer() has been +// implemented + +'use strict'; +const common = require('../common'); +const mustCall = common.mustCall; +const assert = require('assert'); +const dgram = require('dgram'); +// const dns = require('dns'); + +const socket = dgram.createSocket('udp4'); +const buffer = Buffer.from('gary busey'); + +// dns.setServers([]); + +socket.once('error', onEvent); + +// assert that: +// * callbacks act as "error" listeners if given. +// * error is never emitter for missing dns entries +// if a callback that handles error is present +// * error is emitted if a callback with no argument is passed +socket.send(buffer, 0, buffer.length, 100, + 'dne.example.com', mustCall(callbackOnly)); + +function callbackOnly(err) { + assert.ok(err); + socket.removeListener('error', onEvent); + socket.on('error', mustCall(onError)); + socket.send(buffer, 0, buffer.length, 100, 'dne.invalid'); +} + +function onEvent(err) { + assert.fail(`Error should not be emitted if there is callback: ${err}`); +} + +function onError(err) { + assert.ok(err); + socket.close(); +} diff --git a/tests/node_compat/test/parallel/test-dgram-socket-buffer-size.js b/tests/node_compat/test/parallel/test-dgram-socket-buffer-size.js new file mode 100644 index 000000000..b2fc33262 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-socket-buffer-size.js @@ -0,0 +1,178 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Flags: --expose-internals +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const dgram = require('dgram'); +const { inspect } = require('util'); +const { internalBinding } = require('internal/test/binding'); +const { + UV_EBADF, + UV_EINVAL, + UV_ENOTSOCK +} = internalBinding('uv'); + +// Note error test amendments from Node due to Deno formatting errors slightly +// differently. +function getExpectedError(type) { + const code = common.isWindows ? 'ENOTSOCK' : 'EBADF'; + const message = common.isWindows ? + 'socket operation on non-socket' : 'bad file descriptor'; + const errno = common.isWindows ? UV_ENOTSOCK : UV_EBADF; + const syscall = `uv_${type}_buffer_size`; + const suffix = common.isWindows ? + 'ENOTSOCK (socket operation on non-socket)' : 'EBADF (bad file descriptor)'; + const error = { + code: 'ERR_SOCKET_BUFFER_SIZE', + name: 'SystemError', + message: `Could not get or set buffer size: ${syscall} returned ${suffix}`, + info: { + code, + message, + errno, + syscall + } + }; + return error; +} + +{ + // Should throw error if the socket is never bound. + const errorObj = getExpectedError('send'); + + const socket = dgram.createSocket('udp4'); + + assert.throws(() => { + socket.setSendBufferSize(8192); + }, (err) => { + assert.strictEqual( + inspect(err).replace(/^ +at .*\n/gm, ""), + `ERR_SOCKET_BUFFER_SIZE [SystemError]: ${errorObj.message}\n` + + " code: 'ERR_SOCKET_BUFFER_SIZE',\n" + + " info: {\n" + + ` errno: ${errorObj.info.errno},\n` + + ` code: '${errorObj.info.code}',\n` + + ` message: '${errorObj.info.message}',\n` + + ` syscall: '${errorObj.info.syscall}'\n` + + " },\n" + + ` errno: [Getter/Setter],\n` + + ` syscall: [Getter/Setter]\n` + + "}" + ); + return true; + }); + + assert.throws(() => { + socket.getSendBufferSize(); + }, errorObj); +} + +{ + const socket = dgram.createSocket('udp4'); + + // Should throw error if the socket is never bound. + const errorObj = getExpectedError('recv'); + + assert.throws(() => { + socket.setRecvBufferSize(8192); + }, errorObj); + + assert.throws(() => { + socket.getRecvBufferSize(); + }, errorObj); +} + +{ + // Should throw error if invalid buffer size is specified + const errorObj = { + code: 'ERR_SOCKET_BAD_BUFFER_SIZE', + name: 'TypeError', + message: /^Buffer size must be a positive integer$/ + }; + + const badBufferSizes = [-1, Infinity, 'Doh!']; + + const socket = dgram.createSocket('udp4'); + + socket.bind(common.mustCall(() => { + badBufferSizes.forEach((badBufferSize) => { + assert.throws(() => { + socket.setRecvBufferSize(badBufferSize); + }, errorObj); + + assert.throws(() => { + socket.setSendBufferSize(badBufferSize); + }, errorObj); + }); + socket.close(); + })); +} + +{ + // Can set and get buffer sizes after binding the socket. + const socket = dgram.createSocket('udp4'); + + socket.bind(common.mustCall(() => { + socket.setRecvBufferSize(10000); + socket.setSendBufferSize(10000); + + // note: linux will double the buffer size + const expectedBufferSize = common.isLinux ? 20000 : 10000; + assert.strictEqual(socket.getRecvBufferSize(), expectedBufferSize); + assert.strictEqual(socket.getSendBufferSize(), expectedBufferSize); + socket.close(); + })); +} + +{ + const info = { + code: 'EINVAL', + message: 'invalid argument', + errno: UV_EINVAL, + syscall: 'uv_recv_buffer_size' + }; + const errorObj = { + code: 'ERR_SOCKET_BUFFER_SIZE', + name: 'SystemError', + message: 'Could not get or set buffer size: uv_recv_buffer_size ' + + 'returned EINVAL (invalid argument)', + info + }; + const socket = dgram.createSocket('udp4'); + socket.bind(common.mustCall(() => { + assert.throws(() => { + socket.setRecvBufferSize(2147483648); + }, errorObj); + socket.close(); + })); +} + +{ + const info = { + code: 'EINVAL', + message: 'invalid argument', + errno: UV_EINVAL, + syscall: 'uv_send_buffer_size' + }; + const errorObj = { + code: 'ERR_SOCKET_BUFFER_SIZE', + name: 'SystemError', + message: 'Could not get or set buffer size: uv_send_buffer_size ' + + 'returned EINVAL (invalid argument)', + info + }; + const socket = dgram.createSocket('udp4'); + socket.bind(common.mustCall(() => { + assert.throws(() => { + socket.setSendBufferSize(2147483648); + }, errorObj); + socket.close(); + })); +} diff --git a/tests/node_compat/test/parallel/test-dgram-udp6-link-local-address.js b/tests/node_compat/test/parallel/test-dgram-udp6-link-local-address.js new file mode 100644 index 000000000..c828413a2 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-udp6-link-local-address.js @@ -0,0 +1,61 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +'use strict'; +const common = require('../common'); +if (!common.hasIPv6) + common.skip('no IPv6 support'); + +const assert = require('assert'); +const dgram = require('dgram'); +const os = require('os'); + +const { isWindows } = common; + +function linklocal() { + for (const [ifname, entries] of Object.entries(os.networkInterfaces())) { + for (const { address, family, scopeid } of entries) { + if (family === 'IPv6' && address.startsWith('fe80:')) { + return { address, ifname, scopeid }; + } + } + } +} +const iface = linklocal(); + +if (!iface) + common.skip('cannot find any IPv6 interfaces with a link local address'); + +const address = isWindows ? iface.address : `${iface.address}%${iface.ifname}`; +const message = 'Hello, local world!'; + +// Create a client socket for sending to the link-local address. +const client = dgram.createSocket('udp6'); + +// Create the server socket listening on the link-local address. +const server = dgram.createSocket('udp6'); + +server.on('listening', common.mustCall(() => { + const port = server.address().port; + client.send(message, 0, message.length, port, address); +})); + +server.on('message', common.mustCall((buf, info) => { + const received = buf.toString(); + assert.strictEqual(received, message); + // Check that the sender address is the one bound, + // including the link local scope identifier. + // TODO(cmorten): info.address is missing the link local scope identifier + // assert.strictEqual( + // info.address, + // isWindows ? `${iface.address}%${iface.scopeid}` : address + // ); + server.close(); + client.close(); +}, 1)); + +server.bind({ address }); diff --git a/tests/node_compat/test/parallel/test-diagnostics-channel-has-subscribers.js b/tests/node_compat/test/parallel/test-diagnostics-channel-has-subscribers.js new file mode 100644 index 000000000..66a548c37 --- /dev/null +++ b/tests/node_compat/test/parallel/test-diagnostics-channel-has-subscribers.js @@ -0,0 +1,17 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const assert = require('assert'); +const { channel, hasSubscribers } = require('diagnostics_channel'); + +const dc = channel('test'); +assert.ok(!hasSubscribers('test')); + +dc.subscribe(() => {}); +assert.ok(hasSubscribers('test')); diff --git a/tests/node_compat/test/parallel/test-diagnostics-channel-object-channel-pub-sub.js b/tests/node_compat/test/parallel/test-diagnostics-channel-object-channel-pub-sub.js new file mode 100644 index 000000000..00b786582 --- /dev/null +++ b/tests/node_compat/test/parallel/test-diagnostics-channel-object-channel-pub-sub.js @@ -0,0 +1,53 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const dc = require('diagnostics_channel'); +const assert = require('assert'); +const { Channel } = dc; + +const input = { + foo: 'bar' +}; + +// Should not have named channel +assert.ok(!dc.hasSubscribers('test')); + +// Individual channel objects can be created to avoid future lookups +const channel = dc.channel('test'); +assert.ok(channel instanceof Channel); + +// No subscribers yet, should not publish +assert.ok(!channel.hasSubscribers); + +const subscriber = common.mustCall((message, name) => { + assert.strictEqual(name, channel.name); + assert.deepStrictEqual(message, input); +}); + +// Now there's a subscriber, should publish +channel.subscribe(subscriber); +assert.ok(channel.hasSubscribers); + +// The ActiveChannel prototype swap should not fail instanceof +assert.ok(channel instanceof Channel); + +// Should trigger the subscriber once +channel.publish(input); + +// Should not publish after subscriber is unsubscribed +assert.ok(channel.unsubscribe(subscriber)); +assert.ok(!channel.hasSubscribers); + +// unsubscribe() should return false when subscriber is not found +assert.ok(!channel.unsubscribe(subscriber)); + +assert.throws(() => { + channel.subscribe(null); +}, { code: 'ERR_INVALID_ARG_TYPE' }); diff --git a/tests/node_compat/test/parallel/test-diagnostics-channel-pub-sub.js b/tests/node_compat/test/parallel/test-diagnostics-channel-pub-sub.js new file mode 100644 index 000000000..378cf051e --- /dev/null +++ b/tests/node_compat/test/parallel/test-diagnostics-channel-pub-sub.js @@ -0,0 +1,51 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const dc = require('diagnostics_channel'); +const assert = require('assert'); +const { Channel } = dc; + +const name = 'test'; +const input = { + foo: 'bar' +}; + +// Individual channel objects can be created to avoid future lookups +const channel = dc.channel(name); +assert.ok(channel instanceof Channel); + +// No subscribers yet, should not publish +assert.ok(!channel.hasSubscribers); + +const subscriber = common.mustCall((message, name) => { + assert.strictEqual(name, channel.name); + assert.deepStrictEqual(message, input); +}); + +// Now there's a subscriber, should publish +dc.subscribe(name, subscriber); +assert.ok(channel.hasSubscribers); + +// The ActiveChannel prototype swap should not fail instanceof +assert.ok(channel instanceof Channel); + +// Should trigger the subscriber once +channel.publish(input); + +// Should not publish after subscriber is unsubscribed +assert.ok(dc.unsubscribe(name, subscriber)); +assert.ok(!channel.hasSubscribers); + +// unsubscribe() should return false when subscriber is not found +assert.ok(!dc.unsubscribe(name, subscriber)); + +assert.throws(() => { + dc.subscribe(name, null); +}, { code: 'ERR_INVALID_ARG_TYPE' }); diff --git a/tests/node_compat/test/parallel/test-diagnostics-channel-symbol-named.js b/tests/node_compat/test/parallel/test-diagnostics-channel-symbol-named.js new file mode 100644 index 000000000..3067c78e9 --- /dev/null +++ b/tests/node_compat/test/parallel/test-diagnostics-channel-symbol-named.js @@ -0,0 +1,35 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const dc = require('diagnostics_channel'); +const assert = require('assert'); + +const input = { + foo: 'bar' +}; + +const symbol = Symbol('test'); + +// Individual channel objects can be created to avoid future lookups +const channel = dc.channel(symbol); + +// Expect two successful publishes later +channel.subscribe(common.mustCall((message, name) => { + assert.strictEqual(name, symbol); + assert.deepStrictEqual(message, input); +})); + +channel.publish(input); + +{ + assert.throws(() => { + dc.channel(null); + }, /ERR_INVALID_ARG_TYPE/); +} diff --git a/tests/node_compat/test/parallel/test-diagnostics-channel-udp.js b/tests/node_compat/test/parallel/test-diagnostics-channel-udp.js new file mode 100644 index 000000000..ddf757a12 --- /dev/null +++ b/tests/node_compat/test/parallel/test-diagnostics-channel-udp.js @@ -0,0 +1,22 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const dgram = require('dgram'); +const dc = require('diagnostics_channel'); + +const udpSocketChannel = dc.channel('udp.socket'); + +const isUDPSocket = (socket) => socket instanceof dgram.Socket; + +udpSocketChannel.subscribe(common.mustCall(({ socket }) => { + assert.strictEqual(isUDPSocket(socket), true); +})); +const socket = dgram.createSocket('udp4'); +socket.close(); diff --git a/tests/node_compat/test/parallel/test-dns-lookup.js b/tests/node_compat/test/parallel/test-dns-lookup.js new file mode 100644 index 000000000..d137586d2 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dns-lookup.js @@ -0,0 +1,179 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Flags: --expose-internals +'use strict'; + +// TODO: enable remaining tests once functionality is implemented. + +const common = require('../common'); +const assert = require('assert'); +// const { internalBinding } = require('internal/test/binding'); +// const cares = internalBinding('cares_wrap'); + +// Stub `getaddrinfo` to *always* error. This has to be done before we load the +// `dns` module to guarantee that the `dns` module uses the stub. +// cares.getaddrinfo = () => internalBinding('uv').UV_ENOMEM; + +const dns = require('dns'); +const dnsPromises = dns.promises; + +{ + const err = { + code: "ERR_INVALID_ARG_TYPE", + name: "TypeError", + message: + /^The "hostname" argument must be of type string\. Received type number/, + }; + + assert.throws(() => dns.lookup(1, {}), err); + assert.throws(() => dnsPromises.lookup(1, {}), err); +} + +// This also verifies different expectWarning notations. +// common.expectWarning({ +// // For 'internal/test/binding' module. +// 'internal/test/binding': [ +// 'These APIs are for internal testing only. Do not use them.', +// ], +// // For calling `dns.lookup` with falsy `hostname`. +// 'DeprecationWarning': { +// DEP0118: 'The provided hostname "false" is not a valid ' + +// 'hostname, and is supported in the dns module solely for compatibility.' +// } +// }); + +assert.throws( + () => { + dns.lookup(false, "cb"); + }, + { + code: "ERR_INVALID_ARG_TYPE", + name: "TypeError", + } +); + +assert.throws( + () => { + dns.lookup(false, "options", "cb"); + }, + { + code: "ERR_INVALID_ARG_TYPE", + name: "TypeError", + } +); + +{ + const err = { + code: 'ERR_INVALID_ARG_VALUE', + name: 'TypeError', + message: "The argument 'hints' is invalid. Received 100" + }; + const options = { + hints: 100, + family: 0, + all: false + }; + + assert.throws(() => { dnsPromises.lookup(false, options); }, err); + assert.throws(() => { + dns.lookup(false, options, common.mustNotCall()); + }, err); +} + +{ + const family = 20; + const err = { + code: "ERR_INVALID_ARG_VALUE", + name: "TypeError", + message: `The property 'options.family' must be one of: 0, 4, 6. Received ${family}`, + }; + const options = { + hints: 0, + family, + all: false + }; + + assert.throws(() => { dnsPromises.lookup(false, options); }, err); + assert.throws(() => { + dns.lookup(false, options, common.mustNotCall()); + }, err); +} + +(async function() { + let res; + + res = await dnsPromises.lookup(false, { + hints: 0, + family: 0, + all: true + }); + assert.deepStrictEqual(res, []); + + res = await dnsPromises.lookup('127.0.0.1', { + hints: 0, + family: 4, + all: true + }); + assert.deepStrictEqual(res, [{ address: '127.0.0.1', family: 4 }]); + + res = await dnsPromises.lookup('127.0.0.1', { + hints: 0, + family: 4, + all: false + }); + assert.deepStrictEqual(res, { address: '127.0.0.1', family: 4 }); +})().then(common.mustCall()); + +dns.lookup(false, { + hints: 0, + family: 0, + all: true +}, common.mustSucceed((result, addressType) => { + assert.deepStrictEqual(result, []); + assert.strictEqual(addressType, undefined); +})); + +dns.lookup('127.0.0.1', { + hints: 0, + family: 4, + all: true +}, common.mustSucceed((result, addressType) => { + assert.deepStrictEqual(result, [{ + address: '127.0.0.1', + family: 4 + }]); + assert.strictEqual(addressType, undefined); +})); + +dns.lookup('127.0.0.1', { + hints: 0, + family: 4, + all: false +}, common.mustSucceed((result, addressType) => { + assert.deepStrictEqual(result, '127.0.0.1'); + assert.strictEqual(addressType, 4); +})); + +// let tickValue = 0; + +// Should fail due to stub. +// dns.lookup('example.com', common.mustCall((error, result, addressType) => { +// assert(error); +// assert.strictEqual(tickValue, 1); +// assert.strictEqual(error.code, 'ENOMEM'); +// const descriptor = Object.getOwnPropertyDescriptor(error, 'message'); +// // The error message should be non-enumerable. +// assert.strictEqual(descriptor.enumerable, false); +// })); + +// Make sure that the error callback is called on next tick. +// tickValue = 1; + +// Should fail due to stub. +// assert.rejects(dnsPromises.lookup('example.com'), +// { code: 'ENOMEM', hostname: 'example.com' }); diff --git a/tests/node_compat/test/parallel/test-dns-memory-error.js b/tests/node_compat/test/parallel/test-dns-memory-error.js new file mode 100644 index 000000000..6ef6968be --- /dev/null +++ b/tests/node_compat/test/parallel/test-dns-memory-error.js @@ -0,0 +1,23 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Flags: --expose-internals +'use strict'; + +// Check that if libuv reports a memory error on a DNS query, that the memory +// error is passed through and not replaced with ENOTFOUND. + +require('../common'); + +const assert = require('assert'); +const errors = require('internal/errors'); +const { internalBinding } = require('internal/test/binding'); + +const { UV_EAI_MEMORY } = internalBinding('uv'); +const memoryError = errors.dnsException(UV_EAI_MEMORY, 'fhqwhgads'); + +assert.strictEqual(memoryError.code, 'EAI_MEMORY'); diff --git a/tests/node_compat/test/parallel/test-dns-promises-exists.js b/tests/node_compat/test/parallel/test-dns-promises-exists.js new file mode 100644 index 000000000..10f9f81df --- /dev/null +++ b/tests/node_compat/test/parallel/test-dns-promises-exists.js @@ -0,0 +1,40 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); +const dnsPromises = require('dns/promises'); +const dns = require('dns'); + +assert.strictEqual(dnsPromises, dns.promises); + +assert.strictEqual(dnsPromises.NODATA, dns.NODATA); +assert.strictEqual(dnsPromises.FORMERR, dns.FORMERR); +assert.strictEqual(dnsPromises.SERVFAIL, dns.SERVFAIL); +assert.strictEqual(dnsPromises.NOTFOUND, dns.NOTFOUND); +assert.strictEqual(dnsPromises.NOTIMP, dns.NOTIMP); +assert.strictEqual(dnsPromises.REFUSED, dns.REFUSED); +assert.strictEqual(dnsPromises.BADQUERY, dns.BADQUERY); +assert.strictEqual(dnsPromises.BADNAME, dns.BADNAME); +assert.strictEqual(dnsPromises.BADFAMILY, dns.BADFAMILY); +assert.strictEqual(dnsPromises.BADRESP, dns.BADRESP); +assert.strictEqual(dnsPromises.CONNREFUSED, dns.CONNREFUSED); +assert.strictEqual(dnsPromises.TIMEOUT, dns.TIMEOUT); +assert.strictEqual(dnsPromises.EOF, dns.EOF); +assert.strictEqual(dnsPromises.FILE, dns.FILE); +assert.strictEqual(dnsPromises.NOMEM, dns.NOMEM); +assert.strictEqual(dnsPromises.DESTRUCTION, dns.DESTRUCTION); +assert.strictEqual(dnsPromises.BADSTR, dns.BADSTR); +assert.strictEqual(dnsPromises.BADFLAGS, dns.BADFLAGS); +assert.strictEqual(dnsPromises.NONAME, dns.NONAME); +assert.strictEqual(dnsPromises.BADHINTS, dns.BADHINTS); +assert.strictEqual(dnsPromises.NOTINITIALIZED, dns.NOTINITIALIZED); +assert.strictEqual(dnsPromises.LOADIPHLPAPI, dns.LOADIPHLPAPI); +assert.strictEqual(dnsPromises.ADDRGETNETWORKPARAMS, dns.ADDRGETNETWORKPARAMS); +assert.strictEqual(dnsPromises.CANCELLED, dns.CANCELLED); diff --git a/tests/node_compat/test/parallel/test-dns-resolveany.js b/tests/node_compat/test/parallel/test-dns-resolveany.js new file mode 100644 index 000000000..56d533ad9 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dns-resolveany.js @@ -0,0 +1,78 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// TODO: enable remaining tests once functionality is implemented. + +'use strict'; +const common = require('../common'); +const dnstools = require('../common/dns'); +const dns = require('dns'); +const assert = require('assert'); +const dgram = require('dgram'); +const dnsPromises = dns.promises; + +const answers = [ + { type: 'A', address: '1.2.3.4', /*ttl: 123*/ }, + { type: 'AAAA', address: '::42', /*ttl: 123*/ }, + { + type: 'CAA', + critical: 128, + issue: 'platynum.ch' + }, + { type: 'MX', priority: 42, exchange: 'foobar.com', ttl: 124 }, + { type: 'NS', value: 'foobar.org', ttl: 457 }, + { type: 'PTR', value: 'baz.org', ttl: 987 }, + { + type: 'SOA', + nsname: 'ns1.example.com', + hostmaster: 'admin.example.com', + serial: 156696742, + refresh: 900, + retry: 900, + expire: 1800, + minttl: 60 + }, + { type: 'TXT', entries: [ 'v=spf1 ~all', 'xyz\x00foo' ] }, +]; + +const server = dgram.createSocket('udp4'); + +server.on('message', common.mustCall((msg, { address, port }) => { + const parsed = dnstools.parseDNSPacket(msg); + const domain = parsed.questions[0].domain; + assert.strictEqual(domain, 'example.org'); + + server.send(dnstools.writeDNSPacket({ + id: parsed.id, + questions: parsed.questions, + answers: answers.map((answer) => Object.assign({ domain }, answer)), + }), port, address); +}, /*2*/ 30)); + +server.bind(0, common.mustCall(async () => { + const address = server.address(); + dns.setServers([`127.0.0.1:${address.port}`]); + + validateResults(await dnsPromises.resolveAny('example.org')); + + dns.resolveAny('example.org', common.mustSucceed((res) => { + validateResults(res); + server.close(); + })); +})); + +function validateResults(res) { + // TTL values are only provided for A and AAAA entries. + assert.deepStrictEqual(res.map(maybeRedactTTL), answers.map(maybeRedactTTL)); +} + +function maybeRedactTTL(r) { + const ret = { ...r }; + if (!['A', 'AAAA'].includes(r.type)) + delete ret.ttl; + return ret; +} diff --git a/tests/node_compat/test/parallel/test-dns-resolvens-typeerror.js b/tests/node_compat/test/parallel/test-dns-resolvens-typeerror.js new file mode 100644 index 000000000..f4b0770fd --- /dev/null +++ b/tests/node_compat/test/parallel/test-dns-resolvens-typeerror.js @@ -0,0 +1,62 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); + +// This test ensures `dns.resolveNs()` does not raise a C++-land assertion error +// and throw a JavaScript TypeError instead. +// Issue https://github.com/nodejs/node-v0.x-archive/issues/7070 + +const assert = require('assert'); +const dns = require('dns'); +const dnsPromises = dns.promises; + +assert.throws( + () => dnsPromises.resolveNs([]), // bad name + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: /^The "name" argument must be of type string/ + } +); +assert.throws( + () => dns.resolveNs([]), // bad name + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: /^The "name" argument must be of type string/ + } +); +assert.throws( + () => dns.resolveNs(''), // bad callback + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + } +); diff --git a/tests/node_compat/test/parallel/test-dns-setservers-type-check.js b/tests/node_compat/test/parallel/test-dns-setservers-type-check.js new file mode 100644 index 000000000..e4e65b35a --- /dev/null +++ b/tests/node_compat/test/parallel/test-dns-setservers-type-check.js @@ -0,0 +1,127 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const { addresses } = require('../common/internet'); +const assert = require('assert'); +const dns = require('dns'); +const resolver = new dns.promises.Resolver(); +const dnsPromises = dns.promises; +const promiseResolver = new dns.promises.Resolver(); + +{ + [ + null, + undefined, + Number(addresses.DNS4_SERVER), + addresses.DNS4_SERVER, + { + address: addresses.DNS4_SERVER + }, + ].forEach((val) => { + const errObj = { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "servers" argument must be an instance of Array.' + + common.invalidArgTypeHelper(val) + }; + assert.throws( + () => { + dns.setServers(val); + }, errObj + ); + assert.throws( + () => { + resolver.setServers(val); + }, errObj + ); + assert.throws( + () => { + dnsPromises.setServers(val); + }, errObj + ); + assert.throws( + () => { + promiseResolver.setServers(val); + }, errObj + ); + }); +} + +{ + [ + [null], + [undefined], + [Number(addresses.DNS4_SERVER)], + [ + { + address: addresses.DNS4_SERVER + }, + ], + ].forEach((val) => { + const errObj = { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "servers[0]" argument must be of type string.' + + common.invalidArgTypeHelper(val[0]) + }; + assert.throws( + () => { + dns.setServers(val); + }, errObj + ); + assert.throws( + () => { + resolver.setServers(val); + }, errObj + ); + assert.throws( + () => { + dnsPromises.setServers(val); + }, errObj + ); + assert.throws( + () => { + promiseResolver.setServers(val); + }, errObj + ); + }); +} + +// This test for 'dns/promises' +{ + const { + setServers + } = require('dns/promises'); + + // This should not throw any error. + (async () => { + setServers([ '127.0.0.1' ]); + })().then(common.mustCall()); + + [ + [null], + [undefined], + [Number(addresses.DNS4_SERVER)], + [ + { + address: addresses.DNS4_SERVER + }, + ], + ].forEach((val) => { + const errObj = { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "servers[0]" argument must be of type string.' + + common.invalidArgTypeHelper(val[0]) + }; + assert.throws(() => { + setServers(val); + }, errObj); + }); +} diff --git a/tests/node_compat/test/parallel/test-dns.js b/tests/node_compat/test/parallel/test-dns.js new file mode 100644 index 000000000..e56f7ca40 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dns.js @@ -0,0 +1,471 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; + +// TODO: enable remaining tests once functionality is implemented. + +const common = require('../common'); +const dnstools = require('../common/dns'); +const assert = require('assert'); + +const dns = require('dns'); +const dnsPromises = dns.promises; +const dgram = require('dgram'); + +// TODO(cmorten): currently don't expose defaults +// const existing = dns.getServers(); +// assert(existing.length > 0); + +// Verify that setServers() handles arrays with holes and other oddities +{ + const servers = []; + + servers[0] = '127.0.0.1'; + servers[2] = '0.0.0.0'; + dns.setServers(servers); + + assert.deepStrictEqual(dns.getServers(), ['127.0.0.1', '0.0.0.0']); +} + +{ + const servers = ['127.0.0.1', '192.168.1.1']; + + servers[3] = '127.1.0.1'; + servers[4] = '127.1.0.1'; + servers[5] = '127.1.1.1'; + + Object.defineProperty(servers, 2, { + enumerable: true, + get: () => { + servers.length = 3; + return '0.0.0.0'; + } + }); + + dns.setServers(servers); + assert.deepStrictEqual(dns.getServers(), [ + '127.0.0.1', + '192.168.1.1', + '0.0.0.0', + ]); +} + +{ + // Various invalidities, all of which should throw a clean error. + const invalidServers = [ + ' ', + '\n', + '\0', + '1'.repeat(3 * 4), + // Check for REDOS issues. + ':'.repeat(100000), + '['.repeat(100000), + '['.repeat(100000) + ']'.repeat(100000) + 'a', + ]; + invalidServers.forEach((serv) => { + assert.throws( + () => { + dns.setServers([serv]); + }, + { + name: 'TypeError', + code: 'ERR_INVALID_IP_ADDRESS' + } + ); + }); +} + +const goog = [ + '8.8.8.8', + '8.8.4.4', +]; +dns.setServers(goog); +assert.deepStrictEqual(dns.getServers(), goog); +assert.throws(() => dns.setServers(['foobar']), { + code: 'ERR_INVALID_IP_ADDRESS', + name: 'TypeError', + message: 'Invalid IP address: foobar' +}); +assert.throws(() => dns.setServers(['127.0.0.1:va']), { + code: 'ERR_INVALID_IP_ADDRESS', + name: 'TypeError', + message: 'Invalid IP address: 127.0.0.1:va' +}); +assert.deepStrictEqual(dns.getServers(), goog); + +const goog6 = [ + '2001:4860:4860::8888', + '2001:4860:4860::8844', +]; +dns.setServers(goog6); +assert.deepStrictEqual(dns.getServers(), goog6); + +goog6.push('4.4.4.4'); +dns.setServers(goog6); +assert.deepStrictEqual(dns.getServers(), goog6); + +const ports = [ + '4.4.4.4:53', + '[2001:4860:4860::8888]:53', + '103.238.225.181:666', + '[fe80::483a:5aff:fee6:1f04]:666', + '[fe80::483a:5aff:fee6:1f04]', +]; +const portsExpected = [ + '4.4.4.4', + '2001:4860:4860::8888', + '103.238.225.181:666', + '[fe80::483a:5aff:fee6:1f04]:666', + 'fe80::483a:5aff:fee6:1f04', +]; +dns.setServers(ports); +assert.deepStrictEqual(dns.getServers(), portsExpected); + +dns.setServers([]); +assert.deepStrictEqual(dns.getServers(), []); + +{ + const errObj = { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "rrtype" argument must be of type string. ' + + 'Received an instance of Array' + }; + assert.throws(() => { + dns.resolve('example.com', [], common.mustNotCall()); + }, errObj); + assert.throws(() => { + dnsPromises.resolve('example.com', []); + }, errObj); +} +{ + const errObj = { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "name" argument must be of type string. ' + + 'Received undefined' + }; + assert.throws(() => { + dnsPromises.resolve(); + }, errObj); +} + +// dns.lookup should accept only falsey and string values +{ + const errorReg = { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: /^The "hostname" argument must be of type string\. Received .*/ + }; + + assert.throws(() => dns.lookup({}, common.mustNotCall()), errorReg); + + assert.throws(() => dns.lookup([], common.mustNotCall()), errorReg); + + assert.throws(() => dns.lookup(true, common.mustNotCall()), errorReg); + + assert.throws(() => dns.lookup(1, common.mustNotCall()), errorReg); + + assert.throws(() => dns.lookup(common.mustNotCall(), common.mustNotCall()), + errorReg); + + assert.throws(() => dnsPromises.lookup({}), errorReg); + assert.throws(() => dnsPromises.lookup([]), errorReg); + assert.throws(() => dnsPromises.lookup(true), errorReg); + assert.throws(() => dnsPromises.lookup(1), errorReg); + assert.throws(() => dnsPromises.lookup(common.mustNotCall()), errorReg); +} + +// dns.lookup should accept falsey values +{ + const checkCallback = (err, address, family) => { + assert.ifError(err); + assert.strictEqual(address, null); + assert.strictEqual(family, 4); + }; + + ['', null, undefined, 0, NaN].forEach(async (value) => { + const res = await dnsPromises.lookup(value); + assert.deepStrictEqual(res, { address: null, family: 4 }); + dns.lookup(value, common.mustCall(checkCallback)); + }); +} + +{ + // Make sure that dns.lookup throws if hints does not represent a valid flag. + // (dns.V4MAPPED | dns.ADDRCONFIG | dns.ALL) + 1 is invalid because: + // - it's different from dns.V4MAPPED and dns.ADDRCONFIG and dns.ALL. + // - it's different from any subset of them bitwise ored. + // - it's different from 0. + // - it's an odd number different than 1, and thus is invalid, because + // flags are either === 1 or even. + const hints = (dns.V4MAPPED | dns.ADDRCONFIG | dns.ALL) + 1; + const err = { + code: 'ERR_INVALID_ARG_VALUE', + name: 'TypeError', + message: /The argument 'hints' is invalid\. Received \d+/ + }; + + assert.throws(() => { + dnsPromises.lookup('nodejs.org', { hints }); + }, err); + assert.throws(() => { + dns.lookup('nodejs.org', { hints }, common.mustNotCall()); + }, err); +} + +assert.throws(() => dns.lookup("nodejs.org"), { + code: "ERR_INVALID_ARG_TYPE", + name: "TypeError", +}); + +assert.throws(() => dns.lookup("nodejs.org", 4), { + code: "ERR_INVALID_ARG_TYPE", + name: "TypeError", +}); + +dns.lookup('', { family: 4, hints: 0 }, common.mustCall()); + +dns.lookup('', { + family: 6, + hints: dns.ADDRCONFIG +}, common.mustCall()); + +dns.lookup('', { hints: dns.V4MAPPED }, common.mustCall()); + +dns.lookup('', { + hints: dns.ADDRCONFIG | dns.V4MAPPED +}, common.mustCall()); + +dns.lookup('', { + hints: dns.ALL +}, common.mustCall()); + +dns.lookup('', { + hints: dns.V4MAPPED | dns.ALL +}, common.mustCall()); + +dns.lookup('', { + hints: dns.ADDRCONFIG | dns.V4MAPPED | dns.ALL +}, common.mustCall()); + +(async function() { + await dnsPromises.lookup('', { family: 4, hints: 0 }); + await dnsPromises.lookup('', { family: 6, hints: dns.ADDRCONFIG }); + await dnsPromises.lookup('', { hints: dns.V4MAPPED }); + await dnsPromises.lookup('', { hints: dns.ADDRCONFIG | dns.V4MAPPED }); + await dnsPromises.lookup('', { hints: dns.ALL }); + await dnsPromises.lookup('', { hints: dns.V4MAPPED | dns.ALL }); + await dnsPromises.lookup('', { + hints: dns.ADDRCONFIG | dns.V4MAPPED | dns.ALL + }); +})().then(common.mustCall()); + +// { +// const err = { +// code: 'ERR_MISSING_ARGS', +// name: 'TypeError', +// message: 'The "address", "port", and "callback" arguments must be ' + +// 'specified' +// }; + +// assert.throws(() => dns.lookupService('0.0.0.0'), err); +// err.message = 'The "address" and "port" arguments must be specified'; +// assert.throws(() => dnsPromises.lookupService('0.0.0.0'), err); +// } + +// { +// const invalidAddress = 'fasdfdsaf'; +// const err = { +// code: 'ERR_INVALID_ARG_VALUE', +// name: 'TypeError', +// message: `The argument 'address' is invalid. Received '${invalidAddress}'` +// }; + +// assert.throws(() => { +// dnsPromises.lookupService(invalidAddress, 0); +// }, err); + +// assert.throws(() => { +// dns.lookupService(invalidAddress, 0, common.mustNotCall()); +// }, err); +// } + +// const portErr = (port) => { +// const err = { +// code: 'ERR_SOCKET_BAD_PORT', +// message: +// `Port should be >= 0 and < 65536. Received ${port}.`, +// name: 'RangeError' +// }; + +// assert.throws(() => { +// dnsPromises.lookupService('0.0.0.0', port); +// }, err); + +// assert.throws(() => { +// dns.lookupService('0.0.0.0', port, common.mustNotCall()); +// }, err); +// }; +// portErr(null); +// portErr(undefined); +// portErr(65538); +// portErr('test'); + +// assert.throws(() => { +// dns.lookupService('0.0.0.0', 80, null); +// }, { +// code: 'ERR_INVALID_ARG_TYPE', +// name: 'TypeError' +// }); + +{ + dns.resolveMx('foo.onion', function(err) { + assert.deepStrictEqual(err.code, 'ENOTFOUND'); + assert.deepStrictEqual(err.syscall, 'queryMx'); + assert.deepStrictEqual(err.hostname, 'foo.onion'); + assert.deepStrictEqual(err.message, 'queryMx ENOTFOUND foo.onion'); + }); +} + +{ + const cases = [ + { + method: "resolveAny", + answers: [ + { type: "A", address: "1.2.3.4" /*ttl: 3333333333*/ }, + { type: "AAAA", address: "::42" /*ttl: 3333333333*/ }, + { type: "MX", priority: 42, exchange: "foobar.com", ttl: 3333333333 }, + { type: "NS", value: "foobar.org", ttl: 3333333333 }, + { type: "PTR", value: "baz.org", ttl: 3333333333 }, + { + type: "SOA", + nsname: "ns1.example.com", + hostmaster: "admin.example.com", + serial: 3210987654, + refresh: 900, + retry: 900, + expire: 1800, + minttl: 3333333333, + }, + ], + }, + + // TODO(cmorten): support ttl option + // { + // method: "resolve4", + // options: { ttl: true }, + // answers: [{ type: "A", address: "1.2.3.4", ttl: 3333333333 }], + // }, + + // { + // method: "resolve6", + // options: { ttl: true }, + // answers: [{ type: "AAAA", address: "::42", ttl: 3333333333 }], + // }, + + { + method: "resolveSoa", + answers: [ + { + type: "SOA", + nsname: "ns1.example.com", + hostmaster: "admin.example.com", + serial: 3210987654, + refresh: 900, + retry: 900, + expire: 1800, + minttl: 3333333333, + }, + ], + }, + ]; + + const server = dgram.createSocket('udp4'); + + server.on('message', common.mustCall((msg, { address, port }) => { + const parsed = dnstools.parseDNSPacket(msg); + const domain = parsed.questions[0].domain; + assert.strictEqual(domain, 'example.org'); + + server.send(dnstools.writeDNSPacket({ + id: parsed.id, + questions: parsed.questions, + answers: cases[0].answers.map( + (answer) => Object.assign({ domain }, answer) + ), + }), port, address); + // Don't have "ANY" query type available so calls greatly increased with + // polyfill method. + }, /*cases.length * 2*/ 32)); + + server.bind(0, common.mustCall(() => { + const address = server.address(); + dns.setServers([`127.0.0.1:${address.port}`]); + + function validateResults(res) { + if (!Array.isArray(res)) + res = [res]; + + assert.deepStrictEqual(res.map(tweakEntry), + cases[0].answers.map(tweakEntry)); + } + + function tweakEntry(r) { + const ret = { ...r }; + + const { method } = cases[0]; + + // TTL values are only provided for A and AAAA entries. + if (!['A', 'AAAA'].includes(ret.type) && !/^resolve(4|6)?$/.test(method)) + delete ret.ttl; + + if (method !== 'resolveAny') + delete ret.type; + + return ret; + } + + (async function nextCase() { + if (cases.length === 0) + return server.close(); + + const { method, options } = cases[0]; + + validateResults(await dnsPromises[method]('example.org', options)); + + dns[method]('example.org', options, common.mustSucceed((res) => { + validateResults(res); + cases.shift(); + nextCase(); + })); + })().then(common.mustCall()); + + })); +} diff --git a/tests/node_compat/test/parallel/test-eval-strict-referenceerror.js b/tests/node_compat/test/parallel/test-eval-strict-referenceerror.js new file mode 100644 index 000000000..b521b17ba --- /dev/null +++ b/tests/node_compat/test/parallel/test-eval-strict-referenceerror.js @@ -0,0 +1,34 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +/* eslint-disable strict */ +require('../common'); + +// In Node.js 0.10, a bug existed that caused strict functions to not capture +// their environment when evaluated. When run in 0.10 `test()` fails with a +// `ReferenceError`. See https://github.com/nodejs/node/issues/2245 for details. + +const assert = require('assert'); + +function test() { + + const code = [ + 'var foo = {m: 1};', + '', + 'function bar() {', + '\'use strict\';', + 'return foo; // foo isn\'t captured in 0.10', + '};', + ].join('\n'); + + eval(code); + + return bar(); // eslint-disable-line no-undef + +} + +assert.deepStrictEqual(test(), { m: 1 }); diff --git a/tests/node_compat/test/parallel/test-eval.js b/tests/node_compat/test/parallel/test-eval.js new file mode 100644 index 000000000..78254a377 --- /dev/null +++ b/tests/node_compat/test/parallel/test-eval.js @@ -0,0 +1,14 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); + +// Verify that eval is allowed by default. +assert.strictEqual(eval('"eval"'), 'eval'); diff --git a/tests/node_compat/test/parallel/test-event-emitter-add-listeners.js b/tests/node_compat/test/parallel/test-event-emitter-add-listeners.js new file mode 100644 index 000000000..8ad798021 --- /dev/null +++ b/tests/node_compat/test/parallel/test-event-emitter-add-listeners.js @@ -0,0 +1,93 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const EventEmitter = require('events'); + +{ + const ee = new EventEmitter(); + const events_new_listener_emitted = []; + const listeners_new_listener_emitted = []; + + // Sanity check + assert.strictEqual(ee.addListener, ee.on); + + ee.on('newListener', function(event, listener) { + // Don't track newListener listeners. + if (event === 'newListener') + return; + + events_new_listener_emitted.push(event); + listeners_new_listener_emitted.push(listener); + }); + + const hello = common.mustCall(function(a, b) { + assert.strictEqual(a, 'a'); + assert.strictEqual(b, 'b'); + }); + + ee.once('newListener', function(name, listener) { + assert.strictEqual(name, 'hello'); + assert.strictEqual(listener, hello); + assert.deepStrictEqual(this.listeners('hello'), []); + }); + + ee.on('hello', hello); + ee.once('foo', assert.fail); + assert.deepStrictEqual(['hello', 'foo'], events_new_listener_emitted); + assert.deepStrictEqual([hello, assert.fail], listeners_new_listener_emitted); + + ee.emit('hello', 'a', 'b'); +} + +// Just make sure that this doesn't throw: +{ + const f = new EventEmitter(); + + f.setMaxListeners(0); +} + +{ + const listen1 = () => {}; + const listen2 = () => {}; + const ee = new EventEmitter(); + + ee.once('newListener', function() { + assert.deepStrictEqual(ee.listeners('hello'), []); + ee.once('newListener', function() { + assert.deepStrictEqual(ee.listeners('hello'), []); + }); + ee.on('hello', listen2); + }); + ee.on('hello', listen1); + // The order of listeners on an event is not always the order in which the + // listeners were added. + assert.deepStrictEqual(ee.listeners('hello'), [listen2, listen1]); +} diff --git a/tests/node_compat/test/parallel/test-event-emitter-emit-context.js b/tests/node_compat/test/parallel/test-event-emitter-emit-context.js new file mode 100644 index 000000000..d3673827f --- /dev/null +++ b/tests/node_compat/test/parallel/test-event-emitter-emit-context.js @@ -0,0 +1,25 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const EventEmitter = require('events'); + +// Test emit called by other context +const EE = new EventEmitter(); + +// Works as expected if the context has no `constructor.name` +{ + const ctx = Object.create(null); + assert.throws( + () => EE.emit.call(ctx, 'error', new Error('foo')), + common.expectsError({ name: 'Error', message: 'foo' }) + ); +} + +assert.strictEqual(EE.emit.call({}, 'foo'), false); diff --git a/tests/node_compat/test/parallel/test-event-emitter-error-monitor.js b/tests/node_compat/test/parallel/test-event-emitter-error-monitor.js new file mode 100644 index 000000000..714a47e59 --- /dev/null +++ b/tests/node_compat/test/parallel/test-event-emitter-error-monitor.js @@ -0,0 +1,39 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const EventEmitter = require('events'); + +const EE = new EventEmitter(); +const theErr = new Error('MyError'); + +EE.on( + EventEmitter.errorMonitor, + common.mustCall(function onErrorMonitor(e) { + assert.strictEqual(e, theErr); + }, 3) +); + +// Verify with no error listener +assert.throws( + () => EE.emit('error', theErr), theErr +); + +// Verify with error listener +EE.once('error', common.mustCall((e) => assert.strictEqual(e, theErr))); +EE.emit('error', theErr); + + +// Verify it works with once +process.nextTick(() => EE.emit('error', theErr)); +assert.rejects(EventEmitter.once(EE, 'notTriggered'), theErr); + +// Only error events trigger error monitor +EE.on('aEvent', common.mustCall()); +EE.emit('aEvent'); diff --git a/tests/node_compat/test/parallel/test-event-emitter-errors.js b/tests/node_compat/test/parallel/test-event-emitter-errors.js new file mode 100644 index 000000000..39a896b05 --- /dev/null +++ b/tests/node_compat/test/parallel/test-event-emitter-errors.js @@ -0,0 +1,44 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const assert = require('assert'); +const EventEmitter = require('events'); +const util = require('util'); + +const EE = new EventEmitter(); + +assert.throws( + () => EE.emit('error', 'Accepts a string'), + { + code: 'ERR_UNHANDLED_ERROR', + name: 'Error', + message: "Unhandled error. ('Accepts a string')", + } +); + +assert.throws( + () => EE.emit('error', { message: 'Error!' }), + { + code: 'ERR_UNHANDLED_ERROR', + name: 'Error', + message: "Unhandled error. ({ message: 'Error!' })", + } +); + +assert.throws( + () => EE.emit('error', { + message: 'Error!', + [util.inspect.custom]() { throw new Error(); }, + }), + { + code: 'ERR_UNHANDLED_ERROR', + name: 'Error', + message: 'Unhandled error. ([object Object])', + } +); diff --git a/tests/node_compat/test/parallel/test-event-emitter-get-max-listeners.js b/tests/node_compat/test/parallel/test-event-emitter-get-max-listeners.js new file mode 100644 index 000000000..9eeb5ecf9 --- /dev/null +++ b/tests/node_compat/test/parallel/test-event-emitter-get-max-listeners.js @@ -0,0 +1,26 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const assert = require('assert'); +const EventEmitter = require('events'); + +const emitter = new EventEmitter(); + +assert.strictEqual(emitter.getMaxListeners(), EventEmitter.defaultMaxListeners); + +emitter.setMaxListeners(0); +assert.strictEqual(emitter.getMaxListeners(), 0); + +emitter.setMaxListeners(3); +assert.strictEqual(emitter.getMaxListeners(), 3); + +// https://github.com/nodejs/node/issues/523 - second call should not throw. +const recv = {}; +EventEmitter.prototype.on.call(recv, 'event', () => {}); +EventEmitter.prototype.on.call(recv, 'event', () => {}); diff --git a/tests/node_compat/test/parallel/test-event-emitter-invalid-listener.js b/tests/node_compat/test/parallel/test-event-emitter-invalid-listener.js new file mode 100644 index 000000000..604110a5e --- /dev/null +++ b/tests/node_compat/test/parallel/test-event-emitter-invalid-listener.js @@ -0,0 +1,27 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); +const EventEmitter = require('events'); + +const eventsMethods = ['on', 'once', 'removeListener', 'prependOnceListener']; + +// Verify that the listener must be a function for events methods +for (const method of eventsMethods) { + assert.throws(() => { + const ee = new EventEmitter(); + ee[method]('foo', null); + }, { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "listener" argument must be of type function. ' + + 'Received null', + }, `event.${method}('foo', null) should throw the proper error`); +} diff --git a/tests/node_compat/test/parallel/test-event-emitter-listener-count.js b/tests/node_compat/test/parallel/test-event-emitter-listener-count.js new file mode 100644 index 000000000..e86a9512f --- /dev/null +++ b/tests/node_compat/test/parallel/test-event-emitter-listener-count.js @@ -0,0 +1,25 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); +const EventEmitter = require('events'); + +const emitter = new EventEmitter(); +emitter.on('foo', () => {}); +emitter.on('foo', () => {}); +emitter.on('baz', () => {}); +// Allow any type +emitter.on(123, () => {}); + +assert.strictEqual(EventEmitter.listenerCount(emitter, 'foo'), 2); +assert.strictEqual(emitter.listenerCount('foo'), 2); +assert.strictEqual(emitter.listenerCount('bar'), 0); +assert.strictEqual(emitter.listenerCount('baz'), 1); +assert.strictEqual(emitter.listenerCount(123), 1); diff --git a/tests/node_compat/test/parallel/test-event-emitter-listeners-side-effects.js b/tests/node_compat/test/parallel/test-event-emitter-listeners-side-effects.js new file mode 100644 index 000000000..3daa73b21 --- /dev/null +++ b/tests/node_compat/test/parallel/test-event-emitter-listeners-side-effects.js @@ -0,0 +1,67 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; + +require('../common'); +const assert = require('assert'); + +const EventEmitter = require('events').EventEmitter; + +const e = new EventEmitter(); +let fl; // foo listeners + +fl = e.listeners('foo'); +assert(Array.isArray(fl)); +assert.strictEqual(fl.length, 0); +assert(!(e._events instanceof Object)); +assert.deepStrictEqual(Object.keys(e._events), []); + +e.on('foo', assert.fail); +fl = e.listeners('foo'); +assert.strictEqual(e._events.foo, assert.fail); +assert(Array.isArray(fl)); +assert.strictEqual(fl.length, 1); +assert.strictEqual(fl[0], assert.fail); + +e.listeners('bar'); + +e.on('foo', assert.ok); +fl = e.listeners('foo'); + +assert(Array.isArray(e._events.foo)); +assert.strictEqual(e._events.foo.length, 2); +assert.strictEqual(e._events.foo[0], assert.fail); +assert.strictEqual(e._events.foo[1], assert.ok); + +assert(Array.isArray(fl)); +assert.strictEqual(fl.length, 2); +assert.strictEqual(fl[0], assert.fail); +assert.strictEqual(fl[1], assert.ok); + +console.log('ok'); diff --git a/tests/node_compat/test/parallel/test-event-emitter-listeners.js b/tests/node_compat/test/parallel/test-event-emitter-listeners.js new file mode 100644 index 000000000..ddb52da1a --- /dev/null +++ b/tests/node_compat/test/parallel/test-event-emitter-listeners.js @@ -0,0 +1,131 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; + +require('../common'); +const assert = require('assert'); +const events = require('events'); + +function listener() {} + +function listener2() {} + +function listener3() { + return 0; +} + +function listener4() { + return 1; +} + +{ + const ee = new events.EventEmitter(); + ee.on('foo', listener); + const fooListeners = ee.listeners('foo'); + assert.deepStrictEqual(ee.listeners('foo'), [listener]); + ee.removeAllListeners('foo'); + assert.deepStrictEqual(ee.listeners('foo'), []); + assert.deepStrictEqual(fooListeners, [listener]); +} + +{ + const ee = new events.EventEmitter(); + ee.on('foo', listener); + const eeListenersCopy = ee.listeners('foo'); + assert.deepStrictEqual(eeListenersCopy, [listener]); + assert.deepStrictEqual(ee.listeners('foo'), [listener]); + eeListenersCopy.push(listener2); + assert.deepStrictEqual(ee.listeners('foo'), [listener]); + assert.deepStrictEqual(eeListenersCopy, [listener, listener2]); +} + +{ + const ee = new events.EventEmitter(); + ee.on('foo', listener); + const eeListenersCopy = ee.listeners('foo'); + ee.on('foo', listener2); + assert.deepStrictEqual(ee.listeners('foo'), [listener, listener2]); + assert.deepStrictEqual(eeListenersCopy, [listener]); +} + +{ + const ee = new events.EventEmitter(); + ee.once('foo', listener); + assert.deepStrictEqual(ee.listeners('foo'), [listener]); +} + +{ + const ee = new events.EventEmitter(); + ee.on('foo', listener); + ee.once('foo', listener2); + assert.deepStrictEqual(ee.listeners('foo'), [listener, listener2]); +} + +{ + const ee = new events.EventEmitter(); + ee._events = undefined; + assert.deepStrictEqual(ee.listeners('foo'), []); +} + +{ + class TestStream extends events.EventEmitter {} + const s = new TestStream(); + assert.deepStrictEqual(s.listeners('foo'), []); +} + +{ + const ee = new events.EventEmitter(); + ee.on('foo', listener); + const wrappedListener = ee.rawListeners('foo'); + assert.strictEqual(wrappedListener.length, 1); + assert.strictEqual(wrappedListener[0], listener); + assert.notStrictEqual(wrappedListener, ee.rawListeners('foo')); + ee.once('foo', listener); + const wrappedListeners = ee.rawListeners('foo'); + assert.strictEqual(wrappedListeners.length, 2); + assert.strictEqual(wrappedListeners[0], listener); + assert.notStrictEqual(wrappedListeners[1], listener); + assert.strictEqual(wrappedListeners[1].listener, listener); + assert.notStrictEqual(wrappedListeners, ee.rawListeners('foo')); + ee.emit('foo'); + assert.strictEqual(wrappedListeners.length, 2); + assert.strictEqual(wrappedListeners[1].listener, listener); +} + +{ + const ee = new events.EventEmitter(); + ee.once('foo', listener3); + ee.on('foo', listener4); + const rawListeners = ee.rawListeners('foo'); + assert.strictEqual(rawListeners.length, 2); + assert.strictEqual(rawListeners[0](), 0); + const rawListener = ee.rawListeners('foo'); + assert.strictEqual(rawListener.length, 1); + assert.strictEqual(rawListener[0](), 1); +} diff --git a/tests/node_compat/test/parallel/test-event-emitter-max-listeners.js b/tests/node_compat/test/parallel/test-event-emitter-max-listeners.js new file mode 100644 index 000000000..1245c6b92 --- /dev/null +++ b/tests/node_compat/test/parallel/test-event-emitter-max-listeners.js @@ -0,0 +1,80 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const events = require('events'); +const { inspect } = require('util'); +const e = new events.EventEmitter(); + +e.on('maxListeners', common.mustCall()); + +// Should not corrupt the 'maxListeners' queue. +e.setMaxListeners(42); + +const throwsObjs = [NaN, -1, 'and even this']; + +for (const obj of throwsObjs) { + assert.throws( + () => e.setMaxListeners(obj), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "n" is out of range. ' + + `It must be a non-negative number. Received ${inspect(obj)}` + } + ); + + assert.throws( + () => events.defaultMaxListeners = obj, + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "defaultMaxListeners" is out of range. ' + + `It must be a non-negative number. Received ${inspect(obj)}` + } + ); +} + +e.emit('maxListeners'); + +{ + const { EventEmitter, defaultMaxListeners } = events; + for (const obj of throwsObjs) { + assert.throws(() => EventEmitter.setMaxListeners(obj), { + code: 'ERR_OUT_OF_RANGE', + }); + } + + // FIXME(bartlomieju): + // assert.throws( + // () => EventEmitter.setMaxListeners(defaultMaxListeners, 'INVALID_EMITTER'), + // { code: 'ERR_INVALID_ARG_TYPE' } + // ); +} diff --git a/tests/node_compat/test/parallel/test-event-emitter-method-names.js b/tests/node_compat/test/parallel/test-event-emitter-method-names.js new file mode 100644 index 000000000..7b7822fe1 --- /dev/null +++ b/tests/node_compat/test/parallel/test-event-emitter-method-names.js @@ -0,0 +1,42 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const events = require('events'); + +const E = events.EventEmitter.prototype; +assert.strictEqual(E.constructor.name, 'EventEmitter'); +assert.strictEqual(E.on, E.addListener); // Same method. +assert.strictEqual(E.off, E.removeListener); // Same method. +Object.getOwnPropertyNames(E).forEach(function(name) { + if (name === 'constructor' || name === 'on' || name === 'off') return; + if (typeof E[name] !== 'function') return; + assert.strictEqual(E[name].name, name); +}); diff --git a/tests/node_compat/test/parallel/test-event-emitter-modify-in-emit.js b/tests/node_compat/test/parallel/test-event-emitter-modify-in-emit.js new file mode 100644 index 000000000..4953241ba --- /dev/null +++ b/tests/node_compat/test/parallel/test-event-emitter-modify-in-emit.js @@ -0,0 +1,87 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const events = require('events'); + +let callbacks_called = []; + +const e = new events.EventEmitter(); + +function callback1() { + callbacks_called.push('callback1'); + e.on('foo', callback2); + e.on('foo', callback3); + e.removeListener('foo', callback1); +} + +function callback2() { + callbacks_called.push('callback2'); + e.removeListener('foo', callback2); +} + +function callback3() { + callbacks_called.push('callback3'); + e.removeListener('foo', callback3); +} + +e.on('foo', callback1); +assert.strictEqual(e.listeners('foo').length, 1); + +e.emit('foo'); +assert.strictEqual(e.listeners('foo').length, 2); +assert.deepStrictEqual(['callback1'], callbacks_called); + +e.emit('foo'); +assert.strictEqual(e.listeners('foo').length, 0); +assert.deepStrictEqual(['callback1', 'callback2', 'callback3'], + callbacks_called); + +e.emit('foo'); +assert.strictEqual(e.listeners('foo').length, 0); +assert.deepStrictEqual(['callback1', 'callback2', 'callback3'], + callbacks_called); + +e.on('foo', callback1); +e.on('foo', callback2); +assert.strictEqual(e.listeners('foo').length, 2); +e.removeAllListeners('foo'); +assert.strictEqual(e.listeners('foo').length, 0); + +// Verify that removing callbacks while in emit allows emits to propagate to +// all listeners +callbacks_called = []; + +e.on('foo', callback2); +e.on('foo', callback3); +assert.strictEqual(e.listeners('foo').length, 2); +e.emit('foo'); +assert.deepStrictEqual(['callback2', 'callback3'], callbacks_called); +assert.strictEqual(e.listeners('foo').length, 0); diff --git a/tests/node_compat/test/parallel/test-event-emitter-no-error-provided-to-error-event.js b/tests/node_compat/test/parallel/test-event-emitter-no-error-provided-to-error-event.js new file mode 100644 index 000000000..8ab7aec44 --- /dev/null +++ b/tests/node_compat/test/parallel/test-event-emitter-no-error-provided-to-error-event.js @@ -0,0 +1,65 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const events = require('events'); +/* TODO(uki00a): Uncomment this block when the 'domain' module is implemented. +const domain = require('domain'); + +{ + const e = new events.EventEmitter(); + const d = domain.create(); + d.add(e); + d.on('error', common.mustCall((er) => { + assert(er instanceof Error, 'error created'); + })); + e.emit('error'); +} + +for (const arg of [false, null, undefined]) { + const e = new events.EventEmitter(); + const d = domain.create(); + d.add(e); + d.on('error', common.mustCall((er) => { + assert(er instanceof Error, 'error created'); + })); + e.emit('error', arg); +} + +for (const arg of [42, 'fortytwo', true]) { + const e = new events.EventEmitter(); + const d = domain.create(); + d.add(e); + d.on('error', common.mustCall((er) => { + assert.strictEqual(er, arg); + })); + e.emit('error', arg); +} +*/ diff --git a/tests/node_compat/test/parallel/test-event-emitter-num-args.js b/tests/node_compat/test/parallel/test-event-emitter-num-args.js new file mode 100644 index 000000000..05ed54cb6 --- /dev/null +++ b/tests/node_compat/test/parallel/test-event-emitter-num-args.js @@ -0,0 +1,61 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const events = require('events'); + +const e = new events.EventEmitter(); +const num_args_emitted = []; + +e.on('numArgs', function() { + const numArgs = arguments.length; + num_args_emitted.push(numArgs); +}); + +e.on('foo', function() { + num_args_emitted.push(arguments.length); +}); + +e.on('foo', function() { + num_args_emitted.push(arguments.length); +}); + +e.emit('numArgs'); +e.emit('numArgs', null); +e.emit('numArgs', null, null); +e.emit('numArgs', null, null, null); +e.emit('numArgs', null, null, null, null); +e.emit('numArgs', null, null, null, null, null); + +e.emit('foo', null, null, null, null); + +process.on('exit', function() { + assert.deepStrictEqual(num_args_emitted, [0, 1, 2, 3, 4, 5, 4, 4]); +}); diff --git a/tests/node_compat/test/parallel/test-event-emitter-once.js b/tests/node_compat/test/parallel/test-event-emitter-once.js new file mode 100644 index 000000000..1d02a639e --- /dev/null +++ b/tests/node_compat/test/parallel/test-event-emitter-once.js @@ -0,0 +1,77 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const EventEmitter = require('events'); + +const e = new EventEmitter(); + +e.once('hello', common.mustCall()); + +e.emit('hello', 'a', 'b'); +e.emit('hello', 'a', 'b'); +e.emit('hello', 'a', 'b'); +e.emit('hello', 'a', 'b'); + +function remove() { + assert.fail('once->foo should not be emitted'); +} + +e.once('foo', remove); +e.removeListener('foo', remove); +e.emit('foo'); + +e.once('e', common.mustCall(function() { + e.emit('e'); +})); + +e.once('e', common.mustCall()); + +e.emit('e'); + +{ + // once() has different code paths based on the number of arguments being + // emitted. Verify that all of the cases are covered. + const maxArgs = 4; + + for (let i = 0; i <= maxArgs; ++i) { + const ee = new EventEmitter(); + const args = ['foo']; + + for (let j = 0; j < i; ++j) + args.push(j); + + ee.once('foo', common.mustCall((...params) => { + assert.deepStrictEqual(params, args.slice(1)); + })); + + EventEmitter.prototype.emit.apply(ee, args); + } +} diff --git a/tests/node_compat/test/parallel/test-event-emitter-prepend.js b/tests/node_compat/test/parallel/test-event-emitter-prepend.js new file mode 100644 index 000000000..b06722742 --- /dev/null +++ b/tests/node_compat/test/parallel/test-event-emitter-prepend.js @@ -0,0 +1,50 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +'use strict'; + +const common = require('../common'); +const EventEmitter = require('events'); +const assert = require('assert'); + +const myEE = new EventEmitter(); +let m = 0; +// This one comes last. +myEE.on('foo', common.mustCall(() => assert.strictEqual(m, 2))); + +// This one comes second. +myEE.prependListener('foo', common.mustCall(() => assert.strictEqual(m++, 1))); + +// This one comes first. +myEE.prependOnceListener('foo', + common.mustCall(() => assert.strictEqual(m++, 0))); + +myEE.emit('foo'); + +// Test fallback if prependListener is undefined. +const stream = require('stream'); + +delete EventEmitter.prototype.prependListener; + +function Writable() { + this.writable = true; + stream.Stream.call(this); +} +Object.setPrototypeOf(Writable.prototype, stream.Stream.prototype); +Object.setPrototypeOf(Writable, stream.Stream); + +function Readable() { + this.readable = true; + stream.Stream.call(this); +} +Object.setPrototypeOf(Readable.prototype, stream.Stream.prototype); +Object.setPrototypeOf(Readable, stream.Stream); + +// FIXME(bartlomieju): +// const w = new Writable(); +// const r = new Readable(); +// r.pipe(w); diff --git a/tests/node_compat/test/parallel/test-event-emitter-remove-all-listeners.js b/tests/node_compat/test/parallel/test-event-emitter-remove-all-listeners.js new file mode 100644 index 000000000..576c02aa0 --- /dev/null +++ b/tests/node_compat/test/parallel/test-event-emitter-remove-all-listeners.js @@ -0,0 +1,130 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const events = require('events'); + + +function expect(expected) { + const actual = []; + process.on('exit', function() { + assert.deepStrictEqual(actual.sort(), expected.sort()); + }); + function listener(name) { + actual.push(name); + } + return common.mustCall(listener, expected.length); +} + +{ + const ee = new events.EventEmitter(); + const noop = common.mustNotCall(); + ee.on('foo', noop); + ee.on('bar', noop); + ee.on('baz', noop); + ee.on('baz', noop); + const fooListeners = ee.listeners('foo'); + const barListeners = ee.listeners('bar'); + const bazListeners = ee.listeners('baz'); + ee.on('removeListener', expect(['bar', 'baz', 'baz'])); + ee.removeAllListeners('bar'); + ee.removeAllListeners('baz'); + assert.deepStrictEqual(ee.listeners('foo'), [noop]); + assert.deepStrictEqual(ee.listeners('bar'), []); + assert.deepStrictEqual(ee.listeners('baz'), []); + // After calling removeAllListeners(), + // the old listeners array should stay unchanged. + assert.deepStrictEqual(fooListeners, [noop]); + assert.deepStrictEqual(barListeners, [noop]); + assert.deepStrictEqual(bazListeners, [noop, noop]); + // After calling removeAllListeners(), + // new listeners arrays is different from the old. + assert.notStrictEqual(ee.listeners('bar'), barListeners); + assert.notStrictEqual(ee.listeners('baz'), bazListeners); +} + +{ + const ee = new events.EventEmitter(); + ee.on('foo', common.mustNotCall()); + ee.on('bar', common.mustNotCall()); + // Expect LIFO order + ee.on('removeListener', expect(['foo', 'bar', 'removeListener'])); + ee.on('removeListener', expect(['foo', 'bar'])); + ee.removeAllListeners(); + assert.deepStrictEqual([], ee.listeners('foo')); + assert.deepStrictEqual([], ee.listeners('bar')); +} + +{ + const ee = new events.EventEmitter(); + ee.on('removeListener', common.mustNotCall()); + // Check for regression where removeAllListeners() throws when + // there exists a 'removeListener' listener, but there exists + // no listeners for the provided event type. + ee.removeAllListeners.bind(ee, 'foo'); +} + +{ + const ee = new events.EventEmitter(); + let expectLength = 2; + ee.on('removeListener', function(name, noop) { + assert.strictEqual(expectLength--, this.listeners('baz').length); + }); + ee.on('baz', common.mustNotCall()); + ee.on('baz', common.mustNotCall()); + ee.on('baz', common.mustNotCall()); + assert.strictEqual(ee.listeners('baz').length, expectLength + 1); + ee.removeAllListeners('baz'); + assert.strictEqual(ee.listeners('baz').length, 0); +} + +{ + const ee = new events.EventEmitter(); + assert.deepStrictEqual(ee, ee.removeAllListeners()); +} + +{ + const ee = new events.EventEmitter(); + ee._events = undefined; + assert.strictEqual(ee, ee.removeAllListeners()); +} + +{ + const ee = new events.EventEmitter(); + const symbol = Symbol('symbol'); + const noop = common.mustNotCall(); + ee.on(symbol, noop); + + ee.on('removeListener', common.mustCall((...args) => { + assert.deepStrictEqual(args, [symbol, noop]); + })); + + ee.removeAllListeners(); +} diff --git a/tests/node_compat/test/parallel/test-event-emitter-remove-listeners.js b/tests/node_compat/test/parallel/test-event-emitter-remove-listeners.js new file mode 100644 index 000000000..8ee09c30a --- /dev/null +++ b/tests/node_compat/test/parallel/test-event-emitter-remove-listeners.js @@ -0,0 +1,177 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const EventEmitter = require('events'); + +function listener1() {} + +function listener2() {} + +{ + const ee = new EventEmitter(); + ee.on('hello', listener1); + ee.on('removeListener', common.mustCall((name, cb) => { + assert.strictEqual(name, 'hello'); + assert.strictEqual(cb, listener1); + })); + ee.removeListener('hello', listener1); + assert.deepStrictEqual([], ee.listeners('hello')); +} + +{ + const ee = new EventEmitter(); + ee.on('hello', listener1); + ee.on('removeListener', common.mustNotCall()); + ee.removeListener('hello', listener2); + assert.deepStrictEqual([listener1], ee.listeners('hello')); +} + +{ + const ee = new EventEmitter(); + ee.on('hello', listener1); + ee.on('hello', listener2); + ee.once('removeListener', common.mustCall((name, cb) => { + assert.strictEqual(name, 'hello'); + assert.strictEqual(cb, listener1); + assert.deepStrictEqual([listener2], ee.listeners('hello')); + })); + ee.removeListener('hello', listener1); + assert.deepStrictEqual([listener2], ee.listeners('hello')); + ee.once('removeListener', common.mustCall((name, cb) => { + assert.strictEqual(name, 'hello'); + assert.strictEqual(cb, listener2); + assert.deepStrictEqual([], ee.listeners('hello')); + })); + ee.removeListener('hello', listener2); + assert.deepStrictEqual([], ee.listeners('hello')); +} + +{ + const ee = new EventEmitter(); + + function remove1() { + assert.fail('remove1 should not have been called'); + } + + function remove2() { + assert.fail('remove2 should not have been called'); + } + + ee.on('removeListener', common.mustCall(function(name, cb) { + if (cb !== remove1) return; + this.removeListener('quux', remove2); + this.emit('quux'); + }, 2)); + ee.on('quux', remove1); + ee.on('quux', remove2); + ee.removeListener('quux', remove1); +} + +{ + const ee = new EventEmitter(); + ee.on('hello', listener1); + ee.on('hello', listener2); + ee.once('removeListener', common.mustCall((name, cb) => { + assert.strictEqual(name, 'hello'); + assert.strictEqual(cb, listener1); + assert.deepStrictEqual([listener2], ee.listeners('hello')); + ee.once('removeListener', common.mustCall((name, cb) => { + assert.strictEqual(name, 'hello'); + assert.strictEqual(cb, listener2); + assert.deepStrictEqual([], ee.listeners('hello')); + })); + ee.removeListener('hello', listener2); + assert.deepStrictEqual([], ee.listeners('hello')); + })); + ee.removeListener('hello', listener1); + assert.deepStrictEqual([], ee.listeners('hello')); +} + +{ + const ee = new EventEmitter(); + const listener3 = common.mustCall(() => { + ee.removeListener('hello', listener4); + }, 2); + const listener4 = common.mustCall(); + + ee.on('hello', listener3); + ee.on('hello', listener4); + + // listener4 will still be called although it is removed by listener 3. + ee.emit('hello'); + // This is so because the internal listener array at time of emit + // was [listener3,listener4] + + // Internal listener array [listener3] + ee.emit('hello'); +} + +{ + const ee = new EventEmitter(); + + ee.once('hello', listener1); + ee.on('removeListener', common.mustCall((eventName, listener) => { + assert.strictEqual(eventName, 'hello'); + assert.strictEqual(listener, listener1); + })); + ee.emit('hello'); +} + +{ + const ee = new EventEmitter(); + + assert.deepStrictEqual(ee, ee.removeListener('foo', () => {})); +} + +{ + const ee = new EventEmitter(); + const listener = () => {}; + ee._events = undefined; + const e = ee.removeListener('foo', listener); + assert.strictEqual(e, ee); +} + +{ + const ee = new EventEmitter(); + + ee.on('foo', listener1); + ee.on('foo', listener2); + assert.deepStrictEqual(ee.listeners('foo'), [listener1, listener2]); + + ee.removeListener('foo', listener1); + assert.strictEqual(ee._events.foo, listener2); + + ee.on('foo', listener1); + assert.deepStrictEqual(ee.listeners('foo'), [listener2, listener1]); + + ee.removeListener('foo', listener1); + assert.strictEqual(ee._events.foo, listener2); +} diff --git a/tests/node_compat/test/parallel/test-event-emitter-set-max-listeners-side-effects.js b/tests/node_compat/test/parallel/test-event-emitter-set-max-listeners-side-effects.js new file mode 100644 index 000000000..431876fbd --- /dev/null +++ b/tests/node_compat/test/parallel/test-event-emitter-set-max-listeners-side-effects.js @@ -0,0 +1,39 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const events = require('events'); + +const e = new events.EventEmitter(); + +assert(!(e._events instanceof Object)); +assert.deepStrictEqual(Object.keys(e._events), []); +e.setMaxListeners(5); +assert.deepStrictEqual(Object.keys(e._events), []); diff --git a/tests/node_compat/test/parallel/test-event-emitter-special-event-names.js b/tests/node_compat/test/parallel/test-event-emitter-special-event-names.js new file mode 100644 index 000000000..067b557f1 --- /dev/null +++ b/tests/node_compat/test/parallel/test-event-emitter-special-event-names.js @@ -0,0 +1,44 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const EventEmitter = require('events'); +const assert = require('assert'); + +const ee = new EventEmitter(); +const handler = () => {}; + +assert.deepStrictEqual(ee.eventNames(), []); + +assert.strictEqual(ee._events.hasOwnProperty, undefined); +assert.strictEqual(ee._events.toString, undefined); + +ee.on('__proto__', handler); +ee.on('__defineGetter__', handler); +ee.on('toString', handler); + +assert.deepStrictEqual(ee.eventNames(), [ + '__proto__', + '__defineGetter__', + 'toString', +]); + +assert.deepStrictEqual(ee.listeners('__proto__'), [handler]); +assert.deepStrictEqual(ee.listeners('__defineGetter__'), [handler]); +assert.deepStrictEqual(ee.listeners('toString'), [handler]); + +ee.on('__proto__', common.mustCall(function(val) { + assert.strictEqual(val, 1); +})); +ee.emit('__proto__', 1); + +process.on('__proto__', common.mustCall(function(val) { + assert.strictEqual(val, 1); +})); +process.emit('__proto__', 1); diff --git a/tests/node_compat/test/parallel/test-event-emitter-subclass.js b/tests/node_compat/test/parallel/test-event-emitter-subclass.js new file mode 100644 index 000000000..02442c489 --- /dev/null +++ b/tests/node_compat/test/parallel/test-event-emitter-subclass.js @@ -0,0 +1,74 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const EventEmitter = require('events').EventEmitter; + +Object.setPrototypeOf(MyEE.prototype, EventEmitter.prototype); +Object.setPrototypeOf(MyEE, EventEmitter); + +function MyEE(cb) { + this.once(1, cb); + this.emit(1); + this.removeAllListeners(); + EventEmitter.call(this); +} + +const myee = new MyEE(common.mustCall()); + +Object.setPrototypeOf(ErrorEE.prototype, EventEmitter.prototype); +Object.setPrototypeOf(ErrorEE, EventEmitter); +function ErrorEE() { + this.emit('error', new Error('blerg')); +} + +assert.throws(function() { + new ErrorEE(); +}, /blerg/); + +process.on('exit', function() { + assert(!(myee._events instanceof Object)); + assert.deepStrictEqual(Object.keys(myee._events), []); + console.log('ok'); +}); + + +function MyEE2() { + EventEmitter.call(this); +} + +MyEE2.prototype = new EventEmitter(); + +const ee1 = new MyEE2(); +const ee2 = new MyEE2(); + +ee1.on('x', () => {}); + +assert.strictEqual(ee2.listenerCount('x'), 0); diff --git a/tests/node_compat/test/parallel/test-event-emitter-symbols.js b/tests/node_compat/test/parallel/test-event-emitter-symbols.js new file mode 100644 index 000000000..8f95d52bd --- /dev/null +++ b/tests/node_compat/test/parallel/test-event-emitter-symbols.js @@ -0,0 +1,30 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const EventEmitter = require('events'); +const assert = require('assert'); + +const ee = new EventEmitter(); +const foo = Symbol('foo'); +const listener = common.mustCall(); + +ee.on(foo, listener); +assert.deepStrictEqual(ee.listeners(foo), [listener]); + +ee.emit(foo); + +ee.removeAllListeners(); +assert.deepStrictEqual(ee.listeners(foo), []); + +ee.on(foo, listener); +assert.deepStrictEqual(ee.listeners(foo), [listener]); + +ee.removeListener(foo, listener); +assert.deepStrictEqual(ee.listeners(foo), []); diff --git a/tests/node_compat/test/parallel/test-events-list.js b/tests/node_compat/test/parallel/test-events-list.js new file mode 100644 index 000000000..c66da1602 --- /dev/null +++ b/tests/node_compat/test/parallel/test-events-list.js @@ -0,0 +1,26 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const EventEmitter = require('events'); +const assert = require('assert'); + +const EE = new EventEmitter(); +const m = () => {}; +EE.on('foo', () => {}); +assert.deepStrictEqual(['foo'], EE.eventNames()); +EE.on('bar', m); +assert.deepStrictEqual(['foo', 'bar'], EE.eventNames()); +EE.removeListener('bar', m); +assert.deepStrictEqual(['foo'], EE.eventNames()); +const s = Symbol('s'); +EE.on(s, m); +assert.deepStrictEqual(['foo', s], EE.eventNames()); +EE.removeListener(s, m); +assert.deepStrictEqual(['foo'], EE.eventNames()); diff --git a/tests/node_compat/test/parallel/test-events-on-async-iterator.js b/tests/node_compat/test/parallel/test-events-on-async-iterator.js new file mode 100644 index 000000000..87efeb842 --- /dev/null +++ b/tests/node_compat/test/parallel/test-events-on-async-iterator.js @@ -0,0 +1,399 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Flags: --expose-internals --no-warnings +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const { on, EventEmitter } = require('events'); +const { + NodeEventTarget, +} = require('internal/event_target'); + +async function basic() { + const ee = new EventEmitter(); + process.nextTick(() => { + ee.emit('foo', 'bar'); + // 'bar' is a spurious event, we are testing + // that it does not show up in the iterable + ee.emit('bar', 24); + ee.emit('foo', 42); + }); + + const iterable = on(ee, 'foo'); + + const expected = [['bar'], [42]]; + + for await (const event of iterable) { + const current = expected.shift(); + + assert.deepStrictEqual(current, event); + + if (expected.length === 0) { + break; + } + } + assert.strictEqual(ee.listenerCount('foo'), 0); + assert.strictEqual(ee.listenerCount('error'), 0); +} + +async function invalidArgType() { + assert.throws(() => on({}, 'foo'), common.expectsError({ + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + })); +} + +async function error() { + const ee = new EventEmitter(); + const _err = new Error('kaboom'); + process.nextTick(() => { + ee.emit('error', _err); + }); + + const iterable = on(ee, 'foo'); + let looped = false; + let thrown = false; + + try { + // eslint-disable-next-line no-unused-vars + for await (const event of iterable) { + looped = true; + } + } catch (err) { + thrown = true; + assert.strictEqual(err, _err); + } + assert.strictEqual(thrown, true); + assert.strictEqual(looped, false); +} + +async function errorDelayed() { + const ee = new EventEmitter(); + const _err = new Error('kaboom'); + process.nextTick(() => { + ee.emit('foo', 42); + ee.emit('error', _err); + }); + + const iterable = on(ee, 'foo'); + const expected = [[42]]; + let thrown = false; + + try { + for await (const event of iterable) { + const current = expected.shift(); + assert.deepStrictEqual(current, event); + } + } catch (err) { + thrown = true; + assert.strictEqual(err, _err); + } + assert.strictEqual(thrown, true); + assert.strictEqual(ee.listenerCount('foo'), 0); + assert.strictEqual(ee.listenerCount('error'), 0); +} + +async function throwInLoop() { + const ee = new EventEmitter(); + const _err = new Error('kaboom'); + + process.nextTick(() => { + ee.emit('foo', 42); + }); + + try { + for await (const event of on(ee, 'foo')) { + assert.deepStrictEqual(event, [42]); + throw _err; + } + } catch (err) { + assert.strictEqual(err, _err); + } + + assert.strictEqual(ee.listenerCount('foo'), 0); + assert.strictEqual(ee.listenerCount('error'), 0); +} + +async function next() { + const ee = new EventEmitter(); + const iterable = on(ee, 'foo'); + + process.nextTick(function() { + ee.emit('foo', 'bar'); + ee.emit('foo', 42); + iterable.return(); + }); + + const results = await Promise.all([ + iterable.next(), + iterable.next(), + iterable.next(), + ]); + + assert.deepStrictEqual(results, [{ + value: ['bar'], + done: false, + }, { + value: [42], + done: false, + }, { + value: undefined, + done: true, + }]); + + assert.deepStrictEqual(await iterable.next(), { + value: undefined, + done: true, + }); +} + +async function nextError() { + const ee = new EventEmitter(); + const iterable = on(ee, 'foo'); + const _err = new Error('kaboom'); + process.nextTick(function() { + ee.emit('error', _err); + }); + const results = await Promise.allSettled([ + iterable.next(), + iterable.next(), + iterable.next(), + ]); + assert.deepStrictEqual(results, [{ + status: 'rejected', + reason: _err, + }, { + status: 'fulfilled', + value: { + value: undefined, + done: true, + }, + }, { + status: 'fulfilled', + value: { + value: undefined, + done: true, + }, + }]); + assert.strictEqual(ee.listeners('error').length, 0); +} + +async function iterableThrow() { + const ee = new EventEmitter(); + const iterable = on(ee, 'foo'); + + process.nextTick(() => { + ee.emit('foo', 'bar'); + ee.emit('foo', 42); // lost in the queue + iterable.throw(_err); + }); + + const _err = new Error('kaboom'); + let thrown = false; + + assert.throws(() => { + // No argument + iterable.throw(); + }, { + message: 'The "EventEmitter.AsyncIterator" property must be' + + ' an instance of Error. Received undefined', + name: 'TypeError', + }); + + const expected = [['bar'], [42]]; + + try { + for await (const event of iterable) { + assert.deepStrictEqual(event, expected.shift()); + } + } catch (err) { + thrown = true; + assert.strictEqual(err, _err); + } + assert.strictEqual(thrown, true); + assert.strictEqual(expected.length, 0); + assert.strictEqual(ee.listenerCount('foo'), 0); + assert.strictEqual(ee.listenerCount('error'), 0); +} + +async function eventTarget() { + const et = new EventTarget(); + const tick = () => et.dispatchEvent(new Event('tick')); + const interval = setInterval(tick, 0); + let count = 0; + for await (const [ event ] of on(et, 'tick')) { + count++; + assert.strictEqual(event.type, 'tick'); + if (count >= 5) { + break; + } + } + assert.strictEqual(count, 5); + clearInterval(interval); +} + +async function errorListenerCount() { + const et = new EventEmitter(); + on(et, 'foo'); + assert.strictEqual(et.listenerCount('error'), 1); +} + +async function nodeEventTarget() { + const et = new NodeEventTarget(); + const tick = () => et.dispatchEvent(new Event('tick')); + const interval = setInterval(tick, 0); + let count = 0; + for await (const [ event] of on(et, 'tick')) { + count++; + assert.strictEqual(event.type, 'tick'); + if (count >= 5) { + break; + } + } + assert.strictEqual(count, 5); + clearInterval(interval); +} + +async function abortableOnBefore() { + const ee = new EventEmitter(); + const abortedSignal = AbortSignal.abort(); + [1, {}, null, false, 'hi'].forEach((signal) => { + assert.throws(() => on(ee, 'foo', { signal }), { + code: 'ERR_INVALID_ARG_TYPE', + }); + }); + assert.throws(() => on(ee, 'foo', { signal: abortedSignal }), { + name: 'AbortError', + }); +} + +async function eventTargetAbortableOnBefore() { + const et = new EventTarget(); + const abortedSignal = AbortSignal.abort(); + [1, {}, null, false, 'hi'].forEach((signal) => { + assert.throws(() => on(et, 'foo', { signal }), { + code: 'ERR_INVALID_ARG_TYPE', + }); + }); + assert.throws(() => on(et, 'foo', { signal: abortedSignal }), { + name: 'AbortError', + }); +} + +async function abortableOnAfter() { + const ee = new EventEmitter(); + const ac = new AbortController(); + + const i = setInterval(() => ee.emit('foo', 'foo'), 10); + + async function foo() { + for await (const f of on(ee, 'foo', { signal: ac.signal })) { + assert.strictEqual(f, 'foo'); + } + } + + foo().catch(common.mustCall((error) => { + assert.strictEqual(error.name, 'AbortError'); + })).finally(() => { + clearInterval(i); + }); + + process.nextTick(() => ac.abort()); +} + +async function eventTargetAbortableOnAfter() { + const et = new EventTarget(); + const ac = new AbortController(); + + const i = setInterval(() => et.dispatchEvent(new Event('foo')), 10); + + async function foo() { + for await (const f of on(et, 'foo', { signal: ac.signal })) { + assert(f); + } + } + + foo().catch(common.mustCall((error) => { + assert.strictEqual(error.name, 'AbortError'); + })).finally(() => { + clearInterval(i); + }); + + process.nextTick(() => ac.abort()); +} + +async function eventTargetAbortableOnAfter2() { + const et = new EventTarget(); + const ac = new AbortController(); + + const i = setInterval(() => et.dispatchEvent(new Event('foo')), 10); + + async function foo() { + for await (const f of on(et, 'foo', { signal: ac.signal })) { + assert(f); + // Cancel after a single event has been triggered. + ac.abort(); + } + } + + foo().catch(common.mustCall((error) => { + assert.strictEqual(error.name, 'AbortError'); + })).finally(() => { + clearInterval(i); + }); +} + +async function abortableOnAfterDone() { + const ee = new EventEmitter(); + const ac = new AbortController(); + + const i = setInterval(() => ee.emit('foo', 'foo'), 1); + let count = 0; + + async function foo() { + for await (const f of on(ee, 'foo', { signal: ac.signal })) { + assert.strictEqual(f[0], 'foo'); + if (++count === 5) + break; + } + ac.abort(); // No error will occur + } + + foo().finally(() => { + clearInterval(i); + }); +} + +async function run() { + const funcs = [ + basic, + invalidArgType, + error, + errorDelayed, + throwInLoop, + next, + nextError, + iterableThrow, + eventTarget, + errorListenerCount, + nodeEventTarget, + abortableOnBefore, + abortableOnAfter, + eventTargetAbortableOnBefore, + eventTargetAbortableOnAfter, + eventTargetAbortableOnAfter2, + abortableOnAfterDone, + ]; + + for (const fn of funcs) { + await fn(); + } +} + +run().then(common.mustCall()); diff --git a/tests/node_compat/test/parallel/test-events-once.js b/tests/node_compat/test/parallel/test-events-once.js new file mode 100644 index 000000000..7236f9830 --- /dev/null +++ b/tests/node_compat/test/parallel/test-events-once.js @@ -0,0 +1,272 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.8.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// TODO(cjihrig): kEvents is an internally used symbol in Node.js. It is not +// implemented in Deno, so parts of this test must be removed in order to pass. + +'use strict'; +// Flags: --no-warnings + +const common = require('../common'); +const { once, EventEmitter } = require('events'); +const { + strictEqual, + deepStrictEqual, + fail, + rejects, +} = require('assert'); + +async function onceAnEvent() { + const ee = new EventEmitter(); + + process.nextTick(() => { + ee.emit('myevent', 42); + }); + + const [value] = await once(ee, 'myevent'); + strictEqual(value, 42); + strictEqual(ee.listenerCount('error'), 0); + strictEqual(ee.listenerCount('myevent'), 0); +} + +async function onceAnEventWithNullOptions() { + const ee = new EventEmitter(); + + process.nextTick(() => { + ee.emit('myevent', 42); + }); + + const [value] = await once(ee, 'myevent', null); + strictEqual(value, 42); +} + + +async function onceAnEventWithTwoArgs() { + const ee = new EventEmitter(); + + process.nextTick(() => { + ee.emit('myevent', 42, 24); + }); + + const value = await once(ee, 'myevent'); + deepStrictEqual(value, [42, 24]); +} + +async function catchesErrors() { + const ee = new EventEmitter(); + + const expected = new Error('kaboom'); + let err; + process.nextTick(() => { + ee.emit('error', expected); + }); + + try { + await once(ee, 'myevent'); + } catch (_e) { + err = _e; + } + strictEqual(err, expected); + strictEqual(ee.listenerCount('error'), 0); + strictEqual(ee.listenerCount('myevent'), 0); +} + +async function catchesErrorsWithAbortSignal() { + const ee = new EventEmitter(); + const ac = new AbortController(); + const signal = ac.signal; + + const expected = new Error('boom'); + let err; + process.nextTick(() => { + ee.emit('error', expected); + }); + + try { + const promise = once(ee, 'myevent', { signal }); + strictEqual(ee.listenerCount('error'), 1); + + await promise; + } catch (e) { + err = e; + } + strictEqual(err, expected); + strictEqual(ee.listenerCount('error'), 0); + strictEqual(ee.listenerCount('myevent'), 0); +} + +async function stopListeningAfterCatchingError() { + const ee = new EventEmitter(); + + const expected = new Error('kaboom'); + let err; + process.nextTick(() => { + ee.emit('error', expected); + ee.emit('myevent', 42, 24); + }); + + try { + await once(ee, 'myevent'); + } catch (_e) { + err = _e; + } + process.removeAllListeners('multipleResolves'); + strictEqual(err, expected); + strictEqual(ee.listenerCount('error'), 0); + strictEqual(ee.listenerCount('myevent'), 0); +} + +async function onceError() { + const ee = new EventEmitter(); + + const expected = new Error('kaboom'); + process.nextTick(() => { + ee.emit('error', expected); + }); + + const promise = once(ee, 'error'); + strictEqual(ee.listenerCount('error'), 1); + const [ err ] = await promise; + strictEqual(err, expected); + strictEqual(ee.listenerCount('error'), 0); + strictEqual(ee.listenerCount('myevent'), 0); +} + +async function onceWithEventTarget() { + const et = new EventTarget(); + const event = new Event('myevent'); + process.nextTick(() => { + et.dispatchEvent(event); + }); + const [ value ] = await once(et, 'myevent'); + strictEqual(value, event); +} + +async function onceWithEventTargetError() { + const et = new EventTarget(); + const error = new Event('error'); + process.nextTick(() => { + et.dispatchEvent(error); + }); + + const [ err ] = await once(et, 'error'); + strictEqual(err, error); +} + +async function prioritizesEventEmitter() { + const ee = new EventEmitter(); + ee.addEventListener = fail; + ee.removeAllListeners = fail; + process.nextTick(() => ee.emit('foo')); + await once(ee, 'foo'); +} + +async function abortSignalBefore() { + const ee = new EventEmitter(); + ee.on('error', common.mustNotCall()); + const abortedSignal = AbortSignal.abort(); + + await Promise.all([1, {}, 'hi', null, false].map((signal) => { + return rejects(once(ee, 'foo', { signal }), { + code: 'ERR_INVALID_ARG_TYPE' + }); + })); + + return rejects(once(ee, 'foo', { signal: abortedSignal }), { + name: 'AbortError' + }); +} + +async function abortSignalAfter() { + const ee = new EventEmitter(); + const ac = new AbortController(); + ee.on('error', common.mustNotCall()); + const r = rejects(once(ee, 'foo', { signal: ac.signal }), { + name: 'AbortError' + }); + process.nextTick(() => ac.abort()); + return r; +} + +async function abortSignalAfterEvent() { + const ee = new EventEmitter(); + const ac = new AbortController(); + process.nextTick(() => { + ee.emit('foo'); + ac.abort(); + }); + const promise = once(ee, 'foo', { signal: ac.signal }); + await promise; +} + +async function abortSignalRemoveListener() { + const ee = new EventEmitter(); + const ac = new AbortController(); + + try { + process.nextTick(() => ac.abort()); + await once(ee, 'test', { signal: ac.signal }); + } catch { + strictEqual(ee.listeners('test').length, 0); + strictEqual(ee.listeners('error').length, 0); + } +} + +async function eventTargetAbortSignalBefore() { + const et = new EventTarget(); + const abortedSignal = AbortSignal.abort(); + + await Promise.all([1, {}, 'hi', null, false].map((signal) => { + return rejects(once(et, 'foo', { signal }), { + code: 'ERR_INVALID_ARG_TYPE' + }); + })); + + return rejects(once(et, 'foo', { signal: abortedSignal }), { + name: 'AbortError' + }); +} + +async function eventTargetAbortSignalAfter() { + const et = new EventTarget(); + const ac = new AbortController(); + const r = rejects(once(et, 'foo', { signal: ac.signal }), { + name: 'AbortError' + }); + process.nextTick(() => ac.abort()); + return r; +} + +async function eventTargetAbortSignalAfterEvent() { + const et = new EventTarget(); + const ac = new AbortController(); + process.nextTick(() => { + et.dispatchEvent(new Event('foo')); + ac.abort(); + }); + await once(et, 'foo', { signal: ac.signal }); +} + +Promise.all([ + onceAnEvent(), + onceAnEventWithNullOptions(), + onceAnEventWithTwoArgs(), + catchesErrors(), + catchesErrorsWithAbortSignal(), + stopListeningAfterCatchingError(), + onceError(), + onceWithEventTarget(), + onceWithEventTargetError(), + prioritizesEventEmitter(), + abortSignalBefore(), + abortSignalAfter(), + abortSignalAfterEvent(), + abortSignalRemoveListener(), + eventTargetAbortSignalBefore(), + eventTargetAbortSignalAfter(), + eventTargetAbortSignalAfterEvent(), +]).then(common.mustCall()); diff --git a/tests/node_compat/test/parallel/test-events-uncaught-exception-stack.js b/tests/node_compat/test/parallel/test-events-uncaught-exception-stack.js new file mode 100644 index 000000000..d5b39c203 --- /dev/null +++ b/tests/node_compat/test/parallel/test-events-uncaught-exception-stack.js @@ -0,0 +1,23 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const EventEmitter = require('events'); + +// Tests that the error stack where the exception was thrown is *not* appended. + +process.on('uncaughtException', common.mustCall((err) => { + const lines = err.stack.split('\n'); + assert.strictEqual(lines[0], 'Error'); + lines.slice(1).forEach((line) => { + assert.match(line, /^ {4}at/); + }); +})); + +new EventEmitter().emit('error', new Error()); diff --git a/tests/node_compat/test/parallel/test-eventtarget-brandcheck.js b/tests/node_compat/test/parallel/test-eventtarget-brandcheck.js new file mode 100644 index 000000000..db5cd53f6 --- /dev/null +++ b/tests/node_compat/test/parallel/test-eventtarget-brandcheck.js @@ -0,0 +1,104 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Flags: --expose-internals +'use strict'; + +require('../common'); +const assert = require('assert'); + +const { + Event, + CustomEvent, + EventTarget, + NodeEventTarget, +} = require('internal/event_target'); + +[ + 'target', + 'currentTarget', + 'srcElement', + 'type', + 'cancelable', + 'defaultPrevented', + 'timeStamp', + 'returnValue', + 'bubbles', + 'composed', + 'eventPhase', +].forEach((i) => { + assert.throws(() => Reflect.get(Event.prototype, i, {}), { + code: 'ERR_INVALID_THIS', + }); +}); + +[ + 'stopImmediatePropagation', + 'preventDefault', + 'composedPath', + 'cancelBubble', + 'stopPropagation', +].forEach((i) => { + assert.throws(() => Reflect.apply(Event.prototype[i], [], {}), { + code: 'ERR_INVALID_THIS', + }); +}); + +[ + 'target', + 'currentTarget', + 'srcElement', + 'type', + 'cancelable', + 'defaultPrevented', + 'timeStamp', + 'returnValue', + 'bubbles', + 'composed', + 'eventPhase', + 'detail', +].forEach((i) => { + assert.throws(() => Reflect.get(CustomEvent.prototype, i, {}), { + code: 'ERR_INVALID_THIS', + }); +}); + +[ + 'stopImmediatePropagation', + 'preventDefault', + 'composedPath', + 'cancelBubble', + 'stopPropagation', +].forEach((i) => { + assert.throws(() => Reflect.apply(CustomEvent.prototype[i], [], {}), { + code: 'ERR_INVALID_THIS', + }); +}); + +['addEventListener', 'removeEventListener', 'dispatchEvent'].forEach((i) => { + assert.throws(() => Reflect.apply(EventTarget.prototype[i], [], {}), { + code: 'ERR_INVALID_THIS', + }); +}); + +[ + 'setMaxListeners', + 'getMaxListeners', + 'eventNames', + 'listenerCount', + 'off', + 'removeListener', + 'on', + 'addListener', + 'once', + 'emit', + 'removeAllListeners', +].forEach((i) => { + assert.throws(() => Reflect.apply(NodeEventTarget.prototype[i], [], {}), { + code: 'ERR_INVALID_THIS', + }); +}); diff --git a/tests/node_compat/test/parallel/test-exception-handler.js b/tests/node_compat/test/parallel/test-exception-handler.js new file mode 100644 index 000000000..6c76d2463 --- /dev/null +++ b/tests/node_compat/test/parallel/test-exception-handler.js @@ -0,0 +1,47 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const MESSAGE = 'catch me if you can'; + +process.on('uncaughtException', common.mustCall((e) => { + console.log('uncaught exception! 1'); + assert.strictEqual(MESSAGE, e.message); +})); + +process.on('uncaughtException', common.mustCall((e) => { + console.log('uncaught exception! 2'); + assert.strictEqual(MESSAGE, e.message); +})); + +setTimeout(() => { + throw new Error(MESSAGE); +}, 10); diff --git a/tests/node_compat/test/parallel/test-exception-handler2.js b/tests/node_compat/test/parallel/test-exception-handler2.js new file mode 100644 index 000000000..6cb214593 --- /dev/null +++ b/tests/node_compat/test/parallel/test-exception-handler2.js @@ -0,0 +1,43 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +process.on('uncaughtException', function(err) { + console.log(`Caught exception: ${err}`); +}); + +setTimeout(common.mustCall(function() { + console.log('This will still run.'); +}), 50); + +// Intentionally cause an exception, but don't catch it. +nonexistentFunc(); // eslint-disable-line no-undef +assert.fail('This will not run.'); diff --git a/tests/node_compat/test/parallel/test-file-read-noexist.js b/tests/node_compat/test/parallel/test-file-read-noexist.js new file mode 100644 index 000000000..2e2d4320d --- /dev/null +++ b/tests/node_compat/test/parallel/test-file-read-noexist.js @@ -0,0 +1,39 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const fixtures = require('../common/fixtures'); +const assert = require('assert'); +const fs = require('fs'); + +const filename = fixtures.path('does_not_exist.txt'); +fs.readFile(filename, 'latin1', common.mustCall(function(err, content) { + assert.ok(err); + assert.strictEqual(err.code, 'ENOENT'); +})); diff --git a/tests/node_compat/test/parallel/test-file-write-stream.js b/tests/node_compat/test/parallel/test-file-write-stream.js new file mode 100644 index 000000000..199cdd80e --- /dev/null +++ b/tests/node_compat/test/parallel/test-file-write-stream.js @@ -0,0 +1,91 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const path = require('path'); +const fs = require('fs'); +const tmpdir = require('../common/tmpdir'); +const fn = path.join(tmpdir.path, 'write.txt'); +tmpdir.refresh(); +const file = fs.createWriteStream(fn, { + highWaterMark: 10 +}); + +const EXPECTED = '012345678910'; + +const callbacks = { + open: -1, + drain: -2, + close: -1 +}; + +file + .on('open', function(fd) { + console.error('open!'); + callbacks.open++; + assert.strictEqual(typeof fd, 'number'); + }) + .on('drain', function() { + console.error('drain!', callbacks.drain); + callbacks.drain++; + if (callbacks.drain === -1) { + assert.strictEqual(fs.readFileSync(fn, 'utf8'), EXPECTED); + file.write(EXPECTED); + } else if (callbacks.drain === 0) { + assert.strictEqual(fs.readFileSync(fn, 'utf8'), EXPECTED + EXPECTED); + file.end(); + } + }) + .on('close', function() { + console.error('close!'); + assert.strictEqual(file.bytesWritten, EXPECTED.length * 2); + + callbacks.close++; + file.write('should not work anymore', common.expectsError({ + code: 'ERR_STREAM_WRITE_AFTER_END', + name: 'Error', + message: 'write after end' + })); + file.on('error', common.mustNotCall()); + + fs.unlinkSync(fn); + }); + +for (let i = 0; i < 11; i++) { + file.write(`${i}`); +} + +process.on('exit', function() { + for (const k in callbacks) { + assert.strictEqual(callbacks[k], 0, `${k} count off by ${callbacks[k]}`); + } + console.log('ok'); +}); diff --git a/tests/node_compat/test/parallel/test-file-write-stream2.js b/tests/node_compat/test/parallel/test-file-write-stream2.js new file mode 100644 index 000000000..3aa712a2f --- /dev/null +++ b/tests/node_compat/test/parallel/test-file-write-stream2.js @@ -0,0 +1,116 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); + +const path = require('path'); +const fs = require('fs'); + +const tmpdir = require('../common/tmpdir'); + + +const filepath = path.join(tmpdir.path, 'write.txt'); + +const EXPECTED = '012345678910'; + +const cb_expected = 'write open drain write drain close '; +let cb_occurred = ''; + +let countDrains = 0; + + +process.on('exit', function() { + removeTestFile(); + if (cb_occurred !== cb_expected) { + console.log(' Test callback events missing or out of order:'); + console.log(` expected: ${cb_expected}`); + console.log(` occurred: ${cb_occurred}`); + assert.strictEqual( + cb_occurred, cb_expected, + `events missing or out of order: "${cb_occurred}" !== "${cb_expected}"`); + } else { + console.log('ok'); + } +}); + +function removeTestFile() { + try { + fs.unlinkSync(filepath); + } catch { + // Continue regardless of error. + } +} + + +tmpdir.refresh(); + +// Drain at 0, return false at 10. +const file = fs.createWriteStream(filepath, { + highWaterMark: 11 +}); + +file.on('open', function(fd) { + console.error('open'); + cb_occurred += 'open '; + assert.strictEqual(typeof fd, 'number'); +}); + +file.on('drain', function() { + console.error('drain'); + cb_occurred += 'drain '; + ++countDrains; + if (countDrains === 1) { + console.error('drain=1, write again'); + assert.strictEqual(fs.readFileSync(filepath, 'utf8'), EXPECTED); + console.error(`ondrain write ret= ${file.write(EXPECTED)}`); + cb_occurred += 'write '; + } else if (countDrains === 2) { + console.error('second drain, end'); + assert.strictEqual(fs.readFileSync(filepath, 'utf8'), EXPECTED + EXPECTED); + file.end(); + } +}); + +file.on('close', function() { + cb_occurred += 'close '; + assert.strictEqual(file.bytesWritten, EXPECTED.length * 2); + file.write('should not work anymore', (err) => { + assert.ok(err.message.includes('write after end')); + }); +}); + +for (let i = 0; i < 11; i++) { + const ret = file.write(String(i)); + console.error(`${i} ${ret}`); + + // Return false when i hits 10 + assert.strictEqual(ret, i !== 10); +} +cb_occurred += 'write '; diff --git a/tests/node_compat/test/parallel/test-file-write-stream3.js b/tests/node_compat/test/parallel/test-file-write-stream3.js new file mode 100644 index 000000000..d15a0b571 --- /dev/null +++ b/tests/node_compat/test/parallel/test-file-write-stream3.js @@ -0,0 +1,221 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const path = require('path'); +const fs = require('fs'); + +const tmpdir = require('../common/tmpdir'); + + +const filepath = path.join(tmpdir.path, 'write_pos.txt'); + + +const cb_expected = 'write open close write open close write open close '; +let cb_occurred = ''; + +const fileDataInitial = 'abcdefghijklmnopqrstuvwxyz'; + +const fileDataExpected_1 = 'abcdefghijklmnopqrstuvwxyz'; +const fileDataExpected_2 = 'abcdefghij123456qrstuvwxyz'; +const fileDataExpected_3 = 'abcdefghij\u2026\u2026qrstuvwxyz'; + + +process.on('exit', function() { + if (cb_occurred !== cb_expected) { + console.log(' Test callback events missing or out of order:'); + console.log(` expected: ${cb_expected}`); + console.log(` occurred: ${cb_occurred}`); + assert.strictEqual( + cb_occurred, cb_expected, + `events missing or out of order: "${cb_occurred}" !== "${cb_expected}"`); + } +}); + + +tmpdir.refresh(); + + +function run_test_1() { + const options = {}; + const file = fs.createWriteStream(filepath, options); + console.log(' (debug: start ', file.start); + console.log(' (debug: pos ', file.pos); + + file.on('open', function(fd) { + cb_occurred += 'open '; + }); + + file.on('close', function() { + cb_occurred += 'close '; + console.log(' (debug: bytesWritten ', file.bytesWritten); + console.log(' (debug: start ', file.start); + console.log(' (debug: pos ', file.pos); + assert.strictEqual(file.bytesWritten, buffer.length); + const fileData = fs.readFileSync(filepath, 'utf8'); + console.log(' (debug: file data ', fileData); + console.log(' (debug: expected ', fileDataExpected_1); + assert.strictEqual(fileData, fileDataExpected_1); + + run_test_2(); + }); + + file.on('error', function(err) { + cb_occurred += 'error '; + console.log(' (debug: err event ', err); + throw err; + }); + + const buffer = Buffer.from(fileDataInitial); + file.write(buffer); + cb_occurred += 'write '; + + file.end(); +} + + +function run_test_2() { + + const buffer = Buffer.from('123456'); + + const options = { start: 10, + flags: 'r+' }; + const file = fs.createWriteStream(filepath, options); + console.log(' (debug: start ', file.start); + console.log(' (debug: pos ', file.pos); + + file.on('open', function(fd) { + cb_occurred += 'open '; + }); + + file.on('close', function() { + cb_occurred += 'close '; + console.log(' (debug: bytesWritten ', file.bytesWritten); + console.log(' (debug: start ', file.start); + console.log(' (debug: pos ', file.pos); + assert.strictEqual(file.bytesWritten, buffer.length); + const fileData = fs.readFileSync(filepath, 'utf8'); + console.log(' (debug: file data ', fileData); + console.log(' (debug: expected ', fileDataExpected_2); + assert.strictEqual(fileData, fileDataExpected_2); + + run_test_3(); + }); + + file.on('error', function(err) { + cb_occurred += 'error '; + console.log(' (debug: err event ', err); + throw err; + }); + + file.write(buffer); + cb_occurred += 'write '; + + file.end(); +} + + +function run_test_3() { + + const data = '\u2026\u2026'; // 3 bytes * 2 = 6 bytes in UTF-8 + + const options = { start: 10, + flags: 'r+' }; + const file = fs.createWriteStream(filepath, options); + console.log(' (debug: start ', file.start); + console.log(' (debug: pos ', file.pos); + + file.on('open', function(fd) { + cb_occurred += 'open '; + }); + + file.on('close', function() { + cb_occurred += 'close '; + console.log(' (debug: bytesWritten ', file.bytesWritten); + console.log(' (debug: start ', file.start); + console.log(' (debug: pos ', file.pos); + assert.strictEqual(file.bytesWritten, data.length * 3); + const fileData = fs.readFileSync(filepath, 'utf8'); + console.log(' (debug: file data ', fileData); + console.log(' (debug: expected ', fileDataExpected_3); + assert.strictEqual(fileData, fileDataExpected_3); + + run_test_4(); + run_test_5(); + }); + + file.on('error', function(err) { + cb_occurred += 'error '; + console.log(' (debug: err event ', err); + throw err; + }); + + file.write(data, 'utf8'); + cb_occurred += 'write '; + + file.end(); +} + + +const run_test_4 = common.mustCall(function() { + // Error: start must be >= zero + const fn = () => { + fs.createWriteStream(filepath, { start: -5, flags: 'r+' }); + }; + // Verify the range of values using a common integer verifier. + // Limit Number.MAX_SAFE_INTEGER + const err = { + code: 'ERR_OUT_OF_RANGE', + message: 'The value of "start" is out of range. ' + + `It must be >= 0 && <= ${Number.MAX_SAFE_INTEGER}. Received -5`, + name: 'RangeError' + }; + assert.throws(fn, err); +}); + + +const run_test_5 = common.mustCall(function() { + // Error: start must be <= 2 ** 53 - 1 + const fn = () => { + fs.createWriteStream(filepath, { start: 2 ** 53, flags: 'r+' }); + }; + // Verify the range of values using a common integer verifier. + // Limit Number.MAX_SAFE_INTEGER + const err = { + code: 'ERR_OUT_OF_RANGE', + message: 'The value of "start" is out of range. It must be ' + + `>= 0 && <= ${Number.MAX_SAFE_INTEGER}. ` + + 'Received 9_007_199_254_740_992', + name: 'RangeError' + }; + assert.throws(fn, err); +}); + +run_test_1(); diff --git a/tests/node_compat/test/parallel/test-file-write-stream4.js b/tests/node_compat/test/parallel/test-file-write-stream4.js new file mode 100644 index 000000000..392a8ef23 --- /dev/null +++ b/tests/node_compat/test/parallel/test-file-write-stream4.js @@ -0,0 +1,28 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +// Test that 'close' emits once and not twice when `emitClose: true` is set. +// Refs: https://github.com/nodejs/node/issues/31366 + +const common = require('../common'); +const path = require('path'); +const fs = require('fs'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +const filepath = path.join(tmpdir.path, 'write_pos.txt'); + +const fileReadStream = fs.createReadStream(process.execPath); +const fileWriteStream = fs.createWriteStream(filepath, { + emitClose: true +}); + +fileReadStream.pipe(fileWriteStream); +fileWriteStream.on('close', common.mustCall()); diff --git a/tests/node_compat/test/parallel/test-fs-access.js b/tests/node_compat/test/parallel/test-fs-access.js new file mode 100644 index 000000000..2351d4171 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-access.js @@ -0,0 +1,242 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Flags: --expose-internals +'use strict'; + +// This tests that fs.access and fs.accessSync works as expected +// and the errors thrown from these APIs include the desired properties + +const common = require('../common'); +if (!common.isWindows && process.getuid() === 0) + common.skip('as this test should not be run as `root`'); + +if (common.isIBMi) + common.skip('IBMi has a different access permission mechanism'); + +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); + +const { internalBinding } = require('internal/test/binding'); +const { UV_ENOENT } = internalBinding('uv'); + +const tmpdir = require('../common/tmpdir'); +const doesNotExist = path.join(tmpdir.path, '__this_should_not_exist'); +const readOnlyFile = path.join(tmpdir.path, 'read_only_file'); +const readWriteFile = path.join(tmpdir.path, 'read_write_file'); + +function createFileWithPerms(file, mode) { + fs.writeFileSync(file, ''); + fs.chmodSync(file, mode); +} + +tmpdir.refresh(); +createFileWithPerms(readOnlyFile, 0o444); +createFileWithPerms(readWriteFile, 0o666); + +// On non-Windows supported platforms, fs.access(readOnlyFile, W_OK, ...) +// always succeeds if node runs as the super user, which is sometimes the +// case for tests running on our continuous testing platform agents. +// +// In this case, this test tries to change its process user id to a +// non-superuser user so that the test that checks for write access to a +// read-only file can be more meaningful. +// +// The change of user id is done after creating the fixtures files for the same +// reason: the test may be run as the superuser within a directory in which +// only the superuser can create files, and thus it may need superuser +// privileges to create them. +// +// There's not really any point in resetting the process' user id to 0 after +// changing it to 'nobody', since in the case that the test runs without +// superuser privilege, it is not possible to change its process user id to +// superuser. +// +// It can prevent the test from removing files created before the change of user +// id, but that's fine. In this case, it is the responsibility of the +// continuous integration platform to take care of that. +let hasWriteAccessForReadonlyFile = false; +if (!common.isWindows && process.getuid() === 0) { + hasWriteAccessForReadonlyFile = true; + try { + process.setuid('nobody'); + hasWriteAccessForReadonlyFile = false; + } catch { + // Continue regardless of error. + } +} + +assert.strictEqual(typeof fs.F_OK, 'number'); +assert.strictEqual(typeof fs.R_OK, 'number'); +assert.strictEqual(typeof fs.W_OK, 'number'); +assert.strictEqual(typeof fs.X_OK, 'number'); + +const throwNextTick = (e) => { process.nextTick(() => { throw e; }); }; + +fs.access(__filename, common.mustCall(function(...args) { + assert.deepStrictEqual(args, [null]); +})); +fs.promises.access(__filename) + .then(common.mustCall()) + .catch(throwNextTick); +fs.access(__filename, fs.R_OK, common.mustCall(function(...args) { + assert.deepStrictEqual(args, [null]); +})); +fs.promises.access(__filename, fs.R_OK) + .then(common.mustCall()) + .catch(throwNextTick); +fs.access(readOnlyFile, fs.R_OK, common.mustCall(function(...args) { + assert.deepStrictEqual(args, [null]); +})); +fs.promises.access(readOnlyFile, fs.R_OK) + .then(common.mustCall()) + .catch(throwNextTick); + +{ + const expectedError = (err) => { + assert.notStrictEqual(err, null); + assert.strictEqual(err.code, 'ENOENT'); + assert.strictEqual(err.path, doesNotExist); + }; + fs.access(doesNotExist, common.mustCall(expectedError)); + fs.promises.access(doesNotExist) + .then(common.mustNotCall(), common.mustCall(expectedError)) + .catch(throwNextTick); +} + +{ + function expectedError(err) { + assert.strictEqual(this, undefined); + if (hasWriteAccessForReadonlyFile) { + assert.ifError(err); + } else { + assert.notStrictEqual(err, null); + assert.strictEqual(err.path, readOnlyFile); + } + } + fs.access(readOnlyFile, fs.W_OK, common.mustCall(expectedError)); + fs.promises.access(readOnlyFile, fs.W_OK) + .then(common.mustNotCall(), common.mustCall(expectedError)) + .catch(throwNextTick); +} + +{ + const expectedError = (err) => { + assert.strictEqual(err.code, 'ERR_INVALID_ARG_TYPE'); + assert.ok(err instanceof TypeError); + return true; + }; + assert.throws( + () => { fs.access(100, fs.F_OK, common.mustNotCall()); }, + expectedError + ); + + fs.promises.access(100, fs.F_OK) + .then(common.mustNotCall(), common.mustCall(expectedError)) + .catch(throwNextTick); +} + +assert.throws( + () => { + fs.access(__filename, fs.F_OK); + }, + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + }); + +assert.throws( + () => { + fs.access(__filename, fs.F_OK, common.mustNotMutateObjectDeep({})); + }, + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + }); + +// Regular access should not throw. +fs.accessSync(__filename); +const mode = fs.R_OK | fs.W_OK; +fs.accessSync(readWriteFile, mode); + +// Invalid modes should throw. +[ + false, + 1n, + { [Symbol.toPrimitive]() { return fs.R_OK; } }, + [1], + 'r', +].forEach((mode, i) => { + console.log(mode, i); + assert.throws( + () => fs.access(readWriteFile, mode, common.mustNotCall()), + { + code: 'ERR_INVALID_ARG_TYPE', + } + ); + assert.throws( + () => fs.accessSync(readWriteFile, mode), + { + code: 'ERR_INVALID_ARG_TYPE', + } + ); +}); + +// Out of range modes should throw +[ + -1, + 8, + Infinity, + NaN, +].forEach((mode, i) => { + console.log(mode, i); + assert.throws( + () => fs.access(readWriteFile, mode, common.mustNotCall()), + { + code: 'ERR_OUT_OF_RANGE', + } + ); + assert.throws( + () => fs.accessSync(readWriteFile, mode), + { + code: 'ERR_OUT_OF_RANGE', + } + ); +}); + +assert.throws( + () => { fs.accessSync(doesNotExist); }, + (err) => { + assert.strictEqual(err.code, 'ENOENT'); + assert.strictEqual(err.path, doesNotExist); + assert.strictEqual( + err.message, + `ENOENT: no such file or directory, access '${doesNotExist}'` + ); + assert.strictEqual(err.constructor, Error); + assert.strictEqual(err.syscall, 'access'); + assert.strictEqual(err.errno, UV_ENOENT); + return true; + } +); + +assert.throws( + () => { fs.accessSync(Buffer.from(doesNotExist)); }, + (err) => { + assert.strictEqual(err.code, 'ENOENT'); + assert.strictEqual(err.path, doesNotExist); + assert.strictEqual( + err.message, + `ENOENT: no such file or directory, access '${doesNotExist}'` + ); + assert.strictEqual(err.constructor, Error); + assert.strictEqual(err.syscall, 'access'); + assert.strictEqual(err.errno, UV_ENOENT); + return true; + } +); diff --git a/tests/node_compat/test/parallel/test-fs-append-file-sync.js b/tests/node_compat/test/parallel/test-fs-append-file-sync.js new file mode 100644 index 000000000..d5adc427d --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-append-file-sync.js @@ -0,0 +1,115 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const join = require('path').join; +const fs = require('fs'); + +const currentFileData = 'ABCD'; +const m = 0o600; +const num = 220; +const data = '南越国是前203年至前111年存在于岭南地区的一个国家,国都位于番禺,疆域包括今天中国的广东、' + + '广西两省区的大部份地区,福建省、湖南、贵州、云南的一小部份地区和越南的北部。' + + '南越国是秦朝灭亡后,由南海郡尉赵佗于前203年起兵兼并桂林郡和象郡后建立。' + + '前196年和前179年,南越国曾先后两次名义上臣属于西汉,成为西汉的“外臣”。前112年,' + + '南越国末代君主赵建德与西汉发生战争,被汉武帝于前111年所灭。南越国共存在93年,' + + '历经五代君主。南越国是岭南地区的第一个有记载的政权国家,采用封建制和郡县制并存的制度,' + + '它的建立保证了秦末乱世岭南地区社会秩序的稳定,有效的改善了岭南地区落后的政治、##济现状。\n'; + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +// Test that empty file will be created and have content added. +const filename = join(tmpdir.path, 'append-sync.txt'); + +fs.appendFileSync(filename, data); + +const fileData = fs.readFileSync(filename); + +assert.strictEqual(Buffer.byteLength(data), fileData.length); + +// Test that appends data to a non empty file. +const filename2 = join(tmpdir.path, 'append-sync2.txt'); +fs.writeFileSync(filename2, currentFileData); + +fs.appendFileSync(filename2, data); + +const fileData2 = fs.readFileSync(filename2); + +assert.strictEqual(Buffer.byteLength(data) + currentFileData.length, + fileData2.length); + +// Test that appendFileSync accepts buffers. +const filename3 = join(tmpdir.path, 'append-sync3.txt'); +fs.writeFileSync(filename3, currentFileData); + +const buf = Buffer.from(data, 'utf8'); +fs.appendFileSync(filename3, buf); + +const fileData3 = fs.readFileSync(filename3); + +assert.strictEqual(buf.length + currentFileData.length, fileData3.length); + +const filename4 = join(tmpdir.path, 'append-sync4.txt'); +fs.writeFileSync(filename4, currentFileData, common.mustNotMutateObjectDeep({ mode: m })); + +[ + true, false, 0, 1, Infinity, () => {}, {}, [], undefined, null, +].forEach((value) => { + assert.throws( + () => fs.appendFileSync(filename4, value, common.mustNotMutateObjectDeep({ mode: m })), + { message: /data/, code: 'ERR_INVALID_ARG_TYPE' } + ); +}); +fs.appendFileSync(filename4, `${num}`, common.mustNotMutateObjectDeep({ mode: m })); + +// Windows permissions aren't Unix. +if (!common.isWindows) { + const st = fs.statSync(filename4); + assert.strictEqual(st.mode & 0o700, m); +} + +const fileData4 = fs.readFileSync(filename4); + +assert.strictEqual(Buffer.byteLength(String(num)) + currentFileData.length, + fileData4.length); + +// Test that appendFile accepts file descriptors. +const filename5 = join(tmpdir.path, 'append-sync5.txt'); +fs.writeFileSync(filename5, currentFileData); + +const filename5fd = fs.openSync(filename5, 'a+', 0o600); +fs.appendFileSync(filename5fd, data); +fs.closeSync(filename5fd); + +const fileData5 = fs.readFileSync(filename5); + +assert.strictEqual(Buffer.byteLength(data) + currentFileData.length, + fileData5.length); diff --git a/tests/node_compat/test/parallel/test-fs-append-file.js b/tests/node_compat/test/parallel/test-fs-append-file.js new file mode 100644 index 000000000..41c6be684 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-append-file.js @@ -0,0 +1,202 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const fs = require('fs'); +const join = require('path').join; + +const tmpdir = require('../common/tmpdir'); + +const currentFileData = 'ABCD'; + +const s = '南越国是前203年至前111年存在于岭南地区的一个国家,国都位于番禺,疆域包括今天中国的广东、' + + '广西两省区的大部份地区,福建省、湖南、贵州、云南的一小部份地区和越南的北部。' + + '南越国是秦朝灭亡后,由南海郡尉赵佗于前203年起兵兼并桂林郡和象郡后建立。' + + '前196年和前179年,南越国曾先后两次名义上臣属于西汉,成为西汉的“外臣”。前112年,' + + '南越国末代君主赵建德与西汉发生战争,被汉武帝于前111年所灭。南越国共存在93年,' + + '历经五代君主。南越国是岭南地区的第一个有记载的政权国家,采用封建制和郡县制并存的制度,' + + '它的建立保证了秦末乱世岭南地区社会秩序的稳定,有效的改善了岭南地区落后的政治、##济现状。\n'; + +tmpdir.refresh(); + +const throwNextTick = (e) => { process.nextTick(() => { throw e; }); }; + +// Test that empty file will be created and have content added (callback API). +{ + const filename = join(tmpdir.path, 'append.txt'); + + fs.appendFile(filename, s, common.mustSucceed(() => { + fs.readFile(filename, common.mustSucceed((buffer) => { + assert.strictEqual(Buffer.byteLength(s), buffer.length); + })); + })); +} + +// Test that empty file will be created and have content added (promise API). +{ + const filename = join(tmpdir.path, 'append-promise.txt'); + + fs.promises.appendFile(filename, s) + .then(common.mustCall(() => fs.promises.readFile(filename))) + .then((buffer) => { + assert.strictEqual(Buffer.byteLength(s), buffer.length); + }) + .catch(throwNextTick); +} + +// Test that appends data to a non-empty file (callback API). +{ + const filename = join(tmpdir.path, 'append-non-empty.txt'); + fs.writeFileSync(filename, currentFileData); + + fs.appendFile(filename, s, common.mustSucceed(() => { + fs.readFile(filename, common.mustSucceed((buffer) => { + assert.strictEqual(Buffer.byteLength(s) + currentFileData.length, + buffer.length); + })); + })); +} + +// Test that appends data to a non-empty file (promise API). +{ + const filename = join(tmpdir.path, 'append-non-empty-promise.txt'); + fs.writeFileSync(filename, currentFileData); + + fs.promises.appendFile(filename, s) + .then(common.mustCall(() => fs.promises.readFile(filename))) + .then((buffer) => { + assert.strictEqual(Buffer.byteLength(s) + currentFileData.length, + buffer.length); + }) + .catch(throwNextTick); +} + +// Test that appendFile accepts buffers (callback API). +{ + const filename = join(tmpdir.path, 'append-buffer.txt'); + fs.writeFileSync(filename, currentFileData); + + const buf = Buffer.from(s, 'utf8'); + + fs.appendFile(filename, buf, common.mustSucceed(() => { + fs.readFile(filename, common.mustSucceed((buffer) => { + assert.strictEqual(buf.length + currentFileData.length, buffer.length); + })); + })); +} + +// Test that appendFile accepts buffers (promises API). +{ + const filename = join(tmpdir.path, 'append-buffer-promises.txt'); + fs.writeFileSync(filename, currentFileData); + + const buf = Buffer.from(s, 'utf8'); + + fs.promises.appendFile(filename, buf) + .then(common.mustCall(() => fs.promises.readFile(filename))) + .then((buffer) => { + assert.strictEqual(buf.length + currentFileData.length, buffer.length); + }) + .catch(throwNextTick); +} + +// Test that appendFile does not accept invalid data type (callback API). +[false, 5, {}, null, undefined].forEach(async (data) => { + const errObj = { + code: 'ERR_INVALID_ARG_TYPE', + message: /"data"|"buffer"/ + }; + const filename = join(tmpdir.path, 'append-invalid-data.txt'); + + assert.throws( + () => fs.appendFile(filename, data, common.mustNotCall()), + errObj + ); + + assert.throws( + () => fs.appendFileSync(filename, data), + errObj + ); + + await assert.rejects( + fs.promises.appendFile(filename, data), + errObj + ); + // The filename shouldn't exist if throwing error. + assert.throws( + () => fs.statSync(filename), + { + code: 'ENOENT', + message: /no such file or directory/ + } + ); +}); + +// Test that appendFile accepts file descriptors (callback API). +{ + const filename = join(tmpdir.path, 'append-descriptors.txt'); + fs.writeFileSync(filename, currentFileData); + + fs.open(filename, 'a+', common.mustSucceed((fd) => { + fs.appendFile(fd, s, common.mustSucceed(() => { + fs.close(fd, common.mustSucceed(() => { + fs.readFile(filename, common.mustSucceed((buffer) => { + assert.strictEqual(Buffer.byteLength(s) + currentFileData.length, + buffer.length); + })); + })); + })); + })); +} + +// FIXME(F3n67u): fs.promises.appendFile support FileHandle +// Test that appendFile accepts file descriptors (promises API). +// { +// const filename = join(tmpdir.path, 'append-descriptors-promises.txt'); +// fs.writeFileSync(filename, currentFileData); + +// let fd; +// fs.promises.open(filename, 'a+') +// .then(common.mustCall((fileDescriptor) => { +// fd = fileDescriptor; +// return fs.promises.appendFile(fd, s); +// })) +// .then(common.mustCall(() => fd.close())) +// .then(common.mustCall(() => fs.promises.readFile(filename))) +// .then(common.mustCall((buffer) => { +// assert.strictEqual(Buffer.byteLength(s) + currentFileData.length, +// buffer.length); +// })) +// .catch(throwNextTick); +// } + +assert.throws( + () => fs.appendFile(join(tmpdir.path, 'append6.txt'), console.log), + { code: 'ERR_INVALID_ARG_TYPE' }); diff --git a/tests/node_compat/test/parallel/test-fs-chmod-mask.js b/tests/node_compat/test/parallel/test-fs-chmod-mask.js new file mode 100644 index 000000000..f11567c7e --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-chmod-mask.js @@ -0,0 +1,106 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +'use strict'; + +// This tests that the lower bits of mode > 0o777 still works in fs APIs. + +const common = require('../common'); +const assert = require('assert'); +const path = require('path'); +const fs = require('fs'); + +// TODO(f3n67u): fs.chmod is not supported in Windows +if (common.isWindows) { + return; +} + +let mode; +// On Windows chmod is only able to manipulate write permission +if (common.isWindows) { + mode = 0o444; // read-only +} else { + mode = 0o777; +} + +const maskToIgnore = 0o10000; + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +function test(mode, asString) { + const suffix = asString ? 'str' : 'num'; + const input = asString ? + (mode | maskToIgnore).toString(8) : (mode | maskToIgnore); + + { + const file = path.join(tmpdir.path, `chmod-async-${suffix}.txt`); + fs.writeFileSync(file, 'test', 'utf-8'); + + fs.chmod(file, input, common.mustSucceed(() => { + assert.strictEqual(fs.statSync(file).mode & 0o777, mode); + })); + } + + { + const file = path.join(tmpdir.path, `chmodSync-${suffix}.txt`); + fs.writeFileSync(file, 'test', 'utf-8'); + + fs.chmodSync(file, input); + assert.strictEqual(fs.statSync(file).mode & 0o777, mode); + } + + // TODO(f3n67u): implement fs.fchmod + // { + // const file = path.join(tmpdir.path, `fchmod-async-${suffix}.txt`); + // fs.writeFileSync(file, 'test', 'utf-8'); + // fs.open(file, 'w', common.mustSucceed((fd) => { + // fs.fchmod(fd, input, common.mustSucceed(() => { + // assert.strictEqual(fs.fstatSync(fd).mode & 0o777, mode); + // fs.close(fd, assert.ifError); + // })); + // })); + // } + + // TODO(f3n67u): implement fs.fchmodSync + // { + // const file = path.join(tmpdir.path, `fchmodSync-${suffix}.txt`); + // fs.writeFileSync(file, 'test', 'utf-8'); + // const fd = fs.openSync(file, 'w'); + + // fs.fchmodSync(fd, input); + // assert.strictEqual(fs.fstatSync(fd).mode & 0o777, mode); + + // fs.close(fd, assert.ifError); + // } + + // TODO(f3n67u): implement fs.lchmod + // if (fs.lchmod) { + // const link = path.join(tmpdir.path, `lchmod-src-${suffix}`); + // const file = path.join(tmpdir.path, `lchmod-dest-${suffix}`); + // fs.writeFileSync(file, 'test', 'utf-8'); + // fs.symlinkSync(file, link); + + // fs.lchmod(link, input, common.mustSucceed(() => { + // assert.strictEqual(fs.lstatSync(link).mode & 0o777, mode); + // })); + // } + + // TODO(f3n67u): implement fs.lchmodSync + // if (fs.lchmodSync) { + // const link = path.join(tmpdir.path, `lchmodSync-src-${suffix}`); + // const file = path.join(tmpdir.path, `lchmodSync-dest-${suffix}`); + // fs.writeFileSync(file, 'test', 'utf-8'); + // fs.symlinkSync(file, link); + + // fs.lchmodSync(link, input); + // assert.strictEqual(fs.lstatSync(link).mode & 0o777, mode); + // } +} + +test(mode, true); +test(mode, false); diff --git a/tests/node_compat/test/parallel/test-fs-chmod.js b/tests/node_compat/test/parallel/test-fs-chmod.js new file mode 100644 index 000000000..b5f524f64 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-chmod.js @@ -0,0 +1,167 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const path = require('path'); +const fs = require('fs'); + +let mode_async; +let mode_sync; + +// Need to hijack fs.open/close to make sure that things +// get closed once they're opened. +fs._open = fs.open; +fs._openSync = fs.openSync; +fs.open = open; +fs.openSync = openSync; +fs._close = fs.close; +fs._closeSync = fs.closeSync; +fs.close = close; +fs.closeSync = closeSync; + +let openCount = 0; + +function open() { + openCount++; + return fs._open.apply(fs, arguments); +} + +function openSync() { + openCount++; + return fs._openSync.apply(fs, arguments); +} + +function close() { + openCount--; + return fs._close.apply(fs, arguments); +} + +function closeSync() { + openCount--; + return fs._closeSync.apply(fs, arguments); +} + +// TODO(f3n67u): fs.chmod is not supported in Windows +if (common.isWindows) { + return; +} + +// On Windows chmod is only able to manipulate write permission +if (common.isWindows) { + mode_async = 0o400; // read-only + mode_sync = 0o600; // read-write +} else { + mode_async = 0o777; + mode_sync = 0o644; +} + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +const file1 = path.join(tmpdir.path, 'a.js'); +const file2 = path.join(tmpdir.path, 'a1.js'); + +// Create file1. +fs.closeSync(fs.openSync(file1, 'w')); + +fs.chmod(file1, mode_async.toString(8), common.mustSucceed(() => { + if (common.isWindows) { + assert.ok((fs.statSync(file1).mode & 0o777) & mode_async); + } else { + assert.strictEqual(fs.statSync(file1).mode & 0o777, mode_async); + } + + fs.chmodSync(file1, mode_sync); + if (common.isWindows) { + assert.ok((fs.statSync(file1).mode & 0o777) & mode_sync); + } else { + assert.strictEqual(fs.statSync(file1).mode & 0o777, mode_sync); + } +})); + +// TODO(f3n67u): implement fs.fchmod +// fs.open(file2, 'w', common.mustSucceed((fd) => { +// fs.fchmod(fd, mode_async.toString(8), common.mustSucceed(() => { +// if (common.isWindows) { +// assert.ok((fs.fstatSync(fd).mode & 0o777) & mode_async); +// } else { +// assert.strictEqual(fs.fstatSync(fd).mode & 0o777, mode_async); +// } + +// assert.throws( +// () => fs.fchmod(fd, {}), +// { +// code: 'ERR_INVALID_ARG_TYPE', +// } +// ); + +// fs.fchmodSync(fd, mode_sync); +// if (common.isWindows) { +// assert.ok((fs.fstatSync(fd).mode & 0o777) & mode_sync); +// } else { +// assert.strictEqual(fs.fstatSync(fd).mode & 0o777, mode_sync); +// } + +// fs.close(fd, assert.ifError); +// })); +// })); + + +// TODO(f3n67u): implement fs.lchmod +// // lchmod +// if (fs.lchmod) { +// const link = path.join(tmpdir.path, 'symbolic-link'); + +// fs.symlinkSync(file2, link); + +// fs.lchmod(link, mode_async, common.mustSucceed(() => { +// assert.strictEqual(fs.lstatSync(link).mode & 0o777, mode_async); + +// fs.lchmodSync(link, mode_sync); +// assert.strictEqual(fs.lstatSync(link).mode & 0o777, mode_sync); + +// })); +// } + +[false, 1, {}, [], null, undefined].forEach((input) => { + const errObj = { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "path" argument must be of type string or an instance ' + + 'of Buffer or URL.' + + common.invalidArgTypeHelper(input) + }; + assert.throws(() => fs.chmod(input, 1, common.mustNotCall()), errObj); + assert.throws(() => fs.chmodSync(input, 1), errObj); +}); + +process.on('exit', function() { + assert.strictEqual(openCount, 0); +}); diff --git a/tests/node_compat/test/parallel/test-fs-chown-type-check.js b/tests/node_compat/test/parallel/test-fs-chown-type-check.js new file mode 100644 index 000000000..147edf837 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-chown-type-check.js @@ -0,0 +1,60 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const fs = require('fs'); + +[false, 1, {}, [], null, undefined].forEach((i) => { + assert.throws( + () => fs.chown(i, 1, 1, common.mustNotCall()), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + } + ); + assert.throws( + () => fs.chownSync(i, 1, 1), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + } + ); +}); + +[false, 'test', {}, [], null, undefined].forEach((i) => { + assert.throws( + () => fs.chown('not_a_file_that_exists', i, 1, common.mustNotCall()), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + } + ); + assert.throws( + () => fs.chown('not_a_file_that_exists', 1, i, common.mustNotCall()), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + } + ); + assert.throws( + () => fs.chownSync('not_a_file_that_exists', i, 1), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + } + ); + assert.throws( + () => fs.chownSync('not_a_file_that_exists', 1, i), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + } + ); +}); diff --git a/tests/node_compat/test/parallel/test-fs-copyfile.js b/tests/node_compat/test/parallel/test-fs-copyfile.js new file mode 100644 index 000000000..085fc19bf --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-copyfile.js @@ -0,0 +1,174 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Flags: --expose-internals +'use strict'; +const common = require('../common'); +const fixtures = require('../common/fixtures'); +const tmpdir = require('../common/tmpdir'); +const assert = require('assert'); +const fs = require('fs'); +const { internalBinding } = require('internal/test/binding'); +const { + UV_ENOENT, + UV_EEXIST +} = internalBinding('uv'); +const path = require('path'); +const src = fixtures.path('a.js'); +const dest = path.join(tmpdir.path, 'copyfile.out'); +const { + COPYFILE_EXCL, + COPYFILE_FICLONE, + COPYFILE_FICLONE_FORCE, + UV_FS_COPYFILE_EXCL, + UV_FS_COPYFILE_FICLONE, + UV_FS_COPYFILE_FICLONE_FORCE +} = fs.constants; + +function verify(src, dest) { + const srcData = fs.readFileSync(src, 'utf8'); + const srcStat = fs.statSync(src); + const destData = fs.readFileSync(dest, 'utf8'); + const destStat = fs.statSync(dest); + + assert.strictEqual(srcData, destData); + assert.strictEqual(srcStat.mode, destStat.mode); + assert.strictEqual(srcStat.size, destStat.size); +} + +tmpdir.refresh(); + +// Verify that flags are defined. +assert.strictEqual(typeof COPYFILE_EXCL, 'number'); +assert.strictEqual(typeof COPYFILE_FICLONE, 'number'); +assert.strictEqual(typeof COPYFILE_FICLONE_FORCE, 'number'); +assert.strictEqual(typeof UV_FS_COPYFILE_EXCL, 'number'); +assert.strictEqual(typeof UV_FS_COPYFILE_FICLONE, 'number'); +assert.strictEqual(typeof UV_FS_COPYFILE_FICLONE_FORCE, 'number'); +assert.strictEqual(COPYFILE_EXCL, UV_FS_COPYFILE_EXCL); +assert.strictEqual(COPYFILE_FICLONE, UV_FS_COPYFILE_FICLONE); +assert.strictEqual(COPYFILE_FICLONE_FORCE, UV_FS_COPYFILE_FICLONE_FORCE); + +// Verify that files are overwritten when no flags are provided. +fs.writeFileSync(dest, '', 'utf8'); +const result = fs.copyFileSync(src, dest); +assert.strictEqual(result, undefined); +verify(src, dest); + +// Verify that files are overwritten with default flags. +fs.copyFileSync(src, dest, 0); +verify(src, dest); + +// Verify that UV_FS_COPYFILE_FICLONE can be used. +fs.unlinkSync(dest); +fs.copyFileSync(src, dest, UV_FS_COPYFILE_FICLONE); +verify(src, dest); + +// Verify that COPYFILE_FICLONE_FORCE can be used. +try { + fs.unlinkSync(dest); + fs.copyFileSync(src, dest, COPYFILE_FICLONE_FORCE); + verify(src, dest); +} catch (err) { + assert.strictEqual(err.syscall, 'copyfile'); + assert(err.code === 'ENOTSUP' || err.code === 'ENOTTY' || + err.code === 'ENOSYS' || err.code === 'EXDEV'); + assert.strictEqual(err.path, src); + assert.strictEqual(err.dest, dest); +} + +// Copies asynchronously. +tmpdir.refresh(); // Don't use unlinkSync() since the last test may fail. +fs.copyFile(src, dest, common.mustSucceed(() => { + verify(src, dest); + + // Copy asynchronously with flags. + fs.copyFile(src, dest, COPYFILE_EXCL, common.mustCall((err) => { + if (err.code === 'ENOENT') { // Could be ENOENT or EEXIST + assert.strictEqual(err.message, + 'ENOENT: no such file or directory, copyfile ' + + `'${src}' -> '${dest}'`); + assert.strictEqual(err.errno, UV_ENOENT); + assert.strictEqual(err.code, 'ENOENT'); + assert.strictEqual(err.syscall, 'copyfile'); + } else { + assert.strictEqual(err.message, + 'EEXIST: file already exists, copyfile ' + + `'${src}' -> '${dest}'`); + assert.strictEqual(err.errno, UV_EEXIST); + assert.strictEqual(err.code, 'EEXIST'); + assert.strictEqual(err.syscall, 'copyfile'); + } + })); +})); + +// Throws if callback is not a function. +assert.throws(() => { + fs.copyFile(src, dest, 0, 0); +}, { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' +}); + +// Throws if the source path is not a string. +[false, 1, {}, [], null, undefined].forEach((i) => { + assert.throws( + () => fs.copyFile(i, dest, common.mustNotCall()), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: /src/ + } + ); + assert.throws( + () => fs.copyFile(src, i, common.mustNotCall()), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: /dest/ + } + ); + assert.throws( + () => fs.copyFileSync(i, dest), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: /src/ + } + ); + assert.throws( + () => fs.copyFileSync(src, i), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: /dest/ + } + ); +}); + +assert.throws(() => { + fs.copyFileSync(src, dest, 'r'); +}, { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: /mode/ +}); + +assert.throws(() => { + fs.copyFileSync(src, dest, 8); +}, { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', +}); + +assert.throws(() => { + fs.copyFile(src, dest, 'r', common.mustNotCall()); +}, { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: /mode/ +}); diff --git a/tests/node_compat/test/parallel/test-fs-empty-readStream.js b/tests/node_compat/test/parallel/test-fs-empty-readStream.js new file mode 100644 index 000000000..4f70fda27 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-empty-readStream.js @@ -0,0 +1,57 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const fs = require('fs'); +const fixtures = require('../common/fixtures'); + +const emptyFile = fixtures.path('empty.txt'); + +fs.open(emptyFile, 'r', common.mustSucceed((fd) => { + const read = fs.createReadStream(emptyFile, { fd }); + + read.once('data', common.mustNotCall('data event should not emit')); + + read.once('end', common.mustCall()); +})); + +fs.open(emptyFile, 'r', common.mustSucceed((fd) => { + const read = fs.createReadStream(emptyFile, { fd }); + + read.pause(); + + read.once('data', common.mustNotCall('data event should not emit')); + + read.once('end', common.mustNotCall('end event should not emit')); + + setTimeout(common.mustCall(() => { + assert.strictEqual(read.isPaused(), true); + }), common.platformTimeout(50)); +})); diff --git a/tests/node_compat/test/parallel/test-fs-mkdir.js b/tests/node_compat/test/parallel/test-fs-mkdir.js new file mode 100644 index 000000000..5a3897e91 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-mkdir.js @@ -0,0 +1,379 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.8.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +let dirc = 0; +function nextdir() { + return `test${++dirc}`; +} + +// fs.mkdir creates directory using assigned path +{ + const pathname = path.join(tmpdir.path, nextdir()); + + fs.mkdir(pathname, common.mustCall(function(err) { + assert.strictEqual(err, null); + assert.strictEqual(fs.existsSync(pathname), true); + })); +} + +// fs.mkdir creates directory with assigned mode value +{ + const pathname = path.join(tmpdir.path, nextdir()); + + fs.mkdir(pathname, 0o777, common.mustCall(function(err) { + assert.strictEqual(err, null); + assert.strictEqual(fs.existsSync(pathname), true); + })); +} + +// fs.mkdir creates directory with mode passed as an options object +{ + const pathname = path.join(tmpdir.path, nextdir()); + + fs.mkdir(pathname, common.mustNotMutateObjectDeep({ mode: 0o777 }), common.mustCall(function(err) { + assert.strictEqual(err, null); + assert.strictEqual(fs.existsSync(pathname), true); + })); +} + +// fs.mkdirSync creates directory with mode passed as an options object +{ + const pathname = path.join(tmpdir.path, nextdir()); + + fs.mkdirSync(pathname, common.mustNotMutateObjectDeep({ mode: 0o777 })); + + assert.strictEqual(fs.existsSync(pathname), true); +} + +// mkdirSync successfully creates directory from given path +{ + const pathname = path.join(tmpdir.path, nextdir()); + + fs.mkdirSync(pathname); + + const exists = fs.existsSync(pathname); + assert.strictEqual(exists, true); +} + +// mkdirSync and mkdir require path to be a string, buffer or url. +// Anything else generates an error. +[false, 1, {}, [], null, undefined].forEach((i) => { + assert.throws( + () => fs.mkdir(i, common.mustNotCall()), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + } + ); + assert.throws( + () => fs.mkdirSync(i), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + } + ); +}); + +// mkdirpSync when both top-level, and sub-folders do not exist. +{ + const pathname = path.join(tmpdir.path, nextdir(), nextdir()); + + fs.mkdirSync(pathname, common.mustNotMutateObjectDeep({ recursive: true })); + + const exists = fs.existsSync(pathname); + assert.strictEqual(exists, true); + assert.strictEqual(fs.statSync(pathname).isDirectory(), true); +} + +// mkdirpSync when folder already exists. +{ + const pathname = path.join(tmpdir.path, nextdir(), nextdir()); + + fs.mkdirSync(pathname, { recursive: true }); + // Should not cause an error. + fs.mkdirSync(pathname, { recursive: true }); + + const exists = fs.existsSync(pathname); + assert.strictEqual(exists, true); + assert.strictEqual(fs.statSync(pathname).isDirectory(), true); +} + +// mkdirpSync ../ +{ + const pathname = `${tmpdir.path}/${nextdir()}/../${nextdir()}/${nextdir()}`; + fs.mkdirSync(pathname, { recursive: true }); + const exists = fs.existsSync(pathname); + assert.strictEqual(exists, true); + assert.strictEqual(fs.statSync(pathname).isDirectory(), true); +} + +// mkdirpSync when path is a file. +{ + const pathname = path.join(tmpdir.path, nextdir(), nextdir()); + + fs.mkdirSync(path.dirname(pathname)); + fs.writeFileSync(pathname, '', 'utf8'); + + assert.throws( + () => { fs.mkdirSync(pathname, common.mustNotMutateObjectDeep({ recursive: true })); }, + { + code: 'EEXIST', + message: /EEXIST: .*mkdir/, + name: 'Error', + syscall: 'mkdir', + } + ); +} + +// mkdirpSync when part of the path is a file. +{ + const filename = path.join(tmpdir.path, nextdir(), nextdir()); + const pathname = path.join(filename, nextdir(), nextdir()); + + fs.mkdirSync(path.dirname(filename)); + fs.writeFileSync(filename, '', 'utf8'); + + assert.throws( + () => { fs.mkdirSync(pathname, { recursive: true }); }, + { + code: 'ENOTDIR', + message: /ENOTDIR: .*mkdir/, + name: 'Error', + syscall: 'mkdir', + path: pathname // See: https://github.com/nodejs/node/issues/28015 + } + ); +} + +// `mkdirp` when folder does not yet exist. +{ + const pathname = path.join(tmpdir.path, nextdir(), nextdir()); + + fs.mkdir(pathname, common.mustNotMutateObjectDeep({ recursive: true }), common.mustCall(function(err) { + assert.strictEqual(err, null); + assert.strictEqual(fs.existsSync(pathname), true); + assert.strictEqual(fs.statSync(pathname).isDirectory(), true); + })); +} + +// `mkdirp` when path is a file. +{ + const pathname = path.join(tmpdir.path, nextdir(), nextdir()); + + fs.mkdirSync(path.dirname(pathname)); + fs.writeFileSync(pathname, '', 'utf8'); + fs.mkdir(pathname, common.mustNotMutateObjectDeep({ recursive: true }), common.mustCall((err) => { + assert.strictEqual(err.code, 'EEXIST'); + // TODO(wafuwafu13): Enable this + // assert.strictEqual(err.syscall, 'mkdir'); + assert.strictEqual(fs.statSync(pathname).isDirectory(), false); + })); +} + +// `mkdirp` when part of the path is a file. +{ + const filename = path.join(tmpdir.path, nextdir(), nextdir()); + const pathname = path.join(filename, nextdir(), nextdir()); + + fs.mkdirSync(path.dirname(filename)); + fs.writeFileSync(filename, '', 'utf8'); + fs.mkdir(pathname, common.mustNotMutateObjectDeep({ recursive: true }), common.mustCall((err) => { + // TODO(wafuwafu13): Enable this + // assert.strictEqual(err.code, 'ENOTDIR'); + // assert.strictEqual(err.syscall, 'mkdir'); + assert.strictEqual(fs.existsSync(pathname), false); + // See: https://github.com/nodejs/node/issues/28015 + // The path field varies slightly in Windows errors, vs., other platforms + // see: https://github.com/libuv/libuv/issues/2661, for this reason we + // use startsWith() rather than comparing to the full "pathname". + // TODO(wafuwafu13): Enable this + // assert(err.path.startsWith(filename)); + })); +} + +// mkdirpSync dirname loop +// XXX: windows and smartos have issues removing a directory that you're in. +if (common.isMainThread && (common.isLinux || common.isOSX)) { + const pathname = path.join(tmpdir.path, nextdir()); + fs.mkdirSync(pathname); + process.chdir(pathname); + fs.rmdirSync(pathname); + assert.throws( + () => { fs.mkdirSync('X', common.mustNotMutateObjectDeep({ recursive: true })); }, + { + code: 'ENOENT', + message: /ENOENT: .*mkdir/, + name: 'Error', + syscall: 'mkdir', + } + ); + fs.mkdir('X', common.mustNotMutateObjectDeep({ recursive: true }), (err) => { + assert.strictEqual(err.code, 'ENOENT'); + // TODO(wafuwafu13): Enable this + // assert.strictEqual(err.syscall, 'mkdir'); + }); +} + +// mkdirSync and mkdir require options.recursive to be a boolean. +// Anything else generates an error. +{ + const pathname = path.join(tmpdir.path, nextdir()); + ['', 1, {}, [], null, Symbol('test'), () => {}].forEach((recursive) => { + const received = common.invalidArgTypeHelper(recursive); + assert.throws( + () => fs.mkdir(pathname, common.mustNotMutateObjectDeep({ recursive }), common.mustNotCall()), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "options.recursive" property must be of type boolean.' + + received + } + ); + assert.throws( + () => fs.mkdirSync(pathname, common.mustNotMutateObjectDeep({ recursive })), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "options.recursive" property must be of type boolean.' + + received + } + ); + }); +} + +// `mkdirp` returns first folder created, when all folders are new. +{ + const dir1 = nextdir(); + const dir2 = nextdir(); + const firstPathCreated = path.join(tmpdir.path, dir1); + const pathname = path.join(tmpdir.path, dir1, dir2); + + fs.mkdir(pathname, common.mustNotMutateObjectDeep({ recursive: true }), common.mustCall(function(err, path) { + assert.strictEqual(err, null); + assert.strictEqual(fs.existsSync(pathname), true); + assert.strictEqual(fs.statSync(pathname).isDirectory(), true); + // TODO(wafuwafu13): Enable this + // assert.strictEqual(path, firstPathCreated); + })); +} + +// `mkdirp` returns first folder created, when last folder is new. +{ + const dir1 = nextdir(); + const dir2 = nextdir(); + const pathname = path.join(tmpdir.path, dir1, dir2); + fs.mkdirSync(path.join(tmpdir.path, dir1)); + fs.mkdir(pathname, common.mustNotMutateObjectDeep({ recursive: true }), common.mustCall(function(err, path) { + assert.strictEqual(err, null); + assert.strictEqual(fs.existsSync(pathname), true); + assert.strictEqual(fs.statSync(pathname).isDirectory(), true); + // TODO(wafuwafu13): Enable this + // assert.strictEqual(path, pathname); + })); +} + +// `mkdirp` returns undefined, when no new folders are created. +{ + const dir1 = nextdir(); + const dir2 = nextdir(); + const pathname = path.join(tmpdir.path, dir1, dir2); + fs.mkdirSync(path.join(tmpdir.path, dir1, dir2), common.mustNotMutateObjectDeep({ recursive: true })); + fs.mkdir(pathname, common.mustNotMutateObjectDeep({ recursive: true }), common.mustCall(function(err, path) { + assert.strictEqual(err, null); + assert.strictEqual(fs.existsSync(pathname), true); + assert.strictEqual(fs.statSync(pathname).isDirectory(), true); + assert.strictEqual(path, undefined); + })); +} + +// `mkdirp.sync` returns first folder created, when all folders are new. +{ + const dir1 = nextdir(); + const dir2 = nextdir(); + const firstPathCreated = path.join(tmpdir.path, dir1); + const pathname = path.join(tmpdir.path, dir1, dir2); + const p = fs.mkdirSync(pathname, common.mustNotMutateObjectDeep({ recursive: true })); + assert.strictEqual(fs.existsSync(pathname), true); + assert.strictEqual(fs.statSync(pathname).isDirectory(), true); + // TODO(wafuwafu13): Enable this + // assert.strictEqual(p, firstPathCreated); +} + +// `mkdirp.sync` returns first folder created, when last folder is new. +{ + const dir1 = nextdir(); + const dir2 = nextdir(); + const pathname = path.join(tmpdir.path, dir1, dir2); + fs.mkdirSync(path.join(tmpdir.path, dir1), common.mustNotMutateObjectDeep({ recursive: true })); + const p = fs.mkdirSync(pathname, common.mustNotMutateObjectDeep({ recursive: true })); + assert.strictEqual(fs.existsSync(pathname), true); + assert.strictEqual(fs.statSync(pathname).isDirectory(), true); + // TODO(wafuwafu13): Enable this + // assert.strictEqual(p, pathname); +} + +// `mkdirp.sync` returns undefined, when no new folders are created. +{ + const dir1 = nextdir(); + const dir2 = nextdir(); + const pathname = path.join(tmpdir.path, dir1, dir2); + fs.mkdirSync(path.join(tmpdir.path, dir1, dir2), common.mustNotMutateObjectDeep({ recursive: true })); + const p = fs.mkdirSync(pathname, common.mustNotMutateObjectDeep({ recursive: true })); + assert.strictEqual(fs.existsSync(pathname), true); + assert.strictEqual(fs.statSync(pathname).isDirectory(), true); + assert.strictEqual(p, undefined); +} + +// `mkdirp.promises` returns first folder created, when all folders are new. +{ + const dir1 = nextdir(); + const dir2 = nextdir(); + const firstPathCreated = path.join(tmpdir.path, dir1); + const pathname = path.join(tmpdir.path, dir1, dir2); + async function testCase() { + const p = await fs.promises.mkdir(pathname, common.mustNotMutateObjectDeep({ recursive: true })); + assert.strictEqual(fs.existsSync(pathname), true); + assert.strictEqual(fs.statSync(pathname).isDirectory(), true); + // TODO(wafuwafu13): Enable this + // assert.strictEqual(p, firstPathCreated); + } + testCase(); +} + +// Keep the event loop alive so the async mkdir() requests +// have a chance to run (since they don't ref the event loop). +process.nextTick(() => {}); diff --git a/tests/node_compat/test/parallel/test-fs-open-flags.js b/tests/node_compat/test/parallel/test-fs-open-flags.js new file mode 100644 index 000000000..532194e06 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-open-flags.js @@ -0,0 +1,101 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// Flags: --expose-internals +'use strict'; +const common = require('../common'); + +const fixtures = require('../common/fixtures'); + +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); + +// 0 if not found in fs.constants +const { O_APPEND = 0, + O_CREAT = 0, + O_EXCL = 0, + O_RDONLY = 0, + O_RDWR = 0, + O_SYNC = 0, + O_DSYNC = 0, + O_TRUNC = 0, + O_WRONLY = 0 } = fs.constants; + +const { stringToFlags } = require('internal/fs/utils'); + +assert.strictEqual(stringToFlags('r'), O_RDONLY); +assert.strictEqual(stringToFlags('r+'), O_RDWR); +assert.strictEqual(stringToFlags('rs+'), O_RDWR | O_SYNC); +assert.strictEqual(stringToFlags('sr+'), O_RDWR | O_SYNC); +assert.strictEqual(stringToFlags('w'), O_TRUNC | O_CREAT | O_WRONLY); +assert.strictEqual(stringToFlags('w+'), O_TRUNC | O_CREAT | O_RDWR); +assert.strictEqual(stringToFlags('a'), O_APPEND | O_CREAT | O_WRONLY); +assert.strictEqual(stringToFlags('a+'), O_APPEND | O_CREAT | O_RDWR); + +assert.strictEqual(stringToFlags('wx'), O_TRUNC | O_CREAT | O_WRONLY | O_EXCL); +assert.strictEqual(stringToFlags('xw'), O_TRUNC | O_CREAT | O_WRONLY | O_EXCL); +assert.strictEqual(stringToFlags('wx+'), O_TRUNC | O_CREAT | O_RDWR | O_EXCL); +assert.strictEqual(stringToFlags('xw+'), O_TRUNC | O_CREAT | O_RDWR | O_EXCL); +assert.strictEqual(stringToFlags('ax'), O_APPEND | O_CREAT | O_WRONLY | O_EXCL); +assert.strictEqual(stringToFlags('xa'), O_APPEND | O_CREAT | O_WRONLY | O_EXCL); +assert.strictEqual(stringToFlags('as'), O_APPEND | O_CREAT | O_WRONLY | O_SYNC); +assert.strictEqual(stringToFlags('sa'), O_APPEND | O_CREAT | O_WRONLY | O_SYNC); +assert.strictEqual(stringToFlags('ax+'), O_APPEND | O_CREAT | O_RDWR | O_EXCL); +assert.strictEqual(stringToFlags('xa+'), O_APPEND | O_CREAT | O_RDWR | O_EXCL); +assert.strictEqual(stringToFlags('as+'), O_APPEND | O_CREAT | O_RDWR | O_SYNC); +assert.strictEqual(stringToFlags('sa+'), O_APPEND | O_CREAT | O_RDWR | O_SYNC); + +('+ +a +r +w rw wa war raw r++ a++ w++ x +x x+ rx rx+ wxx wax xwx xxx') + .split(' ') + .forEach(function(flags) { + assert.throws( + () => stringToFlags(flags), + { code: 'ERR_INVALID_ARG_VALUE', name: 'TypeError' } + ); + }); + +assert.throws( + () => stringToFlags({}), + { code: 'ERR_INVALID_ARG_VALUE', name: 'TypeError' } +); + +assert.throws( + () => stringToFlags(true), + { code: 'ERR_INVALID_ARG_VALUE', name: 'TypeError' } +); + +if (common.isLinux || common.isOSX) { + const tmpdir = require('../common/tmpdir'); + tmpdir.refresh(); + const file = path.join(tmpdir.path, 'a.js'); + fs.copyFileSync(fixtures.path('a.js'), file); + fs.open(file, O_DSYNC, common.mustSucceed((fd) => { + fs.closeSync(fd); + })); +} diff --git a/tests/node_compat/test/parallel/test-fs-open-mode-mask.js b/tests/node_compat/test/parallel/test-fs-open-mode-mask.js new file mode 100644 index 000000000..4b56b3b38 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-open-mode-mask.js @@ -0,0 +1,48 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +// This tests that the lower bits of mode > 0o777 still works in fs.open(). + +const common = require('../common'); +const assert = require('assert'); +const path = require('path'); +const fs = require('fs'); + +const mode = common.isWindows ? 0o444 : 0o644; + +const maskToIgnore = 0o10000; + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +function test(mode, asString) { + const suffix = asString ? 'str' : 'num'; + const input = asString ? + (mode | maskToIgnore).toString(8) : (mode | maskToIgnore); + + { + const file = path.join(tmpdir.path, `openSync-${suffix}.txt`); + const fd = fs.openSync(file, 'w+', input); + assert.strictEqual(fs.fstatSync(fd).mode & 0o777, mode); + fs.closeSync(fd); + assert.strictEqual(fs.statSync(file).mode & 0o777, mode); + } + + { + const file = path.join(tmpdir.path, `open-${suffix}.txt`); + fs.open(file, 'w+', input, common.mustSucceed((fd) => { + assert.strictEqual(fs.fstatSync(fd).mode & 0o777, mode); + fs.closeSync(fd); + assert.strictEqual(fs.statSync(file).mode & 0o777, mode); + })); + } +} + +test(mode, true); +test(mode, false); diff --git a/tests/node_compat/test/parallel/test-fs-open-no-close.js b/tests/node_compat/test/parallel/test-fs-open-no-close.js new file mode 100644 index 000000000..abde2ad07 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-open-no-close.js @@ -0,0 +1,38 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +// Refs: https://github.com/nodejs/node/issues/34266 +// Failing to close a file should not keep the event loop open. + +const common = require('../common'); +const assert = require('assert'); + +const fs = require('fs'); + +const debuglog = (arg) => { + console.log(new Date().toLocaleString(), arg); +}; + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +let openFd; + +fs.open(`${tmpdir.path}/dummy`, 'wx+', common.mustCall((err, fd) => { + debuglog('fs open() callback'); + assert.ifError(err); + openFd = fd; +})); +debuglog('waiting for callback'); + +process.on('beforeExit', common.mustCall(() => { + if (openFd) { + fs.closeSync(openFd); + } +})); diff --git a/tests/node_compat/test/parallel/test-fs-open-numeric-flags.js b/tests/node_compat/test/parallel/test-fs-open-numeric-flags.js new file mode 100644 index 000000000..3e8efde82 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-open-numeric-flags.js @@ -0,0 +1,23 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); + +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +// O_WRONLY without O_CREAT shall fail with ENOENT +const pathNE = path.join(tmpdir.path, 'file-should-not-exist'); +assert.throws( + () => fs.openSync(pathNE, fs.constants.O_WRONLY), + (e) => e.code === 'ENOENT' +); diff --git a/tests/node_compat/test/parallel/test-fs-open.js b/tests/node_compat/test/parallel/test-fs-open.js new file mode 100644 index 000000000..631e96a2e --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-open.js @@ -0,0 +1,128 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.8.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const fs = require('fs'); + +let caughtException = false; + +try { + // Should throw ENOENT, not EBADF + // see https://github.com/joyent/node/pull/1228 + fs.openSync('/8hvftyuncxrt/path/to/file/that/does/not/exist', 'r'); +} catch (e) { + assert.strictEqual(e.code, 'ENOENT'); + caughtException = true; +} +assert.strictEqual(caughtException, true); + +fs.openSync(__filename); + +fs.open(__filename, common.mustSucceed()); + +fs.open(__filename, 'r', common.mustSucceed()); + +// TODO(wafuwafu13): Support 'rs' flag +// fs.open(__filename, 'rs', common.mustSucceed()); + +fs.open(__filename, 'r', 0, common.mustSucceed()); + +fs.open(__filename, 'r', null, common.mustSucceed()); + +async function promise() { + await fs.promises.open(__filename); + await fs.promises.open(__filename, 'r'); +} + +promise().then(common.mustCall()).catch(common.mustNotCall()); + +assert.throws( + () => fs.open(__filename, 'r', 'boom', common.mustNotCall()), + { + code: 'ERR_INVALID_ARG_VALUE', + name: 'TypeError' + } +); + +for (const extra of [[], ['r'], ['r', 0], ['r', 0, 'bad callback']]) { + assert.throws( + () => fs.open(__filename, ...extra), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + } + ); +} + +[false, 1, [], {}, null, undefined].forEach((i) => { + assert.throws( + () => fs.open(i, 'r', common.mustNotCall()), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + } + ); + assert.throws( + () => fs.openSync(i, 'r', common.mustNotCall()), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + } + ); + assert.rejects( + fs.promises.open(i, 'r'), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + } + ); +}); + +// Check invalid modes. +[false, [], {}].forEach((mode) => { + assert.throws( + () => fs.open(__filename, 'r', mode, common.mustNotCall()), + { + code: 'ERR_INVALID_ARG_TYPE' + } + ); + assert.throws( + () => fs.openSync(__filename, 'r', mode, common.mustNotCall()), + { + code: 'ERR_INVALID_ARG_TYPE' + } + ); + assert.rejects( + fs.promises.open(__filename, 'r', mode), + { + code: 'ERR_INVALID_ARG_TYPE' + } + ); +}); diff --git a/tests/node_compat/test/parallel/test-fs-opendir.js b/tests/node_compat/test/parallel/test-fs-opendir.js new file mode 100644 index 000000000..75c4aa074 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-opendir.js @@ -0,0 +1,300 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.8.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); + +const tmpdir = require('../common/tmpdir'); + +const testDir = tmpdir.path; +const files = ['empty', 'files', 'for', 'just', 'testing']; + +// Make sure tmp directory is clean +tmpdir.refresh(); + +// Create the necessary files +files.forEach(function(filename) { + fs.closeSync(fs.openSync(path.join(testDir, filename), 'w')); +}); + +function assertDirent(dirent) { + assert(dirent instanceof fs.Dirent); + assert.strictEqual(dirent.isFile(), true); + assert.strictEqual(dirent.isDirectory(), false); + // TODO(wafuwafu13): Support these method + // assert.strictEqual(dirent.isSocket(), false); + // assert.strictEqual(dirent.isBlockDevice(), false); + // assert.strictEqual(dirent.isCharacterDevice(), false); + // assert.strictEqual(dirent.isFIFO(), false); + assert.strictEqual(dirent.isSymbolicLink(), false); +} + +// NOTE: this error doesn't occur in Deno +const dirclosedError = { + code: 'ERR_DIR_CLOSED' +}; + +// NOTE: this error doesn't occur in Deno +const dirconcurrentError = { + code: 'ERR_DIR_CONCURRENT_OPERATION' +}; + +const invalidCallbackObj = { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' +}; + +// Check the opendir Sync version +{ + const dir = fs.opendirSync(testDir); + const entries = files.map(() => { + const dirent = dir.readSync(); + assertDirent(dirent); + return dirent.name; + }); + assert.deepStrictEqual(files, entries.sort()); + + // dir.read should return null when no more entries exist + assert.strictEqual(dir.readSync(), null); + + // check .path + assert.strictEqual(dir.path, testDir); + + dir.closeSync(); + + // assert.throws(() => dir.readSync(), dirclosedError); + // assert.throws(() => dir.closeSync(), dirclosedError); +} + +// Check the opendir async version +fs.opendir(testDir, common.mustSucceed((dir) => { + let sync = true; + dir.read(common.mustSucceed((dirent) => { + assert(!sync); + + // Order is operating / file system dependent + assert(files.includes(dirent.name), `'files' should include ${dirent}`); + assertDirent(dirent); + + let syncInner = true; + dir.read(common.mustSucceed((dirent) => { + assert(!syncInner); + + dir.close(common.mustSucceed()); + })); + syncInner = false; + })); + sync = false; +})); + +// opendir() on file should throw ENOTDIR +assert.throws(function() { + fs.opendirSync(__filename); +}, /Error: ENOTDIR: not a directory/); + +assert.throws(function() { + fs.opendir(__filename); +}, /TypeError \[ERR_INVALID_ARG_TYPE\]: The "callback" argument must be of type function/); + +fs.opendir(__filename, common.mustCall(function(e) { + assert.strictEqual(e.code, 'ENOTDIR'); +})); + +[false, 1, [], {}, null, undefined].forEach((i) => { + assert.throws( + () => fs.opendir(i, common.mustNotCall()), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + } + ); + assert.throws( + () => fs.opendirSync(i), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + } + ); +}); + +// Promise-based tests +async function doPromiseTest() { + // Check the opendir Promise version + const dir = await fs.promises.opendir(testDir); + const entries = []; + + let i = files.length; + while (i--) { + const dirent = await dir.read(); + entries.push(dirent.name); + assertDirent(dirent); + } + + assert.deepStrictEqual(files, entries.sort()); + + // dir.read should return null when no more entries exist + assert.strictEqual(await dir.read(), null); + + await dir.close(); +} +doPromiseTest().then(common.mustCall()); + +// Async iterator +async function doAsyncIterTest() { + const entries = []; + for await (const dirent of await fs.promises.opendir(testDir)) { + entries.push(dirent.name); + assertDirent(dirent); + } + + assert.deepStrictEqual(files, entries.sort()); + + // Automatically closed during iterator +} +doAsyncIterTest().then(common.mustCall()); + +// Async iterators should do automatic cleanup + +async function doAsyncIterBreakTest() { + const dir = await fs.promises.opendir(testDir); + for await (const dirent of dir) { // eslint-disable-line no-unused-vars + break; + } + + // await assert.rejects(async () => dir.read(), dirclosedError); +} +doAsyncIterBreakTest().then(common.mustCall()); + +async function doAsyncIterReturnTest() { + const dir = await fs.promises.opendir(testDir); + await (async function() { + for await (const dirent of dir) { + return; + } + })(); + + // await assert.rejects(async () => dir.read(), dirclosedError); +} +doAsyncIterReturnTest().then(common.mustCall()); + +async function doAsyncIterThrowTest() { + const dir = await fs.promises.opendir(testDir); + try { + for await (const dirent of dir) { // eslint-disable-line no-unused-vars + throw new Error('oh no'); + } + } catch (err) { + if (err.message !== 'oh no') { + throw err; + } + } + + // await assert.rejects(async () => dir.read(), dirclosedError); +} +doAsyncIterThrowTest().then(common.mustCall()); + +// Check error thrown on invalid values of bufferSize +for (const bufferSize of [-1, 0, 0.5, 1.5, Infinity, NaN]) { + assert.throws( + () => fs.opendirSync(testDir, common.mustNotMutateObjectDeep({ bufferSize })), + { + code: 'ERR_OUT_OF_RANGE' + }); +} +for (const bufferSize of ['', '1', null]) { + assert.throws( + () => fs.opendirSync(testDir, common.mustNotMutateObjectDeep({ bufferSize })), + { + code: 'ERR_INVALID_ARG_TYPE' + }); +} + +// Check that passing a positive integer as bufferSize works +{ + const dir = fs.opendirSync(testDir, common.mustNotMutateObjectDeep({ bufferSize: 1024 })); + assertDirent(dir.readSync()); + dir.close(); +} + +// TODO(wafuwafu13): enable this +// // Check that when passing a string instead of function - throw an exception +// async function doAsyncIterInvalidCallbackTest() { +// const dir = await fs.promises.opendir(testDir); +// assert.throws(() => dir.close('not function'), invalidCallbackObj); +// } +// doAsyncIterInvalidCallbackTest().then(common.mustCall()); + +// Check first call to close() - should not report an error. +async function doAsyncIterDirClosedTest() { + const dir = await fs.promises.opendir(testDir); + await dir.close(); + // await assert.rejects(() => dir.close(), dirclosedError); +} +doAsyncIterDirClosedTest().then(common.mustCall()); + +// Check that readSync() and closeSync() during read() throw exceptions +async function doConcurrentAsyncAndSyncOps() { + const dir = await fs.promises.opendir(testDir); + const promise = dir.read(); + + // assert.throws(() => dir.closeSync(), dirconcurrentError); + // assert.throws(() => dir.readSync(), dirconcurrentError); + + await promise; + dir.closeSync(); +} +doConcurrentAsyncAndSyncOps().then(common.mustCall()); + +// TODO(wafuwafu13): enable this +// // Check read throw exceptions on invalid callback +// { +// const dir = fs.opendirSync(testDir); +// assert.throws(() => dir.read('INVALID_CALLBACK'), /ERR_INVALID_ARG_TYPE/); +// } + +// Check that concurrent read() operations don't do weird things. +async function doConcurrentAsyncOps() { + const dir = await fs.promises.opendir(testDir); + const promise1 = dir.read(); + const promise2 = dir.read(); + + assertDirent(await promise1); + assertDirent(await promise2); + dir.closeSync(); +} +doConcurrentAsyncOps().then(common.mustCall()); + +// Check that concurrent read() + close() operations don't do weird things. +async function doConcurrentAsyncMixedOps() { + const dir = await fs.promises.opendir(testDir); + const promise1 = dir.read(); + const promise2 = dir.close(); + + assertDirent(await promise1); + await promise2; +} +doConcurrentAsyncMixedOps().then(common.mustCall()); + +// Check if directory already closed - the callback should pass an error. +{ + const dir = fs.opendirSync(testDir); + dir.closeSync(); + dir.close(common.mustCall((error) => { + // assert.strictEqual(error.code, dirclosedError.code); + })); +} + +// Check if directory already closed - throw an promise exception. +{ + const dir = fs.opendirSync(testDir); + dir.closeSync(); + // assert.rejects(dir.close(), dirclosedError).then(common.mustCall()); +} diff --git a/tests/node_compat/test/parallel/test-fs-read-stream-autoClose.js b/tests/node_compat/test/parallel/test-fs-read-stream-autoClose.js new file mode 100644 index 000000000..aaa8b42e8 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-read-stream-autoClose.js @@ -0,0 +1,23 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const fs = require('fs'); +const path = require('path'); +const assert = require('assert'); +const tmpdir = require('../common/tmpdir'); +const writeFile = path.join(tmpdir.path, 'write-autoClose.txt'); +tmpdir.refresh(); + +const file = fs.createWriteStream(writeFile, { autoClose: true }); + +file.on('finish', common.mustCall(() => { + assert.strictEqual(file.destroyed, false); +})); +file.end('asd'); diff --git a/tests/node_compat/test/parallel/test-fs-read-stream-concurrent-reads.js b/tests/node_compat/test/parallel/test-fs-read-stream-concurrent-reads.js new file mode 100644 index 000000000..ac52d66a8 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-read-stream-concurrent-reads.js @@ -0,0 +1,54 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const fixtures = require('../common/fixtures'); +const assert = require('assert'); +const fs = require('fs'); + +// Test that concurrent file read streams don’t interfere with each other’s +// contents, and that the chunks generated by the reads only retain a +// 'reasonable' amount of memory. + +// Refs: https://github.com/nodejs/node/issues/21967 + +const filename = fixtures.path('loop.js'); // Some small non-homogeneous file. +const content = fs.readFileSync(filename); + +const N = 2000; +let started = 0; +let done = 0; + +const arrayBuffers = new Set(); + +function startRead() { + ++started; + const chunks = []; + fs.createReadStream(filename) + .on('data', (chunk) => { + chunks.push(chunk); + arrayBuffers.add(chunk.buffer); + }) + .on('end', common.mustCall(() => { + if (started < N) + startRead(); + assert.deepStrictEqual(Buffer.concat(chunks), content); + if (++done === N) { + const retainedMemory = + [...arrayBuffers].map((ab) => ab.byteLength).reduce((a, b) => a + b); + assert(retainedMemory / (N * content.length) <= 3, + `Retaining ${retainedMemory} bytes in ABs for ${N} ` + + `chunks of size ${content.length}`); + } + })); +} + +// Don’t start the reads all at once – that way we would have to allocate +// a large amount of memory upfront. +for (let i = 0; i < 6; ++i) + startRead(); diff --git a/tests/node_compat/test/parallel/test-fs-read-stream-double-close.js b/tests/node_compat/test/parallel/test-fs-read-stream-double-close.js new file mode 100644 index 000000000..1706dd515 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-read-stream-double-close.js @@ -0,0 +1,26 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const fs = require('fs'); + +{ + const s = fs.createReadStream(__filename); + + s.close(common.mustCall()); + s.close(common.mustCall()); +} + +{ + const s = fs.createReadStream(__filename); + + // This is a private API, but it is worth testing. close calls this + s.destroy(null, common.mustCall()); + s.destroy(null, common.mustCall()); +} diff --git a/tests/node_compat/test/parallel/test-fs-read-stream-encoding.js b/tests/node_compat/test/parallel/test-fs-read-stream-encoding.js new file mode 100644 index 000000000..c3adee739 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-read-stream-encoding.js @@ -0,0 +1,24 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const assert = require('assert'); +const fs = require('fs'); +const stream = require('stream'); +const fixtures = require('../common/fixtures'); +const encoding = 'base64'; + +const example = fixtures.path('x.txt'); +const assertStream = new stream.Writable({ + write: function(chunk, enc, next) { + const expected = Buffer.from('xyz'); + assert(chunk.equals(expected)); + } +}); +assertStream.setDefaultEncoding(encoding); +fs.createReadStream(example, encoding).pipe(assertStream); diff --git a/tests/node_compat/test/parallel/test-fs-read-stream-fd.js b/tests/node_compat/test/parallel/test-fs-read-stream-fd.js new file mode 100644 index 000000000..467c48b8d --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-read-stream-fd.js @@ -0,0 +1,53 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const fs = require('fs'); +const assert = require('assert'); +const path = require('path'); +const tmpdir = require('../common/tmpdir'); +const file = path.join(tmpdir.path, '/read_stream_fd_test.txt'); +const input = 'hello world'; + +let output = ''; +tmpdir.refresh(); +fs.writeFileSync(file, input); + +const fd = fs.openSync(file, 'r'); +const stream = fs.createReadStream(null, { fd: fd, encoding: 'utf8' }); + +assert.strictEqual(stream.path, undefined); + +stream.on('data', common.mustCallAtLeast((data) => { + output += data; +})); + +process.on('exit', () => { + assert.strictEqual(output, input); +}); diff --git a/tests/node_compat/test/parallel/test-fs-read-stream-inherit.js b/tests/node_compat/test/parallel/test-fs-read-stream-inherit.js new file mode 100644 index 000000000..2de42ffb5 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-read-stream-inherit.js @@ -0,0 +1,212 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); + +const assert = require('assert'); +const fs = require('fs'); +const fixtures = require('../common/fixtures'); + +const fn = fixtures.path('elipses.txt'); +const rangeFile = fixtures.path('x.txt'); + +{ + let paused = false; + + const file = fs.ReadStream(fn); + + file.on('open', common.mustCall(function(fd) { + file.length = 0; + assert.strictEqual(typeof fd, 'number'); + assert.ok(file.readable); + + // GH-535 + file.pause(); + file.resume(); + file.pause(); + file.resume(); + })); + + file.on('data', common.mustCallAtLeast(function(data) { + assert.ok(data instanceof Buffer); + assert.ok(!paused); + file.length += data.length; + + paused = true; + file.pause(); + + setTimeout(function() { + paused = false; + file.resume(); + }, 10); + })); + + + file.on('end', common.mustCall()); + + + file.on('close', common.mustCall(function() { + assert.strictEqual(file.length, 30000); + })); +} + +{ + const file = fs.createReadStream(fn, Object.create({ encoding: 'utf8' })); + file.length = 0; + file.on('data', function(data) { + assert.strictEqual(typeof data, 'string'); + file.length += data.length; + + for (let i = 0; i < data.length; i++) { + // http://www.fileformat.info/info/unicode/char/2026/index.htm + assert.strictEqual(data[i], '\u2026'); + } + }); + + file.on('close', common.mustCall(function() { + assert.strictEqual(file.length, 10000); + })); +} + +{ + const options = Object.create({ bufferSize: 1, start: 1, end: 2 }); + const file = fs.createReadStream(rangeFile, options); + assert.strictEqual(file.start, 1); + assert.strictEqual(file.end, 2); + let contentRead = ''; + file.on('data', function(data) { + contentRead += data.toString('utf-8'); + }); + file.on('end', common.mustCall(function() { + assert.strictEqual(contentRead, 'yz'); + })); +} + +{ + const options = Object.create({ bufferSize: 1, start: 1 }); + const file = fs.createReadStream(rangeFile, options); + assert.strictEqual(file.start, 1); + file.data = ''; + file.on('data', function(data) { + file.data += data.toString('utf-8'); + }); + file.on('end', common.mustCall(function() { + assert.strictEqual(file.data, 'yz\n'); + })); +} + +// https://github.com/joyent/node/issues/2320 +{ + const options = Object.create({ bufferSize: 1.23, start: 1 }); + const file = fs.createReadStream(rangeFile, options); + assert.strictEqual(file.start, 1); + file.data = ''; + file.on('data', function(data) { + file.data += data.toString('utf-8'); + }); + file.on('end', common.mustCall(function() { + assert.strictEqual(file.data, 'yz\n'); + })); +} + +{ + const message = + 'The value of "start" is out of range. It must be <= "end" (here: 2).' + + ' Received 10'; + + assert.throws( + () => { + fs.createReadStream(rangeFile, Object.create({ start: 10, end: 2 })); + }, + { + code: 'ERR_OUT_OF_RANGE', + message, + name: 'RangeError' + }); +} + +{ + const options = Object.create({ start: 0, end: 0 }); + const stream = fs.createReadStream(rangeFile, options); + assert.strictEqual(stream.start, 0); + assert.strictEqual(stream.end, 0); + stream.data = ''; + + stream.on('data', function(chunk) { + stream.data += chunk; + }); + + stream.on('end', common.mustCall(function() { + assert.strictEqual(stream.data, 'x'); + })); +} + +// Pause and then resume immediately. +{ + const pauseRes = fs.createReadStream(rangeFile); + pauseRes.pause(); + pauseRes.resume(); +} + +{ + let data = ''; + let file = + fs.createReadStream(rangeFile, Object.create({ autoClose: false })); + assert.strictEqual(file.autoClose, false); + file.on('data', (chunk) => { data += chunk; }); + file.on('end', common.mustCall(function() { + process.nextTick(common.mustCall(function() { + assert(!file.closed); + assert(!file.destroyed); + assert.strictEqual(data, 'xyz\n'); + fileNext(); + })); + })); + + function fileNext() { + // This will tell us if the fd is usable again or not. + file = fs.createReadStream(null, Object.create({ fd: file.fd, start: 0 })); + file.data = ''; + file.on('data', function(data) { + file.data += data; + }); + file.on('end', common.mustCall(function() { + assert.strictEqual(file.data, 'xyz\n'); + })); + } + process.on('exit', function() { + assert(file.closed); + assert(file.destroyed); + }); +} + +// Just to make sure autoClose won't close the stream because of error. +{ + const options = Object.create({ fd: 13337, autoClose: false }); + const file = fs.createReadStream(null, options); + file.on('data', common.mustNotCall()); + file.on('error', common.mustCall()); + process.on('exit', function() { + assert(!file.closed); + assert(!file.destroyed); + assert(file.fd); + }); +} + +// Make sure stream is destroyed when file does not exist. +{ + const file = fs.createReadStream('/path/to/file/that/does/not/exist'); + file.on('data', common.mustNotCall()); + file.on('error', common.mustCall()); + + process.on('exit', function() { + assert(file.closed); + assert(file.destroyed); + }); +} diff --git a/tests/node_compat/test/parallel/test-fs-read-stream-patch-open.js b/tests/node_compat/test/parallel/test-fs-read-stream-patch-open.js new file mode 100644 index 000000000..2f9788894 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-read-stream-patch-open.js @@ -0,0 +1,24 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const fs = require('fs'); + +common.expectWarning( + 'DeprecationWarning', + 'ReadStream.prototype.open() is deprecated', 'DEP0135'); +const s = fs.createReadStream('asd') + // We don't care about errors in this test. + .on('error', () => {}); +s.open(); + +process.nextTick(() => { + // Allow overriding open(). + fs.ReadStream.prototype.open = common.mustCall(); + fs.createReadStream('asd'); +}); diff --git a/tests/node_compat/test/parallel/test-fs-read-stream-resume.js b/tests/node_compat/test/parallel/test-fs-read-stream-resume.js new file mode 100644 index 000000000..50ec85603 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-read-stream-resume.js @@ -0,0 +1,59 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const fixtures = require('../common/fixtures'); +const assert = require('assert'); + +const fs = require('fs'); + +const file = fixtures.path('x.txt'); +let data = ''; +let first = true; + +const stream = fs.createReadStream(file); +stream.setEncoding('utf8'); +stream.on('data', common.mustCallAtLeast(function(chunk) { + data += chunk; + if (first) { + first = false; + stream.resume(); + } +})); + +process.nextTick(function() { + stream.pause(); + setTimeout(function() { + stream.resume(); + }, 100); +}); + +process.on('exit', function() { + assert.strictEqual(data, 'xyz\n'); +}); diff --git a/tests/node_compat/test/parallel/test-fs-read-stream-throw-type-error.js b/tests/node_compat/test/parallel/test-fs-read-stream-throw-type-error.js new file mode 100644 index 000000000..4dda1150f --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-read-stream-throw-type-error.js @@ -0,0 +1,84 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const fixtures = require('../common/fixtures'); +const assert = require('assert'); +const fs = require('fs'); + +// This test ensures that appropriate TypeError is thrown by createReadStream +// when an argument with invalid type is passed + +const example = fixtures.path('x.txt'); +// Should not throw. +fs.createReadStream(example, undefined); +fs.createReadStream(example, null); +fs.createReadStream(example, 'utf8'); +fs.createReadStream(example, { encoding: 'utf8' }); + +const createReadStreamErr = (path, opt, error) => { + assert.throws(() => { + fs.createReadStream(path, opt); + }, error); +}; + +const typeError = { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' +}; + +const rangeError = { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError' +}; + +[123, 0, true, false].forEach((opts) => + createReadStreamErr(example, opts, typeError) +); + +// Case 0: Should not throw if either start or end is undefined +[{}, { start: 0 }, { end: Infinity }].forEach((opts) => + fs.createReadStream(example, opts) +); + +// Case 1: Should throw TypeError if either start or end is not of type 'number' +[ + { start: 'invalid' }, + { end: 'invalid' }, + { start: 'invalid', end: 'invalid' }, +].forEach((opts) => createReadStreamErr(example, opts, typeError)); + +// Case 2: Should throw RangeError if either start or end is NaN +[{ start: NaN }, { end: NaN }, { start: NaN, end: NaN }].forEach((opts) => + createReadStreamErr(example, opts, rangeError) +); + +// Case 3: Should throw RangeError if either start or end is negative +[{ start: -1 }, { end: -1 }, { start: -1, end: -1 }].forEach((opts) => + createReadStreamErr(example, opts, rangeError) +); + +// Case 4: Should throw RangeError if either start or end is fractional +[{ start: 0.1 }, { end: 0.1 }, { start: 0.1, end: 0.1 }].forEach((opts) => + createReadStreamErr(example, opts, rangeError) +); + +// Case 5: Should not throw if both start and end are whole numbers +fs.createReadStream(example, { start: 1, end: 5 }); + +// Case 6: Should throw RangeError if start is greater than end +createReadStreamErr(example, { start: 5, end: 1 }, rangeError); + +// Case 7: Should throw RangeError if start or end is not safe integer +const NOT_SAFE_INTEGER = 2 ** 53; +[ + { start: NOT_SAFE_INTEGER, end: Infinity }, + { start: 0, end: NOT_SAFE_INTEGER }, +].forEach((opts) => + createReadStreamErr(example, opts, rangeError) +); diff --git a/tests/node_compat/test/parallel/test-fs-read-stream.js b/tests/node_compat/test/parallel/test-fs-read-stream.js new file mode 100644 index 000000000..e42347264 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-read-stream.js @@ -0,0 +1,284 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const tmpdir = require('../common/tmpdir'); + +const child_process = require('child_process'); +const assert = require('assert'); +const fs = require('fs'); +const fixtures = require('../common/fixtures'); + +const fn = fixtures.path('elipses.txt'); +const rangeFile = fixtures.path('x.txt'); + +function test1(options) { + let paused = false; + let bytesRead = 0; + + const file = fs.createReadStream(fn, options); + const fileSize = fs.statSync(fn).size; + + assert.strictEqual(file.bytesRead, 0); + + file.on('open', common.mustCall(function(fd) { + file.length = 0; + assert.strictEqual(typeof fd, 'number'); + assert.strictEqual(file.bytesRead, 0); + assert.ok(file.readable); + + // GH-535 + file.pause(); + file.resume(); + file.pause(); + file.resume(); + })); + + file.on('data', function(data) { + assert.ok(data instanceof Buffer); + assert.ok(data.byteOffset % 8 === 0); + assert.ok(!paused); + file.length += data.length; + + bytesRead += data.length; + assert.strictEqual(file.bytesRead, bytesRead); + + paused = true; + file.pause(); + + setTimeout(function() { + paused = false; + file.resume(); + }, 10); + }); + + + file.on('end', common.mustCall(function(chunk) { + assert.strictEqual(bytesRead, fileSize); + assert.strictEqual(file.bytesRead, fileSize); + })); + + + file.on('close', common.mustCall(function() { + assert.strictEqual(bytesRead, fileSize); + assert.strictEqual(file.bytesRead, fileSize); + })); + + process.on('exit', function() { + assert.strictEqual(file.length, 30000); + }); +} + +test1({}); +test1({ + fs: { + open: common.mustCall(fs.open), + read: common.mustCallAtLeast(fs.read, 1), + close: common.mustCall(fs.close), + } +}); + +{ + const file = fs.createReadStream(fn, common.mustNotMutateObjectDeep({ encoding: 'utf8' })); + file.length = 0; + file.on('data', function(data) { + assert.strictEqual(typeof data, 'string'); + file.length += data.length; + + for (let i = 0; i < data.length; i++) { + // http://www.fileformat.info/info/unicode/char/2026/index.htm + assert.strictEqual(data[i], '\u2026'); + } + }); + + file.on('close', common.mustCall()); + + process.on('exit', function() { + assert.strictEqual(file.length, 10000); + }); +} + +{ + const file = + fs.createReadStream(rangeFile, common.mustNotMutateObjectDeep({ bufferSize: 1, start: 1, end: 2 })); + let contentRead = ''; + file.on('data', function(data) { + contentRead += data.toString('utf-8'); + }); + file.on('end', common.mustCall(function(data) { + assert.strictEqual(contentRead, 'yz'); + })); +} + +{ + const file = fs.createReadStream(rangeFile, common.mustNotMutateObjectDeep({ bufferSize: 1, start: 1 })); + file.data = ''; + file.on('data', function(data) { + file.data += data.toString('utf-8'); + }); + file.on('end', common.mustCall(function() { + assert.strictEqual(file.data, 'yz\n'); + })); +} + +{ + // Ref: https://github.com/nodejs/node-v0.x-archive/issues/2320 + const file = fs.createReadStream(rangeFile, common.mustNotMutateObjectDeep({ bufferSize: 1.23, start: 1 })); + file.data = ''; + file.on('data', function(data) { + file.data += data.toString('utf-8'); + }); + file.on('end', common.mustCall(function() { + assert.strictEqual(file.data, 'yz\n'); + })); +} + +assert.throws( + () => { + fs.createReadStream(rangeFile, common.mustNotMutateObjectDeep({ start: 10, end: 2 })); + }, + { + code: 'ERR_OUT_OF_RANGE', + message: 'The value of "start" is out of range. It must be <= "end"' + + ' (here: 2). Received 10', + name: 'RangeError' + }); + +{ + const stream = fs.createReadStream(rangeFile, common.mustNotMutateObjectDeep({ start: 0, end: 0 })); + stream.data = ''; + + stream.on('data', function(chunk) { + stream.data += chunk; + }); + + stream.on('end', common.mustCall(function() { + assert.strictEqual(stream.data, 'x'); + })); +} + +{ + // Verify that end works when start is not specified. + const stream = new fs.createReadStream(rangeFile, common.mustNotMutateObjectDeep({ end: 1 })); + stream.data = ''; + + stream.on('data', function(chunk) { + stream.data += chunk; + }); + + stream.on('end', common.mustCall(function() { + assert.strictEqual(stream.data, 'xy'); + })); +} + +if (!common.isWindows) { + // Verify that end works when start is not specified, and we do not try to + // use positioned reads. This makes sure that this keeps working for + // non-seekable file descriptors. + tmpdir.refresh(); + const filename = `${tmpdir.path}/foo.pipe`; + const mkfifoResult = child_process.spawnSync('mkfifo', [filename]); + if (!mkfifoResult.error) { + child_process.exec(`echo "xyz foobar" > '${filename}'`); + const stream = new fs.createReadStream(filename, common.mustNotMutateObjectDeep({ end: 1 })); + stream.data = ''; + + stream.on('data', function(chunk) { + stream.data += chunk; + }); + + stream.on('end', common.mustCall(function() { + assert.strictEqual(stream.data, 'xy'); + fs.unlinkSync(filename); + })); + } else { + common.printSkipMessage('mkfifo not available'); + } +} + +{ + // Pause and then resume immediately. + const pauseRes = fs.createReadStream(rangeFile); + pauseRes.pause(); + pauseRes.resume(); +} + +{ + let file = fs.createReadStream(rangeFile, common.mustNotMutateObjectDeep({ autoClose: false })); + let data = ''; + file.on('data', function(chunk) { data += chunk; }); + file.on('end', common.mustCall(function() { + assert.strictEqual(data, 'xyz\n'); + process.nextTick(function() { + assert(!file.closed); + assert(!file.destroyed); + fileNext(); + }); + })); + + function fileNext() { + // This will tell us if the fd is usable again or not. + file = fs.createReadStream(null, common.mustNotMutateObjectDeep({ fd: file.fd, start: 0 })); + file.data = ''; + file.on('data', function(data) { + file.data += data; + }); + file.on('end', common.mustCall(function(err) { + assert.strictEqual(file.data, 'xyz\n'); + })); + process.on('exit', function() { + assert(file.closed); + assert(file.destroyed); + }); + } +} + +{ + // Just to make sure autoClose won't close the stream because of error. + const file = fs.createReadStream(null, common.mustNotMutateObjectDeep({ fd: 13337, autoClose: false })); + file.on('data', common.mustNotCall()); + file.on('error', common.mustCall()); + process.on('exit', function() { + assert(!file.closed); + assert(!file.destroyed); + assert(file.fd); + }); +} + +{ + // Make sure stream is destroyed when file does not exist. + const file = fs.createReadStream('/path/to/file/that/does/not/exist'); + file.on('data', common.mustNotCall()); + file.on('error', common.mustCall()); + + process.on('exit', function() { + assert(file.closed); + assert(file.destroyed); + }); +} diff --git a/tests/node_compat/test/parallel/test-fs-read-type.js b/tests/node_compat/test/parallel/test-fs-read-type.js new file mode 100644 index 000000000..99321ce3e --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-read-type.js @@ -0,0 +1,250 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const fs = require('fs'); +const assert = require('assert'); +const fixtures = require('../common/fixtures'); + +const filepath = fixtures.path('x.txt'); +const fd = fs.openSync(filepath, 'r'); +const expected = 'xyz\n'; + + +// Error must be thrown with string +assert.throws( + () => fs.read(fd, expected.length, 0, 'utf-8', common.mustNotCall()), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "buffer" argument must be an instance of Buffer, ' + + 'TypedArray, or DataView. Received type number (4)' + } +); + +[true, null, undefined, () => {}, {}].forEach((value) => { + assert.throws(() => { + fs.read(value, + Buffer.allocUnsafe(expected.length), + 0, + expected.length, + 0, + common.mustNotCall()); + }, { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + }); +}); + +assert.throws(() => { + fs.read(fd, + Buffer.allocUnsafe(expected.length), + -1, + expected.length, + 0, + common.mustNotCall()); +}, { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', +}); + +assert.throws(() => { + fs.read(fd, + Buffer.allocUnsafe(expected.length), + NaN, + expected.length, + 0, + common.mustNotCall()); +}, { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "offset" is out of range. It must be an integer. ' + + 'Received NaN' +}); + +assert.throws(() => { + fs.read(fd, + Buffer.allocUnsafe(expected.length), + 0, + -1, + 0, + common.mustNotCall()); +}, { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "length" is out of range. ' + + 'It must be >= 0. Received -1' +}); + +[true, () => {}, {}, ''].forEach((value) => { + assert.throws(() => { + fs.read(fd, + Buffer.allocUnsafe(expected.length), + 0, + expected.length, + value, + common.mustNotCall()); + }, { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + }); +}); + +[0.5, 2 ** 53, 2n ** 63n].forEach((value) => { + assert.throws(() => { + fs.read(fd, + Buffer.allocUnsafe(expected.length), + 0, + expected.length, + value, + common.mustNotCall()); + }, { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError' + }); +}); + +fs.read(fd, + Buffer.allocUnsafe(expected.length), + 0, + expected.length, + 0n, + common.mustSucceed()); + +fs.read(fd, + Buffer.allocUnsafe(expected.length), + 0, + expected.length, + 2n ** 53n - 1n, + common.mustCall((err) => { + if (err) { + if (common.isIBMi) + assert.strictEqual(err.code, 'EOVERFLOW'); + else + assert.strictEqual(err.code, 'EFBIG'); + } + })); + +assert.throws( + () => fs.readSync(fd, expected.length, 0, 'utf-8'), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "buffer" argument must be an instance of Buffer, ' + + 'TypedArray, or DataView. Received type number (4)' + } +); + +[true, null, undefined, () => {}, {}].forEach((value) => { + assert.throws(() => { + fs.readSync(value, + Buffer.allocUnsafe(expected.length), + 0, + expected.length, + 0); + }, { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + }); +}); + +assert.throws(() => { + fs.readSync(fd, + Buffer.allocUnsafe(expected.length), + -1, + expected.length, + 0); +}, { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', +}); + +assert.throws(() => { + fs.readSync(fd, + Buffer.allocUnsafe(expected.length), + NaN, + expected.length, + 0); +}, { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "offset" is out of range. It must be an integer. ' + + 'Received NaN' +}); + +assert.throws(() => { + fs.readSync(fd, + Buffer.allocUnsafe(expected.length), + 0, + -1, + 0); +}, { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "length" is out of range. ' + + 'It must be >= 0. Received -1' +}); + +assert.throws(() => { + fs.readSync(fd, + Buffer.allocUnsafe(expected.length), + 0, + expected.length + 1, + 0); +}, { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "length" is out of range. ' + + 'It must be <= 4. Received 5' +}); + +[true, () => {}, {}, ''].forEach((value) => { + assert.throws(() => { + fs.readSync(fd, + Buffer.allocUnsafe(expected.length), + 0, + expected.length, + value); + }, { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + }); +}); + +[0.5, 2 ** 53, 2n ** 63n].forEach((value) => { + assert.throws(() => { + fs.readSync(fd, + Buffer.allocUnsafe(expected.length), + 0, + expected.length, + value); + }, { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError' + }); +}); + +fs.readSync(fd, + Buffer.allocUnsafe(expected.length), + 0, + expected.length, + 0n); + +try { + fs.readSync(fd, + Buffer.allocUnsafe(expected.length), + 0, + expected.length, + 2n ** 53n - 1n); +} catch (err) { + // On systems where max file size is below 2^53-1, we'd expect a EFBIG error. + // This is not using `assert.throws` because the above call should not raise + // any error on systems that allows file of that size. + if (err.code !== 'EFBIG' && !(common.isIBMi && err.code === 'EOVERFLOW')) + throw err; +} diff --git a/tests/node_compat/test/parallel/test-fs-read-zero-length.js b/tests/node_compat/test/parallel/test-fs-read-zero-length.js new file mode 100644 index 000000000..3a7501073 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-read-zero-length.js @@ -0,0 +1,25 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const fixtures = require('../common/fixtures'); +const assert = require('assert'); +const fs = require('fs'); +const filepath = fixtures.path('x.txt'); +const fd = fs.openSync(filepath, 'r'); +const bufferAsync = Buffer.alloc(0); +const bufferSync = Buffer.alloc(0); + +fs.read(fd, bufferAsync, 0, 0, 0, common.mustCall((err, bytesRead) => { + assert.strictEqual(bytesRead, 0); + assert.deepStrictEqual(bufferAsync, Buffer.alloc(0)); +})); + +const r = fs.readSync(fd, bufferSync, 0, 0, 0); +assert.deepStrictEqual(bufferSync, Buffer.alloc(0)); +assert.strictEqual(r, 0); diff --git a/tests/node_compat/test/parallel/test-fs-read.js b/tests/node_compat/test/parallel/test-fs-read.js new file mode 100644 index 000000000..2a7a286d9 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-read.js @@ -0,0 +1,109 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const fixtures = require('../common/fixtures'); +const assert = require('assert'); +const fs = require('fs'); +const filepath = fixtures.path('x.txt'); +const fd = fs.openSync(filepath, 'r'); + +const expected = Buffer.from('xyz\n'); + +function test(bufferAsync, bufferSync, expected) { + fs.read(fd, + bufferAsync, + 0, + expected.length, + 0, + common.mustSucceed((bytesRead) => { + assert.strictEqual(bytesRead, expected.length); + assert.deepStrictEqual(bufferAsync, expected); + })); + + const r = fs.readSync(fd, bufferSync, 0, expected.length, 0); + assert.deepStrictEqual(bufferSync, expected); + assert.strictEqual(r, expected.length); +} + +test(Buffer.allocUnsafe(expected.length), + Buffer.allocUnsafe(expected.length), + expected); + +test(new Uint8Array(expected.length), + new Uint8Array(expected.length), + Uint8Array.from(expected)); + +{ + // Reading beyond file length (3 in this case) should return no data. + // This is a test for a bug where reads > uint32 would return data + // from the current position in the file. + const pos = 0xffffffff + 1; // max-uint32 + 1 + const nRead = fs.readSync(fd, Buffer.alloc(1), 0, 1, pos); + assert.strictEqual(nRead, 0); + + fs.read(fd, Buffer.alloc(1), 0, 1, pos, common.mustSucceed((nRead) => { + assert.strictEqual(nRead, 0); + })); +} + +assert.throws(() => new fs.Dir(), { + code: 'ERR_MISSING_ARGS', +}); + +assert.throws( + () => fs.read(fd, Buffer.alloc(1), 0, 1, 0), + { + code: 'ERR_INVALID_ARG_TYPE', + } +); + +assert.throws( + () => fs.read(fd, { buffer: null }, common.mustNotCall()), + /TypeError: Cannot read properties of null \(reading 'byteLength'\)/, + 'throws when options.buffer is null' +); + +assert.throws( + () => fs.readSync(fd, { buffer: null }), + { + name: 'TypeError', + message: 'The "buffer" argument must be an instance of Buffer, ' + + 'TypedArray, or DataView. Received an instance of Object', + }, + 'throws when options.buffer is null' +); + +assert.throws( + () => fs.read(null, Buffer.alloc(1), 0, 1, 0), + { + message: 'The "fd" argument must be of type number. Received null', + code: 'ERR_INVALID_ARG_TYPE', + } +); diff --git a/tests/node_compat/test/parallel/test-fs-readdir-stack-overflow.js b/tests/node_compat/test/parallel/test-fs-readdir-stack-overflow.js new file mode 100644 index 000000000..1a60f9a71 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-readdir-stack-overflow.js @@ -0,0 +1,26 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); + +const assert = require('assert'); +const fs = require('fs'); + +function recurse() { + fs.readdirSync('.'); + recurse(); +} + +assert.throws( + () => recurse(), + { + name: 'RangeError', + message: 'Maximum call stack size exceeded' + } +); diff --git a/tests/node_compat/test/parallel/test-fs-readdir.js b/tests/node_compat/test/parallel/test-fs-readdir.js new file mode 100644 index 000000000..768162fe2 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-readdir.js @@ -0,0 +1,60 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const fs = require('fs'); + +const tmpdir = require('../common/tmpdir'); + +const readdirDir = tmpdir.path; +const files = ['empty', 'files', 'for', 'just', 'testing']; + +// Make sure tmp directory is clean +tmpdir.refresh(); + +// Create the necessary files +files.forEach(function(currentFile) { + fs.closeSync(fs.openSync(`${readdirDir}/${currentFile}`, 'w')); +}); + +// Check the readdir Sync version +assert.deepStrictEqual(files, fs.readdirSync(readdirDir).sort()); + +// Check the readdir async version +fs.readdir(readdirDir, common.mustSucceed((f) => { + assert.deepStrictEqual(files, f.sort()); +})); + +// readdir() on file should throw ENOTDIR +// https://github.com/joyent/node/issues/1869 +assert.throws(function() { + fs.readdirSync(__filename); +}, /Error: ENOTDIR: not a directory/); + +fs.readdir(__filename, common.mustCall(function(e) { + assert.strictEqual(e.code, 'ENOTDIR'); +})); + +[false, 1, [], {}, null, undefined].forEach((i) => { + assert.throws( + () => fs.readdir(i, common.mustNotCall()), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + } + ); + assert.throws( + () => fs.readdirSync(i), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + } + ); +}); diff --git a/tests/node_compat/test/parallel/test-fs-readfile-empty.js b/tests/node_compat/test/parallel/test-fs-readfile-empty.js new file mode 100644 index 000000000..15f08ef8c --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-readfile-empty.js @@ -0,0 +1,52 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; + +// Trivial test of fs.readFile on an empty file. +const common = require('../common'); +const fs = require('fs'); +const assert = require('assert'); +const fixtures = require('../common/fixtures'); + +const fn = fixtures.path('empty.txt'); + +fs.readFile(fn, common.mustCall((err, data) => { + assert.ok(data); +})); + +fs.readFile(fn, 'utf8', common.mustCall((err, data) => { + assert.strictEqual(data, ''); +})); + +fs.readFile(fn, { encoding: 'utf8' }, common.mustCall((err, data) => { + assert.strictEqual(data, ''); +})); + +assert.ok(fs.readFileSync(fn)); +assert.strictEqual(fs.readFileSync(fn, 'utf8'), ''); diff --git a/tests/node_compat/test/parallel/test-fs-realpath-native.js b/tests/node_compat/test/parallel/test-fs-realpath-native.js new file mode 100644 index 000000000..13e5b48cb --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-realpath-native.js @@ -0,0 +1,25 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const fs = require('fs'); + +const filename = __filename.toLowerCase(); + +assert.strictEqual( + fs.realpathSync.native('./test/parallel/test-fs-realpath-native.js') + .toLowerCase(), + filename); + +fs.realpath.native( + './test/parallel/test-fs-realpath-native.js', + common.mustSucceed(function(res) { + assert.strictEqual(res.toLowerCase(), filename); + assert.strictEqual(this, undefined); + })); diff --git a/tests/node_compat/test/parallel/test-fs-rmdir-recursive-sync-warns-not-found.js b/tests/node_compat/test/parallel/test-fs-rmdir-recursive-sync-warns-not-found.js new file mode 100644 index 000000000..92ca59255 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-rmdir-recursive-sync-warns-not-found.js @@ -0,0 +1,30 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const tmpdir = require('../common/tmpdir'); +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); + +tmpdir.refresh(); + +{ + // Should warn when trying to delete a nonexistent path + common.expectWarning( + 'DeprecationWarning', + 'In future versions of Node.js, fs.rmdir(path, { recursive: true }) ' + + 'will be removed. Use fs.rm(path, { recursive: true }) instead', + 'DEP0147' + ); + assert.throws( + () => fs.rmdirSync(path.join(tmpdir.path, 'noexist.txt'), + { recursive: true }), + { code: 'ENOENT' } + ); +} diff --git a/tests/node_compat/test/parallel/test-fs-rmdir-recursive-sync-warns-on-file.js b/tests/node_compat/test/parallel/test-fs-rmdir-recursive-sync-warns-on-file.js new file mode 100644 index 000000000..95703b99f --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-rmdir-recursive-sync-warns-on-file.js @@ -0,0 +1,30 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const tmpdir = require('../common/tmpdir'); +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); + +tmpdir.refresh(); + +{ + common.expectWarning( + 'DeprecationWarning', + 'In future versions of Node.js, fs.rmdir(path, { recursive: true }) ' + + 'will be removed. Use fs.rm(path, { recursive: true }) instead', + 'DEP0147' + ); + const filePath = path.join(tmpdir.path, 'rmdir-recursive.txt'); + fs.writeFileSync(filePath, ''); + assert.throws( + () => fs.rmdirSync(filePath, { recursive: true }), + { code: common.isWindows ? 'ENOENT' : 'ENOTDIR' } + ); +} diff --git a/tests/node_compat/test/parallel/test-fs-rmdir-recursive-throws-not-found.js b/tests/node_compat/test/parallel/test-fs-rmdir-recursive-throws-not-found.js new file mode 100644 index 000000000..9a6d584d9 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-rmdir-recursive-throws-not-found.js @@ -0,0 +1,43 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const tmpdir = require('../common/tmpdir'); +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); + +tmpdir.refresh(); + +{ + assert.throws( + () => + fs.rmdirSync(path.join(tmpdir.path, 'noexist.txt'), { recursive: true }), + { + code: 'ENOENT', + } + ); +} +{ + fs.rmdir( + path.join(tmpdir.path, 'noexist.txt'), + { recursive: true }, + common.mustCall((err) => { + assert.strictEqual(err.code, 'ENOENT'); + }) + ); +} +{ + assert.rejects( + () => fs.promises.rmdir(path.join(tmpdir.path, 'noexist.txt'), + { recursive: true }), + { + code: 'ENOENT', + } + ).then(common.mustCall()); +} diff --git a/tests/node_compat/test/parallel/test-fs-rmdir-recursive-throws-on-file.js b/tests/node_compat/test/parallel/test-fs-rmdir-recursive-throws-on-file.js new file mode 100644 index 000000000..4dc27ab8f --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-rmdir-recursive-throws-on-file.js @@ -0,0 +1,36 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const tmpdir = require('../common/tmpdir'); +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); + +tmpdir.refresh(); + +const code = common.isWindows ? 'ENOENT' : 'ENOTDIR'; + +{ + const filePath = path.join(tmpdir.path, 'rmdir-recursive.txt'); + fs.writeFileSync(filePath, ''); + assert.throws(() => fs.rmdirSync(filePath, { recursive: true }), { code }); +} +{ + const filePath = path.join(tmpdir.path, 'rmdir-recursive.txt'); + fs.writeFileSync(filePath, ''); + fs.rmdir(filePath, { recursive: true }, common.mustCall((err) => { + assert.strictEqual(err.code, code); + })); +} +{ + const filePath = path.join(tmpdir.path, 'rmdir-recursive.txt'); + fs.writeFileSync(filePath, ''); + assert.rejects(() => fs.promises.rmdir(filePath, { recursive: true }), + { code }).then(common.mustCall()); +} diff --git a/tests/node_compat/test/parallel/test-fs-rmdir-recursive-warns-not-found.js b/tests/node_compat/test/parallel/test-fs-rmdir-recursive-warns-not-found.js new file mode 100644 index 000000000..3e9564ec1 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-rmdir-recursive-warns-not-found.js @@ -0,0 +1,29 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const tmpdir = require('../common/tmpdir'); +const fs = require('fs'); +const path = require('path'); + +tmpdir.refresh(); + +{ + // Should warn when trying to delete a nonexistent path + common.expectWarning( + 'DeprecationWarning', + 'In future versions of Node.js, fs.rmdir(path, { recursive: true }) ' + + 'will be removed. Use fs.rm(path, { recursive: true }) instead', + 'DEP0147' + ); + fs.rmdir( + path.join(tmpdir.path, 'noexist.txt'), + { recursive: true }, + common.mustCall() + ); +} diff --git a/tests/node_compat/test/parallel/test-fs-rmdir-recursive-warns-on-file.js b/tests/node_compat/test/parallel/test-fs-rmdir-recursive-warns-on-file.js new file mode 100644 index 000000000..99644e639 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-rmdir-recursive-warns-on-file.js @@ -0,0 +1,29 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const tmpdir = require('../common/tmpdir'); +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); + +tmpdir.refresh(); + +{ + common.expectWarning( + 'DeprecationWarning', + 'In future versions of Node.js, fs.rmdir(path, { recursive: true }) ' + + 'will be removed. Use fs.rm(path, { recursive: true }) instead', + 'DEP0147' + ); + const filePath = path.join(tmpdir.path, 'rmdir-recursive.txt'); + fs.writeFileSync(filePath, ''); + fs.rmdir(filePath, { recursive: true }, common.mustCall((err) => { + assert.strictEqual(err.code, common.isWindows ? 'ENOENT' : 'ENOTDIR'); + })); +} diff --git a/tests/node_compat/test/parallel/test-fs-rmdir-recursive.js b/tests/node_compat/test/parallel/test-fs-rmdir-recursive.js new file mode 100644 index 000000000..31bde4487 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-rmdir-recursive.js @@ -0,0 +1,252 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Flags: --expose-internals +'use strict'; +const common = require('../common'); +const tmpdir = require('../common/tmpdir'); +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); +const { validateRmdirOptions } = require('internal/fs/utils'); + +common.expectWarning( + 'DeprecationWarning', + 'In future versions of Node.js, fs.rmdir(path, { recursive: true }) ' + + 'will be removed. Use fs.rm(path, { recursive: true }) instead', + 'DEP0147' +); + +tmpdir.refresh(); + +let count = 0; +const nextDirPath = (name = 'rmdir-recursive') => + path.join(tmpdir.path, `${name}-${count++}`); + +function makeNonEmptyDirectory(depth, files, folders, dirname, createSymLinks) { + fs.mkdirSync(dirname, { recursive: true }); + fs.writeFileSync(path.join(dirname, 'text.txt'), 'hello', 'utf8'); + + const options = { flag: 'wx' }; + + for (let f = files; f > 0; f--) { + fs.writeFileSync(path.join(dirname, `f-${depth}-${f}`), '', options); + } + + if (createSymLinks) { + // Valid symlink + fs.symlinkSync( + `f-${depth}-1`, + path.join(dirname, `link-${depth}-good`), + 'file' + ); + + // Invalid symlink + fs.symlinkSync( + 'does-not-exist', + path.join(dirname, `link-${depth}-bad`), + 'file' + ); + } + + // File with a name that looks like a glob + fs.writeFileSync(path.join(dirname, '[a-z0-9].txt'), '', options); + + depth--; + if (depth <= 0) { + return; + } + + for (let f = folders; f > 0; f--) { + fs.mkdirSync( + path.join(dirname, `folder-${depth}-${f}`), + { recursive: true } + ); + makeNonEmptyDirectory( + depth, + files, + folders, + path.join(dirname, `d-${depth}-${f}`), + createSymLinks + ); + } +} + +function removeAsync(dir) { + // Removal should fail without the recursive option. + fs.rmdir(dir, common.mustCall((err) => { + assert.strictEqual(err.syscall, 'rmdir'); + + // Removal should fail without the recursive option set to true. + fs.rmdir(dir, { recursive: false }, common.mustCall((err) => { + assert.strictEqual(err.syscall, 'rmdir'); + + // Recursive removal should succeed. + fs.rmdir(dir, { recursive: true }, common.mustSucceed(() => { + // An error should occur if recursive and the directory does not exist. + fs.rmdir(dir, { recursive: true }, common.mustCall((err) => { + assert.strictEqual(err.code, 'ENOENT'); + // Attempted removal should fail now because the directory is gone. + fs.rmdir(dir, common.mustCall((err) => { + assert.strictEqual(err.syscall, 'rmdir'); + })); + })); + })); + })); + })); +} + +// Test the asynchronous version +{ + // Create a 4-level folder hierarchy including symlinks + let dir = nextDirPath(); + makeNonEmptyDirectory(4, 10, 2, dir, true); + removeAsync(dir); + + // Create a 2-level folder hierarchy without symlinks + dir = nextDirPath(); + makeNonEmptyDirectory(2, 10, 2, dir, false); + removeAsync(dir); + + // Create a flat folder including symlinks + dir = nextDirPath(); + makeNonEmptyDirectory(1, 10, 2, dir, true); + removeAsync(dir); +} + +// Test the synchronous version. +{ + const dir = nextDirPath(); + makeNonEmptyDirectory(4, 10, 2, dir, true); + + // Removal should fail without the recursive option set to true. + assert.throws(() => { + fs.rmdirSync(dir); + }, { syscall: 'rmdir' }); + assert.throws(() => { + fs.rmdirSync(dir, { recursive: false }); + }, { syscall: 'rmdir' }); + + // Recursive removal should succeed. + fs.rmdirSync(dir, { recursive: true }); + + // An error should occur if recursive and the directory does not exist. + assert.throws(() => fs.rmdirSync(dir, { recursive: true }), + { code: 'ENOENT' }); + + // Attempted removal should fail now because the directory is gone. + assert.throws(() => fs.rmdirSync(dir), { syscall: 'rmdir' }); +} + +// Test the Promises based version. +(async () => { + const dir = nextDirPath(); + makeNonEmptyDirectory(4, 10, 2, dir, true); + + // Removal should fail without the recursive option set to true. + assert.rejects(fs.promises.rmdir(dir), { syscall: 'rmdir' }); + assert.rejects(fs.promises.rmdir(dir, { recursive: false }), { + syscall: 'rmdir' + }); + + // Recursive removal should succeed. + await fs.promises.rmdir(dir, { recursive: true }); + + // An error should occur if recursive and the directory does not exist. + await assert.rejects(fs.promises.rmdir(dir, { recursive: true }), + { code: 'ENOENT' }); + + // Attempted removal should fail now because the directory is gone. + assert.rejects(fs.promises.rmdir(dir), { syscall: 'rmdir' }); +})().then(common.mustCall()); + +// Test input validation. +{ + const defaults = { + retryDelay: 100, + maxRetries: 0, + recursive: false + }; + const modified = { + retryDelay: 953, + maxRetries: 5, + recursive: true + }; + + assert.deepStrictEqual(validateRmdirOptions(), defaults); + assert.deepStrictEqual(validateRmdirOptions({}), defaults); + assert.deepStrictEqual(validateRmdirOptions(modified), modified); + assert.deepStrictEqual(validateRmdirOptions({ + maxRetries: 99 + }), { + retryDelay: 100, + maxRetries: 99, + recursive: false + }); + + [null, 'foo', 5, NaN].forEach((bad) => { + assert.throws(() => { + validateRmdirOptions(bad); + }, { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: /^The "options" argument must be of type object\./ + }); + }); + + [undefined, null, 'foo', Infinity, function() {}].forEach((bad) => { + assert.throws(() => { + validateRmdirOptions({ recursive: bad }); + }, { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: /^The "options\.recursive" property must be of type boolean\./ + }); + }); + + assert.throws(() => { + validateRmdirOptions({ retryDelay: -1 }); + }, { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: /^The value of "options\.retryDelay" is out of range\./ + }); + + assert.throws(() => { + validateRmdirOptions({ maxRetries: -1 }); + }, { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: /^The value of "options\.maxRetries" is out of range\./ + }); +} + +// FIXME(f3n67u): make this test pass +// It should not pass recursive option to rmdirSync, when called from +// rimraf (see: #35566) +// { +// // Make a non-empty directory: +// const original = fs.rmdirSync; +// const dir = `${nextDirPath()}/foo/bar`; +// fs.mkdirSync(dir, { recursive: true }); +// fs.writeFileSync(`${dir}/foo.txt`, 'hello world', 'utf8'); + +// // When called the second time from rimraf, the recursive option should +// // not be set for rmdirSync: +// let callCount = 0; +// let rmdirSyncOptionsFromRimraf; +// fs.rmdirSync = (path, options) => { +// if (callCount > 0) { +// rmdirSyncOptionsFromRimraf = { ...options }; +// } +// callCount++; +// return original(path, options); +// }; +// fs.rmdirSync(dir, { recursive: true }); +// fs.rmdirSync = original; +// assert.strictEqual(rmdirSyncOptionsFromRimraf.recursive, undefined); +// } diff --git a/tests/node_compat/test/parallel/test-fs-rmdir-type-check.js b/tests/node_compat/test/parallel/test-fs-rmdir-type-check.js new file mode 100644 index 000000000..0ebfdacaf --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-rmdir-type-check.js @@ -0,0 +1,29 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const fs = require('fs'); + +[false, 1, [], {}, null, undefined].forEach((i) => { + assert.throws( + () => fs.rmdir(i, common.mustNotCall()), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + } + ); + assert.throws( + () => fs.rmdirSync(i), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + } + ); +}); diff --git a/tests/node_compat/test/parallel/test-fs-watchfile.js b/tests/node_compat/test/parallel/test-fs-watchfile.js new file mode 100644 index 000000000..3a77fb56d --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-watchfile.js @@ -0,0 +1,112 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); + +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); + +const tmpdir = require('../common/tmpdir'); + +// Basic usage tests. +assert.throws( + () => { + fs.watchFile('./some-file'); + }, + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + }); + +assert.throws( + () => { + fs.watchFile('./another-file', {}, 'bad listener'); + }, + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + }); + +assert.throws(() => { + fs.watchFile(new Object(), common.mustNotCall()); +}, { code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' }); + +const enoentFile = path.join(tmpdir.path, 'non-existent-file'); +const expectedStatObject = new fs.Stats( + 0, // dev + 0, // mode + 0, // nlink + 0, // uid + 0, // gid + 0, // rdev + 0, // blksize + 0, // ino + 0, // size + 0, // blocks + Date.UTC(1970, 0, 1, 0, 0, 0), // atime + Date.UTC(1970, 0, 1, 0, 0, 0), // mtime + Date.UTC(1970, 0, 1, 0, 0, 0), // ctime + Date.UTC(1970, 0, 1, 0, 0, 0) // birthtime +); + +tmpdir.refresh(); + +// If the file initially didn't exist, and gets created at a later point of +// time, the callback should be invoked again with proper values in stat object +let fileExists = false; + +const watcher = + fs.watchFile(enoentFile, { interval: 0 }, common.mustCall((curr, prev) => { + if (!fileExists) { + // If the file does not exist, all the fields should be zero and the date + // fields should be UNIX EPOCH time + assert.deepStrictEqual(curr, expectedStatObject); + assert.deepStrictEqual(prev, expectedStatObject); + // Create the file now, so that the callback will be called back once the + // event loop notices it. + fs.closeSync(fs.openSync(enoentFile, 'w')); + fileExists = true; + } else { + // If the ino (inode) value is greater than zero, it means that the file + // is present in the filesystem and it has a valid inode number. + assert(curr.ino > 0); + // As the file just got created, previous ino value should be lesser than + // or equal to zero (non-existent file). + assert(prev.ino <= 0); + // Stop watching the file + fs.unwatchFile(enoentFile); + watcher.stop(); // Stopping a stopped watcher should be a noop + } + }, 2)); + +// 'stop' should only be emitted once - stopping a stopped watcher should +// not trigger a 'stop' event. +watcher.on('stop', common.mustCall()); + +// Watch events should callback with a filename on supported systems. +// Omitting AIX. It works but not reliably. +if (common.isLinux || common.isOSX || common.isWindows) { + const dir = path.join(tmpdir.path, 'watch'); + + fs.mkdir(dir, common.mustCall(function(err) { + if (err) assert.fail(err); + + fs.watch(dir, common.mustCall(function(eventType, filename) { + clearInterval(interval); + this._handle.close(); + assert.strictEqual(filename, 'foo.txt'); + })); + + const interval = setInterval(() => { + fs.writeFile(path.join(dir, 'foo.txt'), 'foo', common.mustCall((err) => { + if (err) assert.fail(err); + })); + }, 1); + })); +} diff --git a/tests/node_compat/test/parallel/test-fs-write-buffer.js b/tests/node_compat/test/parallel/test-fs-write-buffer.js new file mode 100644 index 000000000..16577a8f2 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-write-buffer.js @@ -0,0 +1,172 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const path = require('path'); +const fs = require('fs'); +const expected = Buffer.from('hello'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +// fs.write with all parameters provided: +{ + const filename = path.join(tmpdir.path, 'write1.txt'); + fs.open(filename, 'w', 0o644, common.mustSucceed((fd) => { + const cb = common.mustSucceed((written) => { + assert.strictEqual(written, expected.length); + fs.closeSync(fd); + + const found = fs.readFileSync(filename, 'utf8'); + assert.strictEqual(found, expected.toString()); + }); + + fs.write(fd, expected, 0, expected.length, null, cb); + })); +} + +// fs.write with a buffer, without the length parameter: +{ + const filename = path.join(tmpdir.path, 'write2.txt'); + fs.open(filename, 'w', 0o644, common.mustSucceed((fd) => { + const cb = common.mustSucceed((written) => { + assert.strictEqual(written, 2); + fs.closeSync(fd); + + const found = fs.readFileSync(filename, 'utf8'); + assert.strictEqual(found, 'lo'); + }); + + fs.write(fd, Buffer.from('hello'), 3, cb); + })); +} + +// fs.write with a buffer, without the offset and length parameters: +{ + const filename = path.join(tmpdir.path, 'write3.txt'); + fs.open(filename, 'w', 0o644, common.mustSucceed((fd) => { + const cb = common.mustSucceed((written) => { + assert.strictEqual(written, expected.length); + fs.closeSync(fd); + + const found = fs.readFileSync(filename, 'utf8'); + assert.deepStrictEqual(expected.toString(), found); + }); + + fs.write(fd, expected, cb); + })); +} + +// fs.write with the offset passed as undefined followed by the callback: +{ + const filename = path.join(tmpdir.path, 'write4.txt'); + fs.open(filename, 'w', 0o644, common.mustSucceed((fd) => { + const cb = common.mustSucceed((written) => { + assert.strictEqual(written, expected.length); + fs.closeSync(fd); + + const found = fs.readFileSync(filename, 'utf8'); + assert.deepStrictEqual(expected.toString(), found); + }); + + fs.write(fd, expected, undefined, cb); + })); +} + +// fs.write with offset and length passed as undefined followed by the callback: +{ + const filename = path.join(tmpdir.path, 'write5.txt'); + fs.open(filename, 'w', 0o644, common.mustSucceed((fd) => { + const cb = common.mustSucceed((written) => { + assert.strictEqual(written, expected.length); + fs.closeSync(fd); + + const found = fs.readFileSync(filename, 'utf8'); + assert.strictEqual(found, expected.toString()); + }); + + fs.write(fd, expected, undefined, undefined, cb); + })); +} + +// fs.write with a Uint8Array, without the offset and length parameters: +{ + const filename = path.join(tmpdir.path, 'write6.txt'); + fs.open(filename, 'w', 0o644, common.mustSucceed((fd) => { + const cb = common.mustSucceed((written) => { + assert.strictEqual(written, expected.length); + fs.closeSync(fd); + + const found = fs.readFileSync(filename, 'utf8'); + assert.strictEqual(found, expected.toString()); + }); + + fs.write(fd, Uint8Array.from(expected), cb); + })); +} + +// fs.write with invalid offset type +{ + const filename = path.join(tmpdir.path, 'write7.txt'); + fs.open(filename, 'w', 0o644, common.mustSucceed((fd) => { + assert.throws(() => { + fs.write(fd, + Buffer.from('abcd'), + NaN, + expected.length, + 0, + common.mustNotCall()); + }, { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "offset" is out of range. ' + + 'It must be an integer. Received NaN' + }); + + fs.closeSync(fd); + })); +} + +// fs.write with a DataView, without the offset and length parameters: +{ + const filename = path.join(tmpdir.path, 'write8.txt'); + fs.open(filename, 'w', 0o644, common.mustSucceed((fd) => { + const cb = common.mustSucceed((written) => { + assert.strictEqual(written, expected.length); + fs.closeSync(fd); + + const found = fs.readFileSync(filename, 'utf8'); + assert.strictEqual(found, expected.toString()); + }); + + const uint8 = Uint8Array.from(expected); + fs.write(fd, new DataView(uint8.buffer), cb); + })); +} diff --git a/tests/node_compat/test/parallel/test-fs-write-file-buffer.js b/tests/node_compat/test/parallel/test-fs-write-file-buffer.js new file mode 100644 index 000000000..9283cc8b4 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-write-file-buffer.js @@ -0,0 +1,62 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const join = require('path').join; +const util = require('util'); +const fs = require('fs'); + +let data = [ + '/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcH', + 'Bw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/', + '2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4e', + 'Hh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAQABADASIAAhEBAxEB/8QA', + 'HwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUF', + 'BAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkK', + 'FhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1', + 'dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXG', + 'x8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEB', + 'AQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAEC', + 'AxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRom', + 'JygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOE', + 'hYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU', + '1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDhfBUFl/wk', + 'OmPqKJJZw3aiZFBw4z93jnkkc9u9dj8XLfSI/EBt7DTo7ea2Ox5YXVo5FC7g', + 'Tjq24nJPXNVtO0KATRvNHCIg3zoWJWQHqp+o4pun+EtJ0zxBq8mnLJa2d1L5', + '0NvnKRjJBUE5PAx3NYxxUY0pRtvYHSc5Ka2X9d7H/9k=']; + +data = data.join('\n'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +const buf = Buffer.from(data, 'base64'); +fs.writeFileSync(join(tmpdir.path, 'test.jpg'), buf); + +util.log('Done!'); diff --git a/tests/node_compat/test/parallel/test-fs-write-file-invalid-path.js b/tests/node_compat/test/parallel/test-fs-write-file-invalid-path.js new file mode 100644 index 000000000..d56aa9a13 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-write-file-invalid-path.js @@ -0,0 +1,53 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); + +if (!common.isWindows) + common.skip('This test is for Windows only.'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +const DATA_VALUE = 'hello'; + +// Refs: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx +// Ignore '/', '\\' and ':' +const RESERVED_CHARACTERS = '<>"|?*'; + +[...RESERVED_CHARACTERS].forEach((ch) => { + const pathname = path.join(tmpdir.path, `somefile_${ch}`); + assert.throws( + () => { + fs.writeFileSync(pathname, DATA_VALUE); + }, + /^Error: ENOENT: no such file or directory, open '.*'$/, + `failed with '${ch}'`); +}); + +// Test for ':' (NTFS data streams). +// Refs: https://msdn.microsoft.com/en-us/library/windows/desktop/bb540537.aspx +const pathname = path.join(tmpdir.path, 'foo:bar'); +fs.writeFileSync(pathname, DATA_VALUE); + +let content = ''; +const fileDataStream = fs.createReadStream(pathname, { + encoding: 'utf8' +}); + +fileDataStream.on('data', (data) => { + content += data; +}); + +fileDataStream.on('end', common.mustCall(() => { + assert.strictEqual(content, DATA_VALUE); +})); diff --git a/tests/node_compat/test/parallel/test-fs-write-file-sync.js b/tests/node_compat/test/parallel/test-fs-write-file-sync.js new file mode 100644 index 000000000..027ba6377 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-write-file-sync.js @@ -0,0 +1,128 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); + +if (!common.isMainThread) + common.skip('Setting process.umask is not supported in Workers'); + +const assert = require('assert'); +const path = require('path'); +const fs = require('fs'); + +// On Windows chmod is only able to manipulate read-only bit. Test if creating +// the file in read-only mode works. +const mode = common.isWindows ? 0o444 : 0o755; + +// Reset the umask for testing +process.umask(0o000); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +// Test writeFileSync +{ + const file = path.join(tmpdir.path, 'testWriteFileSync.txt'); + + fs.writeFileSync(file, '123', { mode }); + const content = fs.readFileSync(file, { encoding: 'utf8' }); + assert.strictEqual(content, '123'); + assert.strictEqual(fs.statSync(file).mode & 0o777, mode); +} + +// Test appendFileSync +{ + const file = path.join(tmpdir.path, 'testAppendFileSync.txt'); + + fs.appendFileSync(file, 'abc', { mode }); + const content = fs.readFileSync(file, { encoding: 'utf8' }); + assert.strictEqual(content, 'abc'); + assert.strictEqual(fs.statSync(file).mode & mode, mode); +} + +// Test writeFileSync with file descriptor +{ + // Need to hijack fs.open/close to make sure that things + // get closed once they're opened. + const _openSync = fs.openSync; + const _closeSync = fs.closeSync; + let openCount = 0; + + fs.openSync = (...args) => { + openCount++; + return _openSync(...args); + }; + + fs.closeSync = (...args) => { + openCount--; + return _closeSync(...args); + }; + + const file = path.join(tmpdir.path, 'testWriteFileSyncFd.txt'); + const fd = fs.openSync(file, 'w+', mode); + + fs.writeFileSync(fd, '123'); + fs.closeSync(fd); + const content = fs.readFileSync(file, { encoding: 'utf8' }); + assert.strictEqual(content, '123'); + assert.strictEqual(fs.statSync(file).mode & 0o777, mode); + + // Verify that all opened files were closed. + assert.strictEqual(openCount, 0); + fs.openSync = _openSync; + fs.closeSync = _closeSync; +} + +// Test writeFileSync with flags +{ + const file = path.join(tmpdir.path, 'testWriteFileSyncFlags.txt'); + + fs.writeFileSync(file, 'hello ', { encoding: 'utf8', flag: 'a' }); + fs.writeFileSync(file, 'world!', { encoding: 'utf8', flag: 'a' }); + const content = fs.readFileSync(file, { encoding: 'utf8' }); + assert.strictEqual(content, 'hello world!'); +} + +// Test writeFileSync with an object with an own toString function +{ + // Runtime deprecated by DEP0162 + common.expectWarning('DeprecationWarning', + 'Implicit coercion of objects with own toString property is deprecated.', + 'DEP0162'); + const file = path.join(tmpdir.path, 'testWriteFileSyncStringify.txt'); + const data = { + toString() { + return 'hello world!'; + } + }; + + fs.writeFileSync(file, data, { encoding: 'utf8', flag: 'a' }); + const content = fs.readFileSync(file, { encoding: 'utf8' }); + assert.strictEqual(content, String(data)); +} diff --git a/tests/node_compat/test/parallel/test-fs-write-file.js b/tests/node_compat/test/parallel/test-fs-write-file.js new file mode 100644 index 000000000..a5c93cd23 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-write-file.js @@ -0,0 +1,115 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const fs = require('fs'); +const join = require('path').join; + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +const filename = join(tmpdir.path, 'test.txt'); + +const s = '南越国是前203年至前111年存在于岭南地区的一个国家,国都位于番禺,疆域包括今天中国的广东、' + + '广西两省区的大部份地区,福建省、湖南、贵州、云南的一小部份地区和越南的北部。' + + '南越国是秦朝灭亡后,由南海郡尉赵佗于前203年起兵兼并桂林郡和象郡后建立。' + + '前196年和前179年,南越国曾先后两次名义上臣属于西汉,成为西汉的“外臣”。前112年,' + + '南越国末代君主赵建德与西汉发生战争,被汉武帝于前111年所灭。南越国共存在93年,' + + '历经五代君主。南越国是岭南地区的第一个有记载的政权国家,采用封建制和郡县制并存的制度,' + + '它的建立保证了秦末乱世岭南地区社会秩序的稳定,有效的改善了岭南地区落后的政治、##济现状。\n'; + +fs.writeFile(filename, s, common.mustSucceed(() => { + fs.readFile(filename, common.mustSucceed((buffer) => { + assert.strictEqual(Buffer.byteLength(s), buffer.length); + })); +})); + +// Test that writeFile accepts buffers. +const filename2 = join(tmpdir.path, 'test2.txt'); +const buf = Buffer.from(s, 'utf8'); + +fs.writeFile(filename2, buf, common.mustSucceed(() => { + fs.readFile(filename2, common.mustSucceed((buffer) => { + assert.strictEqual(buf.length, buffer.length); + })); +})); + +// Test that writeFile accepts file descriptors. +const filename4 = join(tmpdir.path, 'test4.txt'); + +fs.open(filename4, 'w+', common.mustSucceed((fd) => { + fs.writeFile(fd, s, common.mustSucceed(() => { + fs.close(fd, common.mustSucceed(() => { + fs.readFile(filename4, common.mustSucceed((buffer) => { + assert.strictEqual(Buffer.byteLength(s), buffer.length); + })); + })); + })); +})); + + +{ + // Test that writeFile is cancellable with an AbortSignal. + // Before the operation has started + const controller = new AbortController(); + const signal = controller.signal; + const filename3 = join(tmpdir.path, 'test3.txt'); + + fs.writeFile(filename3, s, { signal }, common.mustCall((err) => { + assert.strictEqual(err.name, 'AbortError'); + })); + + controller.abort(); +} + +// FIXME(bartlomieju): +// { +// // Test that writeFile is cancellable with an AbortSignal. +// // After the operation has started +// const controller = new AbortController(); +// const signal = controller.signal; +// const filename4 = join(tmpdir.path, 'test5.txt'); + +// fs.writeFile(filename4, s, { signal }, common.mustCall((err) => { +// assert.strictEqual(err.name, 'AbortError'); +// })); + +// process.nextTick(() => controller.abort()); +// } + +{ + // Test read-only mode + const filename = join(tmpdir.path, 'test6.txt'); + fs.writeFileSync(filename, ''); + + // TODO: Correct the error type + const expectedError = common.isWindows ? /EPERM/ : /EBADF/; + fs.writeFile(filename, s, { flag: 'r' }, common.expectsError(expectedError)); +} diff --git a/tests/node_compat/test/parallel/test-fs-write-no-fd.js b/tests/node_compat/test/parallel/test-fs-write-no-fd.js new file mode 100644 index 000000000..58ab0fa44 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-write-no-fd.js @@ -0,0 +1,19 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const fs = require('fs'); +const assert = require('assert'); + +assert.throws(function() { + fs.write(null, Buffer.allocUnsafe(1), 0, 1, common.mustNotCall()); +}, /TypeError/); + +assert.throws(function() { + fs.write(null, '1', 0, 1, common.mustNotCall()); +}, /TypeError/); diff --git a/tests/node_compat/test/parallel/test-fs-write-stream-autoclose-option.js b/tests/node_compat/test/parallel/test-fs-write-stream-autoclose-option.js new file mode 100644 index 000000000..00958457f --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-write-stream-autoclose-option.js @@ -0,0 +1,66 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const path = require('path'); +const fs = require('fs'); + +const tmpdir = require('../common/tmpdir'); + +const file = path.join(tmpdir.path, 'write-autoclose-opt1.txt'); +tmpdir.refresh(); +let stream = fs.createWriteStream(file, { flags: 'w+', autoClose: false }); +stream.write('Test1'); +stream.end(); +stream.on('finish', common.mustCall(function() { + stream.on('close', common.mustNotCall()); + process.nextTick(common.mustCall(function() { + assert.strictEqual(stream.closed, false); + assert.notStrictEqual(stream.fd, null); + next(); + })); +})); + +function next() { + // This will tell us if the fd is usable again or not + stream = fs.createWriteStream(null, { fd: stream.fd, start: 0 }); + stream.write('Test2'); + stream.end(); + stream.on('finish', common.mustCall(function() { + assert.strictEqual(stream.closed, false); + stream.on('close', common.mustCall(function() { + assert.strictEqual(stream.fd, null); + assert.strictEqual(stream.closed, true); + process.nextTick(next2); + })); + })); +} + +function next2() { + // This will test if after reusing the fd data is written properly + fs.readFile(file, function(err, data) { + assert.ifError(err); + assert.strictEqual(data.toString(), 'Test2'); + process.nextTick(common.mustCall(next3)); + }); +} + +function next3() { + // This is to test success scenario where autoClose is true + const stream = fs.createWriteStream(file, { autoClose: true }); + stream.write('Test3'); + stream.end(); + stream.on('finish', common.mustCall(function() { + assert.strictEqual(stream.closed, false); + stream.on('close', common.mustCall(function() { + assert.strictEqual(stream.fd, null); + assert.strictEqual(stream.closed, true); + })); + })); +} diff --git a/tests/node_compat/test/parallel/test-fs-write-stream-close-without-callback.js b/tests/node_compat/test/parallel/test-fs-write-stream-close-without-callback.js new file mode 100644 index 000000000..61c3120d7 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-write-stream-close-without-callback.js @@ -0,0 +1,20 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const fs = require('fs'); +const path = require('path'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +const s = fs.createWriteStream(path.join(tmpdir.path, 'nocallback')); + +s.end('hello world'); +s.close(); diff --git a/tests/node_compat/test/parallel/test-fs-write-stream-double-close.js b/tests/node_compat/test/parallel/test-fs-write-stream-double-close.js new file mode 100644 index 000000000..1f38a3b7d --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-write-stream-double-close.js @@ -0,0 +1,53 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +{ + const s = fs.createWriteStream(path.join(tmpdir.path, 'rw')); + + s.close(common.mustCall()); + s.close(common.mustCall()); +} + +{ + const s = fs.createWriteStream(path.join(tmpdir.path, 'rw2')); + + let emits = 0; + s.on('close', () => { + emits++; + }); + + s.close(common.mustCall(() => { + assert.strictEqual(emits, 1); + s.close(common.mustCall(() => { + assert.strictEqual(emits, 1); + })); + process.nextTick(() => { + s.close(common.mustCall(() => { + assert.strictEqual(emits, 1); + })); + }); + })); +} + +{ + const s = fs.createWriteStream(path.join(tmpdir.path, 'rw'), { + autoClose: false + }); + + s.close(common.mustCall()); + s.close(common.mustCall()); +} diff --git a/tests/node_compat/test/parallel/test-fs-write-stream-end.js b/tests/node_compat/test/parallel/test-fs-write-stream-end.js new file mode 100644 index 000000000..f11cf86af --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-write-stream-end.js @@ -0,0 +1,67 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const path = require('path'); +const fs = require('fs'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +{ + const file = path.join(tmpdir.path, 'write-end-test0.txt'); + const stream = fs.createWriteStream(file); + stream.end(); + stream.on('close', common.mustCall()); +} + +{ + const file = path.join(tmpdir.path, 'write-end-test1.txt'); + const stream = fs.createWriteStream(file); + stream.end('a\n', 'utf8'); + stream.on('close', common.mustCall(function() { + const content = fs.readFileSync(file, 'utf8'); + assert.strictEqual(content, 'a\n'); + })); +} + +{ + const file = path.join(tmpdir.path, 'write-end-test2.txt'); + const stream = fs.createWriteStream(file); + stream.end(); + + let calledOpen = false; + stream.on('open', () => { + calledOpen = true; + }); + stream.on('finish', common.mustCall(() => { + assert.strictEqual(calledOpen, true); + })); +} diff --git a/tests/node_compat/test/parallel/test-fs-write-stream-fs.js b/tests/node_compat/test/parallel/test-fs-write-stream-fs.js new file mode 100644 index 000000000..533a60d4d --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-write-stream-fs.js @@ -0,0 +1,45 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const path = require('path'); +const fs = require('fs'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +{ + const file = path.join(tmpdir.path, 'write-end-test0.txt'); + const stream = fs.createWriteStream(file, { + fs: { + open: common.mustCall(fs.open), + write: common.mustCallAtLeast(fs.write, 1), + close: common.mustCall(fs.close), + } + }); + stream.end('asd'); + stream.on('close', common.mustCall()); +} + + +{ + const file = path.join(tmpdir.path, 'write-end-test1.txt'); + const stream = fs.createWriteStream(file, { + fs: { + open: common.mustCall(fs.open), + write: fs.write, + writev: common.mustCallAtLeast(fs.writev, 1), + close: common.mustCall(fs.close), + } + }); + stream.write('asd'); + stream.write('asd'); + stream.write('asd'); + stream.end(); + stream.on('close', common.mustCall()); +} diff --git a/tests/node_compat/test/parallel/test-fs-write-stream-throw-type-error.js b/tests/node_compat/test/parallel/test-fs-write-stream-throw-type-error.js new file mode 100644 index 000000000..5540725f7 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-write-stream-throw-type-error.js @@ -0,0 +1,39 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); + +const tmpdir = require('../common/tmpdir'); + +const example = path.join(tmpdir.path, 'dummy'); + +tmpdir.refresh(); +// Should not throw. +fs.createWriteStream(example, undefined).end(); +fs.createWriteStream(example, null).end(); +fs.createWriteStream(example, 'utf8').end(); +fs.createWriteStream(example, { encoding: 'utf8' }).end(); + +const createWriteStreamErr = (path, opt) => { + assert.throws( + () => { + fs.createWriteStream(path, opt); + }, + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + }); +}; + +createWriteStreamErr(example, 123); +createWriteStreamErr(example, 0); +createWriteStreamErr(example, true); +createWriteStreamErr(example, false); diff --git a/tests/node_compat/test/parallel/test-fs-write-stream.js b/tests/node_compat/test/parallel/test-fs-write-stream.js new file mode 100644 index 000000000..4d03d44a8 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-write-stream.js @@ -0,0 +1,74 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const path = require('path'); +const fs = require('fs'); + +const tmpdir = require('../common/tmpdir'); + +const file = path.join(tmpdir.path, 'write.txt'); + +tmpdir.refresh(); + +{ + const stream = fs.WriteStream(file); + const _fs_close = fs.close; + + fs.close = function(fd) { + assert.ok(fd, 'fs.close must not be called without an undefined fd.'); + fs.close = _fs_close; + fs.closeSync(fd); + }; + stream.destroy(); +} + +{ + const stream = fs.createWriteStream(file); + + stream.on('drain', function() { + assert.fail('\'drain\' event must not be emitted before ' + + 'stream.write() has been called at least once.'); + }); + stream.destroy(); +} + +// Throws if data is not of type Buffer. +{ + const stream = fs.createWriteStream(file); + stream.on('error', common.mustNotCall()); + assert.throws(() => { + stream.write(42); + }, { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + }); + stream.destroy(); +} diff --git a/tests/node_compat/test/parallel/test-fs-write-sync.js b/tests/node_compat/test/parallel/test-fs-write-sync.js new file mode 100644 index 000000000..8d9ee9efe --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-write-sync.js @@ -0,0 +1,63 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const path = require('path'); +const fs = require('fs'); +const tmpdir = require('../common/tmpdir'); +const filename = path.join(tmpdir.path, 'write.txt'); + +tmpdir.refresh(); + +{ + const parameters = [Buffer.from('bár'), 0, Buffer.byteLength('bár')]; + + // The first time fs.writeSync is called with all parameters provided. + // After that, each pop in the cycle removes the final parameter. So: + // - The 2nd time fs.writeSync with a buffer, without the length parameter. + // - The 3rd time fs.writeSync with a buffer, without the offset and length + // parameters. + while (parameters.length > 0) { + const fd = fs.openSync(filename, 'w'); + + let written = fs.writeSync(fd, ''); + assert.strictEqual(written, 0); + + fs.writeSync(fd, 'foo'); + + written = fs.writeSync(fd, ...parameters); + assert.ok(written > 3); + fs.closeSync(fd); + + assert.strictEqual(fs.readFileSync(filename, 'utf-8'), 'foobár'); + + parameters.pop(); + } +} diff --git a/tests/node_compat/test/parallel/test-fs-write.js b/tests/node_compat/test/parallel/test-fs-write.js new file mode 100644 index 000000000..33fcb84cf --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-write.js @@ -0,0 +1,212 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// Flags: --expose_externalize_string +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const path = require('path'); +const fs = require('fs'); +const tmpdir = require('../common/tmpdir'); + +tmpdir.refresh(); + +const fn = path.join(tmpdir.path, 'write.txt'); +const fn2 = path.join(tmpdir.path, 'write2.txt'); +const fn3 = path.join(tmpdir.path, 'write3.txt'); +const fn4 = path.join(tmpdir.path, 'write4.txt'); +const fn5 = path.join(tmpdir.path, 'write5.txt'); +const expected = 'ümlaut.'; +const constants = fs.constants; + +const { externalizeString, isOneByteString } = global; + +// Account for extra globals exposed by --expose_externalize_string. +common.allowGlobals(externalizeString, isOneByteString, global.x); + +{ + const expected = 'ümlaut sechzig'; // Must be a unique string. + externalizeString(expected); + assert.strictEqual(isOneByteString(expected), true); + const fd = fs.openSync(fn, 'w'); + fs.writeSync(fd, expected, 0, 'latin1'); + fs.closeSync(fd); + assert.strictEqual(fs.readFileSync(fn, 'latin1'), expected); +} + +{ + const expected = 'ümlaut neunzig'; // Must be a unique string. + externalizeString(expected); + assert.strictEqual(isOneByteString(expected), true); + const fd = fs.openSync(fn, 'w'); + fs.writeSync(fd, expected, 0, 'utf8'); + fs.closeSync(fd); + assert.strictEqual(fs.readFileSync(fn, 'utf8'), expected); +} + +{ + const expected = 'Zhōngwén 1'; // Must be a unique string. + externalizeString(expected); + assert.strictEqual(isOneByteString(expected), false); + const fd = fs.openSync(fn, 'w'); + fs.writeSync(fd, expected, 0, 'ucs2'); + fs.closeSync(fd); + assert.strictEqual(fs.readFileSync(fn, 'ucs2'), expected); +} + +{ + const expected = 'Zhōngwén 2'; // Must be a unique string. + externalizeString(expected); + assert.strictEqual(isOneByteString(expected), false); + const fd = fs.openSync(fn, 'w'); + fs.writeSync(fd, expected, 0, 'utf8'); + fs.closeSync(fd); + assert.strictEqual(fs.readFileSync(fn, 'utf8'), expected); +} + +fs.open(fn, 'w', 0o644, common.mustSucceed((fd) => { + const done = common.mustSucceed((written) => { + assert.strictEqual(written, Buffer.byteLength(expected)); + fs.closeSync(fd); + const found = fs.readFileSync(fn, 'utf8'); + fs.unlinkSync(fn); + assert.strictEqual(found, expected); + }); + + const written = common.mustSucceed((written) => { + assert.strictEqual(written, 0); + fs.write(fd, expected, 0, 'utf8', done); + }); + + fs.write(fd, '', 0, 'utf8', written); +})); + +// TODO(kt3k): Enable this test when fs.open supports number for `flags` +// paramter. +/* +const args = constants.O_CREAT | constants.O_WRONLY | constants.O_TRUNC; +fs.open(fn2, args, 0o644, common.mustSucceed((fd) => { + const done = common.mustSucceed((written) => { + assert.strictEqual(written, Buffer.byteLength(expected)); + fs.closeSync(fd); + const found = fs.readFileSync(fn2, 'utf8'); + fs.unlinkSync(fn2); + assert.strictEqual(found, expected); + }); + + const written = common.mustSucceed((written) => { + assert.strictEqual(written, 0); + fs.write(fd, expected, 0, 'utf8', done); + }); + + fs.write(fd, '', 0, 'utf8', written); +})); +*/ + +fs.open(fn3, 'w', 0o644, common.mustSucceed((fd) => { + const done = common.mustSucceed((written) => { + assert.strictEqual(written, Buffer.byteLength(expected)); + fs.closeSync(fd); + }); + + fs.write(fd, expected, done); +})); + +fs.open(fn4, 'w', 0o644, common.mustSucceed((fd) => { + const done = common.mustSucceed((written) => { + assert.strictEqual(written, Buffer.byteLength(expected)); + fs.closeSync(fd); + }); + + const data = { + toString() { return expected; } + }; + fs.write(fd, data, done); +})); + +[false, 'test', {}, [], null, undefined].forEach((i) => { + assert.throws( + () => fs.write(i, common.mustNotCall()), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + } + ); + assert.throws( + () => fs.writeSync(i), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + } + ); +}); + +[false, 5, {}, [], null, undefined].forEach((data) => { + assert.throws( + () => fs.write(1, data, common.mustNotCall()), + { + code: 'ERR_INVALID_ARG_TYPE', + message: /"buffer"/ + } + ); + assert.throws( + () => fs.writeSync(1, data), + { + code: 'ERR_INVALID_ARG_TYPE', + message: /"buffer"/ + } + ); +}); + +{ + // Regression test for https://github.com/nodejs/node/issues/38168 + const fd = fs.openSync(fn5, 'w'); + + assert.throws( + () => fs.writeSync(fd, 'abc', 0, 'hex'), + { + code: 'ERR_INVALID_ARG_VALUE', + message: /'encoding' is invalid for data of length 3/ + } + ); + + assert.throws( + () => fs.writeSync(fd, 'abc', 0, 'hex', common.mustNotCall()), + { + code: 'ERR_INVALID_ARG_VALUE', + message: /'encoding' is invalid for data of length 3/ + } + ); + + assert.strictEqual(fs.writeSync(fd, 'abcd', 0, 'hex'), 2); + + fs.write(fd, 'abcd', 0, 'hex', common.mustSucceed((written) => { + assert.strictEqual(written, 2); + fs.closeSync(fd); + })); +} diff --git a/tests/node_compat/test/parallel/test-fs-writev-sync.js b/tests/node_compat/test/parallel/test-fs-writev-sync.js new file mode 100644 index 000000000..53fa48af1 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-writev-sync.js @@ -0,0 +1,104 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); +const path = require('path'); +const fs = require('fs'); +const tmpdir = require('../common/tmpdir'); + +tmpdir.refresh(); + +const expected = 'ümlaut. Лорем 運務ホソモ指及 आपको करने विकास 紙読決多密所 أضف'; + +const getFileName = (i) => path.join(tmpdir.path, `writev_sync_${i}.txt`); + +/** + * Testing with a array of buffers input + */ + +// fs.writevSync with array of buffers with all parameters +{ + const filename = getFileName(1); + const fd = fs.openSync(filename, 'w'); + + const buffer = Buffer.from(expected); + const bufferArr = [buffer, buffer]; + const expectedLength = bufferArr.length * buffer.byteLength; + + let written = fs.writevSync(fd, [Buffer.from('')], null); + assert.strictEqual(written, 0); + + written = fs.writevSync(fd, bufferArr, null); + assert.strictEqual(written, expectedLength); + + fs.closeSync(fd); + + assert(Buffer.concat(bufferArr).equals(fs.readFileSync(filename))); +} + +// fs.writevSync with array of buffers without position +{ + const filename = getFileName(2); + const fd = fs.openSync(filename, 'w'); + + const buffer = Buffer.from(expected); + const bufferArr = [buffer, buffer, buffer]; + const expectedLength = bufferArr.length * buffer.byteLength; + + let written = fs.writevSync(fd, [Buffer.from('')]); + assert.strictEqual(written, 0); + + written = fs.writevSync(fd, bufferArr); + assert.strictEqual(written, expectedLength); + + fs.closeSync(fd); + + assert(Buffer.concat(bufferArr).equals(fs.readFileSync(filename))); +} + +// fs.writevSync with empty array of buffers +{ + const filename = getFileName(3); + const fd = fs.openSync(filename, 'w'); + const written = fs.writevSync(fd, []); + assert.strictEqual(written, 0); + fs.closeSync(fd); + +} + +/** + * Testing with wrong input types + */ +{ + const filename = getFileName(4); + const fd = fs.openSync(filename, 'w'); + + [false, 'test', {}, [{}], ['sdf'], null, undefined].forEach((i) => { + assert.throws( + () => fs.writevSync(fd, i, null), { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + } + ); + }); + + fs.closeSync(fd); +} + +// fs.writevSync with wrong fd types +[false, 'test', {}, [{}], null, undefined].forEach((i) => { + assert.throws( + () => fs.writevSync(i), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + } + ); +}); diff --git a/tests/node_compat/test/parallel/test-handle-wrap-close-abort.js b/tests/node_compat/test/parallel/test-handle-wrap-close-abort.js new file mode 100644 index 000000000..d143dd439 --- /dev/null +++ b/tests/node_compat/test/parallel/test-handle-wrap-close-abort.js @@ -0,0 +1,44 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); + +process.on('uncaughtException', common.mustCall(2)); + +setTimeout(function() { + process.nextTick(function() { + const c = setInterval(function() { + clearInterval(c); + throw new Error('setInterval'); + }, 1); + }); + setTimeout(function() { + throw new Error('setTimeout'); + }, 1); +}, 1); diff --git a/tests/node_compat/test/parallel/test-http-agent-getname.js b/tests/node_compat/test/parallel/test-http-agent-getname.js new file mode 100644 index 000000000..3404252a8 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-agent-getname.js @@ -0,0 +1,63 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); +const http = require('http'); +const path = require('path'); + +const tmpdir = require('../common/tmpdir'); + +const agent = new http.Agent(); + +// Default to localhost +assert.strictEqual( + agent.getName({ + port: 80, + localAddress: '192.168.1.1' + }), + 'localhost:80:192.168.1.1' +); + +// empty argument +assert.strictEqual( + agent.getName(), + 'localhost::' +); + +// empty options +assert.strictEqual( + agent.getName({}), + 'localhost::' +); + +// pass all arguments +assert.strictEqual( + agent.getName({ + host: '0.0.0.0', + port: 80, + localAddress: '192.168.1.1' + }), + '0.0.0.0:80:192.168.1.1' +); + +// unix socket +const socketPath = path.join(tmpdir.path, 'foo', 'bar'); +assert.strictEqual( + agent.getName({ + socketPath + }), + `localhost:::${socketPath}` +); + +for (const family of [0, null, undefined, 'bogus']) + assert.strictEqual(agent.getName({ family }), 'localhost::'); + +for (const family of [4, 6]) + assert.strictEqual(agent.getName({ family }), `localhost:::${family}`); diff --git a/tests/node_compat/test/parallel/test-http-client-get-url.js b/tests/node_compat/test/parallel/test-http-client-get-url.js new file mode 100644 index 000000000..a38d3ff7b --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-client-get-url.js @@ -0,0 +1,53 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); +const url = require('url'); +const testPath = '/foo?bar'; + +const server = http.createServer(common.mustCall((req, res) => { + assert.strictEqual(req.method, 'GET'); + assert.strictEqual(req.url, testPath); + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.write('hello\n'); + res.end(); +}, 3)); + +server.listen(0, common.localhostIPv4, common.mustCall(() => { + const u = `http://${common.localhostIPv4}:${server.address().port}${testPath}`; + http.get(u, common.mustCall(() => { + http.get(url.parse(u), common.mustCall(() => { + http.get(new URL(u), common.mustCall(() => { + server.close(); + })); + })); + })); +})); diff --git a/tests/node_compat/test/parallel/test-http-client-read-in-error.js b/tests/node_compat/test/parallel/test-http-client-read-in-error.js new file mode 100644 index 000000000..3c86ad8f5 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-client-read-in-error.js @@ -0,0 +1,48 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const net = require('net'); +const http = require('http'); + +class Agent extends http.Agent { + createConnection() { + const socket = new net.Socket(); + + socket.on('error', function() { + socket.push('HTTP/1.1 200\r\n\r\n'); + }); + + let onNewListener; + socket.on('newListener', onNewListener = (name) => { + if (name !== 'error') + return; + socket.removeListener('newListener', onNewListener); + + // Let other listeners to be set up too + process.nextTick(() => { + this.breakSocket(socket); + }); + }); + + return socket; + } + + breakSocket(socket) { + socket.emit('error', new Error('Intentional error')); + } +} + +const agent = new Agent(); + +http.request({ + agent +}).once('error', function() { + console.log('ignore'); + this.on('data', common.mustNotCall()); +}); diff --git a/tests/node_compat/test/parallel/test-http-localaddress.js b/tests/node_compat/test/parallel/test-http-localaddress.js new file mode 100644 index 000000000..ab3eff808 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-localaddress.js @@ -0,0 +1,64 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// Flags: --expose-internals +'use strict'; +const common = require('../common'); +if (!common.hasMultiLocalhost()) + common.skip('platform-specific test.'); + +const http = require('http'); +const assert = require('assert'); + +const server = http.createServer((req, res) => { + console.log(`Connect from: ${req.connection.remoteAddress}`); + assert.strictEqual(req.connection.remoteAddress, '127.0.0.2'); + + req.on('end', () => { + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.end(`You are from: ${req.connection.remoteAddress}`); + }); + req.resume(); +}); + +server.listen(0, '127.0.0.1', () => { + const options = { host: 'localhost', + port: server.address().port, + family: 4, + path: '/', + method: 'GET', + localAddress: '127.0.0.2' }; + + const req = http.request(options, function(res) { + res.on('end', () => { + server.close(); + }); + res.resume(); + }); + req.end(); +}); diff --git a/tests/node_compat/test/parallel/test-http-outgoing-internal-headernames-getter.js b/tests/node_compat/test/parallel/test-http-outgoing-internal-headernames-getter.js new file mode 100644 index 000000000..e9b324892 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-outgoing-internal-headernames-getter.js @@ -0,0 +1,30 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); + +const { OutgoingMessage } = require('http'); +const assert = require('assert'); + +const warn = 'OutgoingMessage.prototype._headerNames is deprecated'; +common.expectWarning('DeprecationWarning', warn, 'DEP0066'); + +{ + // Tests for _headerNames get method + const outgoingMessage = new OutgoingMessage(); + outgoingMessage._headerNames; // eslint-disable-line no-unused-expressions +} + +{ + // Tests _headerNames getter result after setting a header. + const outgoingMessage = new OutgoingMessage(); + outgoingMessage.setHeader('key', 'value'); + const expect = Object.create(null); + expect.key = 'key'; + assert.deepStrictEqual(outgoingMessage._headerNames, expect); +} diff --git a/tests/node_compat/test/parallel/test-http-outgoing-internal-headernames-setter.js b/tests/node_compat/test/parallel/test-http-outgoing-internal-headernames-setter.js new file mode 100644 index 000000000..9531e5611 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-outgoing-internal-headernames-setter.js @@ -0,0 +1,22 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); + +const { OutgoingMessage } = require('http'); + +const warn = 'OutgoingMessage.prototype._headerNames is deprecated'; +common.expectWarning('DeprecationWarning', warn, 'DEP0066'); + +{ + // Tests for _headerNames set method + const outgoingMessage = new OutgoingMessage(); + outgoingMessage._headerNames = { + 'x-flow-id': '61bba6c5-28a3-4eab-9241-2ecaa6b6a1fd' + }; +} diff --git a/tests/node_compat/test/parallel/test-http-outgoing-internal-headers.js b/tests/node_compat/test/parallel/test-http-outgoing-internal-headers.js new file mode 100644 index 000000000..0e4783a6d --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-outgoing-internal-headers.js @@ -0,0 +1,51 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Flags: --expose-internals +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const { kOutHeaders } = require('internal/http'); +const { OutgoingMessage } = require('http'); + +const warn = 'OutgoingMessage.prototype._headers is deprecated'; +common.expectWarning('DeprecationWarning', warn, 'DEP0066'); + +{ + // Tests for _headers get method + const outgoingMessage = new OutgoingMessage(); + outgoingMessage.getHeaders = common.mustCall(); + outgoingMessage._headers; // eslint-disable-line no-unused-expressions +} + +{ + // Tests for _headers set method + const outgoingMessage = new OutgoingMessage(); + outgoingMessage._headers = { + host: 'risingstack.com', + Origin: 'localhost' + }; + + assert.deepStrictEqual( + Object.entries(outgoingMessage[kOutHeaders]), + Object.entries({ + host: ['host', 'risingstack.com'], + origin: ['Origin', 'localhost'] + })); +} + +{ + // Tests for _headers set method `null` + const outgoingMessage = new OutgoingMessage(); + outgoingMessage._headers = null; + + assert.strictEqual( + outgoingMessage[kOutHeaders], + null + ); +} diff --git a/tests/node_compat/test/parallel/test-http-outgoing-renderHeaders.js b/tests/node_compat/test/parallel/test-http-outgoing-renderHeaders.js new file mode 100644 index 000000000..194a9345a --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-outgoing-renderHeaders.js @@ -0,0 +1,57 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +// Flags: --expose-internals + +require('../common'); +const assert = require('assert'); + +const kOutHeaders = require('internal/http').kOutHeaders; +const http = require('http'); +const OutgoingMessage = http.OutgoingMessage; + +{ + const outgoingMessage = new OutgoingMessage(); + outgoingMessage._header = {}; + assert.throws( + () => outgoingMessage._renderHeaders(), + { + code: 'ERR_HTTP_HEADERS_SENT', + name: 'Error', + message: 'Cannot render headers after they are sent to the client' + } + ); +} + +{ + const outgoingMessage = new OutgoingMessage(); + outgoingMessage[kOutHeaders] = null; + const result = outgoingMessage._renderHeaders(); + assert.deepStrictEqual(result, {}); +} + + +{ + const outgoingMessage = new OutgoingMessage(); + outgoingMessage[kOutHeaders] = {}; + const result = outgoingMessage._renderHeaders(); + assert.deepStrictEqual(result, {}); +} + +{ + const outgoingMessage = new OutgoingMessage(); + outgoingMessage[kOutHeaders] = { + host: ['host', 'nodejs.org'], + origin: ['Origin', 'localhost'] + }; + const result = outgoingMessage._renderHeaders(); + assert.deepStrictEqual(result, { + host: 'nodejs.org', + Origin: 'localhost' + }); +} diff --git a/tests/node_compat/test/parallel/test-http-outgoing-settimeout.js b/tests/node_compat/test/parallel/test-http-outgoing-settimeout.js new file mode 100644 index 000000000..592e576b4 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-outgoing-settimeout.js @@ -0,0 +1,37 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const { OutgoingMessage } = require('http'); + +{ + // Tests for settimeout method with socket + const expectedMsecs = 42; + const outgoingMessage = new OutgoingMessage(); + outgoingMessage.socket = { + setTimeout: common.mustCall((msecs) => { + assert.strictEqual(msecs, expectedMsecs); + }) + }; + outgoingMessage.setTimeout(expectedMsecs); +} + +{ + // Tests for settimeout method without socket + const expectedMsecs = 23; + const outgoingMessage = new OutgoingMessage(); + outgoingMessage.setTimeout(expectedMsecs); + + outgoingMessage.emit('socket', { + setTimeout: common.mustCall((msecs) => { + assert.strictEqual(msecs, expectedMsecs); + }) + }); +} diff --git a/tests/node_compat/test/parallel/test-http-url.parse-auth-with-header-in-request.js b/tests/node_compat/test/parallel/test-http-url.parse-auth-with-header-in-request.js new file mode 100644 index 000000000..24cc2f33d --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-url.parse-auth-with-header-in-request.js @@ -0,0 +1,59 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const http = require('http'); +const url = require('url'); + +function check(request) { + // The correct authorization header is be passed + assert.strictEqual(request.headers.authorization, 'NoAuthForYOU'); +} + +const server = http.createServer(function(request, response) { + // Run the check function + check(request); + response.writeHead(200, {}); + response.end('ok'); + server.close(); +}); + +server.listen(0, function() { + const testURL = + url.parse(`http://asdf:qwer@localhost:${this.address().port}`); + // The test here is if you set a specific authorization header in the + // request we should not override that with basic auth + testURL.headers = { + Authorization: 'NoAuthForYOU' + }; + + // make the request + http.request(testURL).end(); +}); diff --git a/tests/node_compat/test/parallel/test-http-url.parse-auth.js b/tests/node_compat/test/parallel/test-http-url.parse-auth.js new file mode 100644 index 000000000..c9b691aa2 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-url.parse-auth.js @@ -0,0 +1,55 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const http = require('http'); +const url = require('url'); + +function check(request) { + // The correct authorization header is be passed + assert.strictEqual(request.headers.authorization, 'Basic dXNlcjpwYXNzOg=='); +} + +const server = http.createServer(function(request, response) { + // Run the check function + check(request); + response.writeHead(200, {}); + response.end('ok'); + server.close(); +}); + +server.listen(0, function() { + const port = this.address().port; + // username = "user", password = "pass:" + const testURL = url.parse(`http://user:pass%3A@localhost:${port}`); + + // make the request + http.request(testURL).end(); +}); diff --git a/tests/node_compat/test/parallel/test-http-url.parse-basic.js b/tests/node_compat/test/parallel/test-http-url.parse-basic.js new file mode 100644 index 000000000..e41bf41a1 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-url.parse-basic.js @@ -0,0 +1,65 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const http = require('http'); +const url = require('url'); + +let testURL; + +// Make sure the basics work +function check(request) { + // Default method should still be 'GET' + assert.strictEqual(request.method, 'GET'); + // There are no URL params, so you should not see any + assert.strictEqual(request.url, '/'); + // The host header should use the url.parse.hostname + assert.strictEqual(request.headers.host, + `${testURL.hostname}:${testURL.port}`); +} + +const server = http.createServer(function(request, response) { + // Run the check function + check(request); + response.writeHead(200, {}); + response.end('ok'); + server.close(); +}); + +server.listen(0, function() { + testURL = url.parse(`http://localhost:${this.address().port}`); + + // make the request + const clientRequest = http.request(testURL); + // Since there is a little magic with the agent + // make sure that an http request uses the http.Agent + assert.ok(clientRequest.agent instanceof http.Agent); + clientRequest.end(); +}); diff --git a/tests/node_compat/test/parallel/test-http-url.parse-https.request.js b/tests/node_compat/test/parallel/test-http-url.parse-https.request.js new file mode 100644 index 000000000..89c7ca2b4 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-url.parse-https.request.js @@ -0,0 +1,69 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); +const { readKey } = require('../common/fixtures'); + +const assert = require('assert'); +const https = require('https'); +const url = require('url'); + +// https options +const httpsOptions = { + key: readKey('agent1-key.pem'), + cert: readKey('agent1-cert.pem') +}; + +function check(request) { + // Assert that I'm https + assert.ok(request.socket._secureEstablished); +} + +const server = https.createServer(httpsOptions, function(request, response) { + // Run the check function + check(request); + response.writeHead(200, {}); + response.end('ok'); + server.close(); +}); + +// TODO(wafuwafu13): rejectUnauthorized is always true in Deno +// server.listen(0, function() { +// const testURL = url.parse(`https://localhost:${this.address().port}`); +// testURL.rejectUnauthorized = false; + +// // make the request +// const clientRequest = https.request(testURL); +// // Since there is a little magic with the agent +// // make sure that the request uses the https.Agent +// assert.ok(clientRequest.agent instanceof https.Agent); +// clientRequest.end(); +// }); diff --git a/tests/node_compat/test/parallel/test-http-url.parse-only-support-http-https-protocol.js b/tests/node_compat/test/parallel/test-http-url.parse-only-support-http-https-protocol.js new file mode 100644 index 000000000..4f50f8a54 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-url.parse-only-support-http-https-protocol.js @@ -0,0 +1,52 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const http = require('http'); +const url = require('url'); + +const invalidUrls = [ + 'file:///whatever', + 'mailto:asdf@asdf.com', + 'ftp://www.example.com', + 'javascript:alert(\'hello\');', + 'xmpp:foo@bar.com', + 'f://some.host/path', +]; + +invalidUrls.forEach((invalid) => { + assert.throws( + () => { http.request(url.parse(invalid)); }, + { + code: 'ERR_INVALID_PROTOCOL', + name: 'TypeError' + } + ); +}); diff --git a/tests/node_compat/test/parallel/test-http-url.parse-path.js b/tests/node_compat/test/parallel/test-http-url.parse-path.js new file mode 100644 index 000000000..7077fcae1 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-url.parse-path.js @@ -0,0 +1,53 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const http = require('http'); +const url = require('url'); + +function check(request) { + // A path should come over + assert.strictEqual(request.url, '/asdf'); +} + +const server = http.createServer(function(request, response) { + // Run the check function + check(request); + response.writeHead(200, {}); + response.end('ok'); + server.close(); +}); + +server.listen(0, function() { + const testURL = url.parse(`http://localhost:${this.address().port}/asdf`); + + // make the request + http.request(testURL).end(); +}); diff --git a/tests/node_compat/test/parallel/test-http-url.parse-post.js b/tests/node_compat/test/parallel/test-http-url.parse-post.js new file mode 100644 index 000000000..da316d2db --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-url.parse-post.js @@ -0,0 +1,61 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const http = require('http'); +const url = require('url'); + +let testURL; + +function check(request) { + // url.parse should not mess with the method + assert.strictEqual(request.method, 'POST'); + // Everything else should be right + assert.strictEqual(request.url, '/asdf?qwer=zxcv'); + // The host header should use the url.parse.hostname + assert.strictEqual(request.headers.host, + `${testURL.hostname}:${testURL.port}`); +} + +const server = http.createServer(function(request, response) { + // Run the check function + check(request); + response.writeHead(200, {}); + response.end('ok'); + server.close(); +}); + +server.listen(0, function() { + testURL = url.parse(`http://localhost:${this.address().port}/asdf?qwer=zxcv`); + testURL.method = 'POST'; + + // make the request + http.request(testURL).end(); +}); diff --git a/tests/node_compat/test/parallel/test-http-url.parse-search.js b/tests/node_compat/test/parallel/test-http-url.parse-search.js new file mode 100644 index 000000000..52651869d --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-url.parse-search.js @@ -0,0 +1,54 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const http = require('http'); +const url = require('url'); + +function check(request) { + // A path should come over with params + assert.strictEqual(request.url, '/asdf?qwer=zxcv'); +} + +const server = http.createServer(function(request, response) { + // Run the check function + check(request); + response.writeHead(200, {}); + response.end('ok'); + server.close(); +}); + +server.listen(0, function() { + const port = this.address().port; + const testURL = url.parse(`http://localhost:${port}/asdf?qwer=zxcv`); + + // make the request + http.request(testURL).end(); +}); diff --git a/tests/node_compat/test/parallel/test-net-access-byteswritten.js b/tests/node_compat/test/parallel/test-net-access-byteswritten.js new file mode 100644 index 000000000..a20a1a7a7 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-access-byteswritten.js @@ -0,0 +1,28 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const net = require('net'); +const tls = require('tls'); +const tty = require('tty'); + +// Check that the bytesWritten getter doesn't crash if object isn't +// constructed. +assert.strictEqual(net.Socket.prototype.bytesWritten, undefined); +assert.strictEqual(Object.getPrototypeOf(tls.TLSSocket).prototype.bytesWritten, + undefined); +assert.strictEqual(tls.TLSSocket.prototype.bytesWritten, undefined); +assert.strictEqual(Object.getPrototypeOf(tty.ReadStream).prototype.bytesWritten, + undefined); +assert.strictEqual(tty.ReadStream.prototype.bytesWritten, undefined); +assert.strictEqual(tty.WriteStream.prototype.bytesWritten, undefined); diff --git a/tests/node_compat/test/parallel/test-net-better-error-messages-listen-path.js b/tests/node_compat/test/parallel/test-net-better-error-messages-listen-path.js new file mode 100644 index 000000000..edafbcdc4 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-better-error-messages-listen-path.js @@ -0,0 +1,17 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); +const fp = '/blah/fadfa'; +const server = net.createServer(common.mustNotCall()); +server.listen(fp, common.mustNotCall()); +server.on('error', common.mustCall(function(e) { + assert.strictEqual(e.address, fp); +})); diff --git a/tests/node_compat/test/parallel/test-net-better-error-messages-path.js b/tests/node_compat/test/parallel/test-net-better-error-messages-path.js new file mode 100644 index 000000000..d1bada362 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-better-error-messages-path.js @@ -0,0 +1,29 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); + +{ + const fp = '/tmp/fadagagsdfgsdf'; + const c = net.connect(fp); + + c.on('connect', common.mustNotCall()); + c.on('error', common.expectsError({ + code: 'ENOENT', + message: `connect ENOENT ${fp}` + })); +} + +{ + assert.throws( + () => net.createConnection({ path: {} }), + { code: 'ERR_INVALID_ARG_TYPE' } + ); +} diff --git a/tests/node_compat/test/parallel/test-net-better-error-messages-port-hostname.js b/tests/node_compat/test/parallel/test-net-better-error-messages-port-hostname.js new file mode 100644 index 000000000..6db63fef3 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-better-error-messages-port-hostname.js @@ -0,0 +1,44 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +// This tests that the error thrown from net.createConnection +// comes with host and port properties. +// See https://github.com/nodejs/node-v0.x-archive/issues/7005 + +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); + +const { addresses } = require('../common/internet'); +const { + errorLookupMock, + mockedErrorCode +} = require('../common/dns'); + +// Using port 0 as hostname used is already invalid. +const c = net.createConnection({ + port: 0, + host: addresses.INVALID_HOST, + lookup: common.mustCall(errorLookupMock()) +}); + +c.on('connect', common.mustNotCall()); + +c.on('error', common.mustCall((error) => { + assert.ok(!('port' in error)); + assert.ok(!('host' in error)); + assert.throws(() => { throw error; }, { + errno: mockedErrorCode, + code: mockedErrorCode, + name: 'Error', + message: 'getaddrinfo ENOTFOUND something.invalid', + hostname: addresses.INVALID_HOST, + syscall: 'getaddrinfo' + }); +})); diff --git a/tests/node_compat/test/parallel/test-net-connect-after-destroy.js b/tests/node_compat/test/parallel/test-net-connect-after-destroy.js new file mode 100644 index 000000000..e08d7c036 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-connect-after-destroy.js @@ -0,0 +1,16 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +// Regression test for https://github.com/nodejs/node-v0.x-archive/issues/819. + +require('../common'); +const net = require('net'); + +// Connect to something that we need to DNS resolve +const c = net.createConnection(80, 'google.com'); +c.destroy(); diff --git a/tests/node_compat/test/parallel/test-net-connect-buffer.js b/tests/node_compat/test/parallel/test-net-connect-buffer.js new file mode 100644 index 000000000..04e71247e --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-connect-buffer.js @@ -0,0 +1,86 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); + +// TODO: support not using "new" +const tcp = new net.Server(common.mustCall((s) => { + tcp.close(); + + let buf = ''; + s.setEncoding('utf8'); + s.on('data', function(d) { + buf += d; + }); + + s.on('end', common.mustCall(function() { + console.error('SERVER: end', buf); + assert.strictEqual(buf, "L'État, c'est moi"); + s.end(); + })); +})); + +tcp.listen(0, common.mustCall(function() { + // TODO: support not using "new" + const socket = new net.Stream({ highWaterMark: 0 }); + + let connected = false; + assert.strictEqual(socket.pending, true); + socket.connect(this.address().port, common.mustCall(() => connected = true)); + + assert.strictEqual(socket.pending, true); + assert.strictEqual(socket.connecting, true); + assert.strictEqual(socket.readyState, 'opening'); + + // Write a string that contains a multi-byte character sequence to test that + // `bytesWritten` is incremented with the # of bytes, not # of characters. + const a = "L'État, c'est "; + const b = 'moi'; + + // We're still connecting at this point so the datagram is first pushed onto + // the connect queue. Make sure that it's not added to `bytesWritten` again + // when the actual write happens. + const r = socket.write(a, common.mustCall((er) => { + console.error('write cb'); + assert.ok(connected); + assert.strictEqual(socket.bytesWritten, Buffer.from(a + b).length); + assert.strictEqual(socket.pending, false); + })); + socket.on('close', common.mustCall(() => { + assert.strictEqual(socket.pending, true); + })); + + assert.strictEqual(socket.bytesWritten, Buffer.from(a).length); + assert.strictEqual(r, false); + socket.end(b); + + assert.strictEqual(socket.readyState, 'opening'); +})); diff --git a/tests/node_compat/test/parallel/test-net-connect-buffer2.js b/tests/node_compat/test/parallel/test-net-connect-buffer2.js new file mode 100644 index 000000000..499f3849f --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-connect-buffer2.js @@ -0,0 +1,63 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); + +const tcp = new net.Server(common.mustCall((s) => { + tcp.close(); + + let buf = ''; + s.setEncoding('utf8'); + s.on('data', function(d) { + buf += d; + }); + + s.on('end', common.mustCall(function() { + console.error('SERVER: end', buf); + assert.strictEqual(buf, "L'État, c'est moi"); + s.end(); + })); +})); + +tcp.listen(0, common.mustCall(function() { + const socket = new net.Stream({ highWaterMark: 0 }); + + let connected = false; + assert.strictEqual(socket.pending, true); + socket.connect(this.address().port, common.mustCall(() => connected = true)); + + assert.strictEqual(socket.pending, true); + assert.strictEqual(socket.connecting, true); + assert.strictEqual(socket.readyState, 'opening'); + + // Write a string that contains a multi-byte character sequence to test that + // `bytesWritten` is incremented with the # of bytes, not # of characters. + const a = "L'État, c'est "; + const b = 'moi'; + + // We're still connecting at this point so the datagram is first pushed onto + // the connect queue. Make sure that it's not added to `bytesWritten` again + // when the actual write happens. + const r = socket.write(a, common.mustCall((er) => { + console.error('write cb'); + assert.ok(connected); + assert.strictEqual(socket.bytesWritten, Buffer.from(a + b).length); + assert.strictEqual(socket.pending, false); + })); + socket.on('close', common.mustCall(() => { + assert.strictEqual(socket.pending, true); + })); + + assert.strictEqual(socket.bytesWritten, Buffer.from(a).length); + assert.strictEqual(r, false); + socket.end(b); + + assert.strictEqual(socket.readyState, 'opening'); +})); diff --git a/tests/node_compat/test/parallel/test-net-connect-destroy.js b/tests/node_compat/test/parallel/test-net-connect-destroy.js new file mode 100644 index 000000000..2dcea39b2 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-connect-destroy.js @@ -0,0 +1,14 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const net = require('net'); + +const socket = new net.Socket(); +socket.on('close', common.mustCall()); +socket.destroy(); diff --git a/tests/node_compat/test/parallel/test-net-connect-immediate-destroy.js b/tests/node_compat/test/parallel/test-net-connect-immediate-destroy.js new file mode 100644 index 000000000..08d65f75e --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-connect-immediate-destroy.js @@ -0,0 +1,18 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const net = require('net'); + +const server = net.createServer(); +server.listen(0); +const port = server.address().port; +const socket = net.connect(port, common.localhostIPv4, common.mustNotCall()); +socket.on('error', common.mustNotCall()); +server.close(); +socket.destroy(); diff --git a/tests/node_compat/test/parallel/test-net-connect-immediate-finish.js b/tests/node_compat/test/parallel/test-net-connect-immediate-finish.js new file mode 100644 index 000000000..4df92e9c1 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-connect-immediate-finish.js @@ -0,0 +1,66 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; + +// This tests that if the socket is still in the 'connecting' state +// when the user calls socket.end() ('finish'), the socket would emit +// 'connect' and defer the handling until the 'connect' event is handled. + +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); + +const { addresses } = require('../common/internet'); +const { + errorLookupMock, + mockedErrorCode, + mockedSysCall +} = require('../common/dns'); + +const client = net.connect({ + host: addresses.INVALID_HOST, + port: 80, // Port number doesn't matter because host name is invalid + lookup: common.mustCall(errorLookupMock()) +}, common.mustNotCall()); + +client.once('error', common.mustCall((error) => { + // TODO(BridgeAR): Add a better way to handle not defined properties using + // `assert.throws(fn, object)`. + assert.ok(!('port' in error)); + assert.ok(!('host' in error)); + assert.throws(() => { throw error; }, { + code: mockedErrorCode, + errno: mockedErrorCode, + syscall: mockedSysCall, + hostname: addresses.INVALID_HOST, + message: 'getaddrinfo ENOTFOUND something.invalid' + }); +})); + +client.end(); diff --git a/tests/node_compat/test/parallel/test-net-connect-no-arg.js b/tests/node_compat/test/parallel/test-net-connect-no-arg.js new file mode 100644 index 000000000..3e3e3eec4 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-connect-no-arg.js @@ -0,0 +1,42 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); +const net = require('net'); + +// Tests that net.connect() called without arguments throws ERR_MISSING_ARGS. + +assert.throws(() => { + net.connect(); +}, { + code: 'ERR_MISSING_ARGS', + message: 'The "options" or "port" or "path" argument must be specified', +}); + +assert.throws(() => { + new net.Socket().connect(); +}, { + code: 'ERR_MISSING_ARGS', + message: 'The "options" or "port" or "path" argument must be specified', +}); + +assert.throws(() => { + net.connect({}); +}, { + code: 'ERR_MISSING_ARGS', + message: 'The "options" or "port" or "path" argument must be specified', +}); + +assert.throws(() => { + new net.Socket().connect({}); +}, { + code: 'ERR_MISSING_ARGS', + message: 'The "options" or "port" or "path" argument must be specified', +}); diff --git a/tests/node_compat/test/parallel/test-net-dns-error.js b/tests/node_compat/test/parallel/test-net-dns-error.js new file mode 100644 index 000000000..ce326dd6f --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-dns-error.js @@ -0,0 +1,48 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); + +const assert = require('assert'); +const net = require('net'); + +const host = '*'.repeat(64); +// Resolving hostname > 63 characters may return EAI_FAIL (permanent failure). +const errCodes = ['ENOTFOUND', 'EAI_FAIL']; + +const socket = net.connect(42, host, common.mustNotCall()); +socket.on('error', common.mustCall(function(err) { + assert(errCodes.includes(err.code), err); +})); +socket.on('lookup', common.mustCall(function(err, ip, type) { + assert(err instanceof Error); + assert(errCodes.includes(err.code), err); + assert.strictEqual(ip, undefined); + assert.strictEqual(type, undefined); +})); diff --git a/tests/node_compat/test/parallel/test-net-during-close.js b/tests/node_compat/test/parallel/test-net-during-close.js new file mode 100644 index 000000000..f13c9fb18 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-during-close.js @@ -0,0 +1,49 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const net = require('net'); + +const server = net.createServer(function(socket) { + socket.end(); +}); + +server.listen(0, common.mustCall(function() { + /* eslint-disable no-unused-expressions */ + const client = net.createConnection(this.address().port); + server.close(); + // Server connection event has not yet fired client is still attempting to + // connect. Accessing properties should not throw in this case. + client.remoteAddress; + client.remoteFamily; + client.remotePort; + // Exit now, do not wait for the client error event. + process.exit(0); + /* eslint-enable no-unused-expressions */ +})); diff --git a/tests/node_compat/test/parallel/test-net-end-close.js b/tests/node_compat/test/parallel/test-net-end-close.js new file mode 100644 index 000000000..a818dd097 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-end-close.js @@ -0,0 +1,44 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Flags: --expose-internals +'use strict'; +require('../common'); +const assert = require('assert'); +const net = require('net'); + +// const { internalBinding } = require('internal/test/binding'); +// const { UV_EOF } = internalBinding('uv'); +// const { streamBaseState, kReadBytesOrError } = internalBinding('stream_wrap'); + +const s = new net.Socket({ + handle: { + readStart: function() { + setImmediate(() => { + // streamBaseState[kReadBytesOrError] = UV_EOF; + // internal onread has different shape to Node. + this.onread(new Uint8Array(), -4095); + }); + }, + close: (cb) => setImmediate(cb) + }, + writable: false +}); +assert.strictEqual(s, s.resume()); + +const events = []; + +s.on('end', () => { + events.push('end'); +}); +s.on('close', () => { + events.push('close'); +}); + +process.on('exit', () => { + assert.deepStrictEqual(events, [ 'end', 'close' ]); +}); diff --git a/tests/node_compat/test/parallel/test-net-end-without-connect.js b/tests/node_compat/test/parallel/test-net-end-without-connect.js new file mode 100644 index 000000000..f14d81770 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-end-without-connect.js @@ -0,0 +1,34 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const net = require('net'); + +const sock = new net.Socket(); +sock.end(); // Should not throw. diff --git a/tests/node_compat/test/parallel/test-net-isip.js b/tests/node_compat/test/parallel/test-net-isip.js new file mode 100644 index 000000000..016277483 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-isip.js @@ -0,0 +1,103 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const net = require('net'); + +assert.strictEqual(net.isIP('127.0.0.1'), 4); +assert.strictEqual(net.isIP('x127.0.0.1'), 0); +assert.strictEqual(net.isIP('example.com'), 0); +assert.strictEqual(net.isIP('0000:0000:0000:0000:0000:0000:0000:0000'), 6); +assert.strictEqual(net.isIP('0000:0000:0000:0000:0000:0000:0000:0000::0000'), + 0); +assert.strictEqual(net.isIP('1050:0:0:0:5:600:300c:326b'), 6); +assert.strictEqual(net.isIP('2001:252:0:1::2008:6'), 6); +assert.strictEqual(net.isIP('2001:dead:beef:1::2008:6'), 6); +assert.strictEqual(net.isIP('2001::'), 6); +assert.strictEqual(net.isIP('2001:dead::'), 6); +assert.strictEqual(net.isIP('2001:dead:beef::'), 6); +assert.strictEqual(net.isIP('2001:dead:beef:1::'), 6); +assert.strictEqual(net.isIP('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'), 6); +assert.strictEqual(net.isIP(':2001:252:0:1::2008:6:'), 0); +assert.strictEqual(net.isIP(':2001:252:0:1::2008:6'), 0); +assert.strictEqual(net.isIP('2001:252:0:1::2008:6:'), 0); +assert.strictEqual(net.isIP('2001:252::1::2008:6'), 0); +assert.strictEqual(net.isIP('::2001:252:1:2008:6'), 6); +assert.strictEqual(net.isIP('::2001:252:1:1.1.1.1'), 6); +assert.strictEqual(net.isIP('::2001:252:1:255.255.255.255'), 6); +assert.strictEqual(net.isIP('::2001:252:1:255.255.255.255.76'), 0); +assert.strictEqual(net.isIP('fe80::2008%eth0'), 6); +assert.strictEqual(net.isIP('fe80::2008%eth0.0'), 6); +assert.strictEqual(net.isIP('fe80::2008%eth0@1'), 0); +assert.strictEqual(net.isIP('::anything'), 0); +assert.strictEqual(net.isIP('::1'), 6); +assert.strictEqual(net.isIP('::'), 6); +assert.strictEqual(net.isIP('0000:0000:0000:0000:0000:0000:12345:0000'), 0); +assert.strictEqual(net.isIP('0'), 0); +assert.strictEqual(net.isIP(), 0); +assert.strictEqual(net.isIP(''), 0); +assert.strictEqual(net.isIP(null), 0); +assert.strictEqual(net.isIP(123), 0); +assert.strictEqual(net.isIP(true), 0); +assert.strictEqual(net.isIP({}), 0); +assert.strictEqual(net.isIP({ toString: () => '::2001:252:1:255.255.255.255' }), + 6); +assert.strictEqual(net.isIP({ toString: () => '127.0.0.1' }), 4); +assert.strictEqual(net.isIP({ toString: () => 'bla' }), 0); + +assert.strictEqual(net.isIPv4('127.0.0.1'), true); +assert.strictEqual(net.isIPv4('example.com'), false); +assert.strictEqual(net.isIPv4('2001:252:0:1::2008:6'), false); +assert.strictEqual(net.isIPv4(), false); +assert.strictEqual(net.isIPv4(''), false); +assert.strictEqual(net.isIPv4(null), false); +assert.strictEqual(net.isIPv4(123), false); +assert.strictEqual(net.isIPv4(true), false); +assert.strictEqual(net.isIPv4({}), false); +assert.strictEqual(net.isIPv4({ + toString: () => '::2001:252:1:255.255.255.255' +}), false); +assert.strictEqual(net.isIPv4({ toString: () => '127.0.0.1' }), true); +assert.strictEqual(net.isIPv4({ toString: () => 'bla' }), false); + +assert.strictEqual(net.isIPv6('127.0.0.1'), false); +assert.strictEqual(net.isIPv6('example.com'), false); +assert.strictEqual(net.isIPv6('2001:252:0:1::2008:6'), true); +assert.strictEqual(net.isIPv6(), false); +assert.strictEqual(net.isIPv6(''), false); +assert.strictEqual(net.isIPv6(null), false); +assert.strictEqual(net.isIPv6(123), false); +assert.strictEqual(net.isIPv6(true), false); +assert.strictEqual(net.isIPv6({}), false); +assert.strictEqual(net.isIPv6({ + toString: () => '::2001:252:1:255.255.255.255' +}), true); +assert.strictEqual(net.isIPv6({ toString: () => '127.0.0.1' }), false); +assert.strictEqual(net.isIPv6({ toString: () => 'bla' }), false); diff --git a/tests/node_compat/test/parallel/test-net-isipv4.js b/tests/node_compat/test/parallel/test-net-isipv4.js new file mode 100644 index 000000000..a9733c342 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-isipv4.js @@ -0,0 +1,53 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const assert = require('assert'); +const net = require('net'); + +const v4 = [ + '0.0.0.0', + '8.8.8.8', + '127.0.0.1', + '100.100.100.100', + '192.168.0.1', + '18.101.25.153', + '123.23.34.2', + '172.26.168.134', + '212.58.241.131', + '128.0.0.0', + '23.71.254.72', + '223.255.255.255', + '192.0.2.235', + '99.198.122.146', + '46.51.197.88', + '173.194.34.134', +]; + +const v4not = [ + '.100.100.100.100', + '100..100.100.100.', + '100.100.100.100.', + '999.999.999.999', + '256.256.256.256', + '256.100.100.100.100', + '123.123.123', + 'http://123.123.123', + '1000.2.3.4', + '999.2.3.4', + '0000000192.168.0.200', + '192.168.0.2000000000', +]; + +v4.forEach((ip) => { + assert.strictEqual(net.isIPv4(ip), true); +}); + +v4not.forEach((ip) => { + assert.strictEqual(net.isIPv4(ip), false); +}); diff --git a/tests/node_compat/test/parallel/test-net-isipv6.js b/tests/node_compat/test/parallel/test-net-isipv6.js new file mode 100644 index 000000000..cc74fe657 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-isipv6.js @@ -0,0 +1,251 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const assert = require('assert'); +const net = require('net'); + +const v6 = [ + '::', + '1::', + '::1', + '1::8', + '1::7:8', + '1:2:3:4:5:6:7:8', + '1:2:3:4:5:6::8', + '1:2:3:4:5:6:7::', + '1:2:3:4:5::7:8', + '1:2:3:4:5::8', + '1:2:3::8', + '1::4:5:6:7:8', + '1::6:7:8', + '1::3:4:5:6:7:8', + '1:2:3:4::6:7:8', + '1:2::4:5:6:7:8', + '::2:3:4:5:6:7:8', + '1:2::8', + '2001:0000:1234:0000:0000:C1C0:ABCD:0876', + '3ffe:0b00:0000:0000:0001:0000:0000:000a', + 'FF02:0000:0000:0000:0000:0000:0000:0001', + '0000:0000:0000:0000:0000:0000:0000:0001', + '0000:0000:0000:0000:0000:0000:0000:0000', + '::ffff:192.168.1.26', + '2::10', + 'ff02::1', + 'fe80::', + '2002::', + '2001:db8::', + '2001:0db8:1234::', + '::ffff:0:0', + '::ffff:192.168.1.1', + '1:2:3:4::8', + '1::2:3:4:5:6:7', + '1::2:3:4:5:6', + '1::2:3:4:5', + '1::2:3:4', + '1::2:3', + '::2:3:4:5:6:7', + '::2:3:4:5:6', + '::2:3:4:5', + '::2:3:4', + '::2:3', + '::8', + '1:2:3:4:5:6::', + '1:2:3:4:5::', + '1:2:3:4::', + '1:2:3::', + '1:2::', + '1:2:3:4::7:8', + '1:2:3::7:8', + '1:2::7:8', + '1:2:3:4:5:6:1.2.3.4', + '1:2:3:4:5::1.2.3.4', + '1:2:3:4::1.2.3.4', + '1:2:3::1.2.3.4', + '1:2::1.2.3.4', + '1::1.2.3.4', + '1:2:3:4::5:1.2.3.4', + '1:2:3::5:1.2.3.4', + '1:2::5:1.2.3.4', + '1::5:1.2.3.4', + '1::5:11.22.33.44', + 'fe80::217:f2ff:254.7.237.98', + 'fe80::217:f2ff:fe07:ed62', + '2001:DB8:0:0:8:800:200C:417A', + 'FF01:0:0:0:0:0:0:101', + '0:0:0:0:0:0:0:1', + '0:0:0:0:0:0:0:0', + '2001:DB8::8:800:200C:417A', + 'FF01::101', + '0:0:0:0:0:0:13.1.68.3', + '0:0:0:0:0:FFFF:129.144.52.38', + '::13.1.68.3', + '::FFFF:129.144.52.38', + 'fe80:0000:0000:0000:0204:61ff:fe9d:f156', + 'fe80:0:0:0:204:61ff:fe9d:f156', + 'fe80::204:61ff:fe9d:f156', + 'fe80:0:0:0:204:61ff:254.157.241.86', + 'fe80::204:61ff:254.157.241.86', + 'fe80::1', + '2001:0db8:85a3:0000:0000:8a2e:0370:7334', + '2001:db8:85a3:0:0:8a2e:370:7334', + '2001:db8:85a3::8a2e:370:7334', + '2001:0db8:0000:0000:0000:0000:1428:57ab', + '2001:0db8:0000:0000:0000::1428:57ab', + '2001:0db8:0:0:0:0:1428:57ab', + '2001:0db8:0:0::1428:57ab', + '2001:0db8::1428:57ab', + '2001:db8::1428:57ab', + '::ffff:12.34.56.78', + '::ffff:0c22:384e', + '2001:0db8:1234:0000:0000:0000:0000:0000', + '2001:0db8:1234:ffff:ffff:ffff:ffff:ffff', + '2001:db8:a::123', + '::ffff:192.0.2.128', + '::ffff:c000:280', + 'a:b:c:d:e:f:f1:f2', + 'a:b:c::d:e:f:f1', + 'a:b:c::d:e:f', + 'a:b:c::d:e', + 'a:b:c::d', + '::a', + '::a:b:c', + '::a:b:c:d:e:f:f1', + 'a::', + 'a:b:c::', + 'a:b:c:d:e:f:f1::', + 'a:bb:ccc:dddd:000e:00f:0f::', + '0:a:0:a:0:0:0:a', + '0:a:0:0:a:0:0:a', + '2001:db8:1:1:1:1:0:0', + '2001:db8:1:1:1:0:0:0', + '2001:db8:1:1:0:0:0:0', + '2001:db8:1:0:0:0:0:0', + '2001:db8:0:0:0:0:0:0', + '2001:0:0:0:0:0:0:0', + 'A:BB:CCC:DDDD:000E:00F:0F::', + '0:0:0:0:0:0:0:a', + '0:0:0:0:a:0:0:0', + '0:0:0:a:0:0:0:0', + 'a:0:0:a:0:0:a:a', + 'a:0:0:a:0:0:0:a', + 'a:0:0:0:a:0:0:a', + 'a:0:0:0:a:0:0:0', + 'a:0:0:0:0:0:0:0', + 'fe80::7:8%eth0', + 'fe80::7:8%1', +]; + +const v6not = [ + '', + '1:', + ':1', + '11:36:12', + '02001:0000:1234:0000:0000:C1C0:ABCD:0876', + '2001:0000:1234:0000:00001:C1C0:ABCD:0876', + '2001:0000:1234: 0000:0000:C1C0:ABCD:0876', + '2001:1:1:1:1:1:255Z255X255Y255', + '3ffe:0b00:0000:0001:0000:0000:000a', + 'FF02:0000:0000:0000:0000:0000:0000:0000:0001', + '3ffe:b00::1::a', + '::1111:2222:3333:4444:5555:6666::', + '1:2:3::4:5::7:8', + '12345::6:7:8', + '1::5:400.2.3.4', + '1::5:260.2.3.4', + '1::5:256.2.3.4', + '1::5:1.256.3.4', + '1::5:1.2.256.4', + '1::5:1.2.3.256', + '1::5:300.2.3.4', + '1::5:1.300.3.4', + '1::5:1.2.300.4', + '1::5:1.2.3.300', + '1::5:900.2.3.4', + '1::5:1.900.3.4', + '1::5:1.2.900.4', + '1::5:1.2.3.900', + '1::5:300.300.300.300', + '1::5:3000.30.30.30', + '1::400.2.3.4', + '1::260.2.3.4', + '1::256.2.3.4', + '1::1.256.3.4', + '1::1.2.256.4', + '1::1.2.3.256', + '1::300.2.3.4', + '1::1.300.3.4', + '1::1.2.300.4', + '1::1.2.3.300', + '1::900.2.3.4', + '1::1.900.3.4', + '1::1.2.900.4', + '1::1.2.3.900', + '1::300.300.300.300', + '1::3000.30.30.30', + '::400.2.3.4', + '::260.2.3.4', + '::256.2.3.4', + '::1.256.3.4', + '::1.2.256.4', + '::1.2.3.256', + '::300.2.3.4', + '::1.300.3.4', + '::1.2.300.4', + '::1.2.3.300', + '::900.2.3.4', + '::1.900.3.4', + '::1.2.900.4', + '::1.2.3.900', + '::300.300.300.300', + '::3000.30.30.30', + '2001:DB8:0:0:8:800:200C:417A:221', + 'FF01::101::2', + '1111:2222:3333:4444::5555:', + '1111:2222:3333::5555:', + '1111:2222::5555:', + '1111::5555:', + '::5555:', + ':::', + '1111:', + ':', + ':1111:2222:3333:4444::5555', + ':1111:2222:3333::5555', + ':1111:2222::5555', + ':1111::5555', + ':::5555', + '1.2.3.4:1111:2222:3333:4444::5555', + '1.2.3.4:1111:2222:3333::5555', + '1.2.3.4:1111:2222::5555', + '1.2.3.4:1111::5555', + '1.2.3.4::5555', + '1.2.3.4::', + 'fe80:0000:0000:0000:0204:61ff:254.157.241.086', + '123', + 'ldkfj', + '2001::FFD3::57ab', + '2001:db8:85a3::8a2e:37023:7334', + '2001:db8:85a3::8a2e:370k:7334', + '1:2:3:4:5:6:7:8:9', + '1::2::3', + '1:::3:4:5', + '1:2:3::4:5:6:7:8:9', + '::ffff:2.3.4', + '::ffff:257.1.2.3', + '::ffff:12345678901234567890.1.26', + '2001:0000:1234:0000:0000:C1C0:ABCD:0876 0', + '02001:0000:1234:0000:0000:C1C0:ABCD:0876', +]; + +v6.forEach((ip) => { + assert.strictEqual(net.isIPv6(ip), true); +}); + +v6not.forEach((ip) => { + assert.strictEqual(net.isIPv6(ip), false); +}); diff --git a/tests/node_compat/test/parallel/test-net-listen-close-server-callback-is-not-function.js b/tests/node_compat/test/parallel/test-net-listen-close-server-callback-is-not-function.js new file mode 100644 index 000000000..69b72b9c2 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-listen-close-server-callback-is-not-function.js @@ -0,0 +1,18 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const net = require('net'); + +const server = net.createServer(common.mustNotCall()); + +server.on('close', common.mustCall()); + +server.listen(0, common.mustNotCall()); + +server.close('bad argument'); diff --git a/tests/node_compat/test/parallel/test-net-listen-close-server.js b/tests/node_compat/test/parallel/test-net-listen-close-server.js new file mode 100644 index 000000000..441cf4511 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-listen-close-server.js @@ -0,0 +1,37 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const net = require('net'); + +const server = net.createServer(function(socket) { +}); +server.listen(0, common.mustNotCall()); +server.on('error', common.mustNotCall()); +server.close(); diff --git a/tests/node_compat/test/parallel/test-net-listen-invalid-port.js b/tests/node_compat/test/parallel/test-net-listen-invalid-port.js new file mode 100644 index 000000000..10685f1d0 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-listen-invalid-port.js @@ -0,0 +1,52 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +'use strict'; +const common = require('../common'); + +// This test ensures that port numbers are validated in *all* kinds of `listen` +// calls. If an invalid port is supplied, ensures a `RangeError` is thrown. +// https://github.com/nodejs/node/issues/5727 + +const assert = require('assert'); +const net = require('net'); + +const invalidPort = -1 >>> 0; + +// TODO: support net.Server() without new + +new net.Server().listen(0, function() { + const address = this.address(); + const key = `${address.family}:${address.address}:0`; + + assert.strictEqual(this._connectionKey, key); + this.close(); +}); + +// The first argument is a configuration object +assert.throws(() => { + new net.Server().listen({ port: invalidPort }, common.mustNotCall()); +}, { + code: 'ERR_SOCKET_BAD_PORT', + name: 'RangeError' +}); + +// The first argument is the port, no IP given. +assert.throws(() => { + new net.Server().listen(invalidPort, common.mustNotCall()); +}, { + code: 'ERR_SOCKET_BAD_PORT', + name: 'RangeError' +}); + +// The first argument is the port, the second an IP. +assert.throws(() => { + new net.Server().listen(invalidPort, '0.0.0.0', common.mustNotCall()); +}, { + code: 'ERR_SOCKET_BAD_PORT', + name: 'RangeError' +}); diff --git a/tests/node_compat/test/parallel/test-net-listening.js b/tests/node_compat/test/parallel/test-net-listening.js new file mode 100644 index 000000000..275dd06eb --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-listening.js @@ -0,0 +1,23 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); + +const server = net.createServer(); + +assert.strictEqual(server.listening, false); + +server.listen(0, common.mustCall(() => { + assert.strictEqual(server.listening, true); + + server.close(common.mustCall(() => { + assert.strictEqual(server.listening, false); + })); +})); diff --git a/tests/node_compat/test/parallel/test-net-localerror.js b/tests/node_compat/test/parallel/test-net-localerror.js new file mode 100644 index 000000000..9e2080ed4 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-localerror.js @@ -0,0 +1,51 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const net = require('net'); + +const connect = (opts, code, type) => { + assert.throws( + () => net.connect(opts), + { code, name: type.name } + ); +}; + +connect({ + host: 'localhost', + port: 0, + localAddress: 'foobar', +}, 'ERR_INVALID_IP_ADDRESS', TypeError); + +connect({ + host: 'localhost', + port: 0, + localPort: 'foobar', +}, 'ERR_INVALID_ARG_TYPE', TypeError); diff --git a/tests/node_compat/test/parallel/test-net-options-lookup.js b/tests/node_compat/test/parallel/test-net-options-lookup.js new file mode 100644 index 000000000..d3ca0451c --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-options-lookup.js @@ -0,0 +1,59 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); + +['foobar', 1, {}, []].forEach((input) => connectThrows(input)); + +// Using port 0 as lookup is emitted before connecting. +function connectThrows(input) { + const opts = { + host: 'localhost', + port: 0, + lookup: input + }; + + assert.throws(() => { + net.connect(opts); + }, { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + }); +} + +connectDoesNotThrow(() => {}); + +function connectDoesNotThrow(input) { + const opts = { + host: 'localhost', + port: 0, + lookup: input + }; + + return net.connect(opts); +} + +{ + // Verify that an error is emitted when an invalid address family is returned. + const s = connectDoesNotThrow((host, options, cb) => { + if (options.all) { + cb(null, [{ address: '127.0.0.1', family: 100 }]); + } else { + cb(null, '127.0.0.1', 100); + } + }); + + s.on('error', common.expectsError({ + code: 'ERR_INVALID_ADDRESS_FAMILY', + host: 'localhost', + port: 0, + message: 'Invalid address family: 100 localhost:0' + })); +} diff --git a/tests/node_compat/test/parallel/test-net-pipe-connect-errors.js b/tests/node_compat/test/parallel/test-net-pipe-connect-errors.js new file mode 100644 index 000000000..451c9eb92 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-pipe-connect-errors.js @@ -0,0 +1,104 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const fixtures = require('../common/fixtures'); +const fs = require('fs'); +const net = require('net'); +const assert = require('assert'); + +// Test if ENOTSOCK is fired when trying to connect to a file which is not +// a socket. + +let emptyTxt; + +if (common.isWindows) { + // On Win, common.PIPE will be a named pipe, so we use an existing empty + // file instead + emptyTxt = fixtures.path('empty.txt'); +} else { + const tmpdir = require('../common/tmpdir'); + tmpdir.refresh(); + // Keep the file name very short so that we don't exceed the 108 char limit + // on CI for a POSIX socket. Even though this isn't actually a socket file, + // the error will be different from the one we are expecting if we exceed the + // limit. + emptyTxt = `${tmpdir.path}0.txt`; + + function cleanup() { + try { + fs.unlinkSync(emptyTxt); + } catch (e) { + assert.strictEqual(e.code, 'ENOENT'); + } + } + process.on('exit', cleanup); + cleanup(); + fs.writeFileSync(emptyTxt, ''); +} + +const notSocketClient = net.createConnection(emptyTxt, function() { + assert.fail('connection callback should not run'); +}); + +notSocketClient.on('error', common.mustCall(function(err) { + assert(err.code === 'ENOTSOCK' || err.code === 'ECONNREFUSED', + `received ${err.code} instead of ENOTSOCK or ECONNREFUSED`); +})); + + +// Trying to connect to not-existing socket should result in ENOENT error +const noEntSocketClient = net.createConnection('no-ent-file', function() { + assert.fail('connection to non-existent socket, callback should not run'); +}); + +noEntSocketClient.on('error', common.mustCall(function(err) { + assert.strictEqual(err.code, 'ENOENT'); +})); + + +// On Windows or IBMi or when running as root, +// a chmod has no effect on named pipes +if (!common.isWindows && !common.isIBMi && process.getuid() !== 0) { + // Trying to connect to a socket one has no access to should result in EACCES + const accessServer = net.createServer( + common.mustNotCall('server callback should not run')); + accessServer.listen(common.PIPE, common.mustCall(function() { + fs.chmodSync(common.PIPE, 0); + + const accessClient = net.createConnection(common.PIPE, function() { + assert.fail('connection should get EACCES, callback should not run'); + }); + + accessClient.on('error', common.mustCall(function(err) { + assert.strictEqual(err.code, 'EACCES'); + accessServer.close(); + })); + })); +} diff --git a/tests/node_compat/test/parallel/test-net-server-call-listen-multiple-times.js b/tests/node_compat/test/parallel/test-net-server-call-listen-multiple-times.js new file mode 100644 index 000000000..30b443b18 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-server-call-listen-multiple-times.js @@ -0,0 +1,56 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); + +// TODO: support net.Server() without new + +// First test. Check that after error event you can listen right away. +{ + const dummyServer = new net.Server(); + const server = new net.Server(); + + // Run some server in order to simulate EADDRINUSE error. + dummyServer.listen(common.mustCall(() => { + // Try to listen used port. + server.listen(dummyServer.address().port); + })); + + server.on('error', common.mustCall((e) => { + server.listen(common.mustCall(() => { + dummyServer.close(); + server.close(); + })); + })); +} + +// Second test. Check that second listen call throws an error. +{ + const server = new net.Server(); + + server.listen(common.mustCall(() => server.close())); + + assert.throws(() => server.listen(), { + code: 'ERR_SERVER_ALREADY_LISTEN', + name: 'Error' + }); +} + +// Third test. +// Check that after the close call you can run listen method just fine. +{ + const server = new net.Server(); + + server.listen(common.mustCall(() => { + server.close(); + server.listen(common.mustCall(() => server.close())); + })); +} diff --git a/tests/node_compat/test/parallel/test-net-server-listen-options-signal.js b/tests/node_compat/test/parallel/test-net-server-listen-options-signal.js new file mode 100644 index 000000000..b8547f516 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-server-listen-options-signal.js @@ -0,0 +1,39 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); + +{ + // Test bad signal. + const server = net.createServer(); + assert.throws( + () => server.listen({ port: 0, signal: 'INVALID_SIGNAL' }), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + }); +} + +{ + // Test close. + const server = net.createServer(); + const controller = new AbortController(); + server.on('close', common.mustCall()); + server.listen({ port: 0, signal: controller.signal }); + controller.abort(); +} + +{ + // Test close with pre-aborted signal. + const server = net.createServer(); + const signal = AbortSignal.abort(); + server.on('close', common.mustCall()); + server.listen({ port: 0, signal }); +} diff --git a/tests/node_compat/test/parallel/test-net-server-listen-options.js b/tests/node_compat/test/parallel/test-net-server-listen-options.js new file mode 100644 index 000000000..4d76a7ca7 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-server-listen-options.js @@ -0,0 +1,101 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); + +function close() { this.close(); } + +{ + // Test listen() + net.createServer().listen().on('listening', common.mustCall(close)); + // Test listen(cb) + net.createServer().listen(common.mustCall(close)); + // Test listen(port) + net.createServer().listen(0).on('listening', common.mustCall(close)); + // Test listen({port}) + net.createServer().listen({ port: 0 }) + .on('listening', common.mustCall(close)); +} + +// Test listen(port, cb) and listen({ port }, cb) combinations +const listenOnPort = [ + (port, cb) => net.createServer().listen({ port }, cb), + (port, cb) => net.createServer().listen(port, cb), +]; + +{ + const assertPort = () => { + return common.expectsError({ + code: 'ERR_SOCKET_BAD_PORT', + name: 'RangeError' + }); + }; + + for (const listen of listenOnPort) { + // Arbitrary unused ports + listen('0', common.mustCall(close)); + listen(0, common.mustCall(close)); + listen(undefined, common.mustCall(close)); + listen(null, common.mustCall(close)); + // Test invalid ports + assert.throws(() => listen(-1, common.mustNotCall()), assertPort()); + assert.throws(() => listen(NaN, common.mustNotCall()), assertPort()); + assert.throws(() => listen(123.456, common.mustNotCall()), assertPort()); + assert.throws(() => listen(65536, common.mustNotCall()), assertPort()); + assert.throws(() => listen(1 / 0, common.mustNotCall()), assertPort()); + assert.throws(() => listen(-1 / 0, common.mustNotCall()), assertPort()); + } + // In listen(options, cb), port takes precedence over path + assert.throws(() => { + net.createServer().listen({ port: -1, path: common.PIPE }, + common.mustNotCall()); + }, assertPort()); +} + +{ + function shouldFailToListen(options) { + const fn = () => { + net.createServer().listen(options, common.mustNotCall()); + }; + + if (typeof options === 'object' && + !(('port' in options) || ('path' in options))) { + assert.throws(fn, + { + code: 'ERR_INVALID_ARG_VALUE', + name: 'TypeError', + message: /^The argument 'options' must have the property "port" or "path"\. Received .+$/, + }); + } else { + assert.throws(fn, + { + code: 'ERR_INVALID_ARG_VALUE', + name: 'TypeError', + message: /^The argument 'options' is invalid\. Received .+$/, + }); + } + } + + shouldFailToListen(false, { port: false }); + shouldFailToListen({ port: false }); + shouldFailToListen(true); + shouldFailToListen({ port: true }); + // Invalid fd as listen(handle) + shouldFailToListen({ fd: -1 }); + // Invalid path in listen(options) + shouldFailToListen({ path: -1 }); + + // Neither port or path are specified in options + shouldFailToListen({}); + shouldFailToListen({ host: 'localhost' }); + shouldFailToListen({ host: 'localhost:3000' }); + shouldFailToListen({ host: { port: 3000 } }); + shouldFailToListen({ exclusive: true }); +} diff --git a/tests/node_compat/test/parallel/test-net-server-listen-path.js b/tests/node_compat/test/parallel/test-net-server-listen-path.js new file mode 100644 index 000000000..559e9c7eb --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-server-listen-path.js @@ -0,0 +1,100 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +'use strict'; + +const common = require('../common'); +const net = require('net'); +const assert = require('assert'); +const fs = require('fs'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +function closeServer() { + return common.mustCall(function() { + this.close(); + }); +} + +let counter = 0; + +// Avoid conflict with listen-handle +function randomPipePath() { + return `${common.PIPE}-listen-path-${counter++}`; +} + +// Test listen(path) +{ + const handlePath = randomPipePath(); + net.createServer() + .listen(handlePath) + .on('listening', closeServer()); +} + +// Test listen({path}) +{ + const handlePath = randomPipePath(); + net.createServer() + .listen({ path: handlePath }) + .on('listening', closeServer()); +} + +// Test listen(path, cb) +{ + const handlePath = randomPipePath(); + net.createServer() + .listen(handlePath, closeServer()); +} + +// Test listen(path, cb) +{ + const handlePath = randomPipePath(); + net.createServer() + .listen({ path: handlePath }, closeServer()); +} + +// Test pipe chmod +{ + const handlePath = randomPipePath(); + + const server = net.createServer() + .listen({ + path: handlePath, + readableAll: true, + writableAll: true + }, common.mustCall(() => { + if (process.platform !== 'win32') { + const mode = fs.statSync(handlePath).mode; + assert.notStrictEqual(mode & fs.constants.S_IROTH, 0); + assert.notStrictEqual(mode & fs.constants.S_IWOTH, 0); + } + server.close(); + })); +} + +// TODO(cmorten): seems Deno.listen() for Unix domains isn't throwing +// Deno.errors.AddrInUse errors as would expect...? +// Test should emit "error" events when listening fails. +// { +// const handlePath = randomPipePath(); +// const server1 = net.createServer().listen({ path: handlePath }, () => { +// // As the handlePath is in use, binding to the same address again should +// // make the server emit an 'EADDRINUSE' error. +// const server2 = net.createServer() +// .listen({ +// path: handlePath, +// writableAll: true, +// }, common.mustNotCall()); + +// server2.on('error', common.mustCall((err) => { +// server1.close(); +// assert.strictEqual(err.code, 'EADDRINUSE'); +// assert.match(err.message, /^listen EADDRINUSE: address already in use/); +// })); +// }); +// } diff --git a/tests/node_compat/test/parallel/test-net-server-listen-remove-callback.js b/tests/node_compat/test/parallel/test-net-server-listen-remove-callback.js new file mode 100644 index 000000000..15808a7a1 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-server-listen-remove-callback.js @@ -0,0 +1,51 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const net = require('net'); + +// Server should only fire listen callback once +const server = net.createServer(); + +server.on('close', function() { + const listeners = server.listeners('listening'); + console.log('Closed, listeners:', listeners.length); + assert.strictEqual(listeners.length, 0); +}); + +server.listen(0, function() { + server.close(); +}); + +server.once('close', function() { + server.listen(0, function() { + server.close(); + }); +}); diff --git a/tests/node_compat/test/parallel/test-net-server-options.js b/tests/node_compat/test/parallel/test-net-server-options.js new file mode 100644 index 000000000..92086d149 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-server-options.js @@ -0,0 +1,23 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const assert = require('assert'); +const net = require('net'); + +assert.throws(() => net.createServer('path'), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + }); + +assert.throws(() => net.createServer(0), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + }); diff --git a/tests/node_compat/test/parallel/test-net-server-try-ports.js b/tests/node_compat/test/parallel/test-net-server-try-ports.js new file mode 100644 index 000000000..69dbc78b8 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-server-try-ports.js @@ -0,0 +1,54 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +// This test binds to one port, then attempts to start a server on that +// port. It should be EADDRINUSE but be able to then bind to another port. +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); + +// TODO: support net.Server() without new + +const server1 = new net.Server(); + +const server2 = new net.Server(); + +server2.on('error', common.mustCall(function(e) { + assert.strictEqual(e.code, 'EADDRINUSE'); + + server2.listen(0, common.mustCall(function() { + server1.close(); + server2.close(); + })); +})); + +server1.listen(0, common.mustCall(function() { + // This should make server2 emit EADDRINUSE + server2.listen(this.address().port); +})); diff --git a/tests/node_compat/test/parallel/test-net-server-unref-persistent.js b/tests/node_compat/test/parallel/test-net-server-unref-persistent.js new file mode 100644 index 000000000..04b79686e --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-server-unref-persistent.js @@ -0,0 +1,19 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const net = require('net'); +const server = net.createServer(); + +// Unref before listening +server.unref(); +server.listen(); + +// If the timeout fires, that means the server held the event loop open +// and the unref() was not persistent. Close the server and fail the test. +setTimeout(common.mustNotCall(), 1000).unref(); diff --git a/tests/node_compat/test/parallel/test-net-server-unref.js b/tests/node_compat/test/parallel/test-net-server-unref.js new file mode 100644 index 000000000..68fd6edb1 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-server-unref.js @@ -0,0 +1,37 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const net = require('net'); + +const s = net.createServer(); +s.listen(0); +s.unref(); + +setTimeout(common.mustNotCall(), 1000).unref(); diff --git a/tests/node_compat/test/parallel/test-net-socket-destroy-twice.js b/tests/node_compat/test/parallel/test-net-socket-destroy-twice.js new file mode 100644 index 000000000..8cff55d70 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-socket-destroy-twice.js @@ -0,0 +1,43 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const net = require('net'); + +const server = net.createServer(); +server.listen(0); +const port = server.address().port; +const conn = net.createConnection(port); + +conn.on('error', common.mustCall(() => { + conn.destroy(); +})); + +conn.on('close', common.mustCall()); +server.close(); diff --git a/tests/node_compat/test/parallel/test-net-socket-no-halfopen-enforcer.js b/tests/node_compat/test/parallel/test-net-socket-no-halfopen-enforcer.js new file mode 100644 index 000000000..c50b0061a --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-socket-no-halfopen-enforcer.js @@ -0,0 +1,18 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); + +// This test ensures that `net.Socket` does not inherit the no-half-open +// enforcer from `stream.Duplex`. + +const { Socket } = require('net'); +const { strictEqual } = require('assert'); + +const socket = new Socket({ allowHalfOpen: false }); +strictEqual(socket.listenerCount('end'), 1); diff --git a/tests/node_compat/test/parallel/test-net-socket-timeout.js b/tests/node_compat/test/parallel/test-net-socket-timeout.js new file mode 100644 index 000000000..b69e40530 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-socket-timeout.js @@ -0,0 +1,88 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const net = require('net'); +const assert = require('assert'); +const { inspect } = require('util'); + +// Verify that invalid delays throw +const s = new net.Socket(); +const nonNumericDelays = [ + '100', true, false, undefined, null, '', {}, () => {}, [], +]; +const badRangeDelays = [-0.001, -1, -Infinity, Infinity, NaN]; +const validDelays = [0, 0.001, 1, 1e6]; +const invalidCallbacks = [ + 1, '100', true, false, null, {}, [], Symbol('test'), +]; + + +for (let i = 0; i < nonNumericDelays.length; i++) { + assert.throws(() => { + s.setTimeout(nonNumericDelays[i], () => {}); + }, { code: 'ERR_INVALID_ARG_TYPE' }, nonNumericDelays[i]); +} + +for (let i = 0; i < badRangeDelays.length; i++) { + assert.throws(() => { + s.setTimeout(badRangeDelays[i], () => {}); + }, { code: 'ERR_OUT_OF_RANGE' }, badRangeDelays[i]); +} + +for (let i = 0; i < validDelays.length; i++) { + s.setTimeout(validDelays[i], () => {}); +} + +for (let i = 0; i < invalidCallbacks.length; i++) { + [0, 1].forEach((mesc) => + assert.throws( + () => s.setTimeout(mesc, invalidCallbacks[i]), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + } + ) + ); +} + +// TODO: support net.Server() without new + +const server = new net.Server(); +server.listen(0, common.mustCall(() => { + const socket = net.createConnection(server.address().port); + assert.strictEqual( + socket.setTimeout(1, common.mustCall(() => { + socket.destroy(); + assert.strictEqual(socket.setTimeout(1, common.mustNotCall()), socket); + server.close(); + })), + socket + ); +})); diff --git a/tests/node_compat/test/parallel/test-net-timeout-no-handle.js b/tests/node_compat/test/parallel/test-net-timeout-no-handle.js new file mode 100644 index 000000000..1948dc9ad --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-timeout-no-handle.js @@ -0,0 +1,24 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const net = require('net'); +const assert = require('assert'); + +const socket = new net.Socket(); +socket.setTimeout(common.platformTimeout(50)); + +socket.on('timeout', common.mustCall(() => { + assert.strictEqual(socket._handle, null); +})); + +socket.on('connect', common.mustNotCall()); + +// Since the timeout is unrefed, the code will exit without this +setTimeout(() => {}, common.platformTimeout(200)); diff --git a/tests/node_compat/test/parallel/test-net-write-arguments.js b/tests/node_compat/test/parallel/test-net-write-arguments.js new file mode 100644 index 000000000..d6beb72ee --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-write-arguments.js @@ -0,0 +1,46 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +'use strict'; +const common = require('../common'); +const net = require('net'); +const assert = require('assert'); +const socket = new net.Stream({ highWaterMark: 0 }); + +// Make sure that anything besides a buffer or a string throws. +socket.on('error', common.mustNotCall()); +assert.throws(() => { + socket.write(null); +}, { + code: 'ERR_STREAM_NULL_VALUES', + name: 'TypeError', + message: 'May not write null values to stream' +}); + +[ + true, + false, + undefined, + 1, + 1.0, + +Infinity, + -Infinity, + [], + {}, +].forEach((value) => { + const socket = new net.Stream({ highWaterMark: 0 }); + // We need to check the callback since 'error' will only + // be emitted once per instance. + assert.throws(() => { + socket.write(value); + }, { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "chunk" argument must be of type string or an instance of ' + + `Buffer or Uint8Array.${common.invalidArgTypeHelper(value)}` + }); +}); diff --git a/tests/node_compat/test/parallel/test-next-tick-doesnt-hang.js b/tests/node_compat/test/parallel/test-next-tick-doesnt-hang.js new file mode 100644 index 000000000..6d0d6a7e0 --- /dev/null +++ b/tests/node_compat/test/parallel/test-next-tick-doesnt-hang.js @@ -0,0 +1,37 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; + +// This test verifies that having a single nextTick statement and nothing else +// does not hang the event loop. If this test times out it has failed. + +require('../common'); +process.nextTick(function() { + // Nothing +}); diff --git a/tests/node_compat/test/parallel/test-next-tick-fixed-queue-regression.js b/tests/node_compat/test/parallel/test-next-tick-fixed-queue-regression.js new file mode 100644 index 000000000..fff40f754 --- /dev/null +++ b/tests/node_compat/test/parallel/test-next-tick-fixed-queue-regression.js @@ -0,0 +1,25 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); + +// This tests a highly specific regression tied to the FixedQueue size, which +// was introduced in Node.js 9.7.0: https://github.com/nodejs/node/pull/18617 +// More specifically, a nextTick list could potentially end up not fully +// clearing in one run through if exactly 2048 ticks were added after +// microtasks were executed within the nextTick loop. + +process.nextTick(() => { + Promise.resolve(1).then(() => { + for (let i = 0; i < 2047; i++) + process.nextTick(common.mustCall()); + const immediate = setImmediate(common.mustNotCall()); + process.nextTick(common.mustCall(() => clearImmediate(immediate))); + }); +}); diff --git a/tests/node_compat/test/parallel/test-next-tick-intentional-starvation.js b/tests/node_compat/test/parallel/test-next-tick-intentional-starvation.js new file mode 100644 index 000000000..b2c00b43a --- /dev/null +++ b/tests/node_compat/test/parallel/test-next-tick-intentional-starvation.js @@ -0,0 +1,68 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); + +// This is the inverse of test-next-tick-starvation. it verifies +// that process.nextTick will *always* come before other events + +let ran = false; +let starved = false; +const start = +new Date(); +let timerRan = false; + +function spin() { + ran = true; + const now = +new Date(); + if (now - start > 100) { + console.log('The timer is starving, just as we planned.'); + starved = true; + + // now let it out. + return; + } + + process.nextTick(spin); +} + +function onTimeout() { + if (!starved) throw new Error('The timer escaped!'); + console.log('The timer ran once the ban was lifted'); + timerRan = true; +} + +spin(); +setTimeout(onTimeout, 50); + +process.on('exit', function() { + assert.ok(ran); + assert.ok(starved); + assert.ok(timerRan); +}); diff --git a/tests/node_compat/test/parallel/test-next-tick-ordering.js b/tests/node_compat/test/parallel/test-next-tick-ordering.js new file mode 100644 index 000000000..a2839a49e --- /dev/null +++ b/tests/node_compat/test/parallel/test-next-tick-ordering.js @@ -0,0 +1,62 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +let i; + +const N = 30; +const done = []; + +function get_printer(timeout) { + return function() { + console.log(`Running from setTimeout ${timeout}`); + done.push(timeout); + }; +} + +process.nextTick(function() { + console.log('Running from nextTick'); + done.push('nextTick'); +}); + +for (i = 0; i < N; i += 1) { + setTimeout(get_printer(i), i); +} + +console.log('Running from main.'); + + +process.on('exit', function() { + assert.strictEqual(done[0], 'nextTick'); + // Disabling this test. I don't think we can ensure the order + // for (i = 0; i < N; i += 1) { + // assert.strictEqual(i, done[i + 1]); + // } +}); diff --git a/tests/node_compat/test/parallel/test-next-tick-ordering2.js b/tests/node_compat/test/parallel/test-next-tick-ordering2.js new file mode 100644 index 000000000..29c76d32e --- /dev/null +++ b/tests/node_compat/test/parallel/test-next-tick-ordering2.js @@ -0,0 +1,46 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); + +const order = []; +process.nextTick(function() { + setTimeout(function() { + order.push('setTimeout'); + }, 0); + + process.nextTick(function() { + order.push('nextTick'); + }); +}); + +process.on('exit', function() { + assert.deepStrictEqual(order, ['nextTick', 'setTimeout']); +}); diff --git a/tests/node_compat/test/parallel/test-next-tick-when-exiting.js b/tests/node_compat/test/parallel/test-next-tick-when-exiting.js new file mode 100644 index 000000000..5f20b5247 --- /dev/null +++ b/tests/node_compat/test/parallel/test-next-tick-when-exiting.js @@ -0,0 +1,21 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); + +process.on('exit', () => { + assert.strictEqual(process._exiting, true); + + process.nextTick( + common.mustNotCall('process is exiting, should not be called') + ); +}); + +process.exit(); diff --git a/tests/node_compat/test/parallel/test-next-tick.js b/tests/node_compat/test/parallel/test-next-tick.js new file mode 100644 index 000000000..aee5c06a1 --- /dev/null +++ b/tests/node_compat/test/parallel/test-next-tick.js @@ -0,0 +1,70 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); + +const assert = require('assert'); + +process.nextTick(common.mustCall(function() { + process.nextTick(common.mustCall(function() { + process.nextTick(common.mustCall()); + })); +})); + +setTimeout(common.mustCall(function() { + process.nextTick(common.mustCall()); +}), 50); + +process.nextTick(common.mustCall()); + +const obj = {}; + +process.nextTick(function(a, b) { + assert.strictEqual(a, 42); + assert.strictEqual(b, obj); + assert.strictEqual(this, undefined); +}, 42, obj); + +process.nextTick((a, b) => { + assert.strictEqual(a, 42); + assert.strictEqual(b, obj); + assert.deepStrictEqual(this, {}); +}, 42, obj); + +process.nextTick(function() { + assert.strictEqual(this, undefined); +}, 1, 2, 3, 4); + +process.nextTick(() => { + assert.deepStrictEqual(this, {}); +}, 1, 2, 3, 4); + +process.on('exit', function() { + process.nextTick(common.mustNotCall()); +}); diff --git a/tests/node_compat/test/parallel/test-nodeeventtarget.js b/tests/node_compat/test/parallel/test-nodeeventtarget.js new file mode 100644 index 000000000..b5c6e788f --- /dev/null +++ b/tests/node_compat/test/parallel/test-nodeeventtarget.js @@ -0,0 +1,190 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Flags: --expose-internals --no-warnings +'use strict'; + +const common = require('../common'); +const { NodeEventTarget } = require('internal/event_target'); + +const { + deepStrictEqual, + ok, + strictEqual, + throws, +} = require('assert'); + +const { on } = require('events'); + +{ + const eventTarget = new NodeEventTarget(); + strictEqual(eventTarget.listenerCount('foo'), 0); + deepStrictEqual(eventTarget.eventNames(), []); + + const ev1 = common.mustCall(function(event) { + strictEqual(event.type, 'foo'); + strictEqual(this, eventTarget); + }, 2); + + const ev2 = { + handleEvent: common.mustCall(function(event) { + strictEqual(event.type, 'foo'); + strictEqual(this, ev2); + }) + }; + + eventTarget.addEventListener('foo', ev1); + eventTarget.addEventListener('foo', ev2, { once: true }); + strictEqual(eventTarget.listenerCount('foo'), 2); + ok(eventTarget.dispatchEvent(new Event('foo'))); + strictEqual(eventTarget.listenerCount('foo'), 1); + eventTarget.dispatchEvent(new Event('foo')); + + eventTarget.removeEventListener('foo', ev1); + strictEqual(eventTarget.listenerCount('foo'), 0); + eventTarget.dispatchEvent(new Event('foo')); +} + +{ + const eventTarget = new NodeEventTarget(); + strictEqual(eventTarget.listenerCount('foo'), 0); + deepStrictEqual(eventTarget.eventNames(), []); + + const ev1 = common.mustCall((event) => { + strictEqual(event.type, 'foo'); + }, 2); + + const ev2 = { + handleEvent: common.mustCall((event) => { + strictEqual(event.type, 'foo'); + }) + }; + + strictEqual(eventTarget.on('foo', ev1), eventTarget); + strictEqual(eventTarget.once('foo', ev2, { once: true }), eventTarget); + strictEqual(eventTarget.listenerCount('foo'), 2); + eventTarget.dispatchEvent(new Event('foo')); + strictEqual(eventTarget.listenerCount('foo'), 1); + eventTarget.dispatchEvent(new Event('foo')); + + strictEqual(eventTarget.off('foo', ev1), eventTarget); + strictEqual(eventTarget.listenerCount('foo'), 0); + eventTarget.dispatchEvent(new Event('foo')); +} + +{ + const eventTarget = new NodeEventTarget(); + strictEqual(eventTarget.listenerCount('foo'), 0); + deepStrictEqual(eventTarget.eventNames(), []); + + const ev1 = common.mustCall((event) => { + strictEqual(event.type, 'foo'); + }, 2); + + const ev2 = { + handleEvent: common.mustCall((event) => { + strictEqual(event.type, 'foo'); + }) + }; + + eventTarget.addListener('foo', ev1); + eventTarget.once('foo', ev2, { once: true }); + strictEqual(eventTarget.listenerCount('foo'), 2); + eventTarget.dispatchEvent(new Event('foo')); + strictEqual(eventTarget.listenerCount('foo'), 1); + eventTarget.dispatchEvent(new Event('foo')); + + eventTarget.removeListener('foo', ev1); + strictEqual(eventTarget.listenerCount('foo'), 0); + eventTarget.dispatchEvent(new Event('foo')); +} + +{ + const eventTarget = new NodeEventTarget(); + strictEqual(eventTarget.listenerCount('foo'), 0); + deepStrictEqual(eventTarget.eventNames(), []); + + // Won't actually be called. + const ev1 = () => {}; + + // Won't actually be called. + const ev2 = { handleEvent() {} }; + + eventTarget.addListener('foo', ev1); + eventTarget.addEventListener('foo', ev1); + eventTarget.once('foo', ev2, { once: true }); + eventTarget.once('foo', ev2, { once: false }); + eventTarget.on('bar', ev1); + strictEqual(eventTarget.listenerCount('foo'), 2); + strictEqual(eventTarget.listenerCount('bar'), 1); + deepStrictEqual(eventTarget.eventNames(), ['foo', 'bar']); + strictEqual(eventTarget.removeAllListeners('foo'), eventTarget); + strictEqual(eventTarget.listenerCount('foo'), 0); + strictEqual(eventTarget.listenerCount('bar'), 1); + deepStrictEqual(eventTarget.eventNames(), ['bar']); + strictEqual(eventTarget.removeAllListeners(), eventTarget); + strictEqual(eventTarget.listenerCount('foo'), 0); + strictEqual(eventTarget.listenerCount('bar'), 0); + deepStrictEqual(eventTarget.eventNames(), []); +} + +{ + const target = new NodeEventTarget(); + + process.on('warning', common.mustCall((warning) => { + ok(warning instanceof Error); + strictEqual(warning.name, 'MaxListenersExceededWarning'); + strictEqual(warning.target, target); + strictEqual(warning.count, 2); + strictEqual(warning.type, 'foo'); + ok(warning.message.includes( + '2 foo listeners added to NodeEventTarget')); + })); + + strictEqual(target.getMaxListeners(), NodeEventTarget.defaultMaxListeners); + target.setMaxListeners(1); + target.on('foo', () => {}); + target.on('foo', () => {}); +} +{ + // Test NodeEventTarget emit + const emitter = new NodeEventTarget(); + emitter.addEventListener('foo', common.mustCall((e) => { + strictEqual(e.type, 'foo'); + strictEqual(e.detail, 'bar'); + ok(e instanceof Event); + }), { once: true }); + emitter.once('foo', common.mustCall((e, droppedAdditionalArgument) => { + strictEqual(e, 'bar'); + strictEqual(droppedAdditionalArgument, undefined); + })); + emitter.emit('foo', 'bar', 'baz'); +} +{ + // Test NodeEventTarget emit unsupported usage + const emitter = new NodeEventTarget(); + throws(() => { + emitter.emit(); + }, /ERR_INVALID_ARG_TYPE/); +} + +(async () => { + // test NodeEventTarget async-iterability + const emitter = new NodeEventTarget(); + const interval = setInterval(() => { + emitter.dispatchEvent(new Event('foo')); + }, 0); + let count = 0; + for await (const [ item ] of on(emitter, 'foo')) { + count++; + strictEqual(item.type, 'foo'); + if (count > 5) { + break; + } + } + clearInterval(interval); +})().then(common.mustCall()); diff --git a/tests/node_compat/test/parallel/test-os.js b/tests/node_compat/test/parallel/test-os.js new file mode 100644 index 000000000..9de4f516f --- /dev/null +++ b/tests/node_compat/test/parallel/test-os.js @@ -0,0 +1,280 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const os = require('os'); +const path = require('path'); +const { inspect } = require('util'); + +const is = { + number: (value, key) => { + assert(!Number.isNaN(value), `${key} should not be NaN`); + assert.strictEqual(typeof value, 'number'); + }, + string: (value) => { assert.strictEqual(typeof value, 'string'); }, + array: (value) => { assert.ok(Array.isArray(value)); }, + object: (value) => { + assert.strictEqual(typeof value, 'object'); + assert.notStrictEqual(value, null); + } +}; + +/* TODO(kt3k): Enable this test +process.env.TMPDIR = '/tmpdir'; +process.env.TMP = '/tmp'; +process.env.TEMP = '/temp'; +if (common.isWindows) { + assert.strictEqual(os.tmpdir(), '/temp'); + process.env.TEMP = ''; + assert.strictEqual(os.tmpdir(), '/tmp'); + process.env.TMP = ''; + const expected = `${process.env.SystemRoot || process.env.windir}\\temp`; + assert.strictEqual(os.tmpdir(), expected); + process.env.TEMP = '\\temp\\'; + assert.strictEqual(os.tmpdir(), '\\temp'); + process.env.TEMP = '\\tmpdir/'; + assert.strictEqual(os.tmpdir(), '\\tmpdir/'); + process.env.TEMP = '\\'; + assert.strictEqual(os.tmpdir(), '\\'); + process.env.TEMP = 'C:\\'; + assert.strictEqual(os.tmpdir(), 'C:\\'); +} else { + assert.strictEqual(os.tmpdir(), '/tmpdir'); + process.env.TMPDIR = ''; + assert.strictEqual(os.tmpdir(), '/tmp'); + process.env.TMP = ''; + assert.strictEqual(os.tmpdir(), '/temp'); + process.env.TEMP = ''; + assert.strictEqual(os.tmpdir(), '/tmp'); + process.env.TMPDIR = '/tmpdir/'; + assert.strictEqual(os.tmpdir(), '/tmpdir'); + process.env.TMPDIR = '/tmpdir\\'; + assert.strictEqual(os.tmpdir(), '/tmpdir\\'); + process.env.TMPDIR = '/'; + assert.strictEqual(os.tmpdir(), '/'); +} +*/ + +const endianness = os.endianness(); +is.string(endianness); +assert.match(endianness, /[BL]E/); + +const hostname = os.hostname(); +is.string(hostname); +assert.ok(hostname.length > 0); + +// On IBMi, os.uptime() returns 'undefined' +if (!common.isIBMi) { + const uptime = os.uptime(); + is.number(uptime); + assert.ok(uptime > 0); +} + +const cpus = os.cpus(); +is.array(cpus); +assert.ok(cpus.length > 0); +for (const cpu of cpus) { + assert.strictEqual(typeof cpu.model, 'string'); + assert.strictEqual(typeof cpu.speed, 'number'); + assert.strictEqual(typeof cpu.times.user, 'number'); + assert.strictEqual(typeof cpu.times.nice, 'number'); + assert.strictEqual(typeof cpu.times.sys, 'number'); + assert.strictEqual(typeof cpu.times.idle, 'number'); + assert.strictEqual(typeof cpu.times.irq, 'number'); +} + +const type = os.type(); +is.string(type); +assert.ok(type.length > 0); + +const release = os.release(); +is.string(release); +assert.ok(release.length > 0); +// TODO: Check format on more than just AIX +if (common.isAIX) + assert.match(release, /^\d+\.\d+$/); + +const platform = os.platform(); +is.string(platform); +assert.ok(platform.length > 0); + +const availableParallelism = os.availableParallelism(); +assert.ok(availableParallelism === navigator.hardwareConcurrency); + +const arch = os.arch(); +is.string(arch); +assert.ok(arch.length > 0); + +if (!common.isSunOS) { + // not implemented yet + assert.ok(os.loadavg().length > 0); + assert.ok(os.freemem() > 0); + assert.ok(os.totalmem() > 0); +} + +const interfaces = os.networkInterfaces(); +switch (platform) { + case 'linux': { + const filter = (e) => + e.address === '127.0.0.1' && + e.netmask === '255.0.0.0'; + + const actual = interfaces.lo.filter(filter); + const expected = [{ + address: '127.0.0.1', + netmask: '255.0.0.0', + family: 'IPv4', + mac: '00:00:00:00:00:00', + internal: true, + cidr: '127.0.0.1/8' + }]; + assert.deepStrictEqual(actual, expected); + break; + } + case 'win32': { + const filter = (e) => + e.address === '127.0.0.1'; + + const actual = interfaces['Loopback Pseudo-Interface 1'].filter(filter); + const expected = [{ + address: '127.0.0.1', + netmask: '255.0.0.0', + family: 'IPv4', + mac: '00:00:00:00:00:00', + internal: true, + cidr: '127.0.0.1/8' + }]; + assert.deepStrictEqual(actual, expected); + break; + } +} +const netmaskToCIDRSuffixMap = new Map(Object.entries({ + '255.0.0.0': 8, + '255.255.255.0': 24, + 'ffff:ffff:ffff:ffff::': 64, + 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff': 128 +})); + +Object.values(interfaces) + .flat(Infinity) + .map((v) => ({ v, mask: netmaskToCIDRSuffixMap.get(v.netmask) })) + .forEach(({ v, mask }) => { + assert.ok('cidr' in v, `"cidr" prop not found in ${inspect(v)}`); + if (mask) { + assert.strictEqual(v.cidr, `${v.address}/${mask}`); + } + }); + +const EOL = os.EOL; +if (common.isWindows) { + assert.strictEqual(EOL, '\r\n'); +} else { + assert.strictEqual(EOL, '\n'); +} + +const home = os.homedir(); +is.string(home); +assert.ok(home.includes(path.sep)); + +const version = os.version(); +assert.strictEqual(typeof version, 'string'); +assert(version); + +if (common.isWindows && process.env.USERPROFILE) { + assert.strictEqual(home, process.env.USERPROFILE); + delete process.env.USERPROFILE; + assert.ok(os.homedir().includes(path.sep)); + process.env.USERPROFILE = home; +} else if (!common.isWindows && process.env.HOME) { + assert.strictEqual(home, process.env.HOME); + delete process.env.HOME; + assert.ok(os.homedir().includes(path.sep)); + process.env.HOME = home; +} + +const pwd = os.userInfo(); +is.object(pwd); +const pwdBuf = os.userInfo({ encoding: 'buffer' }); + +if (common.isWindows) { + assert.strictEqual(pwd.uid, -1); + assert.strictEqual(pwd.gid, -1); + assert.strictEqual(pwd.shell, null); + assert.strictEqual(pwdBuf.uid, -1); + assert.strictEqual(pwdBuf.gid, -1); + assert.strictEqual(pwdBuf.shell, null); +} else { + is.number(pwd.uid); + is.number(pwd.gid); + assert.strictEqual(typeof pwd.shell, 'string'); + // It's possible for /etc/passwd to leave the user's shell blank. + if (pwd.shell.length > 0) { + assert(pwd.shell.includes(path.sep)); + } + assert.strictEqual(pwd.uid, pwdBuf.uid); + assert.strictEqual(pwd.gid, pwdBuf.gid); + assert.strictEqual(pwd.shell, pwdBuf.shell.toString('utf8')); +} + +is.string(pwd.username); +assert.ok(pwd.homedir.includes(path.sep)); +assert.strictEqual(pwd.username, pwdBuf.username.toString('utf8')); +assert.strictEqual(pwd.homedir, pwdBuf.homedir.toString('utf8')); + + +assert.strictEqual(`${os.hostname}`, os.hostname()); +assert.strictEqual(`${os.homedir}`, os.homedir()); +assert.strictEqual(`${os.release}`, os.release()); +assert.strictEqual(`${os.type}`, os.type()); +assert.strictEqual(`${os.endianness}`, os.endianness()); +// TODO(kt3k): Enable this test +// assert.strictEqual(`${os.tmpdir}`, os.tmpdir()); +assert.strictEqual(`${os.arch}`, os.arch()); +assert.strictEqual(`${os.platform}`, os.platform()); +assert.strictEqual(`${os.version}`, os.version()); + +assert.strictEqual(+os.totalmem, os.totalmem()); + +// Assert that the following values are coercible to numbers. +// On IBMi, os.uptime() returns 'undefined' +if (!common.isIBMi) { + is.number(+os.uptime, 'uptime'); + is.number(os.uptime(), 'uptime'); +} + +is.number(+os.freemem, 'freemem'); +is.number(os.freemem(), 'freemem'); + +const devNull = os.devNull; +if (common.isWindows) { + assert.strictEqual(devNull, '\\\\.\\nul'); +} else { + assert.strictEqual(devNull, '/dev/null'); +} diff --git a/tests/node_compat/test/parallel/test-outgoing-message-destroy.js b/tests/node_compat/test/parallel/test-outgoing-message-destroy.js new file mode 100644 index 000000000..d9a13796f --- /dev/null +++ b/tests/node_compat/test/parallel/test-outgoing-message-destroy.js @@ -0,0 +1,20 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +// Test that http.OutgoingMessage,prototype.destroy() returns `this`. +require('../common'); + +const assert = require('assert'); +const http = require('http'); +const outgoingMessage = new http.OutgoingMessage(); + +assert.strictEqual(outgoingMessage.destroyed, false); +assert.strictEqual(outgoingMessage.destroy(), outgoingMessage); +assert.strictEqual(outgoingMessage.destroyed, true); +assert.strictEqual(outgoingMessage.destroy(), outgoingMessage); diff --git a/tests/node_compat/test/parallel/test-outgoing-message-pipe.js b/tests/node_compat/test/parallel/test-outgoing-message-pipe.js new file mode 100644 index 000000000..ab9063c93 --- /dev/null +++ b/tests/node_compat/test/parallel/test-outgoing-message-pipe.js @@ -0,0 +1,22 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const assert = require('assert'); +const OutgoingMessage = require('_http_outgoing').OutgoingMessage; + +// Verify that an error is thrown upon a call to `OutgoingMessage.pipe`. + +const outgoingMessage = new OutgoingMessage(); +assert.throws( + () => { outgoingMessage.pipe(outgoingMessage); }, + { + code: 'ERR_STREAM_CANNOT_PIPE', + name: 'Error' + } +); diff --git a/tests/node_compat/test/parallel/test-parse-args.mjs b/tests/node_compat/test/parallel/test-parse-args.mjs new file mode 100644 index 000000000..ae8332fa7 --- /dev/null +++ b/tests/node_compat/test/parallel/test-parse-args.mjs @@ -0,0 +1,1001 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +import '../common/index.mjs'; +import assert from 'node:assert'; +import { test } from 'node:test'; +import { parseArgs } from 'node:util'; + +test('when short option used as flag then stored as flag', () => { + const args = ['-f']; + const expected = { values: { __proto__: null, f: true }, positionals: [] }; + const result = parseArgs({ strict: false, args }); + assert.deepStrictEqual(result, expected); +}); + +test('when short option used as flag before positional then stored as flag and positional (and not value)', () => { + const args = ['-f', 'bar']; + const expected = { values: { __proto__: null, f: true }, positionals: [ 'bar' ] }; + const result = parseArgs({ strict: false, args }); + assert.deepStrictEqual(result, expected); +}); + +test('when short option `type: "string"` used with value then stored as value', () => { + const args = ['-f', 'bar']; + const options = { f: { type: 'string' } }; + const expected = { values: { __proto__: null, f: 'bar' }, positionals: [] }; + const result = parseArgs({ args, options }); + assert.deepStrictEqual(result, expected); +}); + +test('when short option listed in short used as flag then long option stored as flag', () => { + const args = ['-f']; + const options = { foo: { short: 'f', type: 'boolean' } }; + const expected = { values: { __proto__: null, foo: true }, positionals: [] }; + const result = parseArgs({ args, options }); + assert.deepStrictEqual(result, expected); +}); + +test('when short option listed in short and long listed in `type: "string"` and ' + + 'used with value then long option stored as value', () => { + const args = ['-f', 'bar']; + const options = { foo: { short: 'f', type: 'string' } }; + const expected = { values: { __proto__: null, foo: 'bar' }, positionals: [] }; + const result = parseArgs({ args, options }); + assert.deepStrictEqual(result, expected); +}); + +test('when short option `type: "string"` used without value then stored as flag', () => { + const args = ['-f']; + const options = { f: { type: 'string' } }; + const expected = { values: { __proto__: null, f: true }, positionals: [] }; + const result = parseArgs({ strict: false, args, options }); + assert.deepStrictEqual(result, expected); +}); + +test('short option group behaves like multiple short options', () => { + const args = ['-rf']; + const options = { }; + const expected = { values: { __proto__: null, r: true, f: true }, positionals: [] }; + const result = parseArgs({ strict: false, args, options }); + assert.deepStrictEqual(result, expected); +}); + +test('short option group does not consume subsequent positional', () => { + const args = ['-rf', 'foo']; + const options = { }; + const expected = { values: { __proto__: null, r: true, f: true }, positionals: ['foo'] }; + const result = parseArgs({ strict: false, args, options }); + assert.deepStrictEqual(result, expected); +}); + +// See: Guideline 5 https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html +test('if terminal of short-option group configured `type: "string"`, subsequent positional is stored', () => { + const args = ['-rvf', 'foo']; + const options = { f: { type: 'string' } }; + const expected = { values: { __proto__: null, r: true, v: true, f: 'foo' }, positionals: [] }; + const result = parseArgs({ strict: false, args, options }); + assert.deepStrictEqual(result, expected); +}); + +test('handles short-option groups in conjunction with long-options', () => { + const args = ['-rf', '--foo', 'foo']; + const options = { foo: { type: 'string' } }; + const expected = { values: { __proto__: null, r: true, f: true, foo: 'foo' }, positionals: [] }; + const result = parseArgs({ strict: false, args, options }); + assert.deepStrictEqual(result, expected); +}); + +test('handles short-option groups with "short" alias configured', () => { + const args = ['-rf']; + const options = { remove: { short: 'r', type: 'boolean' } }; + const expected = { values: { __proto__: null, remove: true, f: true }, positionals: [] }; + const result = parseArgs({ strict: false, args, options }); + assert.deepStrictEqual(result, expected); +}); + +test('handles short-option followed by its value', () => { + const args = ['-fFILE']; + const options = { foo: { short: 'f', type: 'string' } }; + const expected = { values: { __proto__: null, foo: 'FILE' }, positionals: [] }; + const result = parseArgs({ strict: false, args, options }); + assert.deepStrictEqual(result, expected); +}); + +test('Everything after a bare `--` is considered a positional argument', () => { + const args = ['--', 'barepositionals', 'mopositionals']; + const expected = { values: { __proto__: null }, positionals: ['barepositionals', 'mopositionals'] }; + const result = parseArgs({ allowPositionals: true, args }); + assert.deepStrictEqual(result, expected, Error('testing bare positionals')); +}); + +test('args are true', () => { + const args = ['--foo', '--bar']; + const expected = { values: { __proto__: null, foo: true, bar: true }, positionals: [] }; + const result = parseArgs({ strict: false, args }); + assert.deepStrictEqual(result, expected, Error('args are true')); +}); + +test('arg is true and positional is identified', () => { + const args = ['--foo=a', '--foo', 'b']; + const expected = { values: { __proto__: null, foo: true }, positionals: ['b'] }; + const result = parseArgs({ strict: false, args }); + assert.deepStrictEqual(result, expected, Error('arg is true and positional is identified')); +}); + +test('args equals are passed `type: "string"`', () => { + const args = ['--so=wat']; + const options = { so: { type: 'string' } }; + const expected = { values: { __proto__: null, so: 'wat' }, positionals: [] }; + const result = parseArgs({ args, options }); + assert.deepStrictEqual(result, expected, Error('arg value is passed')); +}); + +test('when args include single dash then result stores dash as positional', () => { + const args = ['-']; + const expected = { values: { __proto__: null }, positionals: ['-'] }; + const result = parseArgs({ allowPositionals: true, args }); + assert.deepStrictEqual(result, expected); +}); + +test('zero config args equals are parsed as if `type: "string"`', () => { + const args = ['--so=wat']; + const options = { }; + const expected = { values: { __proto__: null, so: 'wat' }, positionals: [] }; + const result = parseArgs({ strict: false, args, options }); + assert.deepStrictEqual(result, expected, Error('arg value is passed')); +}); + +test('same arg is passed twice `type: "string"` and last value is recorded', () => { + const args = ['--foo=a', '--foo', 'b']; + const options = { foo: { type: 'string' } }; + const expected = { values: { __proto__: null, foo: 'b' }, positionals: [] }; + const result = parseArgs({ args, options }); + assert.deepStrictEqual(result, expected, Error('last arg value is passed')); +}); + +test('args equals pass string including more equals', () => { + const args = ['--so=wat=bing']; + const options = { so: { type: 'string' } }; + const expected = { values: { __proto__: null, so: 'wat=bing' }, positionals: [] }; + const result = parseArgs({ args, options }); + assert.deepStrictEqual(result, expected, Error('arg value is passed')); +}); + +test('first arg passed for `type: "string"` and "multiple" is in array', () => { + const args = ['--foo=a']; + const options = { foo: { type: 'string', multiple: true } }; + const expected = { values: { __proto__: null, foo: ['a'] }, positionals: [] }; + const result = parseArgs({ args, options }); + assert.deepStrictEqual(result, expected, Error('first multiple in array')); +}); + +test('args are passed `type: "string"` and "multiple"', () => { + const args = ['--foo=a', '--foo', 'b']; + const options = { + foo: { + type: 'string', + multiple: true, + }, + }; + const expected = { values: { __proto__: null, foo: ['a', 'b'] }, positionals: [] }; + const result = parseArgs({ args, options }); + assert.deepStrictEqual(result, expected, Error('both arg values are passed')); +}); + +test('when expecting `multiple:true` boolean option and option used multiple times then result includes array of ' + + 'booleans matching usage', () => { + const args = ['--foo', '--foo']; + const options = { + foo: { + type: 'boolean', + multiple: true, + }, + }; + const expected = { values: { __proto__: null, foo: [true, true] }, positionals: [] }; + const result = parseArgs({ args, options }); + assert.deepStrictEqual(result, expected); +}); + +test('order of option and positional does not matter (per README)', () => { + const args1 = ['--foo=bar', 'baz']; + const args2 = ['baz', '--foo=bar']; + const options = { foo: { type: 'string' } }; + const expected = { values: { __proto__: null, foo: 'bar' }, positionals: ['baz'] }; + assert.deepStrictEqual( + parseArgs({ allowPositionals: true, args: args1, options }), + expected, + Error('option then positional') + ); + assert.deepStrictEqual( + parseArgs({ allowPositionals: true, args: args2, options }), + expected, + Error('positional then option') + ); +}); + +test('correct default args when use node -p', () => { + const holdArgv = process.argv; + process.argv = [process.argv0, '--foo']; + const holdExecArgv = process.execArgv; + process.execArgv = ['-p', '0']; + const result = parseArgs({ strict: false }); + + const expected = { values: { __proto__: null, foo: true }, + positionals: [] }; + assert.deepStrictEqual(result, expected); + process.argv = holdArgv; + process.execArgv = holdExecArgv; +}); + +test('correct default args when use node --print', () => { + const holdArgv = process.argv; + process.argv = [process.argv0, '--foo']; + const holdExecArgv = process.execArgv; + process.execArgv = ['--print', '0']; + const result = parseArgs({ strict: false }); + + const expected = { values: { __proto__: null, foo: true }, + positionals: [] }; + assert.deepStrictEqual(result, expected); + process.argv = holdArgv; + process.execArgv = holdExecArgv; +}); + +test('correct default args when use node -e', () => { + const holdArgv = process.argv; + process.argv = [process.argv0, '--foo']; + const holdExecArgv = process.execArgv; + process.execArgv = ['-e', '0']; + const result = parseArgs({ strict: false }); + + const expected = { values: { __proto__: null, foo: true }, + positionals: [] }; + assert.deepStrictEqual(result, expected); + process.argv = holdArgv; + process.execArgv = holdExecArgv; +}); + +test('correct default args when use node --eval', () => { + const holdArgv = process.argv; + process.argv = [process.argv0, '--foo']; + const holdExecArgv = process.execArgv; + process.execArgv = ['--eval', '0']; + const result = parseArgs({ strict: false }); + const expected = { values: { __proto__: null, foo: true }, + positionals: [] }; + assert.deepStrictEqual(result, expected); + process.argv = holdArgv; + process.execArgv = holdExecArgv; +}); + +test('correct default args when normal arguments', () => { + const holdArgv = process.argv; + process.argv = [process.argv0, 'script.js', '--foo']; + const holdExecArgv = process.execArgv; + process.execArgv = []; + const result = parseArgs({ strict: false }); + + const expected = { values: { __proto__: null, foo: true }, + positionals: [] }; + assert.deepStrictEqual(result, expected); + process.argv = holdArgv; + process.execArgv = holdExecArgv; +}); + +test('excess leading dashes on options are retained', () => { + // Enforce a design decision for an edge case. + const args = ['---triple']; + const options = { }; + const expected = { + values: { '__proto__': null, '-triple': true }, + positionals: [] + }; + const result = parseArgs({ strict: false, args, options }); + assert.deepStrictEqual(result, expected, Error('excess option dashes are retained')); +}); + +test('positional arguments are allowed by default in strict:false', () => { + const args = ['foo']; + const options = { }; + const expected = { + values: { __proto__: null }, + positionals: ['foo'] + }; + const result = parseArgs({ strict: false, args, options }); + assert.deepStrictEqual(result, expected); +}); + +test('positional arguments may be explicitly disallowed in strict:false', () => { + const args = ['foo']; + const options = { }; + assert.throws(() => { parseArgs({ strict: false, allowPositionals: false, args, options }); }, { + code: 'ERR_PARSE_ARGS_UNEXPECTED_POSITIONAL' + }); +}); + +// Test bad inputs + +test('invalid argument passed for options', () => { + const args = ['--so=wat']; + const options = 'bad value'; + assert.throws(() => { parseArgs({ args, options }); }, { + code: 'ERR_INVALID_ARG_TYPE' + }); +}); + +test('type property missing for option then throw', () => { + const knownOptions = { foo: { } }; + assert.throws(() => { parseArgs({ options: knownOptions }); }, { + code: 'ERR_INVALID_ARG_TYPE' + }); +}); + +test('boolean passed to "type" option', () => { + const args = ['--so=wat']; + const options = { foo: { type: true } }; + assert.throws(() => { parseArgs({ args, options }); }, { + code: 'ERR_INVALID_ARG_TYPE' + }); +}); + +test('invalid union value passed to "type" option', () => { + const args = ['--so=wat']; + const options = { foo: { type: 'str' } }; + assert.throws(() => { parseArgs({ args, options }); }, { + code: 'ERR_INVALID_ARG_TYPE' + }); +}); + +// Test strict mode + +test('unknown long option --bar', () => { + const args = ['--foo', '--bar']; + const options = { foo: { type: 'boolean' } }; + assert.throws(() => { parseArgs({ args, options }); }, { + code: 'ERR_PARSE_ARGS_UNKNOWN_OPTION' + }); +}); + +test('unknown short option -b', () => { + const args = ['--foo', '-b']; + const options = { foo: { type: 'boolean' } }; + assert.throws(() => { parseArgs({ args, options }); }, { + code: 'ERR_PARSE_ARGS_UNKNOWN_OPTION' + }); +}); + +test('unknown option -r in short option group -bar', () => { + const args = ['-bar']; + const options = { b: { type: 'boolean' }, a: { type: 'boolean' } }; + assert.throws(() => { parseArgs({ args, options }); }, { + code: 'ERR_PARSE_ARGS_UNKNOWN_OPTION' + }); +}); + +test('unknown option with explicit value', () => { + const args = ['--foo', '--bar=baz']; + const options = { foo: { type: 'boolean' } }; + assert.throws(() => { parseArgs({ args, options }); }, { + code: 'ERR_PARSE_ARGS_UNKNOWN_OPTION' + }); +}); + +test('unexpected positional', () => { + const args = ['foo']; + const options = { foo: { type: 'boolean' } }; + assert.throws(() => { parseArgs({ args, options }); }, { + code: 'ERR_PARSE_ARGS_UNEXPECTED_POSITIONAL' + }); +}); + +test('unexpected positional after --', () => { + const args = ['--', 'foo']; + const options = { foo: { type: 'boolean' } }; + assert.throws(() => { parseArgs({ args, options }); }, { + code: 'ERR_PARSE_ARGS_UNEXPECTED_POSITIONAL' + }); +}); + +test('-- by itself is not a positional', () => { + const args = ['--foo', '--']; + const options = { foo: { type: 'boolean' } }; + const result = parseArgs({ args, options }); + const expected = { values: { __proto__: null, foo: true }, + positionals: [] }; + assert.deepStrictEqual(result, expected); +}); + +test('string option used as boolean', () => { + const args = ['--foo']; + const options = { foo: { type: 'string' } }; + assert.throws(() => { parseArgs({ args, options }); }, { + code: 'ERR_PARSE_ARGS_INVALID_OPTION_VALUE' + }); +}); + +test('boolean option used with value', () => { + const args = ['--foo=bar']; + const options = { foo: { type: 'boolean' } }; + assert.throws(() => { parseArgs({ args, options }); }, { + code: 'ERR_PARSE_ARGS_INVALID_OPTION_VALUE' + }); +}); + +test('invalid short option length', () => { + const args = []; + const options = { foo: { short: 'fo', type: 'boolean' } }; + assert.throws(() => { parseArgs({ args, options }); }, { + code: 'ERR_INVALID_ARG_VALUE' + }); +}); + +test('null prototype: when no options then values.toString is undefined', () => { + const result = parseArgs({ args: [] }); + assert.strictEqual(result.values.toString, undefined); +}); + +test('null prototype: when --toString then values.toString is true', () => { + const args = ['--toString']; + const options = { toString: { type: 'boolean' } }; + const expectedResult = { values: { __proto__: null, toString: true }, positionals: [] }; + + const result = parseArgs({ args, options }); + assert.deepStrictEqual(result, expectedResult); +}); + +const candidateGreedyOptions = [ + '', + '-', + '--', + 'abc', + '123', + '-s', + '--foo', +]; + +candidateGreedyOptions.forEach((value) => { + test(`greedy: when short option with value '${value}' then eaten`, () => { + const args = ['-w', value]; + const options = { with: { type: 'string', short: 'w' } }; + const expectedResult = { values: { __proto__: null, with: value }, positionals: [] }; + + const result = parseArgs({ args, options, strict: false }); + assert.deepStrictEqual(result, expectedResult); + }); + + test(`greedy: when long option with value '${value}' then eaten`, () => { + const args = ['--with', value]; + const options = { with: { type: 'string', short: 'w' } }; + const expectedResult = { values: { __proto__: null, with: value }, positionals: [] }; + + const result = parseArgs({ args, options, strict: false }); + assert.deepStrictEqual(result, expectedResult); + }); +}); + +test('strict: when candidate option value is plain text then does not throw', () => { + const args = ['--with', 'abc']; + const options = { with: { type: 'string' } }; + const expectedResult = { values: { __proto__: null, with: 'abc' }, positionals: [] }; + + const result = parseArgs({ args, options, strict: true }); + assert.deepStrictEqual(result, expectedResult); +}); + +test("strict: when candidate option value is '-' then does not throw", () => { + const args = ['--with', '-']; + const options = { with: { type: 'string' } }; + const expectedResult = { values: { __proto__: null, with: '-' }, positionals: [] }; + + const result = parseArgs({ args, options, strict: true }); + assert.deepStrictEqual(result, expectedResult); +}); + +test("strict: when candidate option value is '--' then throws", () => { + const args = ['--with', '--']; + const options = { with: { type: 'string' } }; + + assert.throws(() => { + parseArgs({ args, options }); + }, { + code: 'ERR_PARSE_ARGS_INVALID_OPTION_VALUE' + }); +}); + +test('strict: when candidate option value is short option then throws', () => { + const args = ['--with', '-a']; + const options = { with: { type: 'string' } }; + + assert.throws(() => { + parseArgs({ args, options }); + }, { + code: 'ERR_PARSE_ARGS_INVALID_OPTION_VALUE' + }); +}); + +test('strict: when candidate option value is short option digit then throws', () => { + const args = ['--with', '-1']; + const options = { with: { type: 'string' } }; + + assert.throws(() => { + parseArgs({ args, options }); + }, { + code: 'ERR_PARSE_ARGS_INVALID_OPTION_VALUE' + }); +}); + +test('strict: when candidate option value is long option then throws', () => { + const args = ['--with', '--foo']; + const options = { with: { type: 'string' } }; + + assert.throws(() => { + parseArgs({ args, options }); + }, { + code: 'ERR_PARSE_ARGS_INVALID_OPTION_VALUE' + }); +}); + +test('strict: when short option and suspect value then throws with short option in error message', () => { + const args = ['-w', '--foo']; + const options = { with: { type: 'string', short: 'w' } }; + + assert.throws(() => { + parseArgs({ args, options }); + }, /for '-w'/ + ); +}); + +test('strict: when long option and suspect value then throws with long option in error message', () => { + const args = ['--with', '--foo']; + const options = { with: { type: 'string' } }; + + assert.throws(() => { + parseArgs({ args, options }); + }, /for '--with'/ + ); +}); + +test('strict: when short option and suspect value then throws with whole expected message', () => { + const args = ['-w', '--foo']; + const options = { with: { type: 'string', short: 'w' } }; + + try { + parseArgs({ args, options }); + } catch (err) { + console.info(err.message); + } + + assert.throws(() => { + parseArgs({ args, options }); + }, /To specify an option argument starting with a dash use '--with=-XYZ' or '-w-XYZ'/ + ); +}); + +test('strict: when long option and suspect value then throws with whole expected message', () => { + const args = ['--with', '--foo']; + const options = { with: { type: 'string', short: 'w' } }; + + assert.throws(() => { + parseArgs({ args, options }); + }, /To specify an option argument starting with a dash use '--with=-XYZ'/ + ); +}); + +test('tokens: positional', () => { + const args = ['one']; + const expectedTokens = [ + { kind: 'positional', index: 0, value: 'one' }, + ]; + const { tokens } = parseArgs({ strict: false, args, tokens: true }); + assert.deepStrictEqual(tokens, expectedTokens); +}); + +test('tokens: -- followed by option-like', () => { + const args = ['--', '--foo']; + const expectedTokens = [ + { kind: 'option-terminator', index: 0 }, + { kind: 'positional', index: 1, value: '--foo' }, + ]; + const { tokens } = parseArgs({ strict: false, args, tokens: true }); + assert.deepStrictEqual(tokens, expectedTokens); +}); + +test('tokens: strict:true boolean short', () => { + const args = ['-f']; + const options = { + file: { short: 'f', type: 'boolean' } + }; + const expectedTokens = [ + { kind: 'option', name: 'file', rawName: '-f', + index: 0, value: undefined, inlineValue: undefined }, + ]; + const { tokens } = parseArgs({ strict: true, args, options, tokens: true }); + assert.deepStrictEqual(tokens, expectedTokens); +}); + +test('tokens: strict:true boolean long', () => { + const args = ['--file']; + const options = { + file: { short: 'f', type: 'boolean' } + }; + const expectedTokens = [ + { kind: 'option', name: 'file', rawName: '--file', + index: 0, value: undefined, inlineValue: undefined }, + ]; + const { tokens } = parseArgs({ strict: true, args, options, tokens: true }); + assert.deepStrictEqual(tokens, expectedTokens); +}); + +test('tokens: strict:false boolean short', () => { + const args = ['-f']; + const expectedTokens = [ + { kind: 'option', name: 'f', rawName: '-f', + index: 0, value: undefined, inlineValue: undefined }, + ]; + const { tokens } = parseArgs({ strict: false, args, tokens: true }); + assert.deepStrictEqual(tokens, expectedTokens); +}); + +test('tokens: strict:false boolean long', () => { + const args = ['--file']; + const expectedTokens = [ + { kind: 'option', name: 'file', rawName: '--file', + index: 0, value: undefined, inlineValue: undefined }, + ]; + const { tokens } = parseArgs({ strict: false, args, tokens: true }); + assert.deepStrictEqual(tokens, expectedTokens); +}); + +test('tokens: strict:false boolean option group', () => { + const args = ['-ab']; + const expectedTokens = [ + { kind: 'option', name: 'a', rawName: '-a', + index: 0, value: undefined, inlineValue: undefined }, + { kind: 'option', name: 'b', rawName: '-b', + index: 0, value: undefined, inlineValue: undefined }, + ]; + const { tokens } = parseArgs({ strict: false, args, tokens: true }); + assert.deepStrictEqual(tokens, expectedTokens); +}); + +test('tokens: strict:false boolean option group with repeated option', () => { + // Also positional to check index correct after grouop + const args = ['-aa', 'pos']; + const expectedTokens = [ + { kind: 'option', name: 'a', rawName: '-a', + index: 0, value: undefined, inlineValue: undefined }, + { kind: 'option', name: 'a', rawName: '-a', + index: 0, value: undefined, inlineValue: undefined }, + { kind: 'positional', index: 1, value: 'pos' }, + ]; + const { tokens } = parseArgs({ strict: false, allowPositionals: true, args, tokens: true }); + assert.deepStrictEqual(tokens, expectedTokens); +}); + +test('tokens: strict:true string short with value after space', () => { + // Also positional to check index correct after out-of-line. + const args = ['-f', 'bar', 'ppp']; + const options = { + file: { short: 'f', type: 'string' } + }; + const expectedTokens = [ + { kind: 'option', name: 'file', rawName: '-f', + index: 0, value: 'bar', inlineValue: false }, + { kind: 'positional', index: 2, value: 'ppp' }, + ]; + const { tokens } = parseArgs({ strict: true, allowPositionals: true, args, options, tokens: true }); + assert.deepStrictEqual(tokens, expectedTokens); +}); + +test('tokens: strict:true string short with value inline', () => { + const args = ['-fBAR']; + const options = { + file: { short: 'f', type: 'string' } + }; + const expectedTokens = [ + { kind: 'option', name: 'file', rawName: '-f', + index: 0, value: 'BAR', inlineValue: true }, + ]; + const { tokens } = parseArgs({ strict: true, args, options, tokens: true }); + assert.deepStrictEqual(tokens, expectedTokens); +}); + +test('tokens: strict:false string short missing value', () => { + const args = ['-f']; + const options = { + file: { short: 'f', type: 'string' } + }; + const expectedTokens = [ + { kind: 'option', name: 'file', rawName: '-f', + index: 0, value: undefined, inlineValue: undefined }, + ]; + const { tokens } = parseArgs({ strict: false, args, options, tokens: true }); + assert.deepStrictEqual(tokens, expectedTokens); +}); + +test('tokens: strict:true string long with value after space', () => { + // Also positional to check index correct after out-of-line. + const args = ['--file', 'bar', 'ppp']; + const options = { + file: { short: 'f', type: 'string' } + }; + const expectedTokens = [ + { kind: 'option', name: 'file', rawName: '--file', + index: 0, value: 'bar', inlineValue: false }, + { kind: 'positional', index: 2, value: 'ppp' }, + ]; + const { tokens } = parseArgs({ strict: true, allowPositionals: true, args, options, tokens: true }); + assert.deepStrictEqual(tokens, expectedTokens); +}); + +test('tokens: strict:true string long with value inline', () => { + // Also positional to check index correct after out-of-line. + const args = ['--file=bar', 'pos']; + const options = { + file: { short: 'f', type: 'string' } + }; + const expectedTokens = [ + { kind: 'option', name: 'file', rawName: '--file', + index: 0, value: 'bar', inlineValue: true }, + { kind: 'positional', index: 1, value: 'pos' }, + ]; + const { tokens } = parseArgs({ strict: true, allowPositionals: true, args, options, tokens: true }); + assert.deepStrictEqual(tokens, expectedTokens); +}); + +test('tokens: strict:false string long with value inline', () => { + const args = ['--file=bar']; + const expectedTokens = [ + { kind: 'option', name: 'file', rawName: '--file', + index: 0, value: 'bar', inlineValue: true }, + ]; + const { tokens } = parseArgs({ strict: false, args, tokens: true }); + assert.deepStrictEqual(tokens, expectedTokens); +}); + +test('tokens: strict:false string long missing value', () => { + const args = ['--file']; + const options = { + file: { short: 'f', type: 'string' } + }; + const expectedTokens = [ + { kind: 'option', name: 'file', rawName: '--file', + index: 0, value: undefined, inlineValue: undefined }, + ]; + const { tokens } = parseArgs({ strict: false, args, options, tokens: true }); + assert.deepStrictEqual(tokens, expectedTokens); +}); + +test('tokens: strict:true complex option group with value after space', () => { + // Also positional to check index correct afterwards. + const args = ['-ab', 'c', 'pos']; + const options = { + alpha: { short: 'a', type: 'boolean' }, + beta: { short: 'b', type: 'string' }, + }; + const expectedTokens = [ + { kind: 'option', name: 'alpha', rawName: '-a', + index: 0, value: undefined, inlineValue: undefined }, + { kind: 'option', name: 'beta', rawName: '-b', + index: 0, value: 'c', inlineValue: false }, + { kind: 'positional', index: 2, value: 'pos' }, + ]; + const { tokens } = parseArgs({ strict: true, allowPositionals: true, args, options, tokens: true }); + assert.deepStrictEqual(tokens, expectedTokens); +}); + +test('tokens: strict:true complex option group with inline value', () => { + // Also positional to check index correct afterwards. + const args = ['-abc', 'pos']; + const options = { + alpha: { short: 'a', type: 'boolean' }, + beta: { short: 'b', type: 'string' }, + }; + const expectedTokens = [ + { kind: 'option', name: 'alpha', rawName: '-a', + index: 0, value: undefined, inlineValue: undefined }, + { kind: 'option', name: 'beta', rawName: '-b', + index: 0, value: 'c', inlineValue: true }, + { kind: 'positional', index: 1, value: 'pos' }, + ]; + const { tokens } = parseArgs({ strict: true, allowPositionals: true, args, options, tokens: true }); + assert.deepStrictEqual(tokens, expectedTokens); +}); + +test('tokens: strict:false with single dashes', () => { + const args = ['--file', '-', '-']; + const options = { + file: { short: 'f', type: 'string' }, + }; + const expectedTokens = [ + { kind: 'option', name: 'file', rawName: '--file', + index: 0, value: '-', inlineValue: false }, + { kind: 'positional', index: 2, value: '-' }, + ]; + const { tokens } = parseArgs({ strict: false, args, options, tokens: true }); + assert.deepStrictEqual(tokens, expectedTokens); +}); + +test('tokens: strict:false with -- --', () => { + const args = ['--', '--']; + const expectedTokens = [ + { kind: 'option-terminator', index: 0 }, + { kind: 'positional', index: 1, value: '--' }, + ]; + const { tokens } = parseArgs({ strict: false, args, tokens: true }); + assert.deepStrictEqual(tokens, expectedTokens); +}); + +test('default must be a boolean when option type is boolean', () => { + const args = []; + const options = { alpha: { type: 'boolean', default: 'not a boolean' } }; + assert.throws(() => { + parseArgs({ args, options }); + }, /"options\.alpha\.default" property must be of type boolean/ + ); +}); + +test('default must accept undefined value', () => { + const args = []; + const options = { alpha: { type: 'boolean', default: undefined } }; + const result = parseArgs({ args, options }); + const expected = { + values: { + __proto__: null, + }, + positionals: [] + }; + assert.deepStrictEqual(result, expected); +}); + +test('default must be a boolean array when option type is boolean and multiple', () => { + const args = []; + const options = { alpha: { type: 'boolean', multiple: true, default: 'not an array' } }; + assert.throws(() => { + parseArgs({ args, options }); + }, /"options\.alpha\.default" property must be an instance of Array/ + ); +}); + +test('default must be a boolean array when option type is string and multiple is true', () => { + const args = []; + const options = { alpha: { type: 'boolean', multiple: true, default: [true, true, 42] } }; + assert.throws(() => { + parseArgs({ args, options }); + }, /"options\.alpha\.default\[2\]" property must be of type boolean/ + ); +}); + +test('default must be a string when option type is string', () => { + const args = []; + const options = { alpha: { type: 'string', default: true } }; + assert.throws(() => { + parseArgs({ args, options }); + }, /"options\.alpha\.default" property must be of type string/ + ); +}); + +test('default must be an array when option type is string and multiple is true', () => { + const args = []; + const options = { alpha: { type: 'string', multiple: true, default: 'not an array' } }; + assert.throws(() => { + parseArgs({ args, options }); + }, /"options\.alpha\.default" property must be an instance of Array/ + ); +}); + +test('default must be a string array when option type is string and multiple is true', () => { + const args = []; + const options = { alpha: { type: 'string', multiple: true, default: ['str', 42] } }; + assert.throws(() => { + parseArgs({ args, options }); + }, /"options\.alpha\.default\[1\]" property must be of type string/ + ); +}); + +test('default accepted input when multiple is true', () => { + const args = ['--inputStringArr', 'c', '--inputStringArr', 'd', '--inputBoolArr', '--inputBoolArr']; + const options = { + inputStringArr: { type: 'string', multiple: true, default: ['a', 'b'] }, + emptyStringArr: { type: 'string', multiple: true, default: [] }, + fullStringArr: { type: 'string', multiple: true, default: ['a', 'b'] }, + inputBoolArr: { type: 'boolean', multiple: true, default: [false, true, false] }, + emptyBoolArr: { type: 'boolean', multiple: true, default: [] }, + fullBoolArr: { type: 'boolean', multiple: true, default: [false, true, false] }, + }; + const expected = { values: { __proto__: null, + inputStringArr: ['c', 'd'], + inputBoolArr: [true, true], + emptyStringArr: [], + fullStringArr: ['a', 'b'], + emptyBoolArr: [], + fullBoolArr: [false, true, false] }, + positionals: [] }; + const result = parseArgs({ args, options }); + assert.deepStrictEqual(result, expected); +}); + +test('when default is set, the option must be added as result', () => { + const args = []; + const options = { + a: { type: 'string', default: 'HELLO' }, + b: { type: 'boolean', default: false }, + c: { type: 'boolean', default: true } + }; + const expected = { values: { __proto__: null, a: 'HELLO', b: false, c: true }, positionals: [] }; + + const result = parseArgs({ args, options }); + assert.deepStrictEqual(result, expected); +}); + +test('when default is set, the args value takes precedence', () => { + const args = ['--a', 'WORLD', '--b', '-c']; + const options = { + a: { type: 'string', default: 'HELLO' }, + b: { type: 'boolean', default: false }, + c: { type: 'boolean', default: true } + }; + const expected = { values: { __proto__: null, a: 'WORLD', b: true, c: true }, positionals: [] }; + + const result = parseArgs({ args, options }); + assert.deepStrictEqual(result, expected); +}); + +test('tokens should not include the default options', () => { + const args = []; + const options = { + a: { type: 'string', default: 'HELLO' }, + b: { type: 'boolean', default: false }, + c: { type: 'boolean', default: true } + }; + + const expectedTokens = []; + + const { tokens } = parseArgs({ args, options, tokens: true }); + assert.deepStrictEqual(tokens, expectedTokens); +}); + +test('tokens:true should not include the default options after the args input', () => { + const args = ['--z', 'zero', 'positional-item']; + const options = { + z: { type: 'string' }, + a: { type: 'string', default: 'HELLO' }, + b: { type: 'boolean', default: false }, + c: { type: 'boolean', default: true } + }; + + const expectedTokens = [ + { kind: 'option', name: 'z', rawName: '--z', index: 0, value: 'zero', inlineValue: false }, + { kind: 'positional', index: 2, value: 'positional-item' }, + ]; + + const { tokens } = parseArgs({ args, options, tokens: true, allowPositionals: true }); + assert.deepStrictEqual(tokens, expectedTokens); +}); + +test('proto as default value must be ignored', () => { + const args = []; + const options = Object.create(null); + + // eslint-disable-next-line no-proto + options.__proto__ = { type: 'string', default: 'HELLO' }; + + const result = parseArgs({ args, options, allowPositionals: true }); + const expected = { values: { __proto__: null }, positionals: [] }; + assert.deepStrictEqual(result, expected); +}); + + +test('multiple as false should expect a String', () => { + const args = []; + const options = { alpha: { type: 'string', multiple: false, default: ['array'] } }; + assert.throws(() => { + parseArgs({ args, options }); + }, /"options\.alpha\.default" property must be of type string/ + ); +}); diff --git a/tests/node_compat/test/parallel/test-path-basename.js b/tests/node_compat/test/parallel/test-path-basename.js new file mode 100644 index 000000000..9e8e9ecf8 --- /dev/null +++ b/tests/node_compat/test/parallel/test-path-basename.js @@ -0,0 +1,83 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const assert = require('assert'); +const path = require('path'); + +assert.strictEqual(path.basename(__filename), 'test-path-basename.js'); +assert.strictEqual(path.basename(__filename, '.js'), 'test-path-basename'); +assert.strictEqual(path.basename('.js', '.js'), ''); +assert.strictEqual(path.basename('js', '.js'), 'js'); +assert.strictEqual(path.basename('file.js', '.ts'), 'file.js'); +assert.strictEqual(path.basename('file', '.js'), 'file'); +assert.strictEqual(path.basename('file.js.old', '.js.old'), 'file'); +assert.strictEqual(path.basename(''), ''); +assert.strictEqual(path.basename('/dir/basename.ext'), 'basename.ext'); +assert.strictEqual(path.basename('/basename.ext'), 'basename.ext'); +assert.strictEqual(path.basename('basename.ext'), 'basename.ext'); +assert.strictEqual(path.basename('basename.ext/'), 'basename.ext'); +assert.strictEqual(path.basename('basename.ext//'), 'basename.ext'); +assert.strictEqual(path.basename('aaa/bbb', '/bbb'), 'bbb'); +assert.strictEqual(path.basename('aaa/bbb', 'a/bbb'), 'bbb'); +assert.strictEqual(path.basename('aaa/bbb', 'bbb'), 'bbb'); +assert.strictEqual(path.basename('aaa/bbb//', 'bbb'), 'bbb'); +assert.strictEqual(path.basename('aaa/bbb', 'bb'), 'b'); +assert.strictEqual(path.basename('aaa/bbb', 'b'), 'bb'); +assert.strictEqual(path.basename('/aaa/bbb', '/bbb'), 'bbb'); +assert.strictEqual(path.basename('/aaa/bbb', 'a/bbb'), 'bbb'); +assert.strictEqual(path.basename('/aaa/bbb', 'bbb'), 'bbb'); +assert.strictEqual(path.basename('/aaa/bbb//', 'bbb'), 'bbb'); +assert.strictEqual(path.basename('/aaa/bbb', 'bb'), 'b'); +assert.strictEqual(path.basename('/aaa/bbb', 'b'), 'bb'); +assert.strictEqual(path.basename('/aaa/bbb'), 'bbb'); +assert.strictEqual(path.basename('/aaa/'), 'aaa'); +assert.strictEqual(path.basename('/aaa/b'), 'b'); +assert.strictEqual(path.basename('/a/b'), 'b'); +assert.strictEqual(path.basename('//a'), 'a'); +assert.strictEqual(path.basename('a', 'a'), ''); + +// On Windows a backslash acts as a path separator. +assert.strictEqual(path.win32.basename('\\dir\\basename.ext'), 'basename.ext'); +assert.strictEqual(path.win32.basename('\\basename.ext'), 'basename.ext'); +assert.strictEqual(path.win32.basename('basename.ext'), 'basename.ext'); +assert.strictEqual(path.win32.basename('basename.ext\\'), 'basename.ext'); +assert.strictEqual(path.win32.basename('basename.ext\\\\'), 'basename.ext'); +assert.strictEqual(path.win32.basename('foo'), 'foo'); +assert.strictEqual(path.win32.basename('aaa\\bbb', '\\bbb'), 'bbb'); +assert.strictEqual(path.win32.basename('aaa\\bbb', 'a\\bbb'), 'bbb'); +assert.strictEqual(path.win32.basename('aaa\\bbb', 'bbb'), 'bbb'); +assert.strictEqual(path.win32.basename('aaa\\bbb\\\\\\\\', 'bbb'), 'bbb'); +assert.strictEqual(path.win32.basename('aaa\\bbb', 'bb'), 'b'); +assert.strictEqual(path.win32.basename('aaa\\bbb', 'b'), 'bb'); +assert.strictEqual(path.win32.basename('C:'), ''); +assert.strictEqual(path.win32.basename('C:.'), '.'); +assert.strictEqual(path.win32.basename('C:\\'), ''); +assert.strictEqual(path.win32.basename('C:\\dir\\base.ext'), 'base.ext'); +assert.strictEqual(path.win32.basename('C:\\basename.ext'), 'basename.ext'); +assert.strictEqual(path.win32.basename('C:basename.ext'), 'basename.ext'); +assert.strictEqual(path.win32.basename('C:basename.ext\\'), 'basename.ext'); +assert.strictEqual(path.win32.basename('C:basename.ext\\\\'), 'basename.ext'); +assert.strictEqual(path.win32.basename('C:foo'), 'foo'); +assert.strictEqual(path.win32.basename('file:stream'), 'file:stream'); +assert.strictEqual(path.win32.basename('a', 'a'), ''); + +// On unix a backslash is just treated as any other character. +assert.strictEqual(path.posix.basename('\\dir\\basename.ext'), + '\\dir\\basename.ext'); +assert.strictEqual(path.posix.basename('\\basename.ext'), '\\basename.ext'); +assert.strictEqual(path.posix.basename('basename.ext'), 'basename.ext'); +assert.strictEqual(path.posix.basename('basename.ext\\'), 'basename.ext\\'); +assert.strictEqual(path.posix.basename('basename.ext\\\\'), 'basename.ext\\\\'); +assert.strictEqual(path.posix.basename('foo'), 'foo'); + +// POSIX filenames may include control characters +// c.f. http://www.dwheeler.com/essays/fixing-unix-linux-filenames.html +const controlCharFilename = `Icon${String.fromCharCode(13)}`; +assert.strictEqual(path.posix.basename(`/a/b/${controlCharFilename}`), + controlCharFilename); diff --git a/tests/node_compat/test/parallel/test-path-dirname.js b/tests/node_compat/test/parallel/test-path-dirname.js new file mode 100644 index 000000000..0b123fcdf --- /dev/null +++ b/tests/node_compat/test/parallel/test-path-dirname.js @@ -0,0 +1,66 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const path = require('path'); + +assert.strictEqual(path.dirname(__filename).substr(-13), + common.isWindows ? 'test\\parallel' : 'test/parallel'); + +assert.strictEqual(path.posix.dirname('/a/b/'), '/a'); +assert.strictEqual(path.posix.dirname('/a/b'), '/a'); +assert.strictEqual(path.posix.dirname('/a'), '/'); +assert.strictEqual(path.posix.dirname(''), '.'); +assert.strictEqual(path.posix.dirname('/'), '/'); +assert.strictEqual(path.posix.dirname('////'), '/'); +assert.strictEqual(path.posix.dirname('//a'), '//'); +assert.strictEqual(path.posix.dirname('foo'), '.'); + +assert.strictEqual(path.win32.dirname('c:\\'), 'c:\\'); +assert.strictEqual(path.win32.dirname('c:\\foo'), 'c:\\'); +assert.strictEqual(path.win32.dirname('c:\\foo\\'), 'c:\\'); +assert.strictEqual(path.win32.dirname('c:\\foo\\bar'), 'c:\\foo'); +assert.strictEqual(path.win32.dirname('c:\\foo\\bar\\'), 'c:\\foo'); +assert.strictEqual(path.win32.dirname('c:\\foo\\bar\\baz'), 'c:\\foo\\bar'); +assert.strictEqual(path.win32.dirname('c:\\foo bar\\baz'), 'c:\\foo bar'); +assert.strictEqual(path.win32.dirname('\\'), '\\'); +assert.strictEqual(path.win32.dirname('\\foo'), '\\'); +assert.strictEqual(path.win32.dirname('\\foo\\'), '\\'); +assert.strictEqual(path.win32.dirname('\\foo\\bar'), '\\foo'); +assert.strictEqual(path.win32.dirname('\\foo\\bar\\'), '\\foo'); +assert.strictEqual(path.win32.dirname('\\foo\\bar\\baz'), '\\foo\\bar'); +assert.strictEqual(path.win32.dirname('\\foo bar\\baz'), '\\foo bar'); +assert.strictEqual(path.win32.dirname('c:'), 'c:'); +assert.strictEqual(path.win32.dirname('c:foo'), 'c:'); +assert.strictEqual(path.win32.dirname('c:foo\\'), 'c:'); +assert.strictEqual(path.win32.dirname('c:foo\\bar'), 'c:foo'); +assert.strictEqual(path.win32.dirname('c:foo\\bar\\'), 'c:foo'); +assert.strictEqual(path.win32.dirname('c:foo\\bar\\baz'), 'c:foo\\bar'); +assert.strictEqual(path.win32.dirname('c:foo bar\\baz'), 'c:foo bar'); +assert.strictEqual(path.win32.dirname('file:stream'), '.'); +assert.strictEqual(path.win32.dirname('dir\\file:stream'), 'dir'); +assert.strictEqual(path.win32.dirname('\\\\unc\\share'), + '\\\\unc\\share'); +assert.strictEqual(path.win32.dirname('\\\\unc\\share\\foo'), + '\\\\unc\\share\\'); +assert.strictEqual(path.win32.dirname('\\\\unc\\share\\foo\\'), + '\\\\unc\\share\\'); +assert.strictEqual(path.win32.dirname('\\\\unc\\share\\foo\\bar'), + '\\\\unc\\share\\foo'); +assert.strictEqual(path.win32.dirname('\\\\unc\\share\\foo\\bar\\'), + '\\\\unc\\share\\foo'); +assert.strictEqual(path.win32.dirname('\\\\unc\\share\\foo\\bar\\baz'), + '\\\\unc\\share\\foo\\bar'); +assert.strictEqual(path.win32.dirname('/a/b/'), '/a'); +assert.strictEqual(path.win32.dirname('/a/b'), '/a'); +assert.strictEqual(path.win32.dirname('/a'), '/'); +assert.strictEqual(path.win32.dirname(''), '.'); +assert.strictEqual(path.win32.dirname('/'), '/'); +assert.strictEqual(path.win32.dirname('////'), '/'); +assert.strictEqual(path.win32.dirname('foo'), '.'); diff --git a/tests/node_compat/test/parallel/test-path-extname.js b/tests/node_compat/test/parallel/test-path-extname.js new file mode 100644 index 000000000..d1ed0342b --- /dev/null +++ b/tests/node_compat/test/parallel/test-path-extname.js @@ -0,0 +1,106 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const assert = require('assert'); +const path = require('path'); + +const failures = []; +const slashRE = /\//g; + +[ + [__filename, '.js'], + ['', ''], + ['/path/to/file', ''], + ['/path/to/file.ext', '.ext'], + ['/path.to/file.ext', '.ext'], + ['/path.to/file', ''], + ['/path.to/.file', ''], + ['/path.to/.file.ext', '.ext'], + ['/path/to/f.ext', '.ext'], + ['/path/to/..ext', '.ext'], + ['/path/to/..', ''], + ['file', ''], + ['file.ext', '.ext'], + ['.file', ''], + ['.file.ext', '.ext'], + ['/file', ''], + ['/file.ext', '.ext'], + ['/.file', ''], + ['/.file.ext', '.ext'], + ['.path/file.ext', '.ext'], + ['file.ext.ext', '.ext'], + ['file.', '.'], + ['.', ''], + ['./', ''], + ['.file.ext', '.ext'], + ['.file', ''], + ['.file.', '.'], + ['.file..', '.'], + ['..', ''], + ['../', ''], + ['..file.ext', '.ext'], + ['..file', '.file'], + ['..file.', '.'], + ['..file..', '.'], + ['...', '.'], + ['...ext', '.ext'], + ['....', '.'], + ['file.ext/', '.ext'], + ['file.ext//', '.ext'], + ['file/', ''], + ['file//', ''], + ['file./', '.'], + ['file.//', '.'], +].forEach((test) => { + const expected = test[1]; + [path.posix.extname, path.win32.extname].forEach((extname) => { + let input = test[0]; + let os; + if (extname === path.win32.extname) { + input = input.replace(slashRE, '\\'); + os = 'win32'; + } else { + os = 'posix'; + } + const actual = extname(input); + const message = `path.${os}.extname(${JSON.stringify(input)})\n expect=${ + JSON.stringify(expected)}\n actual=${JSON.stringify(actual)}`; + if (actual !== expected) + failures.push(`\n${message}`); + }); + { + const input = `C:${test[0].replace(slashRE, '\\')}`; + const actual = path.win32.extname(input); + const message = `path.win32.extname(${JSON.stringify(input)})\n expect=${ + JSON.stringify(expected)}\n actual=${JSON.stringify(actual)}`; + if (actual !== expected) + failures.push(`\n${message}`); + } +}); +assert.strictEqual(failures.length, 0, failures.join('')); + +// On Windows, backslash is a path separator. +assert.strictEqual(path.win32.extname('.\\'), ''); +assert.strictEqual(path.win32.extname('..\\'), ''); +assert.strictEqual(path.win32.extname('file.ext\\'), '.ext'); +assert.strictEqual(path.win32.extname('file.ext\\\\'), '.ext'); +assert.strictEqual(path.win32.extname('file\\'), ''); +assert.strictEqual(path.win32.extname('file\\\\'), ''); +assert.strictEqual(path.win32.extname('file.\\'), '.'); +assert.strictEqual(path.win32.extname('file.\\\\'), '.'); + +// On *nix, backslash is a valid name component like any other character. +assert.strictEqual(path.posix.extname('.\\'), ''); +assert.strictEqual(path.posix.extname('..\\'), '.\\'); +assert.strictEqual(path.posix.extname('file.ext\\'), '.ext\\'); +assert.strictEqual(path.posix.extname('file.ext\\\\'), '.ext\\\\'); +assert.strictEqual(path.posix.extname('file\\'), ''); +assert.strictEqual(path.posix.extname('file\\\\'), ''); +assert.strictEqual(path.posix.extname('file.\\'), '.\\'); +assert.strictEqual(path.posix.extname('file.\\\\'), '.\\\\'); diff --git a/tests/node_compat/test/parallel/test-path-isabsolute.js b/tests/node_compat/test/parallel/test-path-isabsolute.js new file mode 100644 index 000000000..ff64fc7ff --- /dev/null +++ b/tests/node_compat/test/parallel/test-path-isabsolute.js @@ -0,0 +1,35 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const assert = require('assert'); +const path = require('path'); + +assert.strictEqual(path.win32.isAbsolute('/'), true); +assert.strictEqual(path.win32.isAbsolute('//'), true); +assert.strictEqual(path.win32.isAbsolute('//server'), true); +assert.strictEqual(path.win32.isAbsolute('//server/file'), true); +assert.strictEqual(path.win32.isAbsolute('\\\\server\\file'), true); +assert.strictEqual(path.win32.isAbsolute('\\\\server'), true); +assert.strictEqual(path.win32.isAbsolute('\\\\'), true); +assert.strictEqual(path.win32.isAbsolute('c'), false); +assert.strictEqual(path.win32.isAbsolute('c:'), false); +assert.strictEqual(path.win32.isAbsolute('c:\\'), true); +assert.strictEqual(path.win32.isAbsolute('c:/'), true); +assert.strictEqual(path.win32.isAbsolute('c://'), true); +assert.strictEqual(path.win32.isAbsolute('C:/Users/'), true); +assert.strictEqual(path.win32.isAbsolute('C:\\Users\\'), true); +assert.strictEqual(path.win32.isAbsolute('C:cwd/another'), false); +assert.strictEqual(path.win32.isAbsolute('C:cwd\\another'), false); +assert.strictEqual(path.win32.isAbsolute('directory/directory'), false); +assert.strictEqual(path.win32.isAbsolute('directory\\directory'), false); + +assert.strictEqual(path.posix.isAbsolute('/home/foo'), true); +assert.strictEqual(path.posix.isAbsolute('/home/foo/..'), true); +assert.strictEqual(path.posix.isAbsolute('bar/'), false); +assert.strictEqual(path.posix.isAbsolute('./baz'), false); diff --git a/tests/node_compat/test/parallel/test-path-join.js b/tests/node_compat/test/parallel/test-path-join.js new file mode 100644 index 000000000..2b958b720 --- /dev/null +++ b/tests/node_compat/test/parallel/test-path-join.js @@ -0,0 +1,150 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const assert = require('assert'); +const path = require('path'); + +const failures = []; +const backslashRE = /\\/g; + +const joinTests = [ + [ [path.posix.join, path.win32.join], + // Arguments result + [[['.', 'x/b', '..', '/b/c.js'], 'x/b/c.js'], + [[], '.'], + [['/.', 'x/b', '..', '/b/c.js'], '/x/b/c.js'], + [['/foo', '../../../bar'], '/bar'], + [['foo', '../../../bar'], '../../bar'], + [['foo/', '../../../bar'], '../../bar'], + [['foo/x', '../../../bar'], '../bar'], + [['foo/x', './bar'], 'foo/x/bar'], + [['foo/x/', './bar'], 'foo/x/bar'], + [['foo/x/', '.', 'bar'], 'foo/x/bar'], + [['./'], './'], + [['.', './'], './'], + [['.', '.', '.'], '.'], + [['.', './', '.'], '.'], + [['.', '/./', '.'], '.'], + [['.', '/////./', '.'], '.'], + [['.'], '.'], + [['', '.'], '.'], + [['', 'foo'], 'foo'], + [['foo', '/bar'], 'foo/bar'], + [['', '/foo'], '/foo'], + [['', '', '/foo'], '/foo'], + [['', '', 'foo'], 'foo'], + [['foo', ''], 'foo'], + [['foo/', ''], 'foo/'], + [['foo', '', '/bar'], 'foo/bar'], + [['./', '..', '/foo'], '../foo'], + [['./', '..', '..', '/foo'], '../../foo'], + [['.', '..', '..', '/foo'], '../../foo'], + [['', '..', '..', '/foo'], '../../foo'], + [['/'], '/'], + [['/', '.'], '/'], + [['/', '..'], '/'], + [['/', '..', '..'], '/'], + [[''], '.'], + [['', ''], '.'], + [[' /foo'], ' /foo'], + [[' ', 'foo'], ' /foo'], + [[' ', '.'], ' '], + [[' ', '/'], ' /'], + [[' ', ''], ' '], + [['/', 'foo'], '/foo'], + [['/', '/foo'], '/foo'], + [['/', '//foo'], '/foo'], + [['/', '', '/foo'], '/foo'], + [['', '/', 'foo'], '/foo'], + [['', '/', '/foo'], '/foo'], + ], + ], +]; + +// Windows-specific join tests +joinTests.push([ + path.win32.join, + joinTests[0][1].slice(0).concat( + [// Arguments result + // UNC path expected + [['//foo/bar'], '\\\\foo\\bar\\'], + [['\\/foo/bar'], '\\\\foo\\bar\\'], + [['\\\\foo/bar'], '\\\\foo\\bar\\'], + // UNC path expected - server and share separate + [['//foo', 'bar'], '\\\\foo\\bar\\'], + [['//foo/', 'bar'], '\\\\foo\\bar\\'], + [['//foo', '/bar'], '\\\\foo\\bar\\'], + // UNC path expected - questionable + [['//foo', '', 'bar'], '\\\\foo\\bar\\'], + [['//foo/', '', 'bar'], '\\\\foo\\bar\\'], + [['//foo/', '', '/bar'], '\\\\foo\\bar\\'], + // UNC path expected - even more questionable + [['', '//foo', 'bar'], '\\\\foo\\bar\\'], + [['', '//foo/', 'bar'], '\\\\foo\\bar\\'], + [['', '//foo/', '/bar'], '\\\\foo\\bar\\'], + // No UNC path expected (no double slash in first component) + [['\\', 'foo/bar'], '\\foo\\bar'], + [['\\', '/foo/bar'], '\\foo\\bar'], + [['', '/', '/foo/bar'], '\\foo\\bar'], + // No UNC path expected (no non-slashes in first component - + // questionable) + [['//', 'foo/bar'], '\\foo\\bar'], + [['//', '/foo/bar'], '\\foo\\bar'], + [['\\\\', '/', '/foo/bar'], '\\foo\\bar'], + [['//'], '\\'], + // No UNC path expected (share name missing - questionable). + [['//foo'], '\\foo'], + [['//foo/'], '\\foo\\'], + [['//foo', '/'], '\\foo\\'], + [['//foo', '', '/'], '\\foo\\'], + // No UNC path expected (too many leading slashes - questionable) + [['///foo/bar'], '\\foo\\bar'], + [['////foo', 'bar'], '\\foo\\bar'], + [['\\\\\\/foo/bar'], '\\foo\\bar'], + // Drive-relative vs drive-absolute paths. This merely describes the + // status quo, rather than being obviously right + [['c:'], 'c:.'], + [['c:.'], 'c:.'], + [['c:', ''], 'c:.'], + [['', 'c:'], 'c:.'], + [['c:.', '/'], 'c:.\\'], + [['c:.', 'file'], 'c:file'], + [['c:', '/'], 'c:\\'], + [['c:', 'file'], 'c:\\file'], + ] + ), +]); +joinTests.forEach((test) => { + if (!Array.isArray(test[0])) + test[0] = [test[0]]; + test[0].forEach((join) => { + test[1].forEach((test) => { + const actual = join.apply(null, test[0]); + const expected = test[1]; + // For non-Windows specific tests with the Windows join(), we need to try + // replacing the slashes since the non-Windows specific tests' `expected` + // use forward slashes + let actualAlt; + let os; + if (join === path.win32.join) { + actualAlt = actual.replace(backslashRE, '/'); + os = 'win32'; + } else { + os = 'posix'; + } + if (actual !== expected && actualAlt !== expected) { + const delimiter = test[0].map(JSON.stringify).join(','); + const message = `path.${os}.join(${delimiter})\n expect=${ + JSON.stringify(expected)}\n actual=${JSON.stringify(actual)}`; + failures.push(`\n${message}`); + } + }); + }); +}); +assert.strictEqual(failures.length, 0, failures.join('')); diff --git a/tests/node_compat/test/parallel/test-path-makelong.js b/tests/node_compat/test/parallel/test-path-makelong.js new file mode 100644 index 000000000..694240109 --- /dev/null +++ b/tests/node_compat/test/parallel/test-path-makelong.js @@ -0,0 +1,94 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const fixtures = require('../common/fixtures'); +const assert = require('assert'); +const path = require('path'); + +if (common.isWindows) { + const file = fixtures.path('a.js'); + const resolvedFile = path.resolve(file); + + assert.strictEqual(path.toNamespacedPath(file), + `\\\\?\\${resolvedFile}`); + assert.strictEqual(path.toNamespacedPath(`\\\\?\\${file}`), + `\\\\?\\${resolvedFile}`); + assert.strictEqual(path.toNamespacedPath( + '\\\\someserver\\someshare\\somefile'), + '\\\\?\\UNC\\someserver\\someshare\\somefile'); + assert.strictEqual(path.toNamespacedPath( + '\\\\?\\UNC\\someserver\\someshare\\somefile'), + '\\\\?\\UNC\\someserver\\someshare\\somefile'); + assert.strictEqual(path.toNamespacedPath('\\\\.\\pipe\\somepipe'), + '\\\\.\\pipe\\somepipe'); +} + +assert.strictEqual(path.toNamespacedPath(''), ''); +assert.strictEqual(path.toNamespacedPath(null), null); +assert.strictEqual(path.toNamespacedPath(100), 100); +assert.strictEqual(path.toNamespacedPath(path), path); +assert.strictEqual(path.toNamespacedPath(false), false); +assert.strictEqual(path.toNamespacedPath(true), true); + +const emptyObj = {}; +assert.strictEqual(path.posix.toNamespacedPath('/foo/bar'), '/foo/bar'); +assert.strictEqual(path.posix.toNamespacedPath('foo/bar'), 'foo/bar'); +assert.strictEqual(path.posix.toNamespacedPath(null), null); +assert.strictEqual(path.posix.toNamespacedPath(true), true); +assert.strictEqual(path.posix.toNamespacedPath(1), 1); +assert.strictEqual(path.posix.toNamespacedPath(), undefined); +assert.strictEqual(path.posix.toNamespacedPath(emptyObj), emptyObj); +if (common.isWindows) { + // These tests cause resolve() to insert the cwd, so we cannot test them from + // non-Windows platforms (easily) + assert.strictEqual(path.toNamespacedPath(''), ''); + assert.strictEqual(path.win32.toNamespacedPath('foo\\bar').toLowerCase(), + `\\\\?\\${process.cwd().toLowerCase()}\\foo\\bar`); + assert.strictEqual(path.win32.toNamespacedPath('foo/bar').toLowerCase(), + `\\\\?\\${process.cwd().toLowerCase()}\\foo\\bar`); + const currentDeviceLetter = path.parse(process.cwd()).root.substring(0, 2); + assert.strictEqual( + path.win32.toNamespacedPath(currentDeviceLetter).toLowerCase(), + `\\\\?\\${process.cwd().toLowerCase()}`); + assert.strictEqual(path.win32.toNamespacedPath('C').toLowerCase(), + `\\\\?\\${process.cwd().toLowerCase()}\\c`); +} +assert.strictEqual(path.win32.toNamespacedPath('C:\\foo'), '\\\\?\\C:\\foo'); +assert.strictEqual(path.win32.toNamespacedPath('C:/foo'), '\\\\?\\C:\\foo'); +assert.strictEqual(path.win32.toNamespacedPath('\\\\foo\\bar'), + '\\\\?\\UNC\\foo\\bar\\'); +assert.strictEqual(path.win32.toNamespacedPath('//foo//bar'), + '\\\\?\\UNC\\foo\\bar\\'); +assert.strictEqual(path.win32.toNamespacedPath('\\\\?\\foo'), '\\\\?\\foo'); +assert.strictEqual(path.win32.toNamespacedPath(null), null); +assert.strictEqual(path.win32.toNamespacedPath(true), true); +assert.strictEqual(path.win32.toNamespacedPath(1), 1); +assert.strictEqual(path.win32.toNamespacedPath(), undefined); +assert.strictEqual(path.win32.toNamespacedPath(emptyObj), emptyObj); diff --git a/tests/node_compat/test/parallel/test-path-normalize.js b/tests/node_compat/test/parallel/test-path-normalize.js new file mode 100644 index 000000000..543be42e6 --- /dev/null +++ b/tests/node_compat/test/parallel/test-path-normalize.js @@ -0,0 +1,79 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const assert = require('assert'); +const path = require('path'); + +assert.strictEqual(path.win32.normalize('./fixtures///b/../b/c.js'), + 'fixtures\\b\\c.js'); +assert.strictEqual(path.win32.normalize('/foo/../../../bar'), '\\bar'); +assert.strictEqual(path.win32.normalize('a//b//../b'), 'a\\b'); +assert.strictEqual(path.win32.normalize('a//b//./c'), 'a\\b\\c'); +assert.strictEqual(path.win32.normalize('a//b//.'), 'a\\b'); +assert.strictEqual(path.win32.normalize('//server/share/dir/file.ext'), + '\\\\server\\share\\dir\\file.ext'); +assert.strictEqual(path.win32.normalize('/a/b/c/../../../x/y/z'), '\\x\\y\\z'); +assert.strictEqual(path.win32.normalize('C:'), 'C:.'); +assert.strictEqual(path.win32.normalize('C:..\\abc'), 'C:..\\abc'); +assert.strictEqual(path.win32.normalize('C:..\\..\\abc\\..\\def'), + 'C:..\\..\\def'); +assert.strictEqual(path.win32.normalize('C:\\.'), 'C:\\'); +assert.strictEqual(path.win32.normalize('file:stream'), 'file:stream'); +assert.strictEqual(path.win32.normalize('bar\\foo..\\..\\'), 'bar\\'); +assert.strictEqual(path.win32.normalize('bar\\foo..\\..'), 'bar'); +assert.strictEqual(path.win32.normalize('bar\\foo..\\..\\baz'), 'bar\\baz'); +assert.strictEqual(path.win32.normalize('bar\\foo..\\'), 'bar\\foo..\\'); +assert.strictEqual(path.win32.normalize('bar\\foo..'), 'bar\\foo..'); +assert.strictEqual(path.win32.normalize('..\\foo..\\..\\..\\bar'), + '..\\..\\bar'); +assert.strictEqual(path.win32.normalize('..\\...\\..\\.\\...\\..\\..\\bar'), + '..\\..\\bar'); +assert.strictEqual(path.win32.normalize('../../../foo/../../../bar'), + '..\\..\\..\\..\\..\\bar'); +assert.strictEqual(path.win32.normalize('../../../foo/../../../bar/../../'), + '..\\..\\..\\..\\..\\..\\'); +assert.strictEqual( + path.win32.normalize('../foobar/barfoo/foo/../../../bar/../../'), + '..\\..\\' +); +assert.strictEqual( + path.win32.normalize('../.../../foobar/../../../bar/../../baz'), + '..\\..\\..\\..\\baz' +); +assert.strictEqual(path.win32.normalize('foo/bar\\baz'), 'foo\\bar\\baz'); + +assert.strictEqual(path.posix.normalize('./fixtures///b/../b/c.js'), + 'fixtures/b/c.js'); +assert.strictEqual(path.posix.normalize('/foo/../../../bar'), '/bar'); +assert.strictEqual(path.posix.normalize('a//b//../b'), 'a/b'); +assert.strictEqual(path.posix.normalize('a//b//./c'), 'a/b/c'); +assert.strictEqual(path.posix.normalize('a//b//.'), 'a/b'); +assert.strictEqual(path.posix.normalize('/a/b/c/../../../x/y/z'), '/x/y/z'); +assert.strictEqual(path.posix.normalize('///..//./foo/.//bar'), '/foo/bar'); +assert.strictEqual(path.posix.normalize('bar/foo../../'), 'bar/'); +assert.strictEqual(path.posix.normalize('bar/foo../..'), 'bar'); +assert.strictEqual(path.posix.normalize('bar/foo../../baz'), 'bar/baz'); +assert.strictEqual(path.posix.normalize('bar/foo../'), 'bar/foo../'); +assert.strictEqual(path.posix.normalize('bar/foo..'), 'bar/foo..'); +assert.strictEqual(path.posix.normalize('../foo../../../bar'), '../../bar'); +assert.strictEqual(path.posix.normalize('../.../.././.../../../bar'), + '../../bar'); +assert.strictEqual(path.posix.normalize('../../../foo/../../../bar'), + '../../../../../bar'); +assert.strictEqual(path.posix.normalize('../../../foo/../../../bar/../../'), + '../../../../../../'); +assert.strictEqual( + path.posix.normalize('../foobar/barfoo/foo/../../../bar/../../'), + '../../' +); +assert.strictEqual( + path.posix.normalize('../.../../foobar/../../../bar/../../baz'), + '../../../../baz' +); +assert.strictEqual(path.posix.normalize('foo/bar\\baz'), 'foo/bar\\baz'); diff --git a/tests/node_compat/test/parallel/test-path-parse-format.js b/tests/node_compat/test/parallel/test-path-parse-format.js new file mode 100644 index 000000000..657503d3c --- /dev/null +++ b/tests/node_compat/test/parallel/test-path-parse-format.js @@ -0,0 +1,233 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const path = require('path'); + +const winPaths = [ + // [path, root] + ['C:\\path\\dir\\index.html', 'C:\\'], + ['C:\\another_path\\DIR\\1\\2\\33\\\\index', 'C:\\'], + ['another_path\\DIR with spaces\\1\\2\\33\\index', ''], + ['\\', '\\'], + ['\\foo\\C:', '\\'], + ['file', ''], + ['file:stream', ''], + ['.\\file', ''], + ['C:', 'C:'], + ['C:.', 'C:'], + ['C:..', 'C:'], + ['C:abc', 'C:'], + ['C:\\', 'C:\\'], + ['C:\\abc', 'C:\\' ], + ['', ''], + + // unc + ['\\\\server\\share\\file_path', '\\\\server\\share\\'], + ['\\\\server two\\shared folder\\file path.zip', + '\\\\server two\\shared folder\\'], + ['\\\\teela\\admin$\\system32', '\\\\teela\\admin$\\'], + ['\\\\?\\UNC\\server\\share', '\\\\?\\UNC\\'], +]; + +const winSpecialCaseParseTests = [ + ['t', { base: 't', name: 't', root: '', dir: '', ext: '' }], + ['/foo/bar', { root: '/', dir: '/foo', base: 'bar', ext: '', name: 'bar' }], +]; + +const winSpecialCaseFormatTests = [ + [{ dir: 'some\\dir' }, 'some\\dir\\'], + [{ base: 'index.html' }, 'index.html'], + [{ root: 'C:\\' }, 'C:\\'], + [{ name: 'index', ext: '.html' }, 'index.html'], + [{ dir: 'some\\dir', name: 'index', ext: '.html' }, 'some\\dir\\index.html'], + [{ root: 'C:\\', name: 'index', ext: '.html' }, 'C:\\index.html'], + [{}, ''], +]; + +const unixPaths = [ + // [path, root] + ['/home/user/dir/file.txt', '/'], + ['/home/user/a dir/another File.zip', '/'], + ['/home/user/a dir//another&File.', '/'], + ['/home/user/a$$$dir//another File.zip', '/'], + ['user/dir/another File.zip', ''], + ['file', ''], + ['.\\file', ''], + ['./file', ''], + ['C:\\foo', ''], + ['/', '/'], + ['', ''], + ['.', ''], + ['..', ''], + ['/foo', '/'], + ['/foo.', '/'], + ['/foo.bar', '/'], + ['/.', '/'], + ['/.foo', '/'], + ['/.foo.bar', '/'], + ['/foo/bar.baz', '/'], +]; + +const unixSpecialCaseFormatTests = [ + [{ dir: 'some/dir' }, 'some/dir/'], + [{ base: 'index.html' }, 'index.html'], + [{ root: '/' }, '/'], + [{ name: 'index', ext: '.html' }, 'index.html'], + [{ dir: 'some/dir', name: 'index', ext: '.html' }, 'some/dir/index.html'], + [{ root: '/', name: 'index', ext: '.html' }, '/index.html'], + [{}, ''], +]; + +const errors = [ + { method: 'parse', input: [null] }, + { method: 'parse', input: [{}] }, + { method: 'parse', input: [true] }, + { method: 'parse', input: [1] }, + { method: 'parse', input: [] }, + { method: 'format', input: [null] }, + { method: 'format', input: [''] }, + { method: 'format', input: [true] }, + { method: 'format', input: [1] }, +]; + +checkParseFormat(path.win32, winPaths); +checkParseFormat(path.posix, unixPaths); +checkSpecialCaseParseFormat(path.win32, winSpecialCaseParseTests); +checkErrors(path.win32); +checkErrors(path.posix); +checkFormat(path.win32, winSpecialCaseFormatTests); +checkFormat(path.posix, unixSpecialCaseFormatTests); + +// Test removal of trailing path separators +const trailingTests = [ + [ path.win32.parse, + [['.\\', { root: '', dir: '', base: '.', ext: '', name: '.' }], + ['\\\\', { root: '\\', dir: '\\', base: '', ext: '', name: '' }], + ['\\\\', { root: '\\', dir: '\\', base: '', ext: '', name: '' }], + ['c:\\foo\\\\\\', + { root: 'c:\\', dir: 'c:\\', base: 'foo', ext: '', name: 'foo' }], + ['D:\\foo\\\\\\bar.baz', + { root: 'D:\\', + dir: 'D:\\foo\\\\', + base: 'bar.baz', + ext: '.baz', + name: 'bar' }, + ], + ], + ], + [ path.posix.parse, + [['./', { root: '', dir: '', base: '.', ext: '', name: '.' }], + ['//', { root: '/', dir: '/', base: '', ext: '', name: '' }], + ['///', { root: '/', dir: '/', base: '', ext: '', name: '' }], + ['/foo///', { root: '/', dir: '/', base: 'foo', ext: '', name: 'foo' }], + ['/foo///bar.baz', + { root: '/', dir: '/foo//', base: 'bar.baz', ext: '.baz', name: 'bar' }, + ], + ], + ], +]; +const failures = []; +trailingTests.forEach((test) => { + const parse = test[0]; + const os = parse === path.win32.parse ? 'win32' : 'posix'; + test[1].forEach((test) => { + const actual = parse(test[0]); + const expected = test[1]; + const message = `path.${os}.parse(${JSON.stringify(test[0])})\n expect=${ + JSON.stringify(expected)}\n actual=${JSON.stringify(actual)}`; + const actualKeys = Object.keys(actual); + const expectedKeys = Object.keys(expected); + let failed = (actualKeys.length !== expectedKeys.length); + if (!failed) { + for (let i = 0; i < actualKeys.length; ++i) { + const key = actualKeys[i]; + if (!expectedKeys.includes(key) || actual[key] !== expected[key]) { + failed = true; + break; + } + } + } + if (failed) + failures.push(`\n${message}`); + }); +}); +assert.strictEqual(failures.length, 0, failures.join('')); + +function checkErrors(path) { + errors.forEach(({ method, input }) => { + assert.throws(() => { + path[method].apply(path, input); + }, { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + }); + }); +} + +function checkParseFormat(path, paths) { + paths.forEach(([element, root]) => { + const output = path.parse(element); + assert.strictEqual(typeof output.root, 'string'); + assert.strictEqual(typeof output.dir, 'string'); + assert.strictEqual(typeof output.base, 'string'); + assert.strictEqual(typeof output.ext, 'string'); + assert.strictEqual(typeof output.name, 'string'); + assert.strictEqual(path.format(output), element); + assert.strictEqual(output.root, root); + assert(output.dir.startsWith(output.root)); + assert.strictEqual(output.dir, output.dir ? path.dirname(element) : ''); + assert.strictEqual(output.base, path.basename(element)); + assert.strictEqual(output.ext, path.extname(element)); + }); +} + +function checkSpecialCaseParseFormat(path, testCases) { + testCases.forEach(([element, expect]) => { + assert.deepStrictEqual(path.parse(element), expect); + }); +} + +function checkFormat(path, testCases) { + testCases.forEach(([element, expect]) => { + assert.strictEqual(path.format(element), expect); + }); + + [null, undefined, 1, true, false, 'string'].forEach((pathObject) => { + assert.throws(() => { + path.format(pathObject); + }, { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "pathObject" argument must be of type object.' + + common.invalidArgTypeHelper(pathObject) + }); + }); +} diff --git a/tests/node_compat/test/parallel/test-path-posix-exists.js b/tests/node_compat/test/parallel/test-path-posix-exists.js new file mode 100644 index 000000000..97f2c4ae6 --- /dev/null +++ b/tests/node_compat/test/parallel/test-path-posix-exists.js @@ -0,0 +1,13 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); + +assert.strictEqual(require('path/posix'), require('path').posix); diff --git a/tests/node_compat/test/parallel/test-path-relative.js b/tests/node_compat/test/parallel/test-path-relative.js new file mode 100644 index 000000000..7b89cc2cd --- /dev/null +++ b/tests/node_compat/test/parallel/test-path-relative.js @@ -0,0 +1,76 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const assert = require('assert'); +const path = require('path'); + +const failures = []; + +const relativeTests = [ + [ path.win32.relative, + // Arguments result + [['c:/blah\\blah', 'd:/games', 'd:\\games'], + ['c:/aaaa/bbbb', 'c:/aaaa', '..'], + ['c:/aaaa/bbbb', 'c:/cccc', '..\\..\\cccc'], + ['c:/aaaa/bbbb', 'c:/aaaa/bbbb', ''], + ['c:/aaaa/bbbb', 'c:/aaaa/cccc', '..\\cccc'], + ['c:/aaaa/', 'c:/aaaa/cccc', 'cccc'], + ['c:/', 'c:\\aaaa\\bbbb', 'aaaa\\bbbb'], + ['c:/aaaa/bbbb', 'd:\\', 'd:\\'], + ['c:/AaAa/bbbb', 'c:/aaaa/bbbb', ''], + ['c:/aaaaa/', 'c:/aaaa/cccc', '..\\aaaa\\cccc'], + ['C:\\foo\\bar\\baz\\quux', 'C:\\', '..\\..\\..\\..'], + ['C:\\foo\\test', 'C:\\foo\\test\\bar\\package.json', 'bar\\package.json'], + ['C:\\foo\\bar\\baz-quux', 'C:\\foo\\bar\\baz', '..\\baz'], + ['C:\\foo\\bar\\baz', 'C:\\foo\\bar\\baz-quux', '..\\baz-quux'], + ['\\\\foo\\bar', '\\\\foo\\bar\\baz', 'baz'], + ['\\\\foo\\bar\\baz', '\\\\foo\\bar', '..'], + ['\\\\foo\\bar\\baz-quux', '\\\\foo\\bar\\baz', '..\\baz'], + ['\\\\foo\\bar\\baz', '\\\\foo\\bar\\baz-quux', '..\\baz-quux'], + ['C:\\baz-quux', 'C:\\baz', '..\\baz'], + ['C:\\baz', 'C:\\baz-quux', '..\\baz-quux'], + ['\\\\foo\\baz-quux', '\\\\foo\\baz', '..\\baz'], + ['\\\\foo\\baz', '\\\\foo\\baz-quux', '..\\baz-quux'], + ['C:\\baz', '\\\\foo\\bar\\baz', '\\\\foo\\bar\\baz'], + ['\\\\foo\\bar\\baz', 'C:\\baz', 'C:\\baz'], + ], + ], + [ path.posix.relative, + // Arguments result + [['/var/lib', '/var', '..'], + ['/var/lib', '/bin', '../../bin'], + ['/var/lib', '/var/lib', ''], + ['/var/lib', '/var/apache', '../apache'], + ['/var/', '/var/lib', 'lib'], + ['/', '/var/lib', 'var/lib'], + ['/foo/test', '/foo/test/bar/package.json', 'bar/package.json'], + ['/Users/a/web/b/test/mails', '/Users/a/web/b', '../..'], + ['/foo/bar/baz-quux', '/foo/bar/baz', '../baz'], + ['/foo/bar/baz', '/foo/bar/baz-quux', '../baz-quux'], + ['/baz-quux', '/baz', '../baz'], + ['/baz', '/baz-quux', '../baz-quux'], + ['/page1/page2/foo', '/', '../../..'], + ], + ], +]; +relativeTests.forEach((test) => { + const relative = test[0]; + test[1].forEach((test) => { + const actual = relative(test[0], test[1]); + const expected = test[2]; + if (actual !== expected) { + const os = relative === path.win32.relative ? 'win32' : 'posix'; + const message = `path.${os}.relative(${ + test.slice(0, 2).map(JSON.stringify).join(',')})\n expect=${ + JSON.stringify(expected)}\n actual=${JSON.stringify(actual)}`; + failures.push(`\n${message}`); + } + }); +}); +assert.strictEqual(failures.length, 0, failures.join('')); diff --git a/tests/node_compat/test/parallel/test-path-resolve.js b/tests/node_compat/test/parallel/test-path-resolve.js new file mode 100644 index 000000000..be010ed83 --- /dev/null +++ b/tests/node_compat/test/parallel/test-path-resolve.js @@ -0,0 +1,96 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +'use strict'; +const common = require('../common'); +const fixtures = require('../common/fixtures'); +const assert = require('assert'); +const child = require('child_process'); +const path = require('path'); + +const failures = []; +const slashRE = /\//g; +const backslashRE = /\\/g; + +const posixyCwd = common.isWindows ? + (() => { + const _ = process.cwd() + .replaceAll(path.sep, path.posix.sep); + return _.slice(_.indexOf(path.posix.sep)); + })() : + process.cwd(); + +const resolveTests = [ + [ path.win32.resolve, + // Arguments result + [[['c:/blah\\blah', 'd:/games', 'c:../a'], 'c:\\blah\\a'], + [['c:/ignore', 'd:\\a/b\\c/d', '\\e.exe'], 'd:\\e.exe'], + [['c:/ignore', 'c:/some/file'], 'c:\\some\\file'], + [['d:/ignore', 'd:some/dir//'], 'd:\\ignore\\some\\dir'], + [['.'], process.cwd()], + [['//server/share', '..', 'relative\\'], '\\\\server\\share\\relative'], + [['c:/', '//'], 'c:\\'], + [['c:/', '//dir'], 'c:\\dir'], + [['c:/', '//server/share'], '\\\\server\\share\\'], + [['c:/', '//server//share'], '\\\\server\\share\\'], + [['c:/', '///some//dir'], 'c:\\some\\dir'], + [['C:\\foo\\tmp.3\\', '..\\tmp.3\\cycles\\root.js'], + 'C:\\foo\\tmp.3\\cycles\\root.js'], + ], + ], + [ path.posix.resolve, + // Arguments result + [[['/var/lib', '../', 'file/'], '/var/file'], + [['/var/lib', '/../', 'file/'], '/file'], + // TODO(wafuwafu13): Enable this + // [['a/b/c/', '../../..'], posixyCwd], + // [['.'], posixyCwd], + [['/some/dir', '.', '/absolute/'], '/absolute'], + [['/foo/tmp.3/', '../tmp.3/cycles/root.js'], '/foo/tmp.3/cycles/root.js'], + ], + ], +]; +resolveTests.forEach(([resolve, tests]) => { + tests.forEach(([test, expected]) => { + const actual = resolve.apply(null, test); + let actualAlt; + const os = resolve === path.win32.resolve ? 'win32' : 'posix'; + if (resolve === path.win32.resolve && !common.isWindows) + actualAlt = actual.replace(backslashRE, '/'); + else if (resolve !== path.win32.resolve && common.isWindows) + actualAlt = actual.replace(slashRE, '\\'); + + const message = + `path.${os}.resolve(${test.map(JSON.stringify).join(',')})\n expect=${ + JSON.stringify(expected)}\n actual=${JSON.stringify(actual)}`; + if (actual !== expected && actualAlt !== expected) + failures.push(message); + }); +}); +assert.strictEqual(failures.length, 0, failures.join('\n')); + +if (common.isWindows) { + // Test resolving the current Windows drive letter from a spawned process. + // See https://github.com/nodejs/node/issues/7215 + const currentDriveLetter = path.parse(process.cwd()).root.substring(0, 2); + const resolveFixture = fixtures.path('path-resolve.js'); + // TODO(wafuwafu13): Enable this + // const spawnResult = child.spawnSync( + // process.argv[0], [resolveFixture, currentDriveLetter]); + // const resolvedPath = spawnResult.stdout.toString().trim(); + // assert.strictEqual(resolvedPath.toLowerCase(), process.cwd().toLowerCase()); +} + +if (!common.isWindows) { + // Test handling relative paths to be safe when process.cwd() fails. + process.cwd = () => ''; + assert.strictEqual(process.cwd(), ''); + const resolved = path.resolve(); + const expected = '.'; + // TODO(wafuwafu13): Enable this + // assert.strictEqual(resolved, expected); +} diff --git a/tests/node_compat/test/parallel/test-path-win32-exists.js b/tests/node_compat/test/parallel/test-path-win32-exists.js new file mode 100644 index 000000000..8bb1850dc --- /dev/null +++ b/tests/node_compat/test/parallel/test-path-win32-exists.js @@ -0,0 +1,13 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); + +assert.strictEqual(require('path/win32'), require('path').win32); diff --git a/tests/node_compat/test/parallel/test-path-zero-length-strings.js b/tests/node_compat/test/parallel/test-path-zero-length-strings.js new file mode 100644 index 000000000..5fa1eafbf --- /dev/null +++ b/tests/node_compat/test/parallel/test-path-zero-length-strings.js @@ -0,0 +1,46 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +// These testcases are specific to one uncommon behavior in path module. Few +// of the functions in path module, treat '' strings as current working +// directory. This test makes sure that the behavior is intact between commits. +// See: https://github.com/nodejs/node/pull/2106 + +require('../common'); +const assert = require('assert'); +const path = require('path'); +const pwd = process.cwd(); + +// Join will internally ignore all the zero-length strings and it will return +// '.' if the joined string is a zero-length string. +assert.strictEqual(path.posix.join(''), '.'); +assert.strictEqual(path.posix.join('', ''), '.'); +assert.strictEqual(path.win32.join(''), '.'); +assert.strictEqual(path.win32.join('', ''), '.'); +assert.strictEqual(path.join(pwd), pwd); +assert.strictEqual(path.join(pwd, ''), pwd); + +// Normalize will return '.' if the input is a zero-length string +assert.strictEqual(path.posix.normalize(''), '.'); +assert.strictEqual(path.win32.normalize(''), '.'); +assert.strictEqual(path.normalize(pwd), pwd); + +// Since '' is not a valid path in any of the common environments, return false +assert.strictEqual(path.posix.isAbsolute(''), false); +assert.strictEqual(path.win32.isAbsolute(''), false); + +// Resolve, internally ignores all the zero-length strings and returns the +// current working directory +assert.strictEqual(path.resolve(''), pwd); +assert.strictEqual(path.resolve('', ''), pwd); + +// Relative, internally calls resolve. So, '' is actually the current directory +assert.strictEqual(path.relative('', pwd), ''); +assert.strictEqual(path.relative(pwd, ''), ''); +assert.strictEqual(path.relative(pwd, pwd), ''); diff --git a/tests/node_compat/test/parallel/test-path.js b/tests/node_compat/test/parallel/test-path.js new file mode 100644 index 000000000..b68f0c2d4 --- /dev/null +++ b/tests/node_compat/test/parallel/test-path.js @@ -0,0 +1,80 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const path = require('path'); + +// Test thrown TypeErrors +const typeErrorTests = [true, false, 7, null, {}, undefined, [], NaN]; + +function fail(fn) { + const args = Array.from(arguments).slice(1); + + assert.throws(() => { + fn.apply(null, args); + }, { code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' }); +} + +typeErrorTests.forEach((test) => { + [path.posix, path.win32].forEach((namespace) => { + fail(namespace.join, test); + fail(namespace.resolve, test); + fail(namespace.normalize, test); + fail(namespace.isAbsolute, test); + fail(namespace.relative, test, 'foo'); + fail(namespace.relative, 'foo', test); + fail(namespace.parse, test); + fail(namespace.dirname, test); + fail(namespace.basename, test); + fail(namespace.extname, test); + + // Undefined is a valid value as the second argument to basename + if (test !== undefined) { + fail(namespace.basename, 'foo', test); + } + }); +}); + +// path.sep tests +// windows +assert.strictEqual(path.win32.sep, '\\'); +// posix +assert.strictEqual(path.posix.sep, '/'); + +// path.delimiter tests +// windows +assert.strictEqual(path.win32.delimiter, ';'); +// posix +assert.strictEqual(path.posix.delimiter, ':'); + +if (common.isWindows) + assert.strictEqual(path, path.win32); +else + assert.strictEqual(path, path.posix); diff --git a/tests/node_compat/test/parallel/test-process-beforeexit.js b/tests/node_compat/test/parallel/test-process-beforeexit.js new file mode 100644 index 000000000..7ac789c69 --- /dev/null +++ b/tests/node_compat/test/parallel/test-process-beforeexit.js @@ -0,0 +1,88 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const net = require('net'); + +process.once('beforeExit', common.mustCall(tryImmediate)); + +function tryImmediate() { + setImmediate(common.mustCall(() => { + process.once('beforeExit', common.mustCall(tryTimer)); + })); +} + +function tryTimer() { + setTimeout(common.mustCall(() => { + process.once('beforeExit', common.mustCall(tryListen)); + }), 1); +} + +function tryListen() { + net.createServer() + .listen(0) + .on('listening', common.mustCall(function() { + this.close(); + process.once('beforeExit', common.mustCall(tryRepeatedTimer)); + })); +} + +// Test that a function invoked from the beforeExit handler can use a timer +// to keep the event loop open, which can use another timer to keep the event +// loop open, etc. +// +// After N times, call function `tryNextTick` to test behaviors of the +// `process.nextTick`. +function tryRepeatedTimer() { + const N = 5; + let n = 0; + const repeatedTimer = common.mustCall(function() { + if (++n < N) + setTimeout(repeatedTimer, 1); + else // n == N + process.once('beforeExit', common.mustCall(tryNextTickSetImmediate)); + }, N); + setTimeout(repeatedTimer, 1); +} + +// Test if the callback of `process.nextTick` can be invoked. +function tryNextTickSetImmediate() { + process.nextTick(common.mustCall(function() { + setImmediate(common.mustCall(() => { + process.once('beforeExit', common.mustCall(tryNextTick)); + })); + })); +} + +// Test that `process.nextTick` won't keep the event loop running by itself. +function tryNextTick() { + process.nextTick(common.mustCall(function() { + process.once('beforeExit', common.mustNotCall()); + })); +} diff --git a/tests/node_compat/test/parallel/test-process-binding-internalbinding-allowlist.js b/tests/node_compat/test/parallel/test-process-binding-internalbinding-allowlist.js new file mode 100644 index 000000000..28a9a31e9 --- /dev/null +++ b/tests/node_compat/test/parallel/test-process-binding-internalbinding-allowlist.js @@ -0,0 +1,48 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Flags: --no-warnings +'use strict'; + +const common = require('../common'); +const assert = require('assert'); + +// Assert that allowed internalBinding modules are accessible via +// process.binding(). +assert(process.binding('async_wrap')); +assert(process.binding('buffer')); +assert(process.binding('cares_wrap')); +assert(process.binding('constants')); +assert(process.binding('contextify')); +if (common.hasCrypto) { // eslint-disable-line node-core/crypto-check + assert(process.binding('crypto')); +} +assert(process.binding('fs')); +assert(process.binding('fs_event_wrap')); +assert(process.binding('http_parser')); +if (common.hasIntl) { + assert(process.binding('icu')); +} +assert(process.binding('inspector')); +assert(process.binding('js_stream')); +assert(process.binding('natives')); +assert(process.binding('os')); +assert(process.binding('pipe_wrap')); +assert(process.binding('signal_wrap')); +assert(process.binding('spawn_sync')); +assert(process.binding('stream_wrap')); +assert(process.binding('tcp_wrap')); +if (common.hasCrypto) { // eslint-disable-line node-core/crypto-check + assert(process.binding('tls_wrap')); +} +assert(process.binding('tty_wrap')); +assert(process.binding('udp_wrap')); +assert(process.binding('url')); +assert(process.binding('util')); +assert(process.binding('uv')); +assert(process.binding('v8')); +assert(process.binding('zlib')); diff --git a/tests/node_compat/test/parallel/test-process-env-allowed-flags.js b/tests/node_compat/test/parallel/test-process-env-allowed-flags.js new file mode 100644 index 000000000..1b2c96e68 --- /dev/null +++ b/tests/node_compat/test/parallel/test-process-env-allowed-flags.js @@ -0,0 +1,109 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); + +// Assert legit flags are allowed, and bogus flags are disallowed +{ + const goodFlags = [ + '--perf_basic_prof', + '--perf-basic-prof', + 'perf-basic-prof', + '--perf_basic-prof', + 'perf_basic-prof', + 'perf_basic_prof', + '-r', + 'r', + '--stack-trace-limit=100', + '--stack-trace-limit=-=xX_nodejs_Xx=-', + ].concat(process.features.inspector ? [ + '--inspect-brk', + 'inspect-brk', + '--inspect_brk', + ] : []); + + const badFlags = [ + 'INSPECT-BRK', + '--INSPECT-BRK', + '--r', + '-R', + '---inspect-brk', + '--cheeseburgers', + ]; + + goodFlags.forEach((flag) => { + assert.strictEqual( + process.allowedNodeEnvironmentFlags.has(flag), + true, + `flag should be in set: ${flag}` + ); + }); + + badFlags.forEach((flag) => { + assert.strictEqual( + process.allowedNodeEnvironmentFlags.has(flag), + false, + `flag should not be in set: ${flag}` + ); + }); +} + +// Assert all "canonical" flags begin with dash(es) +{ + process.allowedNodeEnvironmentFlags.forEach((flag) => { + assert.match(flag, /^--?[a-zA-Z0-9._-]+$/); + }); +} + +// Assert immutability of process.allowedNodeEnvironmentFlags +{ + assert.strictEqual(Object.isFrozen(process.allowedNodeEnvironmentFlags), + true); + + process.allowedNodeEnvironmentFlags.add('foo'); + assert.strictEqual(process.allowedNodeEnvironmentFlags.has('foo'), false); + Set.prototype.add.call(process.allowedNodeEnvironmentFlags, 'foo'); + assert.strictEqual(process.allowedNodeEnvironmentFlags.has('foo'), false); + + const thisArg = {}; + process.allowedNodeEnvironmentFlags.forEach( + common.mustCallAtLeast(function(flag, _, set) { + assert.notStrictEqual(flag, 'foo'); + assert.strictEqual(this, thisArg); + assert.strictEqual(set, process.allowedNodeEnvironmentFlags); + }), + thisArg + ); + + for (const flag of process.allowedNodeEnvironmentFlags.keys()) { + assert.notStrictEqual(flag, 'foo'); + } + for (const flag of process.allowedNodeEnvironmentFlags.values()) { + assert.notStrictEqual(flag, 'foo'); + } + for (const flag of process.allowedNodeEnvironmentFlags) { + assert.notStrictEqual(flag, 'foo'); + } + for (const [flag] of process.allowedNodeEnvironmentFlags.entries()) { + assert.notStrictEqual(flag, 'foo'); + } + + const size = process.allowedNodeEnvironmentFlags.size; + + process.allowedNodeEnvironmentFlags.clear(); + assert.strictEqual(process.allowedNodeEnvironmentFlags.size, size); + Set.prototype.clear.call(process.allowedNodeEnvironmentFlags); + assert.strictEqual(process.allowedNodeEnvironmentFlags.size, size); + + process.allowedNodeEnvironmentFlags.delete('-r'); + assert.strictEqual(process.allowedNodeEnvironmentFlags.size, size); + Set.prototype.delete.call(process.allowedNodeEnvironmentFlags, '-r'); + assert.strictEqual(process.allowedNodeEnvironmentFlags.size, size); +} diff --git a/tests/node_compat/test/parallel/test-process-exit-from-before-exit.js b/tests/node_compat/test/parallel/test-process-exit-from-before-exit.js new file mode 100644 index 000000000..a1472e538 --- /dev/null +++ b/tests/node_compat/test/parallel/test-process-exit-from-before-exit.js @@ -0,0 +1,37 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +process.on('beforeExit', common.mustCall(function() { + setTimeout(common.mustNotCall(), 5); + process.exit(0); // Should execute immediately even if we schedule new work. + assert.fail(); +})); diff --git a/tests/node_compat/test/parallel/test-process-exit-handler.js b/tests/node_compat/test/parallel/test-process-exit-handler.js new file mode 100644 index 000000000..7069c73e9 --- /dev/null +++ b/tests/node_compat/test/parallel/test-process-exit-handler.js @@ -0,0 +1,21 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); + +if (!common.isMainThread) + common.skip('execArgv does not affect Workers'); + +// This test ensures that no asynchronous operations are performed in the 'exit' +// handler. +// https://github.com/nodejs/node/issues/12322 + +process.on('exit', () => { + setTimeout(() => process.abort(), 0); // Should not run. + for (const start = Date.now(); Date.now() - start < 10;); +}); diff --git a/tests/node_compat/test/parallel/test-process-exit-recursive.js b/tests/node_compat/test/parallel/test-process-exit-recursive.js new file mode 100644 index 000000000..054b23271 --- /dev/null +++ b/tests/node_compat/test/parallel/test-process-exit-recursive.js @@ -0,0 +1,44 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); + +// Recursively calling .exit() should not overflow the call stack +let nexits = 0; + +process.on('exit', function(code) { + assert.strictEqual(nexits++, 0); + assert.strictEqual(code, 1); + + // Now override the exit code of 1 with 0 so that the test passes + process.exit(0); +}); + +process.exit(1); diff --git a/tests/node_compat/test/parallel/test-process-exit.js b/tests/node_compat/test/parallel/test-process-exit.js new file mode 100644 index 000000000..50a3bd3b1 --- /dev/null +++ b/tests/node_compat/test/parallel/test-process-exit.js @@ -0,0 +1,42 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); + +// Calling .exit() from within "exit" should not overflow the call stack +let nexits = 0; + +process.on('exit', function(code) { + assert.strictEqual(nexits++, 0); + assert.strictEqual(code, 0); + process.exit(); +}); + +// "exit" should be emitted unprovoked diff --git a/tests/node_compat/test/parallel/test-process-kill-pid.js b/tests/node_compat/test/parallel/test-process-kill-pid.js new file mode 100644 index 000000000..f6e612f2b --- /dev/null +++ b/tests/node_compat/test/parallel/test-process-kill-pid.js @@ -0,0 +1,116 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +// Test variants of pid +// +// null: TypeError +// undefined: TypeError +// +// 'SIGTERM': TypeError +// +// String(process.pid): TypeError +// +// Nan, Infinity, -Infinity: TypeError +// +// 0, String(0): our group process +// +// process.pid, String(process.pid): ourself + +['SIGTERM', null, undefined, NaN, Infinity, -Infinity].forEach((val) => { + assert.throws(() => process.kill(val), { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "pid" argument must be of type number.' + + common.invalidArgTypeHelper(val) + }); +}); + +// Test that kill throws an error for unknown signal names +assert.throws(() => process.kill(0, 'test'), { + code: 'ERR_UNKNOWN_SIGNAL', + name: 'TypeError', + message: 'Unknown signal: test' +}); + +// Test that kill throws an error for invalid signal numbers +assert.throws(() => process.kill(0, 987), { + code: 'EINVAL', + name: 'Error', + message: 'kill EINVAL' +}); + +// Test kill argument processing in valid cases. +// +// Monkey patch _kill so that we don't actually send any signals, particularly +// that we don't kill our process group, or try to actually send ANY signals on +// windows, which doesn't support them. +function kill(tryPid, trySig, expectPid, expectSig) { + let getPid; + let getSig; + const origKill = process._kill; + process._kill = function(pid, sig) { + getPid = pid; + getSig = sig; + + // un-monkey patch process._kill + process._kill = origKill; + }; + + process.kill(tryPid, trySig); + + assert.strictEqual(getPid.toString(), expectPid.toString()); + assert.strictEqual(getSig, expectSig); +} + +// Note that SIGHUP and SIGTERM map to 1 and 15 respectively, even on Windows +// (for Windows, libuv maps 1 and 15 to the correct behavior). + +kill(0, 'SIGHUP', 0, 1); +kill(0, undefined, 0, 15); +kill('0', 'SIGHUP', 0, 1); +kill('0', undefined, 0, 15); + +// Confirm that numeric signal arguments are supported + +kill(0, 1, 0, 1); +kill(0, 15, 0, 15); + +// Negative numbers are meaningful on unix +kill(-1, 'SIGHUP', -1, 1); +kill(-1, undefined, -1, 15); +kill('-1', 'SIGHUP', -1, 1); +kill('-1', undefined, -1, 15); + +kill(process.pid, 'SIGHUP', process.pid, 1); +kill(process.pid, undefined, process.pid, 15); +kill(String(process.pid), 'SIGHUP', process.pid, 1); +kill(String(process.pid), undefined, process.pid, 15); diff --git a/tests/node_compat/test/parallel/test-process-uptime.js b/tests/node_compat/test/parallel/test-process-uptime.js new file mode 100644 index 000000000..74d2c13bd --- /dev/null +++ b/tests/node_compat/test/parallel/test-process-uptime.js @@ -0,0 +1,44 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); + +console.error(process.uptime()); +// Add some wiggle room for different platforms. +// Verify that the returned value is in seconds - +// 15 seconds should be a good estimate. +assert.ok(process.uptime() <= 15); + +const original = process.uptime(); + +setTimeout(function() { + const uptime = process.uptime(); + assert.ok(original < uptime); +}, 10); diff --git a/tests/node_compat/test/parallel/test-promise-unhandled-silent.js b/tests/node_compat/test/parallel/test-promise-unhandled-silent.js new file mode 100644 index 000000000..3b2dcde15 --- /dev/null +++ b/tests/node_compat/test/parallel/test-promise-unhandled-silent.js @@ -0,0 +1,28 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Flags: --unhandled-rejections=none +'use strict'; + +const common = require('../common'); + +// Verify that ignoring unhandled rejection works fine and that no warning is +// logged. + +new Promise(() => { + throw new Error('One'); +}); + +Promise.reject('test'); + +process.on('warning', common.mustNotCall('warning')); +process.on('uncaughtException', common.mustNotCall('uncaughtException')); +process.on('rejectionHandled', common.mustNotCall('rejectionHandled')); + +process.on('unhandledRejection', common.mustCall(2)); + +setTimeout(common.mustCall(), 2); diff --git a/tests/node_compat/test/parallel/test-promise-unhandled-throw-handler.js b/tests/node_compat/test/parallel/test-promise-unhandled-throw-handler.js new file mode 100644 index 000000000..a911f096a --- /dev/null +++ b/tests/node_compat/test/parallel/test-promise-unhandled-throw-handler.js @@ -0,0 +1,43 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Flags: --unhandled-rejections=throw +'use strict'; + +const common = require('../common'); +const Countdown = require('../common/countdown'); +const assert = require('assert'); + +// Verify that the unhandledRejection handler prevents triggering +// uncaught exceptions + +const err1 = new Error('One'); + +const errors = [err1, null]; + +const ref = new Promise(() => { + throw err1; +}); +// Explicitly reject `null`. +Promise.reject(null); + +process.on('warning', common.mustNotCall('warning')); +process.on('rejectionHandled', common.mustNotCall('rejectionHandled')); +process.on('exit', assert.strictEqual.bind(null, 0)); +process.on('uncaughtException', common.mustNotCall('uncaughtException')); + +const timer = setTimeout(() => console.log(ref), 1000); + +const counter = new Countdown(2, () => { + clearTimeout(timer); +}); + +process.on('unhandledRejection', common.mustCall((err) => { + counter.dec(); + const knownError = errors.shift(); + assert.deepStrictEqual(err, knownError); +}, 2)); diff --git a/tests/node_compat/test/parallel/test-querystring-escape.js b/tests/node_compat/test/parallel/test-querystring-escape.js new file mode 100644 index 000000000..f4f635af1 --- /dev/null +++ b/tests/node_compat/test/parallel/test-querystring-escape.js @@ -0,0 +1,48 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const assert = require('assert'); + +const qs = require('querystring'); + +assert.strictEqual(qs.escape(5), '5'); +assert.strictEqual(qs.escape('test'), 'test'); +assert.strictEqual(qs.escape({}), '%5Bobject%20Object%5D'); +assert.strictEqual(qs.escape([5, 10]), '5%2C10'); +assert.strictEqual(qs.escape('Ŋōđĕ'), '%C5%8A%C5%8D%C4%91%C4%95'); +assert.strictEqual(qs.escape('testŊōđĕ'), 'test%C5%8A%C5%8D%C4%91%C4%95'); +assert.strictEqual(qs.escape(`${String.fromCharCode(0xD800 + 1)}test`), + '%F0%90%91%B4est'); + +assert.throws( + () => qs.escape(String.fromCharCode(0xD800 + 1)), + { + code: 'ERR_INVALID_URI', + name: 'URIError', + message: 'URI malformed' + } +); + +// Using toString for objects +assert.strictEqual( + qs.escape({ test: 5, toString: () => 'test', valueOf: () => 10 }), + 'test' +); + +// `toString` is not callable, must throw an error. +// Error message will vary between different JavaScript engines, so only check +// that it is a `TypeError`. +assert.throws(() => qs.escape({ toString: 5 }), TypeError); + +// Should use valueOf instead of non-callable toString. +assert.strictEqual(qs.escape({ toString: 5, valueOf: () => 'test' }), 'test'); + +// Error message will vary between different JavaScript engines, so only check +// that it is a `TypeError`. +assert.throws(() => qs.escape(Symbol('test')), TypeError); diff --git a/tests/node_compat/test/parallel/test-querystring-maxKeys-non-finite.js b/tests/node_compat/test/parallel/test-querystring-maxKeys-non-finite.js new file mode 100644 index 000000000..4a8c7ab0d --- /dev/null +++ b/tests/node_compat/test/parallel/test-querystring-maxKeys-non-finite.js @@ -0,0 +1,65 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +// This test was originally written to test a regression +// that was introduced by +// https://github.com/nodejs/node/pull/2288#issuecomment-179543894 +require('../common'); + +const assert = require('assert'); +const parse = require('querystring').parse; + +// Taken from express-js/body-parser +// https://github.com/expressjs/body-parser/blob/ed25264fb494cf0c8bc992b8257092cd4f694d5e/test/urlencoded.js#L636-L651 +function createManyParams(count) { + let str = ''; + + if (count === 0) { + return str; + } + + str += '0=0'; + + for (let i = 1; i < count; i++) { + const n = i.toString(36); + str += `&${n}=${n}`; + } + + return str; +} + +const count = 10000; +const originalMaxLength = 1000; +const params = createManyParams(count); + +// thealphanerd +// 27def4f introduced a change to parse that would cause Infinity +// to be passed to String.prototype.split as an argument for limit +// In this instance split will always return an empty array +// this test confirms that the output of parse is the expected length +// when passed Infinity as the argument for maxKeys +const resultInfinity = parse(params, undefined, undefined, { + maxKeys: Infinity +}); +const resultNaN = parse(params, undefined, undefined, { + maxKeys: NaN +}); +const resultInfinityString = parse(params, undefined, undefined, { + maxKeys: 'Infinity' +}); +const resultNaNString = parse(params, undefined, undefined, { + maxKeys: 'NaN' +}); + +// Non Finite maxKeys should return the length of input +assert.strictEqual(Object.keys(resultInfinity).length, count); +assert.strictEqual(Object.keys(resultNaN).length, count); +// Strings maxKeys should return the maxLength +// defined by parses internals +assert.strictEqual(Object.keys(resultInfinityString).length, originalMaxLength); +assert.strictEqual(Object.keys(resultNaNString).length, originalMaxLength); diff --git a/tests/node_compat/test/parallel/test-querystring-multichar-separator.js b/tests/node_compat/test/parallel/test-querystring-multichar-separator.js new file mode 100644 index 000000000..3234dcd60 --- /dev/null +++ b/tests/node_compat/test/parallel/test-querystring-multichar-separator.js @@ -0,0 +1,32 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const assert = require('assert'); +const qs = require('querystring'); + +function check(actual, expected) { + assert(!(actual instanceof Object)); + assert.deepStrictEqual(Object.keys(actual).sort(), + Object.keys(expected).sort()); + Object.keys(expected).forEach(function(key) { + assert.deepStrictEqual(actual[key], expected[key]); + }); +} + +check(qs.parse('foo=>bar&&bar=>baz', '&&', '=>'), + { foo: 'bar', bar: 'baz' }); + +check(qs.stringify({ foo: 'bar', bar: 'baz' }, '&&', '=>'), + 'foo=>bar&&bar=>baz'); + +check(qs.parse('foo==>bar, bar==>baz', ', ', '==>'), + { foo: 'bar', bar: 'baz' }); + +check(qs.stringify({ foo: 'bar', bar: 'baz' }, ', ', '==>'), + 'foo==>bar, bar==>baz'); diff --git a/tests/node_compat/test/parallel/test-querystring.js b/tests/node_compat/test/parallel/test-querystring.js new file mode 100644 index 000000000..fb8176da5 --- /dev/null +++ b/tests/node_compat/test/parallel/test-querystring.js @@ -0,0 +1,489 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.12.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const inspect = require('util').inspect; + +// test using assert +const qs = require('querystring'); + +function createWithNoPrototype(properties) { + const noProto = Object.create(null); + properties.forEach((property) => { + noProto[property.key] = property.value; + }); + return noProto; +} +// Folding block, commented to pass gjslint +// {{{ +// [ wonkyQS, canonicalQS, obj ] +const qsTestCases = [ + ['__proto__=1', + '__proto__=1', + createWithNoPrototype([{ key: '__proto__', value: '1' }])], + ['__defineGetter__=asdf', + '__defineGetter__=asdf', + JSON.parse('{"__defineGetter__":"asdf"}')], + ['foo=918854443121279438895193', + 'foo=918854443121279438895193', + { 'foo': '918854443121279438895193' }], + ['foo=bar', 'foo=bar', { 'foo': 'bar' }], + ['foo=bar&foo=quux', 'foo=bar&foo=quux', { 'foo': ['bar', 'quux'] }], + ['foo=1&bar=2', 'foo=1&bar=2', { 'foo': '1', 'bar': '2' }], + ['my+weird+field=q1%212%22%27w%245%267%2Fz8%29%3F', + 'my%20weird%20field=q1!2%22\'w%245%267%2Fz8)%3F', + { 'my weird field': 'q1!2"\'w$5&7/z8)?' }], + ['foo%3Dbaz=bar', 'foo%3Dbaz=bar', { 'foo=baz': 'bar' }], + ['foo=baz=bar', 'foo=baz%3Dbar', { 'foo': 'baz=bar' }], + ['str=foo&arr=1&arr=2&arr=3&somenull=&undef=', + 'str=foo&arr=1&arr=2&arr=3&somenull=&undef=', + { 'str': 'foo', + 'arr': ['1', '2', '3'], + 'somenull': '', + 'undef': '' }], + [' foo = bar ', '%20foo%20=%20bar%20', { ' foo ': ' bar ' }], + ['foo=%zx', 'foo=%25zx', { 'foo': '%zx' }], + ['foo=%EF%BF%BD', 'foo=%EF%BF%BD', { 'foo': '\ufffd' }], + // See: https://github.com/joyent/node/issues/1707 + ['hasOwnProperty=x&toString=foo&valueOf=bar&__defineGetter__=baz', + 'hasOwnProperty=x&toString=foo&valueOf=bar&__defineGetter__=baz', + { hasOwnProperty: 'x', + toString: 'foo', + valueOf: 'bar', + __defineGetter__: 'baz' }], + // See: https://github.com/joyent/node/issues/3058 + ['foo&bar=baz', 'foo=&bar=baz', { foo: '', bar: 'baz' }], + ['a=b&c&d=e', 'a=b&c=&d=e', { a: 'b', c: '', d: 'e' }], + ['a=b&c=&d=e', 'a=b&c=&d=e', { a: 'b', c: '', d: 'e' }], + ['a=b&=c&d=e', 'a=b&=c&d=e', { 'a': 'b', '': 'c', 'd': 'e' }], + ['a=b&=&c=d', 'a=b&=&c=d', { 'a': 'b', '': '', 'c': 'd' }], + ['&&foo=bar&&', 'foo=bar', { foo: 'bar' }], + ['&', '', {}], + ['&&&&', '', {}], + ['&=&', '=', { '': '' }], + ['&=&=', '=&=', { '': [ '', '' ] }], + ['=', '=', { '': '' }], + ['+', '%20=', { ' ': '' }], + ['+=', '%20=', { ' ': '' }], + ['+&', '%20=', { ' ': '' }], + ['=+', '=%20', { '': ' ' }], + ['+=&', '%20=', { ' ': '' }], + ['a&&b', 'a=&b=', { 'a': '', 'b': '' }], + ['a=a&&b=b', 'a=a&b=b', { 'a': 'a', 'b': 'b' }], + ['&a', 'a=', { 'a': '' }], + ['&=', '=', { '': '' }], + ['a&a&', 'a=&a=', { a: [ '', '' ] }], + ['a&a&a&', 'a=&a=&a=', { a: [ '', '', '' ] }], + ['a&a&a&a&', 'a=&a=&a=&a=', { a: [ '', '', '', '' ] }], + ['a=&a=value&a=', 'a=&a=value&a=', { a: [ '', 'value', '' ] }], + ['foo+bar=baz+quux', 'foo%20bar=baz%20quux', { 'foo bar': 'baz quux' }], + ['+foo=+bar', '%20foo=%20bar', { ' foo': ' bar' }], + ['a+', 'a%20=', { 'a ': '' }], + ['=a+', '=a%20', { '': 'a ' }], + ['a+&', 'a%20=', { 'a ': '' }], + ['=a+&', '=a%20', { '': 'a ' }], + ['%20+', '%20%20=', { ' ': '' }], + ['=%20+', '=%20%20', { '': ' ' }], + ['%20+&', '%20%20=', { ' ': '' }], + ['=%20+&', '=%20%20', { '': ' ' }], + [null, '', {}], + [undefined, '', {}], +]; + +// [ wonkyQS, canonicalQS, obj ] +const qsColonTestCases = [ + ['foo:bar', 'foo:bar', { 'foo': 'bar' }], + ['foo:bar;foo:quux', 'foo:bar;foo:quux', { 'foo': ['bar', 'quux'] }], + ['foo:1&bar:2;baz:quux', + 'foo:1%26bar%3A2;baz:quux', + { 'foo': '1&bar:2', 'baz': 'quux' }], + ['foo%3Abaz:bar', 'foo%3Abaz:bar', { 'foo:baz': 'bar' }], + ['foo:baz:bar', 'foo:baz%3Abar', { 'foo': 'baz:bar' }], +]; + +// [wonkyObj, qs, canonicalObj] +function extendedFunction() {} +extendedFunction.prototype = { a: 'b' }; +const qsWeirdObjects = [ + // eslint-disable-next-line node-core/no-unescaped-regexp-dot + [{ regexp: /./g }, 'regexp=', { 'regexp': '' }], + // eslint-disable-next-line node-core/no-unescaped-regexp-dot + [{ regexp: new RegExp('.', 'g') }, 'regexp=', { 'regexp': '' }], + [{ fn: () => {} }, 'fn=', { 'fn': '' }], + [{ fn: new Function('') }, 'fn=', { 'fn': '' }], + [{ math: Math }, 'math=', { 'math': '' }], + [{ e: extendedFunction }, 'e=', { 'e': '' }], + [{ d: new Date() }, 'd=', { 'd': '' }], + [{ d: Date }, 'd=', { 'd': '' }], + [ + { f: new Boolean(false), t: new Boolean(true) }, + 'f=&t=', + { 'f': '', 't': '' }, + ], + [{ f: false, t: true }, 'f=false&t=true', { 'f': 'false', 't': 'true' }], + [{ n: null }, 'n=', { 'n': '' }], + [{ nan: NaN }, 'nan=', { 'nan': '' }], + [{ inf: Infinity }, 'inf=', { 'inf': '' }], + [{ a: [], b: [] }, '', {}], + [{ a: 1, b: [] }, 'a=1', { 'a': '1' }], +]; + +const vm = require('vm'); +const foreignObject = vm.runInNewContext('({"foo": ["bar", "baz"]})'); + +const qsNoMungeTestCases = [ + ['', {}], + ['foo=bar&foo=baz', { 'foo': ['bar', 'baz'] }], + ['foo=bar&foo=baz', foreignObject], + ['blah=burp', { 'blah': 'burp' }], + ['a=!-._~\'()*', { 'a': '!-._~\'()*' }], + ['a=abcdefghijklmnopqrstuvwxyz', { 'a': 'abcdefghijklmnopqrstuvwxyz' }], + ['a=ABCDEFGHIJKLMNOPQRSTUVWXYZ', { 'a': 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' }], + ['a=0123456789', { 'a': '0123456789' }], + ['gragh=1&gragh=3&goo=2', { 'gragh': ['1', '3'], 'goo': '2' }], + ['frappucino=muffin&goat%5B%5D=scone&pond=moose', + { 'frappucino': 'muffin', 'goat[]': 'scone', 'pond': 'moose' }], + ['trololol=yes&lololo=no', { 'trololol': 'yes', 'lololo': 'no' }], +]; + +const qsUnescapeTestCases = [ + ['there is nothing to unescape here', + 'there is nothing to unescape here'], + ['there%20are%20several%20spaces%20that%20need%20to%20be%20unescaped', + 'there are several spaces that need to be unescaped'], + ['there%2Qare%0-fake%escaped values in%%%%this%9Hstring', + 'there%2Qare%0-fake%escaped values in%%%%this%9Hstring'], + ['%20%21%22%23%24%25%26%27%28%29%2A%2B%2C%2D%2E%2F%30%31%32%33%34%35%36%37', + ' !"#$%&\'()*+,-./01234567'], + ['%%2a', '%*'], + ['%2sf%2a', '%2sf*'], + ['%2%2af%2a', '%2*f*'], +]; + +assert.strictEqual(qs.parse('id=918854443121279438895193').id, + '918854443121279438895193'); + +function check(actual, expected, input) { + assert(!(actual instanceof Object)); + const actualKeys = Object.keys(actual).sort(); + const expectedKeys = Object.keys(expected).sort(); + let msg; + if (typeof input === 'string') { + msg = `Input: ${inspect(input)}\n` + + `Actual keys: ${inspect(actualKeys)}\n` + + `Expected keys: ${inspect(expectedKeys)}`; + } + assert.deepStrictEqual(actualKeys, expectedKeys, msg); + expectedKeys.forEach((key) => { + if (typeof input === 'string') { + msg = `Input: ${inspect(input)}\n` + + `Key: ${inspect(key)}\n` + + `Actual value: ${inspect(actual[key])}\n` + + `Expected value: ${inspect(expected[key])}`; + } else { + msg = undefined; + } + assert.deepStrictEqual(actual[key], expected[key], msg); + }); +} + +// Test that the canonical qs is parsed properly. +qsTestCases.forEach((testCase) => { + check(qs.parse(testCase[0]), testCase[2], testCase[0]); +}); + +// Test that the colon test cases can do the same +qsColonTestCases.forEach((testCase) => { + check(qs.parse(testCase[0], ';', ':'), testCase[2], testCase[0]); +}); + +// Test the weird objects, that they get parsed properly +qsWeirdObjects.forEach((testCase) => { + check(qs.parse(testCase[1]), testCase[2], testCase[1]); +}); + +qsNoMungeTestCases.forEach((testCase) => { + assert.deepStrictEqual(qs.stringify(testCase[1], '&', '='), testCase[0]); +}); + +// Test the nested qs-in-qs case +{ + const f = qs.parse('a=b&q=x%3Dy%26y%3Dz'); + check(f, createWithNoPrototype([ + { key: 'a', value: 'b' }, + { key: 'q', value: 'x=y&y=z' }, + ])); + + f.q = qs.parse(f.q); + const expectedInternal = createWithNoPrototype([ + { key: 'x', value: 'y' }, + { key: 'y', value: 'z' }, + ]); + check(f.q, expectedInternal); +} + +// nested in colon +{ + const f = qs.parse('a:b;q:x%3Ay%3By%3Az', ';', ':'); + check(f, createWithNoPrototype([ + { key: 'a', value: 'b' }, + { key: 'q', value: 'x:y;y:z' }, + ])); + f.q = qs.parse(f.q, ';', ':'); + const expectedInternal = createWithNoPrototype([ + { key: 'x', value: 'y' }, + { key: 'y', value: 'z' }, + ]); + check(f.q, expectedInternal); +} + +// Now test stringifying + +// basic +qsTestCases.forEach((testCase) => { + assert.strictEqual(qs.stringify(testCase[2]), testCase[1]); +}); + +qsColonTestCases.forEach((testCase) => { + assert.strictEqual(qs.stringify(testCase[2], ';', ':'), testCase[1]); +}); + +qsWeirdObjects.forEach((testCase) => { + assert.strictEqual(qs.stringify(testCase[0]), testCase[1]); +}); + +// BigInt values + +assert.strictEqual(qs.stringify({ foo: 2n ** 1023n }), + 'foo=' + 2n ** 1023n); +assert.strictEqual(qs.stringify([0n, 1n, 2n]), + '0=0&1=1&2=2'); + +assert.strictEqual(qs.stringify({ foo: 2n ** 1023n }, + null, + null, + { encodeURIComponent: (c) => c }), + 'foo=' + 2n ** 1023n); +assert.strictEqual(qs.stringify([0n, 1n, 2n], + null, + null, + { encodeURIComponent: (c) => c }), + '0=0&1=1&2=2'); + +// Invalid surrogate pair throws URIError +assert.throws( + () => qs.stringify({ foo: '\udc00' }), + { + code: 'ERR_INVALID_URI', + name: 'URIError', + message: 'URI malformed' + } +); + +// Coerce numbers to string +assert.strictEqual(qs.stringify({ foo: 0 }), 'foo=0'); +assert.strictEqual(qs.stringify({ foo: -0 }), 'foo=0'); +assert.strictEqual(qs.stringify({ foo: 3 }), 'foo=3'); +assert.strictEqual(qs.stringify({ foo: -72.42 }), 'foo=-72.42'); +assert.strictEqual(qs.stringify({ foo: NaN }), 'foo='); +assert.strictEqual(qs.stringify({ foo: 1e21 }), 'foo=1e%2B21'); +assert.strictEqual(qs.stringify({ foo: Infinity }), 'foo='); + +// nested +{ + const f = qs.stringify({ + a: 'b', + q: qs.stringify({ + x: 'y', + y: 'z' + }) + }); + assert.strictEqual(f, 'a=b&q=x%3Dy%26y%3Dz'); +} + +qs.parse(undefined); // Should not throw. + +// nested in colon +{ + const f = qs.stringify({ + a: 'b', + q: qs.stringify({ + x: 'y', + y: 'z' + }, ';', ':') + }, ';', ':'); + assert.strictEqual(f, 'a:b;q:x%3Ay%3By%3Az'); +} + +// empty string +assert.strictEqual(qs.stringify(), ''); +assert.strictEqual(qs.stringify(0), ''); +assert.strictEqual(qs.stringify([]), ''); +assert.strictEqual(qs.stringify(null), ''); +assert.strictEqual(qs.stringify(true), ''); + +check(qs.parse(), {}); + +// empty sep +check(qs.parse('a', []), { a: '' }); + +// empty eq +check(qs.parse('a', null, []), { '': 'a' }); + +// Test limiting +assert.strictEqual( + Object.keys(qs.parse('a=1&b=1&c=1', null, null, { maxKeys: 1 })).length, + 1); + +// Test limiting with a case that starts from `&` +assert.strictEqual( + Object.keys(qs.parse('&a', null, null, { maxKeys: 1 })).length, + 0); + +// Test removing limit +{ + function testUnlimitedKeys() { + const query = {}; + + for (let i = 0; i < 2000; i++) query[i] = i; + + const url = qs.stringify(query); + + assert.strictEqual( + Object.keys(qs.parse(url, null, null, { maxKeys: 0 })).length, + 2000); + } + + testUnlimitedKeys(); +} + +{ + const b = qs.unescapeBuffer('%d3%f2Ug%1f6v%24%5e%98%cb' + + '%0d%ac%a2%2f%9d%eb%d8%a2%e6'); + // + assert.strictEqual(b[0], 0xd3); + assert.strictEqual(b[1], 0xf2); + assert.strictEqual(b[2], 0x55); + assert.strictEqual(b[3], 0x67); + assert.strictEqual(b[4], 0x1f); + assert.strictEqual(b[5], 0x36); + assert.strictEqual(b[6], 0x76); + assert.strictEqual(b[7], 0x24); + assert.strictEqual(b[8], 0x5e); + assert.strictEqual(b[9], 0x98); + assert.strictEqual(b[10], 0xcb); + assert.strictEqual(b[11], 0x0d); + assert.strictEqual(b[12], 0xac); + assert.strictEqual(b[13], 0xa2); + assert.strictEqual(b[14], 0x2f); + assert.strictEqual(b[15], 0x9d); + assert.strictEqual(b[16], 0xeb); + assert.strictEqual(b[17], 0xd8); + assert.strictEqual(b[18], 0xa2); + assert.strictEqual(b[19], 0xe6); +} + +assert.strictEqual(qs.unescapeBuffer('a+b', true).toString(), 'a b'); +assert.strictEqual(qs.unescapeBuffer('a+b').toString(), 'a+b'); +assert.strictEqual(qs.unescapeBuffer('a%').toString(), 'a%'); +assert.strictEqual(qs.unescapeBuffer('a%2').toString(), 'a%2'); +assert.strictEqual(qs.unescapeBuffer('a%20').toString(), 'a '); +assert.strictEqual(qs.unescapeBuffer('a%2g').toString(), 'a%2g'); +assert.strictEqual(qs.unescapeBuffer('a%%').toString(), 'a%%'); + +// Test invalid encoded string +check(qs.parse('%\u0100=%\u0101'), { '%Ā': '%ā' }); + +// Test custom decode +{ + function demoDecode(str) { + return str + str; + } + + check( + qs.parse('a=a&b=b&c=c', null, null, { decodeURIComponent: demoDecode }), + { aa: 'aa', bb: 'bb', cc: 'cc' }); + check( + qs.parse('a=a&b=b&c=c', null, '==', { decodeURIComponent: (str) => str }), + { 'a=a': '', 'b=b': '', 'c=c': '' }); +} + +// TODO(wafuwafu13): Enable this +// // Test QueryString.unescape +// { +// function errDecode(str) { +// throw new Error('To jump to the catch scope'); +// } + +// check(qs.parse('a=a', null, null, { decodeURIComponent: errDecode }), +// { a: 'a' }); +// } + +// Test custom encode +{ + function demoEncode(str) { + return str[0]; + } + + const obj = { aa: 'aa', bb: 'bb', cc: 'cc' }; + assert.strictEqual( + qs.stringify(obj, null, null, { encodeURIComponent: demoEncode }), + 'a=a&b=b&c=c'); +} + +// Test custom encode for different types +{ + const obj = { number: 1, bigint: 2n, true: true, false: false, object: {} }; + assert.strictEqual( + qs.stringify(obj, null, null, { encodeURIComponent: (v) => v }), + 'number=1&bigint=2&true=true&false=false&object='); +} + +// Test QueryString.unescapeBuffer +qsUnescapeTestCases.forEach((testCase) => { + assert.strictEqual(qs.unescape(testCase[0]), testCase[1]); + assert.strictEqual(qs.unescapeBuffer(testCase[0]).toString(), testCase[1]); +}); + +// TODO(wafuwafu13): Enable this +// // Test overriding .unescape +// { +// const prevUnescape = qs.unescape; +// qs.unescape = (str) => { +// return str.replace(/o/g, '_'); +// }; +// check( +// qs.parse('foo=bor'), +// createWithNoPrototype([{ key: 'f__', value: 'b_r' }])); +// qs.unescape = prevUnescape; +// } + +// Test separator and "equals" parsing order +check(qs.parse('foo&bar', '&', '&'), { foo: '', bar: '' }); diff --git a/tests/node_compat/test/parallel/test-readline-emit-keypress-events.js b/tests/node_compat/test/parallel/test-readline-emit-keypress-events.js new file mode 100644 index 000000000..542616424 --- /dev/null +++ b/tests/node_compat/test/parallel/test-readline-emit-keypress-events.js @@ -0,0 +1,79 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +// emitKeypressEvents is thoroughly tested in test-readline-keys.js. +// However, that test calls it implicitly. This is just a quick sanity check +// to verify that it works when called explicitly. + +require('../common'); +const assert = require('assert'); +const readline = require('readline'); +const PassThrough = require('stream').PassThrough; + +const expectedSequence = ['f', 'o', 'o']; +const expectedKeys = [ + { sequence: 'f', name: 'f', ctrl: false, meta: false, shift: false }, + { sequence: 'o', name: 'o', ctrl: false, meta: false, shift: false }, + { sequence: 'o', name: 'o', ctrl: false, meta: false, shift: false }, +]; + +{ + const stream = new PassThrough(); + const sequence = []; + const keys = []; + + readline.emitKeypressEvents(stream); + stream.on('keypress', (s, k) => { + sequence.push(s); + keys.push(k); + }); + stream.write('foo'); + + assert.deepStrictEqual(sequence, expectedSequence); + assert.deepStrictEqual(keys, expectedKeys); +} + +{ + const stream = new PassThrough(); + const sequence = []; + const keys = []; + + stream.on('keypress', (s, k) => { + sequence.push(s); + keys.push(k); + }); + readline.emitKeypressEvents(stream); + stream.write('foo'); + + assert.deepStrictEqual(sequence, expectedSequence); + assert.deepStrictEqual(keys, expectedKeys); +} + +{ + const stream = new PassThrough(); + const sequence = []; + const keys = []; + const keypressListener = (s, k) => { + sequence.push(s); + keys.push(k); + }; + + stream.on('keypress', keypressListener); + readline.emitKeypressEvents(stream); + stream.removeListener('keypress', keypressListener); + stream.write('foo'); + + assert.deepStrictEqual(sequence, []); + assert.deepStrictEqual(keys, []); + + stream.on('keypress', keypressListener); + stream.write('foo'); + + assert.deepStrictEqual(sequence, expectedSequence); + assert.deepStrictEqual(keys, expectedKeys); +} diff --git a/tests/node_compat/test/parallel/test-readline-interface-escapecodetimeout.js b/tests/node_compat/test/parallel/test-readline-interface-escapecodetimeout.js new file mode 100644 index 000000000..584dc1110 --- /dev/null +++ b/tests/node_compat/test/parallel/test-readline-interface-escapecodetimeout.js @@ -0,0 +1,53 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); + +// This test ensures that the escapeCodeTimeout option set correctly + +const assert = require('assert'); +const readline = require('readline'); +const EventEmitter = require('events').EventEmitter; + +class FakeInput extends EventEmitter { + resume() {} + pause() {} + write() {} + end() {} +} + +{ + const fi = new FakeInput(); + const rli = new readline.Interface({ + input: fi, + output: fi, + escapeCodeTimeout: 50 + }); + assert.strictEqual(rli.escapeCodeTimeout, 50); + rli.close(); +} + +[ + null, + {}, + NaN, + '50', +].forEach((invalidInput) => { + assert.throws(() => { + const fi = new FakeInput(); + const rli = new readline.Interface({ + input: fi, + output: fi, + escapeCodeTimeout: invalidInput + }); + rli.close(); + }, { + name: 'TypeError', + code: 'ERR_INVALID_ARG_VALUE' + }); +}); diff --git a/tests/node_compat/test/parallel/test-readline-interface.js b/tests/node_compat/test/parallel/test-readline-interface.js new file mode 100644 index 000000000..e8e48dd1e --- /dev/null +++ b/tests/node_compat/test/parallel/test-readline-interface.js @@ -0,0 +1,1217 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// Flags: --expose-internals +'use strict'; +const common = require('../common'); +common.skipIfDumbTerminal(); + +const assert = require('assert'); +const readline = require('readline'); +const util = require('util'); +const { + getStringWidth, + stripVTControlCharacters +} = require('internal/util/inspect'); +const { EventEmitter, getEventListeners } = require('events'); +const { Writable, Readable } = require('stream'); + +class FakeInput extends EventEmitter { + resume() {} + pause() {} + write() {} + end() {} +} + +function isWarned(emitter) { + for (const name in emitter) { + const listeners = emitter[name]; + if (listeners.warned) return true; + } + return false; +} + +function getInterface(options) { + const fi = new FakeInput(); + const rli = new readline.Interface({ + input: fi, + output: fi, + ...options, + }); + return [rli, fi]; +} + +function assertCursorRowsAndCols(rli, rows, cols) { + const cursorPos = rli.getCursorPos(); + assert.strictEqual(cursorPos.rows, rows); + assert.strictEqual(cursorPos.cols, cols); +} + +{ + const input = new FakeInput(); + const rl = readline.Interface({ input }); + assert(rl instanceof readline.Interface); +} + +[ + undefined, + 50, + 0, + 100.5, + 5000, +].forEach((crlfDelay) => { + const [rli] = getInterface({ crlfDelay }); + assert.strictEqual(rli.crlfDelay, Math.max(crlfDelay || 100, 100)); + rli.close(); +}); + +{ + const input = new FakeInput(); + + // Constructor throws if completer is not a function or undefined + ['not an array', 123, 123n, {}, true, Symbol(), null].forEach((invalid) => { + assert.throws(() => { + readline.createInterface({ + input, + completer: invalid + }); + }, { + name: 'TypeError', + code: 'ERR_INVALID_ARG_VALUE' + }); + }); + + // Constructor throws if history is not an array + ['not an array', 123, 123n, {}, true, Symbol(), null].forEach((history) => { + assert.throws(() => { + readline.createInterface({ + input, + history, + }); + }, { + name: 'TypeError', + code: 'ERR_INVALID_ARG_TYPE' + }); + }); + + // Constructor throws if historySize is not a positive number + ['not a number', -1, NaN, {}, true, Symbol(), null].forEach((historySize) => { + assert.throws(() => { + readline.createInterface({ + input, + historySize, + }); + }, { + name: 'RangeError', + code: 'ERR_INVALID_ARG_VALUE' + }); + }); + + // Check for invalid tab sizes. + assert.throws( + () => new readline.Interface({ + input, + tabSize: 0 + }), + { + message: 'The value of "tabSize" is out of range. ' + + 'It must be >= 1 && < 4294967296. Received 0', + code: 'ERR_OUT_OF_RANGE' + } + ); + + assert.throws( + () => new readline.Interface({ + input, + tabSize: '4' + }), + { code: 'ERR_INVALID_ARG_TYPE' } + ); + + assert.throws( + () => new readline.Interface({ + input, + tabSize: 4.5 + }), + { + code: 'ERR_OUT_OF_RANGE', + message: 'The value of "tabSize" is out of range. ' + + 'It must be an integer. Received 4.5' + } + ); +} + +// Sending a single character with no newline +{ + const fi = new FakeInput(); + const rli = new readline.Interface(fi, {}); + rli.on('line', common.mustNotCall()); + fi.emit('data', 'a'); + rli.close(); +} + +// Sending multiple newlines at once that does not end with a new line and a +// `end` event(last line is). \r should behave like \n when alone. +{ + const [rli, fi] = getInterface({ terminal: true }); + const expectedLines = ['foo', 'bar', 'baz', 'bat']; + rli.on('line', common.mustCall((line) => { + assert.strictEqual(line, expectedLines.shift()); + }, expectedLines.length - 1)); + fi.emit('data', expectedLines.join('\r')); + rli.close(); +} + +// \r at start of input should output blank line +{ + const [rli, fi] = getInterface({ terminal: true }); + const expectedLines = ['', 'foo' ]; + rli.on('line', common.mustCall((line) => { + assert.strictEqual(line, expectedLines.shift()); + }, expectedLines.length)); + fi.emit('data', '\rfoo\r'); + rli.close(); +} + +// \t does not become part of the input when there is a completer function +{ + const completer = (line) => [[], line]; + const [rli, fi] = getInterface({ terminal: true, completer }); + rli.on('line', common.mustCall((line) => { + assert.strictEqual(line, 'foo'); + })); + for (const character of '\tfo\to\t') { + fi.emit('data', character); + } + fi.emit('data', '\n'); + rli.close(); +} + +// \t when there is no completer function should behave like an ordinary +// character +{ + const [rli, fi] = getInterface({ terminal: true }); + rli.on('line', common.mustCall((line) => { + assert.strictEqual(line, '\t'); + })); + fi.emit('data', '\t'); + fi.emit('data', '\n'); + rli.close(); +} + +// Adding history lines should emit the history event with +// the history array +{ + const [rli, fi] = getInterface({ terminal: true }); + const expectedLines = ['foo', 'bar', 'baz', 'bat']; + rli.on('history', common.mustCall((history) => { + const expectedHistory = expectedLines.slice(0, history.length).reverse(); + assert.deepStrictEqual(history, expectedHistory); + }, expectedLines.length)); + for (const line of expectedLines) { + fi.emit('data', `${line}\n`); + } + rli.close(); +} + +// Altering the history array in the listener should not alter +// the line being processed +{ + const [rli, fi] = getInterface({ terminal: true }); + const expectedLine = 'foo'; + rli.on('history', common.mustCall((history) => { + assert.strictEqual(history[0], expectedLine); + history.shift(); + })); + rli.on('line', common.mustCall((line) => { + assert.strictEqual(line, expectedLine); + assert.strictEqual(rli.history.length, 0); + })); + fi.emit('data', `${expectedLine}\n`); + rli.close(); +} + +// Duplicate lines are removed from history when +// `options.removeHistoryDuplicates` is `true` +{ + const [rli, fi] = getInterface({ + terminal: true, + removeHistoryDuplicates: true + }); + const expectedLines = ['foo', 'bar', 'baz', 'bar', 'bat', 'bat']; + // ['foo', 'baz', 'bar', bat']; + let callCount = 0; + rli.on('line', (line) => { + assert.strictEqual(line, expectedLines[callCount]); + callCount++; + }); + fi.emit('data', `${expectedLines.join('\n')}\n`); + assert.strictEqual(callCount, expectedLines.length); + fi.emit('keypress', '.', { name: 'up' }); // 'bat' + assert.strictEqual(rli.line, expectedLines[--callCount]); + fi.emit('keypress', '.', { name: 'up' }); // 'bar' + assert.notStrictEqual(rli.line, expectedLines[--callCount]); + assert.strictEqual(rli.line, expectedLines[--callCount]); + fi.emit('keypress', '.', { name: 'up' }); // 'baz' + assert.strictEqual(rli.line, expectedLines[--callCount]); + fi.emit('keypress', '.', { name: 'up' }); // 'foo' + assert.notStrictEqual(rli.line, expectedLines[--callCount]); + assert.strictEqual(rli.line, expectedLines[--callCount]); + assert.strictEqual(callCount, 0); + fi.emit('keypress', '.', { name: 'down' }); // 'baz' + assert.strictEqual(rli.line, 'baz'); + assert.strictEqual(rli.historyIndex, 2); + fi.emit('keypress', '.', { name: 'n', ctrl: true }); // 'bar' + assert.strictEqual(rli.line, 'bar'); + assert.strictEqual(rli.historyIndex, 1); + fi.emit('keypress', '.', { name: 'n', ctrl: true }); + assert.strictEqual(rli.line, 'bat'); + assert.strictEqual(rli.historyIndex, 0); + // Activate the substring history search. + fi.emit('keypress', '.', { name: 'down' }); // 'bat' + assert.strictEqual(rli.line, 'bat'); + assert.strictEqual(rli.historyIndex, -1); + // Deactivate substring history search. + fi.emit('keypress', '.', { name: 'backspace' }); // 'ba' + assert.strictEqual(rli.historyIndex, -1); + assert.strictEqual(rli.line, 'ba'); + // Activate the substring history search. + fi.emit('keypress', '.', { name: 'down' }); // 'ba' + assert.strictEqual(rli.historyIndex, -1); + assert.strictEqual(rli.line, 'ba'); + fi.emit('keypress', '.', { name: 'down' }); // 'ba' + assert.strictEqual(rli.historyIndex, -1); + assert.strictEqual(rli.line, 'ba'); + fi.emit('keypress', '.', { name: 'up' }); // 'bat' + assert.strictEqual(rli.historyIndex, 0); + assert.strictEqual(rli.line, 'bat'); + fi.emit('keypress', '.', { name: 'up' }); // 'bar' + assert.strictEqual(rli.historyIndex, 1); + assert.strictEqual(rli.line, 'bar'); + fi.emit('keypress', '.', { name: 'up' }); // 'baz' + assert.strictEqual(rli.historyIndex, 2); + assert.strictEqual(rli.line, 'baz'); + fi.emit('keypress', '.', { name: 'up' }); // 'ba' + assert.strictEqual(rli.historyIndex, 4); + assert.strictEqual(rli.line, 'ba'); + fi.emit('keypress', '.', { name: 'up' }); // 'ba' + assert.strictEqual(rli.historyIndex, 4); + assert.strictEqual(rli.line, 'ba'); + // Deactivate substring history search and reset history index. + fi.emit('keypress', '.', { name: 'right' }); // 'ba' + assert.strictEqual(rli.historyIndex, -1); + assert.strictEqual(rli.line, 'ba'); + // Substring history search activated. + fi.emit('keypress', '.', { name: 'up' }); // 'ba' + assert.strictEqual(rli.historyIndex, 0); + assert.strictEqual(rli.line, 'bat'); + rli.close(); +} + +// Duplicate lines are not removed from history when +// `options.removeHistoryDuplicates` is `false` +{ + const [rli, fi] = getInterface({ + terminal: true, + removeHistoryDuplicates: false + }); + const expectedLines = ['foo', 'bar', 'baz', 'bar', 'bat', 'bat']; + let callCount = 0; + rli.on('line', (line) => { + assert.strictEqual(line, expectedLines[callCount]); + callCount++; + }); + fi.emit('data', `${expectedLines.join('\n')}\n`); + assert.strictEqual(callCount, expectedLines.length); + fi.emit('keypress', '.', { name: 'up' }); // 'bat' + assert.strictEqual(rli.line, expectedLines[--callCount]); + fi.emit('keypress', '.', { name: 'up' }); // 'bar' + assert.notStrictEqual(rli.line, expectedLines[--callCount]); + assert.strictEqual(rli.line, expectedLines[--callCount]); + fi.emit('keypress', '.', { name: 'up' }); // 'baz' + assert.strictEqual(rli.line, expectedLines[--callCount]); + fi.emit('keypress', '.', { name: 'up' }); // 'bar' + assert.strictEqual(rli.line, expectedLines[--callCount]); + fi.emit('keypress', '.', { name: 'up' }); // 'foo' + assert.strictEqual(rli.line, expectedLines[--callCount]); + assert.strictEqual(callCount, 0); + rli.close(); +} + +// Regression test for repl freeze, #1968: +// check that nothing fails if 'keypress' event throws. +{ + const [rli, fi] = getInterface({ terminal: true }); + const keys = []; + const err = new Error('bad thing happened'); + fi.on('keypress', (key) => { + keys.push(key); + if (key === 'X') { + throw err; + } + }); + assert.throws( + () => fi.emit('data', 'fooX'), + (e) => { + assert.strictEqual(e, err); + return true; + } + ); + fi.emit('data', 'bar'); + assert.strictEqual(keys.join(''), 'fooXbar'); + rli.close(); +} + +// History is bound +{ + const [rli, fi] = getInterface({ terminal: true, historySize: 2 }); + const lines = ['line 1', 'line 2', 'line 3']; + fi.emit('data', lines.join('\n') + '\n'); + assert.strictEqual(rli.history.length, 2); + assert.strictEqual(rli.history[0], 'line 3'); + assert.strictEqual(rli.history[1], 'line 2'); +} + +// Question +{ + const [rli] = getInterface({ terminal: true }); + const expectedLines = ['foo']; + rli.question(expectedLines[0], () => rli.close()); + assertCursorRowsAndCols(rli, 0, expectedLines[0].length); + rli.close(); +} + +// Sending a multi-line question +{ + const [rli] = getInterface({ terminal: true }); + const expectedLines = ['foo', 'bar']; + rli.question(expectedLines.join('\n'), () => rli.close()); + assertCursorRowsAndCols( + rli, expectedLines.length - 1, expectedLines.slice(-1)[0].length); + rli.close(); +} + +{ + // Beginning and end of line + const [rli, fi] = getInterface({ terminal: true, prompt: '' }); + fi.emit('data', 'the quick brown fox'); + fi.emit('keypress', '.', { ctrl: true, name: 'a' }); + assertCursorRowsAndCols(rli, 0, 0); + fi.emit('keypress', '.', { ctrl: true, name: 'e' }); + assertCursorRowsAndCols(rli, 0, 19); + rli.close(); +} + +{ + // Back and Forward one character + const [rli, fi] = getInterface({ terminal: true, prompt: '' }); + fi.emit('data', 'the quick brown fox'); + assertCursorRowsAndCols(rli, 0, 19); + + // Back one character + fi.emit('keypress', '.', { ctrl: true, name: 'b' }); + assertCursorRowsAndCols(rli, 0, 18); + // Back one character + fi.emit('keypress', '.', { ctrl: true, name: 'b' }); + assertCursorRowsAndCols(rli, 0, 17); + // Forward one character + fi.emit('keypress', '.', { ctrl: true, name: 'f' }); + assertCursorRowsAndCols(rli, 0, 18); + // Forward one character + fi.emit('keypress', '.', { ctrl: true, name: 'f' }); + assertCursorRowsAndCols(rli, 0, 19); + rli.close(); +} + +// Back and Forward one astral character +{ + const [rli, fi] = getInterface({ terminal: true, prompt: '' }); + fi.emit('data', '💻'); + + // Move left one character/code point + fi.emit('keypress', '.', { name: 'left' }); + assertCursorRowsAndCols(rli, 0, 0); + + // Move right one character/code point + fi.emit('keypress', '.', { name: 'right' }); + assertCursorRowsAndCols(rli, 0, 2); + + rli.on('line', common.mustCall((line) => { + assert.strictEqual(line, '💻'); + })); + fi.emit('data', '\n'); + rli.close(); +} + +// Two astral characters left +{ + const [rli, fi] = getInterface({ terminal: true, prompt: '' }); + fi.emit('data', '💻'); + + // Move left one character/code point + fi.emit('keypress', '.', { name: 'left' }); + assertCursorRowsAndCols(rli, 0, 0); + + fi.emit('data', '🐕'); + assertCursorRowsAndCols(rli, 0, 2); + + rli.on('line', common.mustCall((line) => { + assert.strictEqual(line, '🐕💻'); + })); + fi.emit('data', '\n'); + rli.close(); +} + +// Two astral characters right +{ + const [rli, fi] = getInterface({ terminal: true, prompt: '' }); + fi.emit('data', '💻'); + + // Move left one character/code point + fi.emit('keypress', '.', { name: 'right' }); + assertCursorRowsAndCols(rli, 0, 2); + + fi.emit('data', '🐕'); + assertCursorRowsAndCols(rli, 0, 4); + + rli.on('line', common.mustCall((line) => { + assert.strictEqual(line, '💻🐕'); + })); + fi.emit('data', '\n'); + rli.close(); +} + +{ + // `wordLeft` and `wordRight` + const [rli, fi] = getInterface({ terminal: true, prompt: '' }); + fi.emit('data', 'the quick brown fox'); + fi.emit('keypress', '.', { ctrl: true, name: 'left' }); + assertCursorRowsAndCols(rli, 0, 16); + fi.emit('keypress', '.', { meta: true, name: 'b' }); + assertCursorRowsAndCols(rli, 0, 10); + fi.emit('keypress', '.', { ctrl: true, name: 'right' }); + assertCursorRowsAndCols(rli, 0, 16); + fi.emit('keypress', '.', { meta: true, name: 'f' }); + assertCursorRowsAndCols(rli, 0, 19); + rli.close(); +} + +// `deleteWordLeft` +[ + { ctrl: true, name: 'w' }, + { ctrl: true, name: 'backspace' }, + { meta: true, name: 'backspace' }, +].forEach((deleteWordLeftKey) => { + let [rli, fi] = getInterface({ terminal: true, prompt: '' }); + fi.emit('data', 'the quick brown fox'); + fi.emit('keypress', '.', { ctrl: true, name: 'left' }); + rli.on('line', common.mustCall((line) => { + assert.strictEqual(line, 'the quick fox'); + })); + fi.emit('keypress', '.', deleteWordLeftKey); + fi.emit('data', '\n'); + rli.close(); + + // No effect if pressed at beginning of line + [rli, fi] = getInterface({ terminal: true, prompt: '' }); + fi.emit('data', 'the quick brown fox'); + fi.emit('keypress', '.', { ctrl: true, name: 'a' }); + rli.on('line', common.mustCall((line) => { + assert.strictEqual(line, 'the quick brown fox'); + })); + fi.emit('keypress', '.', deleteWordLeftKey); + fi.emit('data', '\n'); + rli.close(); +}); + +// `deleteWordRight` +[ + { ctrl: true, name: 'delete' }, + { meta: true, name: 'delete' }, + { meta: true, name: 'd' }, +].forEach((deleteWordRightKey) => { + let [rli, fi] = getInterface({ terminal: true, prompt: '' }); + fi.emit('data', 'the quick brown fox'); + fi.emit('keypress', '.', { ctrl: true, name: 'left' }); + fi.emit('keypress', '.', { ctrl: true, name: 'left' }); + rli.on('line', common.mustCall((line) => { + assert.strictEqual(line, 'the quick fox'); + })); + fi.emit('keypress', '.', deleteWordRightKey); + fi.emit('data', '\n'); + rli.close(); + + // No effect if pressed at end of line + [rli, fi] = getInterface({ terminal: true, prompt: '' }); + fi.emit('data', 'the quick brown fox'); + rli.on('line', common.mustCall((line) => { + assert.strictEqual(line, 'the quick brown fox'); + })); + fi.emit('keypress', '.', deleteWordRightKey); + fi.emit('data', '\n'); + rli.close(); +}); + +// deleteLeft +{ + const [rli, fi] = getInterface({ terminal: true, prompt: '' }); + fi.emit('data', 'the quick brown fox'); + assertCursorRowsAndCols(rli, 0, 19); + + // Delete left character + fi.emit('keypress', '.', { ctrl: true, name: 'h' }); + assertCursorRowsAndCols(rli, 0, 18); + rli.on('line', common.mustCall((line) => { + assert.strictEqual(line, 'the quick brown fo'); + })); + fi.emit('data', '\n'); + rli.close(); +} + +// deleteLeft astral character +{ + const [rli, fi] = getInterface({ terminal: true, prompt: '' }); + fi.emit('data', '💻'); + assertCursorRowsAndCols(rli, 0, 2); + // Delete left character + fi.emit('keypress', '.', { ctrl: true, name: 'h' }); + assertCursorRowsAndCols(rli, 0, 0); + rli.on('line', common.mustCall((line) => { + assert.strictEqual(line, ''); + })); + fi.emit('data', '\n'); + rli.close(); +} + +// deleteRight +{ + const [rli, fi] = getInterface({ terminal: true, prompt: '' }); + fi.emit('data', 'the quick brown fox'); + + // Go to the start of the line + fi.emit('keypress', '.', { ctrl: true, name: 'a' }); + assertCursorRowsAndCols(rli, 0, 0); + + // Delete right character + fi.emit('keypress', '.', { ctrl: true, name: 'd' }); + assertCursorRowsAndCols(rli, 0, 0); + rli.on('line', common.mustCall((line) => { + assert.strictEqual(line, 'he quick brown fox'); + })); + fi.emit('data', '\n'); + rli.close(); +} + +// deleteRight astral character +{ + const [rli, fi] = getInterface({ terminal: true, prompt: '' }); + fi.emit('data', '💻'); + + // Go to the start of the line + fi.emit('keypress', '.', { ctrl: true, name: 'a' }); + assertCursorRowsAndCols(rli, 0, 0); + + // Delete right character + fi.emit('keypress', '.', { ctrl: true, name: 'd' }); + assertCursorRowsAndCols(rli, 0, 0); + rli.on('line', common.mustCall((line) => { + assert.strictEqual(line, ''); + })); + fi.emit('data', '\n'); + rli.close(); +} + +// deleteLineLeft +{ + const [rli, fi] = getInterface({ terminal: true, prompt: '' }); + fi.emit('data', 'the quick brown fox'); + assertCursorRowsAndCols(rli, 0, 19); + + // Delete from current to start of line + fi.emit('keypress', '.', { ctrl: true, shift: true, name: 'backspace' }); + assertCursorRowsAndCols(rli, 0, 0); + rli.on('line', common.mustCall((line) => { + assert.strictEqual(line, ''); + })); + fi.emit('data', '\n'); + rli.close(); +} + +// deleteLineRight +{ + const [rli, fi] = getInterface({ terminal: true, prompt: '' }); + fi.emit('data', 'the quick brown fox'); + + // Go to the start of the line + fi.emit('keypress', '.', { ctrl: true, name: 'a' }); + assertCursorRowsAndCols(rli, 0, 0); + + // Delete from current to end of line + fi.emit('keypress', '.', { ctrl: true, shift: true, name: 'delete' }); + assertCursorRowsAndCols(rli, 0, 0); + rli.on('line', common.mustCall((line) => { + assert.strictEqual(line, ''); + })); + fi.emit('data', '\n'); + rli.close(); +} + +// Close readline interface +{ + const [rli, fi] = getInterface({ terminal: true, prompt: '' }); + fi.emit('keypress', '.', { ctrl: true, name: 'c' }); + assert(rli.closed); +} + +// Multi-line input cursor position +{ + const [rli, fi] = getInterface({ terminal: true, prompt: '' }); + fi.columns = 10; + fi.emit('data', 'multi-line text'); + assertCursorRowsAndCols(rli, 1, 5); + rli.close(); +} + +// Multi-line input cursor position and long tabs +{ + const [rli, fi] = getInterface({ tabSize: 16, terminal: true, prompt: '' }); + fi.columns = 10; + fi.emit('data', 'multi-line\ttext \t'); + assert.strictEqual(rli.cursor, 17); + assertCursorRowsAndCols(rli, 3, 2); + rli.close(); +} + +// Check for the default tab size. +{ + const [rli, fi] = getInterface({ terminal: true, prompt: '' }); + fi.emit('data', 'the quick\tbrown\tfox'); + assert.strictEqual(rli.cursor, 19); + // The first tab is 7 spaces long, the second one 3 spaces. + assertCursorRowsAndCols(rli, 0, 27); +} + +// Multi-line prompt cursor position +{ + const [rli, fi] = getInterface({ + terminal: true, + prompt: '\nfilledline\nwraping text\n> ' + }); + fi.columns = 10; + fi.emit('data', 't'); + assertCursorRowsAndCols(rli, 4, 3); + rli.close(); +} + +// Clear the whole screen +{ + const [rli, fi] = getInterface({ terminal: true, prompt: '' }); + const lines = ['line 1', 'line 2', 'line 3']; + fi.emit('data', lines.join('\n')); + fi.emit('keypress', '.', { ctrl: true, name: 'l' }); + assertCursorRowsAndCols(rli, 0, 6); + rli.on('line', common.mustCall((line) => { + assert.strictEqual(line, 'line 3'); + })); + fi.emit('data', '\n'); + rli.close(); +} + +// Wide characters should be treated as two columns. +assert.strictEqual(getStringWidth('a'), 1); +assert.strictEqual(getStringWidth('あ'), 2); +assert.strictEqual(getStringWidth('谢'), 2); +assert.strictEqual(getStringWidth('고'), 2); +assert.strictEqual(getStringWidth(String.fromCodePoint(0x1f251)), 2); +assert.strictEqual(getStringWidth('abcde'), 5); +assert.strictEqual(getStringWidth('古池や'), 6); +assert.strictEqual(getStringWidth('ノード.js'), 9); +assert.strictEqual(getStringWidth('你好'), 4); +assert.strictEqual(getStringWidth('안녕하세요'), 10); +assert.strictEqual(getStringWidth('A\ud83c\ude00BC'), 5); +assert.strictEqual(getStringWidth('👨‍👩‍👦‍👦'), 8); +assert.strictEqual(getStringWidth('🐕𐐷あ💻😀'), 9); +// TODO(BridgeAR): This should have a width of 4. +assert.strictEqual(getStringWidth('⓬⓪'), 2); +assert.strictEqual(getStringWidth('\u0301\u200D\u200E'), 0); + +// Check if vt control chars are stripped +assert.strictEqual(stripVTControlCharacters('\u001b[31m> \u001b[39m'), '> '); +assert.strictEqual( + stripVTControlCharacters('\u001b[31m> \u001b[39m> '), + '> > ' +); +assert.strictEqual(stripVTControlCharacters('\u001b[31m\u001b[39m'), ''); +assert.strictEqual(stripVTControlCharacters('> '), '> '); +assert.strictEqual(getStringWidth('\u001b[31m> \u001b[39m'), 2); +assert.strictEqual(getStringWidth('\u001b[31m> \u001b[39m> '), 4); +assert.strictEqual(getStringWidth('\u001b[31m\u001b[39m'), 0); +assert.strictEqual(getStringWidth('> '), 2); + +// FIXME(bartlomieju): this causes hang +// Check EventEmitter memory leak +// for (let i = 0; i < 12; i++) { +// const rl = readline.createInterface({ +// input: process.stdin, +// output: process.stdout +// }); +// rl.close(); +// assert.strictEqual(isWarned(process.stdin._events), false); +// assert.strictEqual(isWarned(process.stdout._events), false); +// } + +[true, false].forEach((terminal) => { + // Disable history + { + const [rli, fi] = getInterface({ terminal, historySize: 0 }); + assert.strictEqual(rli.historySize, 0); + + fi.emit('data', 'asdf\n'); + assert.deepStrictEqual(rli.history, []); + rli.close(); + } + + // Default history size 30 + { + const [rli, fi] = getInterface({ terminal }); + assert.strictEqual(rli.historySize, 30); + + fi.emit('data', 'asdf\n'); + assert.deepStrictEqual(rli.history, terminal ? ['asdf'] : []); + rli.close(); + } + + // Sending a full line + { + const [rli, fi] = getInterface({ terminal }); + rli.on('line', common.mustCall((line) => { + assert.strictEqual(line, 'asdf'); + })); + fi.emit('data', 'asdf\n'); + } + + // Sending a blank line + { + const [rli, fi] = getInterface({ terminal }); + rli.on('line', common.mustCall((line) => { + assert.strictEqual(line, ''); + })); + fi.emit('data', '\n'); + } + + // Sending a single character with no newline and then a newline + { + const [rli, fi] = getInterface({ terminal }); + let called = false; + rli.on('line', (line) => { + called = true; + assert.strictEqual(line, 'a'); + }); + fi.emit('data', 'a'); + assert.ok(!called); + fi.emit('data', '\n'); + assert.ok(called); + rli.close(); + } + + // Sending multiple newlines at once + { + const [rli, fi] = getInterface({ terminal }); + const expectedLines = ['foo', 'bar', 'baz']; + rli.on('line', common.mustCall((line) => { + assert.strictEqual(line, expectedLines.shift()); + }, expectedLines.length)); + fi.emit('data', `${expectedLines.join('\n')}\n`); + rli.close(); + } + + // Sending multiple newlines at once that does not end with a new line + { + const [rli, fi] = getInterface({ terminal }); + const expectedLines = ['foo', 'bar', 'baz', 'bat']; + rli.on('line', common.mustCall((line) => { + assert.strictEqual(line, expectedLines.shift()); + }, expectedLines.length - 1)); + fi.emit('data', expectedLines.join('\n')); + rli.close(); + } + + // Sending multiple newlines at once that does not end with a new(empty) + // line and a `end` event + { + const [rli, fi] = getInterface({ terminal }); + const expectedLines = ['foo', 'bar', 'baz', '']; + rli.on('line', common.mustCall((line) => { + assert.strictEqual(line, expectedLines.shift()); + }, expectedLines.length - 1)); + rli.on('close', common.mustCall()); + fi.emit('data', expectedLines.join('\n')); + fi.emit('end'); + rli.close(); + } + + // Sending a multi-byte utf8 char over multiple writes + { + const buf = Buffer.from('☮', 'utf8'); + const [rli, fi] = getInterface({ terminal }); + let callCount = 0; + rli.on('line', (line) => { + callCount++; + assert.strictEqual(line, buf.toString('utf8')); + }); + for (const i of buf) { + fi.emit('data', Buffer.from([i])); + } + assert.strictEqual(callCount, 0); + fi.emit('data', '\n'); + assert.strictEqual(callCount, 1); + rli.close(); + } + + // Calling readline without `new` + { + const [rli, fi] = getInterface({ terminal }); + rli.on('line', common.mustCall((line) => { + assert.strictEqual(line, 'asdf'); + })); + fi.emit('data', 'asdf\n'); + rli.close(); + } + + // Calling the question callback + { + const [rli] = getInterface({ terminal }); + rli.question('foo?', common.mustCall((answer) => { + assert.strictEqual(answer, 'bar'); + })); + rli.write('bar\n'); + rli.close(); + } + + // Calling the question multiple times + { + const [rli] = getInterface({ terminal }); + rli.question('foo?', common.mustCall((answer) => { + assert.strictEqual(answer, 'baz'); + })); + rli.question('bar?', common.mustNotCall(() => { + })); + rli.write('baz\n'); + rli.close(); + } + + // Calling the promisified question + { + const [rli] = getInterface({ terminal }); + const question = util.promisify(rli.question).bind(rli); + question('foo?') + .then(common.mustCall((answer) => { + assert.strictEqual(answer, 'bar'); + })); + rli.write('bar\n'); + rli.close(); + } + + // Aborting a question + { + const ac = new AbortController(); + const signal = ac.signal; + const [rli] = getInterface({ terminal }); + rli.on('line', common.mustCall((line) => { + assert.strictEqual(line, 'bar'); + })); + rli.question('hello?', { signal }, common.mustNotCall()); + ac.abort(); + rli.write('bar\n'); + rli.close(); + } + + // Aborting a promisified question + { + const ac = new AbortController(); + const signal = ac.signal; + const [rli] = getInterface({ terminal }); + const question = util.promisify(rli.question).bind(rli); + rli.on('line', common.mustCall((line) => { + assert.strictEqual(line, 'bar'); + })); + question('hello?', { signal }) + .then(common.mustNotCall()) + .catch(common.mustCall((error) => { + assert.strictEqual(error.name, 'AbortError'); + })); + ac.abort(); + rli.write('bar\n'); + rli.close(); + } + + // pre-aborted signal + { + const signal = AbortSignal.abort(); + const [rli] = getInterface({ terminal }); + rli.pause(); + rli.on('resume', common.mustNotCall()); + rli.question('hello?', { signal }, common.mustNotCall()); + rli.close(); + } + + // pre-aborted signal promisified question + { + const signal = AbortSignal.abort(); + const [rli] = getInterface({ terminal }); + const question = util.promisify(rli.question).bind(rli); + rli.on('resume', common.mustNotCall()); + rli.pause(); + question('hello?', { signal }) + .then(common.mustNotCall()) + .catch(common.mustCall((error) => { + assert.strictEqual(error.name, 'AbortError'); + })); + rli.close(); + } + + // Can create a new readline Interface with a null output argument + { + const [rli, fi] = getInterface({ output: null, terminal }); + rli.on('line', common.mustCall((line) => { + assert.strictEqual(line, 'asdf'); + })); + fi.emit('data', 'asdf\n'); + + rli.setPrompt('ddd> '); + rli.prompt(); + rli.write("really shouldn't be seeing this"); + rli.question('What do you think of node.js? ', (answer) => { + console.log('Thank you for your valuable feedback:', answer); + rli.close(); + }); + } + + // Calling the getPrompt method + { + const expectedPrompts = ['$ ', '> ']; + const [rli] = getInterface({ terminal }); + for (const prompt of expectedPrompts) { + rli.setPrompt(prompt); + assert.strictEqual(rli.getPrompt(), prompt); + } + } + + { + const expected = terminal ? + ['\u001b[1G', '\u001b[0J', '$ ', '\u001b[3G'] : + ['$ ']; + + const output = new Writable({ + write: common.mustCall((chunk, enc, cb) => { + assert.strictEqual(chunk.toString(), expected.shift()); + cb(); + rl.close(); + }, expected.length) + }); + + const rl = readline.createInterface({ + input: new Readable({ read: common.mustCall() }), + output, + prompt: '$ ', + terminal + }); + + rl.prompt(); + + assert.strictEqual(rl.getPrompt(), '$ '); + } + + { + const fi = new FakeInput(); + assert.deepStrictEqual(fi.listeners(terminal ? 'keypress' : 'data'), []); + } + + // Emit two line events when the delay + // between \r and \n exceeds crlfDelay + { + const crlfDelay = 200; + const [rli, fi] = getInterface({ terminal, crlfDelay }); + let callCount = 0; + rli.on('line', () => { + callCount++; + }); + fi.emit('data', '\r'); + setTimeout(common.mustCall(() => { + fi.emit('data', '\n'); + assert.strictEqual(callCount, 2); + rli.close(); + }), crlfDelay + 10); + } + + // For the purposes of the following tests, we do not care about the exact + // value of crlfDelay, only that the behaviour conforms to what's expected. + // Setting it to Infinity allows the test to succeed even under extreme + // CPU stress. + const crlfDelay = Infinity; + + // Set crlfDelay to `Infinity` is allowed + { + const delay = 200; + const [rli, fi] = getInterface({ terminal, crlfDelay }); + let callCount = 0; + rli.on('line', () => { + callCount++; + }); + fi.emit('data', '\r'); + setTimeout(common.mustCall(() => { + fi.emit('data', '\n'); + assert.strictEqual(callCount, 1); + rli.close(); + }), delay); + } + + // Sending multiple newlines at once that does not end with a new line + // and a `end` event(last line is) + + // \r\n should emit one line event, not two + { + const [rli, fi] = getInterface({ terminal, crlfDelay }); + const expectedLines = ['foo', 'bar', 'baz', 'bat']; + rli.on('line', common.mustCall((line) => { + assert.strictEqual(line, expectedLines.shift()); + }, expectedLines.length - 1)); + fi.emit('data', expectedLines.join('\r\n')); + rli.close(); + } + + // \r\n should emit one line event when split across multiple writes. + { + const [rli, fi] = getInterface({ terminal, crlfDelay }); + const expectedLines = ['foo', 'bar', 'baz', 'bat']; + let callCount = 0; + rli.on('line', common.mustCall((line) => { + assert.strictEqual(line, expectedLines[callCount]); + callCount++; + }, expectedLines.length)); + expectedLines.forEach((line) => { + fi.emit('data', `${line}\r`); + fi.emit('data', '\n'); + }); + rli.close(); + } + + // Emit one line event when the delay between \r and \n is + // over the default crlfDelay but within the setting value. + { + const delay = 125; + const [rli, fi] = getInterface({ terminal, crlfDelay }); + let callCount = 0; + rli.on('line', () => callCount++); + fi.emit('data', '\r'); + setTimeout(common.mustCall(() => { + fi.emit('data', '\n'); + assert.strictEqual(callCount, 1); + rli.close(); + }), delay); + } +}); + +// Ensure that the _wordLeft method works even for large input +{ + const input = new Readable({ + read() { + this.push('\x1B[1;5D'); // CTRL + Left + this.push(null); + }, + }); + const output = new Writable({ + write: common.mustCall((data, encoding, cb) => { + assert.strictEqual(rl.cursor, rl.line.length - 1); + cb(); + }), + }); + const rl = new readline.createInterface({ + input, + output, + terminal: true, + }); + rl.line = `a${' '.repeat(1e6)}a`; + rl.cursor = rl.line.length; +} + +// FIXME(bartlomieju): these tests depend on "event_target" module +// { +// const fi = new FakeInput(); +// const signal = AbortSignal.abort(); + +// const rl = readline.createInterface({ +// input: fi, +// output: fi, +// signal, +// }); +// rl.on('close', common.mustCall()); +// assert.strictEqual(getEventListeners(signal, 'abort').length, 0); +// } + +// { +// const fi = new FakeInput(); +// const ac = new AbortController(); +// const { signal } = ac; +// const rl = readline.createInterface({ +// input: fi, +// output: fi, +// signal, +// }); +// assert.strictEqual(getEventListeners(signal, 'abort').length, 1); +// rl.on('close', common.mustCall()); +// ac.abort(); +// assert.strictEqual(getEventListeners(signal, 'abort').length, 0); +// } + +// { +// const fi = new FakeInput(); +// const ac = new AbortController(); +// const { signal } = ac; +// const rl = readline.createInterface({ +// input: fi, +// output: fi, +// signal, +// }); +// assert.strictEqual(getEventListeners(signal, 'abort').length, 1); +// rl.close(); +// assert.strictEqual(getEventListeners(signal, 'abort').length, 0); +// } + +{ + // Constructor throws if signal is not an abort signal + assert.throws(() => { + readline.createInterface({ + input: new FakeInput(), + signal: {}, + }); + }, { + name: 'TypeError', + code: 'ERR_INVALID_ARG_TYPE' + }); +} diff --git a/tests/node_compat/test/parallel/test-readline-keys.js b/tests/node_compat/test/parallel/test-readline-keys.js new file mode 100644 index 000000000..aeeb5fffc --- /dev/null +++ b/tests/node_compat/test/parallel/test-readline-keys.js @@ -0,0 +1,351 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const PassThrough = require('stream').PassThrough; +const assert = require('assert'); +const Interface = require('readline').Interface; + +class FakeInput extends PassThrough {} + +function extend(k) { + return Object.assign({ ctrl: false, meta: false, shift: false }, k); +} + + +const fi = new FakeInput(); +const fo = new FakeInput(); +new Interface({ input: fi, output: fo, terminal: true }); + +let keys = []; +fi.on('keypress', (s, k) => { + keys.push(k); +}); + + +function addTest(sequences, expectedKeys) { + if (!Array.isArray(sequences)) { + sequences = [ sequences ]; + } + + if (!Array.isArray(expectedKeys)) { + expectedKeys = [ expectedKeys ]; + } + + expectedKeys = expectedKeys.map(extend); + + keys = []; + + sequences.forEach((sequence) => { + fi.write(sequence); + }); + assert.deepStrictEqual(keys, expectedKeys); +} + +// Simulate key interval test cases +// Returns a function that takes `next` test case and returns a thunk +// that can be called to run tests in sequence +// e.g. +// addKeyIntervalTest(..) +// (addKeyIntervalTest(..) +// (addKeyIntervalTest(..)(noop)))() +// where noop is a terminal function(() => {}). + +const addKeyIntervalTest = (sequences, expectedKeys, interval = 550, + assertDelay = 550) => { + const fn = common.mustCall((next) => () => { + + if (!Array.isArray(sequences)) { + sequences = [ sequences ]; + } + + if (!Array.isArray(expectedKeys)) { + expectedKeys = [ expectedKeys ]; + } + + expectedKeys = expectedKeys.map(extend); + + const keys = []; + fi.on('keypress', (s, k) => keys.push(k)); + + const emitKeys = ([head, ...tail]) => { + if (head) { + fi.write(head); + setTimeout(() => emitKeys(tail), interval); + } else { + setTimeout(() => { + next(); + assert.deepStrictEqual(keys, expectedKeys); + }, assertDelay); + } + }; + emitKeys(sequences); + }); + return fn; +}; + +// Regular alphanumerics +addTest('io.JS', [ + { name: 'i', sequence: 'i' }, + { name: 'o', sequence: 'o' }, + { name: undefined, sequence: '.' }, + { name: 'j', sequence: 'J', shift: true }, + { name: 's', sequence: 'S', shift: true }, +]); + +// Named characters +addTest('\n\r\t\x1b\n\x1b\r\x1b\t', [ + { name: 'enter', sequence: '\n' }, + { name: 'return', sequence: '\r' }, + { name: 'tab', sequence: '\t' }, + { name: 'enter', sequence: '\x1b\n', meta: true }, + { name: 'return', sequence: '\x1b\r', meta: true }, + { name: 'tab', sequence: '\x1b\t', meta: true }, +]); + +// Space and backspace +addTest('\b\x7f\x1b\b\x1b\x7f\x1b\x1b \x1b ', [ + { name: 'backspace', sequence: '\b' }, + { name: 'backspace', sequence: '\x7f' }, + { name: 'backspace', sequence: '\x1b\b', meta: true }, + { name: 'backspace', sequence: '\x1b\x7f', meta: true }, + { name: 'space', sequence: '\x1b\x1b ', meta: true }, + { name: 'space', sequence: ' ' }, + { name: 'space', sequence: '\x1b ', meta: true }, +]); + +// Escape key +addTest('\x1b\x1b\x1b', [ + { name: 'escape', sequence: '\x1b\x1b\x1b', meta: true }, +]); + +// Escape sequence +addTest('\x1b]', [{ name: undefined, sequence: '\x1B]', meta: true }]); + +// Control keys +addTest('\x01\x0b\x10', [ + { name: 'a', sequence: '\x01', ctrl: true }, + { name: 'k', sequence: '\x0b', ctrl: true }, + { name: 'p', sequence: '\x10', ctrl: true }, +]); + +// Alt keys +addTest('a\x1baA\x1bA', [ + { name: 'a', sequence: 'a' }, + { name: 'a', sequence: '\x1ba', meta: true }, + { name: 'a', sequence: 'A', shift: true }, + { name: 'a', sequence: '\x1bA', meta: true, shift: true }, +]); + +// xterm/gnome ESC [ letter (with modifiers) +addTest('\x1b[2P\x1b[3P\x1b[4P\x1b[5P\x1b[6P\x1b[7P\x1b[8P\x1b[3Q\x1b[8Q\x1b[3R\x1b[8R\x1b[3S\x1b[8S', [ + { name: 'f1', sequence: '\x1b[2P', code: '[P', shift: true, meta: false, ctrl: false }, + { name: 'f1', sequence: '\x1b[3P', code: '[P', shift: false, meta: true, ctrl: false }, + { name: 'f1', sequence: '\x1b[4P', code: '[P', shift: true, meta: true, ctrl: false }, + { name: 'f1', sequence: '\x1b[5P', code: '[P', shift: false, meta: false, ctrl: true }, + { name: 'f1', sequence: '\x1b[6P', code: '[P', shift: true, meta: false, ctrl: true }, + { name: 'f1', sequence: '\x1b[7P', code: '[P', shift: false, meta: true, ctrl: true }, + { name: 'f1', sequence: '\x1b[8P', code: '[P', shift: true, meta: true, ctrl: true }, + { name: 'f2', sequence: '\x1b[3Q', code: '[Q', meta: true }, + { name: 'f2', sequence: '\x1b[8Q', code: '[Q', shift: true, meta: true, ctrl: true }, + { name: 'f3', sequence: '\x1b[3R', code: '[R', meta: true }, + { name: 'f3', sequence: '\x1b[8R', code: '[R', shift: true, meta: true, ctrl: true }, + { name: 'f4', sequence: '\x1b[3S', code: '[S', meta: true }, + { name: 'f4', sequence: '\x1b[8S', code: '[S', shift: true, meta: true, ctrl: true }, +]); + +// xterm/gnome ESC O letter +addTest('\x1bOP\x1bOQ\x1bOR\x1bOS', [ + { name: 'f1', sequence: '\x1bOP', code: 'OP' }, + { name: 'f2', sequence: '\x1bOQ', code: 'OQ' }, + { name: 'f3', sequence: '\x1bOR', code: 'OR' }, + { name: 'f4', sequence: '\x1bOS', code: 'OS' }, +]); + +// xterm/rxvt ESC [ number ~ */ +addTest('\x1b[11~\x1b[12~\x1b[13~\x1b[14~', [ + { name: 'f1', sequence: '\x1b[11~', code: '[11~' }, + { name: 'f2', sequence: '\x1b[12~', code: '[12~' }, + { name: 'f3', sequence: '\x1b[13~', code: '[13~' }, + { name: 'f4', sequence: '\x1b[14~', code: '[14~' }, +]); + +// From Cygwin and used in libuv +addTest('\x1b[[A\x1b[[B\x1b[[C\x1b[[D\x1b[[E', [ + { name: 'f1', sequence: '\x1b[[A', code: '[[A' }, + { name: 'f2', sequence: '\x1b[[B', code: '[[B' }, + { name: 'f3', sequence: '\x1b[[C', code: '[[C' }, + { name: 'f4', sequence: '\x1b[[D', code: '[[D' }, + { name: 'f5', sequence: '\x1b[[E', code: '[[E' }, +]); + +// Common +addTest('\x1b[15~\x1b[17~\x1b[18~\x1b[19~\x1b[20~\x1b[21~\x1b[23~\x1b[24~', [ + { name: 'f5', sequence: '\x1b[15~', code: '[15~' }, + { name: 'f6', sequence: '\x1b[17~', code: '[17~' }, + { name: 'f7', sequence: '\x1b[18~', code: '[18~' }, + { name: 'f8', sequence: '\x1b[19~', code: '[19~' }, + { name: 'f9', sequence: '\x1b[20~', code: '[20~' }, + { name: 'f10', sequence: '\x1b[21~', code: '[21~' }, + { name: 'f11', sequence: '\x1b[23~', code: '[23~' }, + { name: 'f12', sequence: '\x1b[24~', code: '[24~' }, +]); + +// xterm ESC [ letter +addTest('\x1b[A\x1b[B\x1b[C\x1b[D\x1b[E\x1b[F\x1b[H', [ + { name: 'up', sequence: '\x1b[A', code: '[A' }, + { name: 'down', sequence: '\x1b[B', code: '[B' }, + { name: 'right', sequence: '\x1b[C', code: '[C' }, + { name: 'left', sequence: '\x1b[D', code: '[D' }, + { name: 'clear', sequence: '\x1b[E', code: '[E' }, + { name: 'end', sequence: '\x1b[F', code: '[F' }, + { name: 'home', sequence: '\x1b[H', code: '[H' }, +]); + +// xterm/gnome ESC O letter +addTest('\x1bOA\x1bOB\x1bOC\x1bOD\x1bOE\x1bOF\x1bOH', [ + { name: 'up', sequence: '\x1bOA', code: 'OA' }, + { name: 'down', sequence: '\x1bOB', code: 'OB' }, + { name: 'right', sequence: '\x1bOC', code: 'OC' }, + { name: 'left', sequence: '\x1bOD', code: 'OD' }, + { name: 'clear', sequence: '\x1bOE', code: 'OE' }, + { name: 'end', sequence: '\x1bOF', code: 'OF' }, + { name: 'home', sequence: '\x1bOH', code: 'OH' }, +]); + +// Old xterm shift-arrows +addTest('\x1bO2A\x1bO2B', [ + { name: 'up', sequence: '\x1bO2A', code: 'OA', shift: true }, + { name: 'down', sequence: '\x1bO2B', code: 'OB', shift: true }, +]); + +// xterm/rxvt ESC [ number ~ +addTest('\x1b[1~\x1b[2~\x1b[3~\x1b[4~\x1b[5~\x1b[6~', [ + { name: 'home', sequence: '\x1b[1~', code: '[1~' }, + { name: 'insert', sequence: '\x1b[2~', code: '[2~' }, + { name: 'delete', sequence: '\x1b[3~', code: '[3~' }, + { name: 'end', sequence: '\x1b[4~', code: '[4~' }, + { name: 'pageup', sequence: '\x1b[5~', code: '[5~' }, + { name: 'pagedown', sequence: '\x1b[6~', code: '[6~' }, +]); + +// putty +addTest('\x1b[[5~\x1b[[6~', [ + { name: 'pageup', sequence: '\x1b[[5~', code: '[[5~' }, + { name: 'pagedown', sequence: '\x1b[[6~', code: '[[6~' }, +]); + +// rxvt +addTest('\x1b[7~\x1b[8~', [ + { name: 'home', sequence: '\x1b[7~', code: '[7~' }, + { name: 'end', sequence: '\x1b[8~', code: '[8~' }, +]); + +// gnome terminal +addTest('\x1b[A\x1b[B\x1b[2A\x1b[2B', [ + { name: 'up', sequence: '\x1b[A', code: '[A' }, + { name: 'down', sequence: '\x1b[B', code: '[B' }, + { name: 'up', sequence: '\x1b[2A', code: '[A', shift: true }, + { name: 'down', sequence: '\x1b[2B', code: '[B', shift: true }, +]); + +// `rxvt` keys with modifiers. +addTest('\x1b[20~\x1b[2$\x1b[2^\x1b[3$\x1b[3^\x1b[5$\x1b[5^\x1b[6$\x1b[6^\x1b[7$\x1b[7^\x1b[8$\x1b[8^', [ + { name: 'f9', sequence: '\x1b[20~', code: '[20~' }, + { name: 'insert', sequence: '\x1b[2$', code: '[2$', shift: true }, + { name: 'insert', sequence: '\x1b[2^', code: '[2^', ctrl: true }, + { name: 'delete', sequence: '\x1b[3$', code: '[3$', shift: true }, + { name: 'delete', sequence: '\x1b[3^', code: '[3^', ctrl: true }, + { name: 'pageup', sequence: '\x1b[5$', code: '[5$', shift: true }, + { name: 'pageup', sequence: '\x1b[5^', code: '[5^', ctrl: true }, + { name: 'pagedown', sequence: '\x1b[6$', code: '[6$', shift: true }, + { name: 'pagedown', sequence: '\x1b[6^', code: '[6^', ctrl: true }, + { name: 'home', sequence: '\x1b[7$', code: '[7$', shift: true }, + { name: 'home', sequence: '\x1b[7^', code: '[7^', ctrl: true }, + { name: 'end', sequence: '\x1b[8$', code: '[8$', shift: true }, + { name: 'end', sequence: '\x1b[8^', code: '[8^', ctrl: true }, +]); + +// Misc +addTest('\x1b[Z', [ + { name: 'tab', sequence: '\x1b[Z', code: '[Z', shift: true }, +]); + +// xterm + modifiers +addTest('\x1b[20;5~\x1b[6;5^', [ + { name: 'f9', sequence: '\x1b[20;5~', code: '[20~', ctrl: true }, + { name: 'pagedown', sequence: '\x1b[6;5^', code: '[6^', ctrl: true }, +]); + +addTest('\x1b[H\x1b[5H\x1b[1;5H', [ + { name: 'home', sequence: '\x1b[H', code: '[H' }, + { name: 'home', sequence: '\x1b[5H', code: '[H', ctrl: true }, + { name: 'home', sequence: '\x1b[1;5H', code: '[H', ctrl: true }, +]); + +// Escape sequences broken into multiple data chunks +addTest('\x1b[D\x1b[C\x1b[D\x1b[C'.split(''), [ + { name: 'left', sequence: '\x1b[D', code: '[D' }, + { name: 'right', sequence: '\x1b[C', code: '[C' }, + { name: 'left', sequence: '\x1b[D', code: '[D' }, + { name: 'right', sequence: '\x1b[C', code: '[C' }, +]); + +// Escape sequences mixed with regular ones +addTest('\x1b[DD\x1b[2DD\x1b[2^D', [ + { name: 'left', sequence: '\x1b[D', code: '[D' }, + { name: 'd', sequence: 'D', shift: true }, + { name: 'left', sequence: '\x1b[2D', code: '[D', shift: true }, + { name: 'd', sequence: 'D', shift: true }, + { name: 'insert', sequence: '\x1b[2^', code: '[2^', ctrl: true }, + { name: 'd', sequence: 'D', shift: true }, +]); + +// Color sequences +addTest('\x1b[31ma\x1b[39ma', [ + { name: 'undefined', sequence: '\x1b[31m', code: '[31m' }, + { name: 'a', sequence: 'a' }, + { name: 'undefined', sequence: '\x1b[39m', code: '[39m' }, + { name: 'a', sequence: 'a' }, +]); + +// `rxvt` keys with modifiers. +addTest('\x1b[a\x1b[b\x1b[c\x1b[d\x1b[e', [ + { name: 'up', sequence: '\x1b[a', code: '[a', shift: true }, + { name: 'down', sequence: '\x1b[b', code: '[b', shift: true }, + { name: 'right', sequence: '\x1b[c', code: '[c', shift: true }, + { name: 'left', sequence: '\x1b[d', code: '[d', shift: true }, + { name: 'clear', sequence: '\x1b[e', code: '[e', shift: true }, +]); + +addTest('\x1bOa\x1bOb\x1bOc\x1bOd\x1bOe', [ + { name: 'up', sequence: '\x1bOa', code: 'Oa', ctrl: true }, + { name: 'down', sequence: '\x1bOb', code: 'Ob', ctrl: true }, + { name: 'right', sequence: '\x1bOc', code: 'Oc', ctrl: true }, + { name: 'left', sequence: '\x1bOd', code: 'Od', ctrl: true }, + { name: 'clear', sequence: '\x1bOe', code: 'Oe', ctrl: true }, +]); + +// Reduce array of addKeyIntervalTest(..) right to left +// with () => {} as initial function. +const runKeyIntervalTests = [ + // Escape character + addKeyIntervalTest('\x1b', [ + { name: 'escape', sequence: '\x1b', meta: true }, + ]), + // Chain of escape characters. + addKeyIntervalTest('\x1b\x1b\x1b\x1b'.split(''), [ + { name: 'escape', sequence: '\x1b', meta: true }, + { name: 'escape', sequence: '\x1b', meta: true }, + { name: 'escape', sequence: '\x1b', meta: true }, + { name: 'escape', sequence: '\x1b', meta: true }, + ]), +].reverse().reduce((acc, fn) => fn(acc), () => {}); + +// Run key interval tests one after another. +runKeyIntervalTests(); diff --git a/tests/node_compat/test/parallel/test-readline-position.js b/tests/node_compat/test/parallel/test-readline-position.js new file mode 100644 index 000000000..5ee445c8e --- /dev/null +++ b/tests/node_compat/test/parallel/test-readline-position.js @@ -0,0 +1,43 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Flags: --expose-internals +'use strict'; +const common = require('../common'); +const { PassThrough } = require('stream'); +const readline = require('readline'); +const assert = require('assert'); + +const ctrlU = { ctrl: true, name: 'u' }; + +common.skipIfDumbTerminal(); + +{ + const input = new PassThrough(); + const rl = readline.createInterface({ + terminal: true, + input: input, + prompt: '' + }); + + const tests = [ + [1, 'a'], + [2, 'ab'], + [2, '丁'], + [0, '\u0301'], // COMBINING ACUTE ACCENT + [1, 'a\u0301'], // á + [0, '\u20DD'], // COMBINING ENCLOSING CIRCLE + [2, 'a\u20DDb'], // a⃝b + [0, '\u200E'], // LEFT-TO-RIGHT MARK + ]; + + for (const [cursor, string] of tests) { + rl.write(string); + assert.strictEqual(rl.getCursorPos().cols, cursor); + rl.write(null, ctrlU); + } +} diff --git a/tests/node_compat/test/parallel/test-readline-reopen.js b/tests/node_compat/test/parallel/test-readline-reopen.js new file mode 100644 index 000000000..6d3207220 --- /dev/null +++ b/tests/node_compat/test/parallel/test-readline-reopen.js @@ -0,0 +1,51 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +// Regression test for https://github.com/nodejs/node/issues/13557 +// Tests that multiple subsequent readline instances can re-use an input stream. + +const common = require('../common'); +const assert = require('assert'); +const readline = require('readline'); +const { PassThrough } = require('stream'); + +const input = new PassThrough(); +const output = new PassThrough(); + +const rl1 = readline.createInterface({ + input, + output, + terminal: true +}); + +rl1.on('line', common.mustCall(rl1OnLine)); + +// Write a line plus the first byte of a UTF-8 multibyte character to make sure +// that it doesn’t get lost when closing the readline instance. +input.write(Buffer.concat([ + Buffer.from('foo\n'), + Buffer.from([ 0xe2 ]), // Exactly one third of a ☃ snowman. +])); + +function rl1OnLine(line) { + assert.strictEqual(line, 'foo'); + rl1.close(); + const rl2 = readline.createInterface({ + input, + output, + terminal: true + }); + + rl2.on('line', common.mustCall((line) => { + assert.strictEqual(line, '☃bar'); + rl2.close(); + })); + input.write(Buffer.from([0x98, 0x83])); // The rest of the ☃ snowman. + input.write('bar\n'); +} diff --git a/tests/node_compat/test/parallel/test-readline-set-raw-mode.js b/tests/node_compat/test/parallel/test-readline-set-raw-mode.js new file mode 100644 index 000000000..a1f4f743d --- /dev/null +++ b/tests/node_compat/test/parallel/test-readline-set-raw-mode.js @@ -0,0 +1,97 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const readline = require('readline'); +const Stream = require('stream'); + +const stream = new Stream(); +let expectedRawMode = true; +let rawModeCalled = false; +let resumeCalled = false; +let pauseCalled = false; + +stream.setRawMode = function(mode) { + rawModeCalled = true; + assert.strictEqual(mode, expectedRawMode); +}; +stream.resume = function() { + resumeCalled = true; +}; +stream.pause = function() { + pauseCalled = true; +}; + +// When the "readline" starts in "terminal" mode, +// then setRawMode(true) should be called +const rli = readline.createInterface({ + input: stream, + output: stream, + terminal: true +}); +assert(rli.terminal); +assert(rawModeCalled); +assert(resumeCalled); +assert(!pauseCalled); + + +// pause() should call *not* call setRawMode() +rawModeCalled = false; +resumeCalled = false; +pauseCalled = false; +rli.pause(); +assert(!rawModeCalled); +assert(!resumeCalled); +assert(pauseCalled); + + +// resume() should *not* call setRawMode() +rawModeCalled = false; +resumeCalled = false; +pauseCalled = false; +rli.resume(); +assert(!rawModeCalled); +assert(resumeCalled); +assert(!pauseCalled); + + +// close() should call setRawMode(false) +expectedRawMode = false; +rawModeCalled = false; +resumeCalled = false; +pauseCalled = false; +rli.close(); +assert(rawModeCalled); +assert(!resumeCalled); +assert(pauseCalled); + +assert.deepStrictEqual(stream.listeners('keypress'), []); +// One data listener for the keypress events. +assert.strictEqual(stream.listeners('data').length, 1); diff --git a/tests/node_compat/test/parallel/test-readline-undefined-columns.js b/tests/node_compat/test/parallel/test-readline-undefined-columns.js new file mode 100644 index 000000000..e41798ae3 --- /dev/null +++ b/tests/node_compat/test/parallel/test-readline-undefined-columns.js @@ -0,0 +1,53 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const PassThrough = require('stream').PassThrough; +const readline = require('readline'); + +common.skipIfDumbTerminal(); + +// Checks that tab completion still works +// when output column size is undefined + +const iStream = new PassThrough(); +const oStream = new PassThrough(); + +readline.createInterface({ + terminal: true, + input: iStream, + output: oStream, + completer: function(line, cb) { + cb(null, [['process.stdout', 'process.stdin', 'process.stderr'], line]); + } +}); + +let output = ''; + +oStream.on('data', function(data) { + output += data; +}); + +oStream.on('end', common.mustCall(() => { + const expect = 'process.stdout\r\n' + + 'process.stdin\r\n' + + 'process.stderr'; + assert.match(output, new RegExp(expect)); +})); + +iStream.write('process.s\t'); + +// Completion works. +assert.match(output, /process\.std\b/); +// Completion doesn’t show all results yet. +assert.doesNotMatch(output, /stdout/); + +iStream.write('\t'); +oStream.end(); diff --git a/tests/node_compat/test/parallel/test-readline.js b/tests/node_compat/test/parallel/test-readline.js new file mode 100644 index 000000000..15f1b4f0c --- /dev/null +++ b/tests/node_compat/test/parallel/test-readline.js @@ -0,0 +1,158 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const { PassThrough } = require('stream'); +const readline = require('readline'); +const assert = require('assert'); + +common.skipIfDumbTerminal(); + +{ + const input = new PassThrough(); + const rl = readline.createInterface({ + terminal: true, + input: input + }); + + rl.on('line', common.mustCall((data) => { + assert.strictEqual(data, 'abc'); + })); + + input.end('abc'); +} + +{ + const input = new PassThrough(); + const rl = readline.createInterface({ + terminal: true, + input: input + }); + + rl.on('line', common.mustNotCall('must not be called before newline')); + + input.write('abc'); +} + +{ + const input = new PassThrough(); + const rl = readline.createInterface({ + terminal: true, + input: input + }); + + rl.on('line', common.mustCall((data) => { + assert.strictEqual(data, 'abc'); + })); + + input.write('abc\n'); +} + +{ + const input = new PassThrough(); + const rl = readline.createInterface({ + terminal: true, + input: input + }); + + rl.write('foo'); + assert.strictEqual(rl.cursor, 3); + + const key = { + xterm: { + home: ['\x1b[H', { ctrl: true, name: 'a' }], + end: ['\x1b[F', { ctrl: true, name: 'e' }], + }, + gnome: { + home: ['\x1bOH', { ctrl: true, name: 'a' }], + end: ['\x1bOF', { ctrl: true, name: 'e' }] + }, + rxvt: { + home: ['\x1b[7', { ctrl: true, name: 'a' }], + end: ['\x1b[8', { ctrl: true, name: 'e' }] + }, + putty: { + home: ['\x1b[1~', { ctrl: true, name: 'a' }], + end: ['\x1b[>~', { ctrl: true, name: 'e' }] + } + }; + + [key.xterm, key.gnome, key.rxvt, key.putty].forEach(function(key) { + rl.write.apply(rl, key.home); + assert.strictEqual(rl.cursor, 0); + rl.write.apply(rl, key.end); + assert.strictEqual(rl.cursor, 3); + }); + +} + +{ + const input = new PassThrough(); + const rl = readline.createInterface({ + terminal: true, + input: input + }); + + const key = { + xterm: { + home: ['\x1b[H', { ctrl: true, name: 'a' }], + metab: ['\x1bb', { meta: true, name: 'b' }], + metaf: ['\x1bf', { meta: true, name: 'f' }], + } + }; + + rl.write('foo bar.hop/zoo'); + rl.write.apply(rl, key.xterm.home); + [ + { cursor: 4, key: key.xterm.metaf }, + { cursor: 7, key: key.xterm.metaf }, + { cursor: 8, key: key.xterm.metaf }, + { cursor: 11, key: key.xterm.metaf }, + { cursor: 12, key: key.xterm.metaf }, + { cursor: 15, key: key.xterm.metaf }, + { cursor: 12, key: key.xterm.metab }, + { cursor: 11, key: key.xterm.metab }, + { cursor: 8, key: key.xterm.metab }, + { cursor: 7, key: key.xterm.metab }, + { cursor: 4, key: key.xterm.metab }, + { cursor: 0, key: key.xterm.metab }, + ].forEach(function(action) { + rl.write.apply(rl, action.key); + assert.strictEqual(rl.cursor, action.cursor); + }); +} + +{ + const input = new PassThrough(); + const rl = readline.createInterface({ + terminal: true, + input: input + }); + + const key = { + xterm: { + home: ['\x1b[H', { ctrl: true, name: 'a' }], + metad: ['\x1bd', { meta: true, name: 'd' }] + } + }; + + rl.write('foo bar.hop/zoo'); + rl.write.apply(rl, key.xterm.home); + [ + 'bar.hop/zoo', + '.hop/zoo', + 'hop/zoo', + '/zoo', + 'zoo', + '', + ].forEach(function(expectedLine) { + rl.write.apply(rl, key.xterm.metad); + assert.strictEqual(rl.cursor, 0); + assert.strictEqual(rl.line, expectedLine); + }); +} diff --git a/tests/node_compat/test/parallel/test-stdin-from-file-spawn.js b/tests/node_compat/test/parallel/test-stdin-from-file-spawn.js new file mode 100644 index 000000000..2f6b41898 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stdin-from-file-spawn.js @@ -0,0 +1,52 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.8.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// TODO(cjihrig): 'run -A runner.ts' should not be needed in +// execSync() call at the bottom of this test. + +'use strict'; +const common = require('../common'); +const process = require('process'); + +let defaultShell; +if (process.platform === 'linux' || process.platform === 'darwin') { + defaultShell = '/bin/sh'; +} else if (process.platform === 'win32') { + defaultShell = 'cmd.exe'; +} else { + common.skip('This is test exists only on Linux/Win32/OSX'); +} + +const { execSync } = require('child_process'); +const fs = require('fs'); +const path = require('path'); +const tmpdir = require('../common/tmpdir'); + +const tmpDir = tmpdir.path; +tmpdir.refresh(); +const tmpCmdFile = path.join(tmpDir, 'test-stdin-from-file-spawn-cmd'); +const tmpJsFile = path.join(tmpDir, 'test-stdin-from-file-spawn.js'); +fs.writeFileSync(tmpCmdFile, 'echo hello'); +fs.writeFileSync(tmpJsFile, ` +'use strict'; +const { spawn } = require('child_process'); +// Reference the object to invoke the getter +process.stdin; +setTimeout(() => { + let ok = false; + const child = spawn(process.env.SHELL || '${defaultShell}', + [], { stdio: ['inherit', 'pipe'] }); + child.stdout.on('data', () => { + ok = true; + }); + child.on('close', () => { + process.exit(ok ? 0 : -1); + }); +}, 100); +`); + +execSync(`${process.argv[0]} run -A runner.ts ${tmpJsFile} < ${tmpCmdFile}`); diff --git a/tests/node_compat/test/parallel/test-stream-add-abort-signal.js b/tests/node_compat/test/parallel/test-stream-add-abort-signal.js new file mode 100644 index 000000000..cf598b547 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-add-abort-signal.js @@ -0,0 +1,34 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Flags: --expose-internals +'use strict'; + +require('../common'); +const assert = require('assert'); +const { addAbortSignal, Readable } = require('stream'); +const { + addAbortSignalNoValidate, +} = require('internal/streams/add-abort-signal'); + +{ + assert.throws(() => { + addAbortSignal('INVALID_SIGNAL'); + }, /ERR_INVALID_ARG_TYPE/); + + const ac = new AbortController(); + assert.throws(() => { + addAbortSignal(ac.signal, 'INVALID_STREAM'); + }, /ERR_INVALID_ARG_TYPE/); +} + +{ + const r = new Readable({ + read: () => {}, + }); + assert.deepStrictEqual(r, addAbortSignalNoValidate('INVALID_SIGNAL', r)); +} diff --git a/tests/node_compat/test/parallel/test-stream-aliases-legacy.js b/tests/node_compat/test/parallel/test-stream-aliases-legacy.js new file mode 100644 index 000000000..e0af8bb47 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-aliases-legacy.js @@ -0,0 +1,21 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); + +const assert = require('assert'); +const stream = require('stream'); + +// Verify that all individual aliases are left in place. + +assert.strictEqual(stream.Readable, require('_stream_readable')); +assert.strictEqual(stream.Writable, require('_stream_writable')); +assert.strictEqual(stream.Duplex, require('_stream_duplex')); +assert.strictEqual(stream.Transform, require('_stream_transform')); +assert.strictEqual(stream.PassThrough, require('_stream_passthrough')); diff --git a/tests/node_compat/test/parallel/test-stream-auto-destroy.js b/tests/node_compat/test/parallel/test-stream-auto-destroy.js new file mode 100644 index 000000000..a0947ba39 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-auto-destroy.js @@ -0,0 +1,119 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const stream = require('stream'); +const assert = require('assert'); + +{ + const r = new stream.Readable({ + autoDestroy: true, + read() { + this.push('hello'); + this.push('world'); + this.push(null); + }, + destroy: common.mustCall((err, cb) => cb()) + }); + + let ended = false; + + r.resume(); + + r.on('end', common.mustCall(() => { + ended = true; + })); + + r.on('close', common.mustCall(() => { + assert(ended); + })); +} + +{ + const w = new stream.Writable({ + autoDestroy: true, + write(data, enc, cb) { + cb(null); + }, + destroy: common.mustCall((err, cb) => cb()) + }); + + let finished = false; + + w.write('hello'); + w.write('world'); + w.end(); + + w.on('finish', common.mustCall(() => { + finished = true; + })); + + w.on('close', common.mustCall(() => { + assert(finished); + })); +} + +{ + const t = new stream.Transform({ + autoDestroy: true, + transform(data, enc, cb) { + cb(null, data); + }, + destroy: common.mustCall((err, cb) => cb()) + }); + + let ended = false; + let finished = false; + + t.write('hello'); + t.write('world'); + t.end(); + + t.resume(); + + t.on('end', common.mustCall(() => { + ended = true; + })); + + t.on('finish', common.mustCall(() => { + finished = true; + })); + + t.on('close', common.mustCall(() => { + assert(ended); + assert(finished); + })); +} + +{ + const r = new stream.Readable({ + read() { + r2.emit('error', new Error('fail')); + } + }); + const r2 = new stream.Readable({ + autoDestroy: true, + destroy: common.mustCall((err, cb) => cb()) + }); + + r.pipe(r2); +} + +{ + const r = new stream.Readable({ + read() { + w.emit('error', new Error('fail')); + } + }); + const w = new stream.Writable({ + autoDestroy: true, + destroy: common.mustCall((err, cb) => cb()) + }); + + r.pipe(w); +} diff --git a/tests/node_compat/test/parallel/test-stream-await-drain-writers-in-synchronously-recursion-write.js b/tests/node_compat/test/parallel/test-stream-await-drain-writers-in-synchronously-recursion-write.js new file mode 100644 index 000000000..84095dbf1 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-await-drain-writers-in-synchronously-recursion-write.js @@ -0,0 +1,35 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const { PassThrough } = require('stream'); + +const encode = new PassThrough({ + highWaterMark: 1 +}); + +const decode = new PassThrough({ + highWaterMark: 1 +}); + +const send = common.mustCall((buf) => { + encode.write(buf); +}, 4); + +let i = 0; +const onData = common.mustCall(() => { + if (++i === 2) { + send(Buffer.from([0x3])); + send(Buffer.from([0x4])); + } +}, 4); + +encode.pipe(decode).on('data', onData); + +send(Buffer.from([0x1])); +send(Buffer.from([0x2])); diff --git a/tests/node_compat/test/parallel/test-stream-backpressure.js b/tests/node_compat/test/parallel/test-stream-backpressure.js new file mode 100644 index 000000000..f1e14bb5d --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-backpressure.js @@ -0,0 +1,46 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const stream = require('stream'); + +let pushes = 0; +const total = 65500 + 40 * 1024; +const rs = new stream.Readable({ + read: common.mustCall(function() { + if (pushes++ === 10) { + this.push(null); + return; + } + + const length = this._readableState.length; + + // We are at most doing two full runs of _reads + // before stopping, because Readable is greedy + // to keep its buffer full + assert(length <= total); + + this.push(Buffer.alloc(65500)); + for (let i = 0; i < 40; i++) { + this.push(Buffer.alloc(1024)); + } + + // We will be over highWaterMark at this point + // but a new call to _read is scheduled anyway. + }, 11) +}); + +const ws = stream.Writable({ + write: common.mustCall(function(data, enc, cb) { + setImmediate(cb); + }, 41 * 10) +}); + +rs.pipe(ws); diff --git a/tests/node_compat/test/parallel/test-stream-big-packet.js b/tests/node_compat/test/parallel/test-stream-big-packet.js new file mode 100644 index 000000000..4e816cc2d --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-big-packet.js @@ -0,0 +1,72 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const stream = require('stream'); + +let passed = false; + +class TestStream extends stream.Transform { + _transform(chunk, encoding, done) { + if (!passed) { + // Char 'a' only exists in the last write + passed = chunk.toString().includes('a'); + } + done(); + } +} + +const s1 = new stream.Transform({ + transform(chunk, encoding, cb) { + process.nextTick(cb, null, chunk); + } +}); +const s2 = new stream.PassThrough(); +const s3 = new TestStream(); +s1.pipe(s3); +// Don't let s2 auto close which may close s3 +s2.pipe(s3, { end: false }); + +// We must write a buffer larger than highWaterMark +const big = Buffer.alloc(s1.writableHighWaterMark + 1, 'x'); + +// Since big is larger than highWaterMark, it will be buffered internally. +assert(!s1.write(big)); +// 'tiny' is small enough to pass through internal buffer. +assert(s2.write('tiny')); + +// Write some small data in next IO loop, which will never be written to s3 +// Because 'drain' event is not emitted from s1 and s1 is still paused +setImmediate(s1.write.bind(s1), 'later'); + +// Assert after two IO loops when all operations have been done. +process.on('exit', function() { + assert(passed, 'Large buffer is not handled properly by Writable Stream'); +}); diff --git a/tests/node_compat/test/parallel/test-stream-big-push.js b/tests/node_compat/test/parallel/test-stream-big-push.js new file mode 100644 index 000000000..2e6d01fe2 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-big-push.js @@ -0,0 +1,81 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const stream = require('stream'); +const str = 'asdfasdfasdfasdfasdf'; + +const r = new stream.Readable({ + highWaterMark: 5, + encoding: 'utf8' +}); + +let reads = 0; + +function _read() { + if (reads === 0) { + setTimeout(() => { + r.push(str); + }, 1); + reads++; + } else if (reads === 1) { + const ret = r.push(str); + assert.strictEqual(ret, false); + reads++; + } else { + r.push(null); + } +} + +r._read = common.mustCall(_read, 3); + +r.on('end', common.mustCall()); + +// Push some data in to start. +// We've never gotten any read event at this point. +const ret = r.push(str); +// Should be false. > hwm +assert(!ret); +let chunk = r.read(); +assert.strictEqual(chunk, str); +chunk = r.read(); +assert.strictEqual(chunk, null); + +r.once('readable', () => { + // This time, we'll get *all* the remaining data, because + // it's been added synchronously, as the read WOULD take + // us below the hwm, and so it triggered a _read() again, + // which synchronously added more, which we then return. + chunk = r.read(); + assert.strictEqual(chunk, str + str); + + chunk = r.read(); + assert.strictEqual(chunk, null); +}); diff --git a/tests/node_compat/test/parallel/test-stream-buffer-list.js b/tests/node_compat/test/parallel/test-stream-buffer-list.js new file mode 100644 index 000000000..7b16f5d83 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-buffer-list.js @@ -0,0 +1,91 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Flags: --expose-internals +'use strict'; +require('../common'); +const assert = require('assert'); +const BufferList = require('internal/streams/buffer_list'); + +// Test empty buffer list. +const emptyList = new BufferList(); + +emptyList.shift(); +assert.deepStrictEqual(emptyList, new BufferList()); + +assert.strictEqual(emptyList.join(','), ''); + +assert.deepStrictEqual(emptyList.concat(0), Buffer.alloc(0)); + +const buf = Buffer.from('foo'); + +function testIterator(list, count) { + // test iterator + let len = 0; + // eslint-disable-next-line no-unused-vars + for (const x of list) { + len++; + } + assert.strictEqual(len, count); +} + +// Test buffer list with one element. +const list = new BufferList(); +testIterator(list, 0); + +list.push(buf); +testIterator(list, 1); +for (const x of list) { + assert.strictEqual(x, buf); +} + +const copy = list.concat(3); +testIterator(copy, 3); + +assert.notStrictEqual(copy, buf); +assert.deepStrictEqual(copy, buf); + +assert.strictEqual(list.join(','), 'foo'); + +const shifted = list.shift(); +testIterator(list, 0); +assert.strictEqual(shifted, buf); +assert.deepStrictEqual(list, new BufferList()); + +{ + const list = new BufferList(); + list.push('foo'); + list.push('bar'); + list.push('foo'); + list.push('bar'); + assert.strictEqual(list.consume(6, true), 'foobar'); + assert.strictEqual(list.consume(6, true), 'foobar'); +} + +{ + const list = new BufferList(); + list.push('foo'); + list.push('bar'); + assert.strictEqual(list.consume(5, true), 'fooba'); +} + +{ + const list = new BufferList(); + list.push(buf); + list.push(buf); + list.push(buf); + list.push(buf); + assert.strictEqual(list.consume(6).toString(), 'foofoo'); + assert.strictEqual(list.consume(6).toString(), 'foofoo'); +} + +{ + const list = new BufferList(); + list.push(buf); + list.push(buf); + assert.strictEqual(list.consume(5).toString(), 'foofo'); +} diff --git a/tests/node_compat/test/parallel/test-stream-construct.js b/tests/node_compat/test/parallel/test-stream-construct.js new file mode 100644 index 000000000..0cd93c9e9 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-construct.js @@ -0,0 +1,287 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const { Writable, Readable, Duplex } = require('stream'); +const assert = require('assert'); + +{ + // Multiple callback. + new Writable({ + construct: common.mustCall((callback) => { + callback(); + callback(); + }) + }).on('error', common.expectsError({ + name: 'Error', + code: 'ERR_MULTIPLE_CALLBACK' + })); +} + +{ + // Multiple callback. + new Readable({ + construct: common.mustCall((callback) => { + callback(); + callback(); + }) + }).on('error', common.expectsError({ + name: 'Error', + code: 'ERR_MULTIPLE_CALLBACK' + })); +} + +{ + // Synchronous error. + + new Writable({ + construct: common.mustCall((callback) => { + callback(new Error('test')); + }) + }).on('error', common.expectsError({ + name: 'Error', + message: 'test' + })); +} + +{ + // Synchronous error. + + new Readable({ + construct: common.mustCall((callback) => { + callback(new Error('test')); + }) + }).on('error', common.expectsError({ + name: 'Error', + message: 'test' + })); +} + +{ + // Asynchronous error. + + new Writable({ + construct: common.mustCall((callback) => { + process.nextTick(callback, new Error('test')); + }) + }).on('error', common.expectsError({ + name: 'Error', + message: 'test' + })); +} + +{ + // Asynchronous error. + + new Readable({ + construct: common.mustCall((callback) => { + process.nextTick(callback, new Error('test')); + }) + }).on('error', common.expectsError({ + name: 'Error', + message: 'test' + })); +} + +function testDestroy(factory) { + { + let constructed = false; + const s = factory({ + construct: common.mustCall((cb) => { + constructed = true; + process.nextTick(cb); + }) + }); + s.on('close', common.mustCall(() => { + assert.strictEqual(constructed, true); + })); + s.destroy(); + } + + { + let constructed = false; + const s = factory({ + construct: common.mustCall((cb) => { + constructed = true; + process.nextTick(cb); + }) + }); + s.on('close', common.mustCall(() => { + assert.strictEqual(constructed, true); + })); + s.destroy(null, () => { + assert.strictEqual(constructed, true); + }); + } + + { + let constructed = false; + const s = factory({ + construct: common.mustCall((cb) => { + constructed = true; + process.nextTick(cb); + }) + }); + s.on('close', common.mustCall(() => { + assert.strictEqual(constructed, true); + })); + s.destroy(); + } + + + { + let constructed = false; + const s = factory({ + construct: common.mustCall((cb) => { + constructed = true; + process.nextTick(cb); + }) + }); + s.on('close', common.mustCall(() => { + assert.strictEqual(constructed, true); + })); + s.on('error', common.mustCall((err) => { + assert.strictEqual(err.message, 'kaboom'); + })); + s.destroy(new Error('kaboom'), (err) => { + assert.strictEqual(err.message, 'kaboom'); + assert.strictEqual(constructed, true); + }); + } + + { + let constructed = false; + const s = factory({ + construct: common.mustCall((cb) => { + constructed = true; + process.nextTick(cb); + }) + }); + s.on('error', common.mustCall(() => { + assert.strictEqual(constructed, true); + })); + s.on('close', common.mustCall(() => { + assert.strictEqual(constructed, true); + })); + s.destroy(new Error()); + } +} +testDestroy((opts) => new Readable({ + read: common.mustNotCall(), + ...opts +})); +testDestroy((opts) => new Writable({ + write: common.mustNotCall(), + final: common.mustNotCall(), + ...opts +})); + +{ + let constructed = false; + const r = new Readable({ + autoDestroy: true, + construct: common.mustCall((cb) => { + constructed = true; + process.nextTick(cb); + }), + read: common.mustCall(() => { + assert.strictEqual(constructed, true); + r.push(null); + }) + }); + r.on('close', common.mustCall(() => { + assert.strictEqual(constructed, true); + })); + r.on('data', common.mustNotCall()); +} + +{ + let constructed = false; + const w = new Writable({ + autoDestroy: true, + construct: common.mustCall((cb) => { + constructed = true; + process.nextTick(cb); + }), + write: common.mustCall((chunk, encoding, cb) => { + assert.strictEqual(constructed, true); + process.nextTick(cb); + }), + final: common.mustCall((cb) => { + assert.strictEqual(constructed, true); + process.nextTick(cb); + }) + }); + w.on('close', common.mustCall(() => { + assert.strictEqual(constructed, true); + })); + w.end('data'); +} + +{ + let constructed = false; + const w = new Writable({ + autoDestroy: true, + construct: common.mustCall((cb) => { + constructed = true; + process.nextTick(cb); + }), + write: common.mustNotCall(), + final: common.mustCall((cb) => { + assert.strictEqual(constructed, true); + process.nextTick(cb); + }) + }); + w.on('close', common.mustCall(() => { + assert.strictEqual(constructed, true); + })); + w.end(); +} + +{ + new Duplex({ + construct: common.mustCall() + }); +} + +{ + // https://github.com/nodejs/node/issues/34448 + + let constructed = false; + const d = new Duplex({ + readable: false, + construct: common.mustCall((callback) => { + setImmediate(common.mustCall(() => { + constructed = true; + callback(); + })); + }), + write(chunk, encoding, callback) { + callback(); + }, + read() { + this.push(null); + } + }); + d.resume(); + d.end('foo'); + d.on('close', common.mustCall(() => { + assert.strictEqual(constructed, true); + })); +} + +{ + // Construct should not cause stream to read. + new Readable({ + construct: common.mustCall((callback) => { + callback(); + }), + read: common.mustNotCall() + }); +} diff --git a/tests/node_compat/test/parallel/test-stream-destroy-event-order.js b/tests/node_compat/test/parallel/test-stream-destroy-event-order.js new file mode 100644 index 000000000..09802b2a3 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-destroy-event-order.js @@ -0,0 +1,31 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const { Readable } = require('stream'); + +const rs = new Readable({ + read() {} +}); + +let closed = false; +let errored = false; + +rs.on('close', common.mustCall(() => { + closed = true; + assert(errored); +})); + +rs.on('error', common.mustCall((err) => { + errored = true; + assert(!closed); +})); + +rs.destroy(new Error('kaboom')); diff --git a/tests/node_compat/test/parallel/test-stream-duplex-destroy.js b/tests/node_compat/test/parallel/test-stream-duplex-destroy.js new file mode 100644 index 000000000..73cf75fe3 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-duplex-destroy.js @@ -0,0 +1,264 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const { Duplex } = require('stream'); +const assert = require('assert'); + +{ + const duplex = new Duplex({ + write(chunk, enc, cb) { cb(); }, + read() {} + }); + + duplex.resume(); + + duplex.on('end', common.mustNotCall()); + duplex.on('finish', common.mustNotCall()); + duplex.on('close', common.mustCall()); + + duplex.destroy(); + assert.strictEqual(duplex.destroyed, true); +} + +{ + const duplex = new Duplex({ + write(chunk, enc, cb) { cb(); }, + read() {} + }); + duplex.resume(); + + const expected = new Error('kaboom'); + + duplex.on('end', common.mustNotCall()); + duplex.on('finish', common.mustNotCall()); + duplex.on('error', common.mustCall((err) => { + assert.strictEqual(err, expected); + })); + + duplex.destroy(expected); + assert.strictEqual(duplex.destroyed, true); +} + +{ + const duplex = new Duplex({ + write(chunk, enc, cb) { cb(); }, + read() {} + }); + + duplex._destroy = common.mustCall(function(err, cb) { + assert.strictEqual(err, expected); + cb(err); + }); + + const expected = new Error('kaboom'); + + duplex.on('finish', common.mustNotCall('no finish event')); + duplex.on('error', common.mustCall((err) => { + assert.strictEqual(err, expected); + })); + + duplex.destroy(expected); + assert.strictEqual(duplex.destroyed, true); +} + +{ + const expected = new Error('kaboom'); + const duplex = new Duplex({ + write(chunk, enc, cb) { cb(); }, + read() {}, + destroy: common.mustCall(function(err, cb) { + assert.strictEqual(err, expected); + cb(); + }) + }); + duplex.resume(); + + duplex.on('end', common.mustNotCall('no end event')); + duplex.on('finish', common.mustNotCall('no finish event')); + + // Error is swallowed by the custom _destroy + duplex.on('error', common.mustNotCall('no error event')); + duplex.on('close', common.mustCall()); + + duplex.destroy(expected); + assert.strictEqual(duplex.destroyed, true); +} + +{ + const duplex = new Duplex({ + write(chunk, enc, cb) { cb(); }, + read() {} + }); + + duplex._destroy = common.mustCall(function(err, cb) { + assert.strictEqual(err, null); + cb(); + }); + + duplex.destroy(); + assert.strictEqual(duplex.destroyed, true); +} + +{ + const duplex = new Duplex({ + write(chunk, enc, cb) { cb(); }, + read() {} + }); + duplex.resume(); + + duplex._destroy = common.mustCall(function(err, cb) { + assert.strictEqual(err, null); + process.nextTick(() => { + this.push(null); + this.end(); + cb(); + }); + }); + + const fail = common.mustNotCall('no finish or end event'); + + duplex.on('finish', fail); + duplex.on('end', fail); + + duplex.destroy(); + + duplex.removeListener('end', fail); + duplex.removeListener('finish', fail); + duplex.on('end', common.mustNotCall()); + duplex.on('finish', common.mustNotCall()); + assert.strictEqual(duplex.destroyed, true); +} + +{ + const duplex = new Duplex({ + write(chunk, enc, cb) { cb(); }, + read() {} + }); + + const expected = new Error('kaboom'); + + duplex._destroy = common.mustCall(function(err, cb) { + assert.strictEqual(err, null); + cb(expected); + }); + + duplex.on('finish', common.mustNotCall('no finish event')); + duplex.on('end', common.mustNotCall('no end event')); + duplex.on('error', common.mustCall((err) => { + assert.strictEqual(err, expected); + })); + + duplex.destroy(); + assert.strictEqual(duplex.destroyed, true); +} + +{ + const duplex = new Duplex({ + write(chunk, enc, cb) { cb(); }, + read() {}, + allowHalfOpen: true + }); + duplex.resume(); + + duplex.on('finish', common.mustNotCall()); + duplex.on('end', common.mustNotCall()); + + duplex.destroy(); + assert.strictEqual(duplex.destroyed, true); +} + +{ + const duplex = new Duplex({ + write(chunk, enc, cb) { cb(); }, + read() {}, + }); + + duplex.destroyed = true; + assert.strictEqual(duplex.destroyed, true); + + // The internal destroy() mechanism should not be triggered + duplex.on('finish', common.mustNotCall()); + duplex.on('end', common.mustNotCall()); + duplex.destroy(); +} + +{ + function MyDuplex() { + assert.strictEqual(this.destroyed, false); + this.destroyed = false; + Duplex.call(this); + } + + Object.setPrototypeOf(MyDuplex.prototype, Duplex.prototype); + Object.setPrototypeOf(MyDuplex, Duplex); + + new MyDuplex(); +} + +{ + const duplex = new Duplex({ + writable: false, + autoDestroy: true, + write(chunk, enc, cb) { cb(); }, + read() {}, + }); + duplex.push(null); + duplex.resume(); + duplex.on('close', common.mustCall()); +} + +{ + const duplex = new Duplex({ + readable: false, + autoDestroy: true, + write(chunk, enc, cb) { cb(); }, + read() {}, + }); + duplex.end(); + duplex.on('close', common.mustCall()); +} + +{ + const duplex = new Duplex({ + allowHalfOpen: false, + autoDestroy: true, + write(chunk, enc, cb) { cb(); }, + read() {}, + }); + duplex.push(null); + duplex.resume(); + const orgEnd = duplex.end; + duplex.end = common.mustNotCall(); + duplex.on('end', () => { + // Ensure end() is called in next tick to allow + // any pending writes to be invoked first. + process.nextTick(() => { + duplex.end = common.mustCall(orgEnd); + }); + }); + duplex.on('close', common.mustCall()); +} +{ + // Check abort signal + const controller = new AbortController(); + const { signal } = controller; + const duplex = new Duplex({ + write(chunk, enc, cb) { cb(); }, + read() {}, + signal, + }); + let count = 0; + duplex.on('error', common.mustCall((e) => { + assert.strictEqual(count++, 0); // Ensure not called twice + assert.strictEqual(e.name, 'AbortError'); + })); + duplex.on('close', common.mustCall()); + controller.abort(); +} diff --git a/tests/node_compat/test/parallel/test-stream-duplex-end.js b/tests/node_compat/test/parallel/test-stream-duplex-end.js new file mode 100644 index 000000000..b6d95a448 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-duplex-end.js @@ -0,0 +1,48 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const Duplex = require('stream').Duplex; + +{ + const stream = new Duplex({ + read() {} + }); + assert.strictEqual(stream.allowHalfOpen, true); + stream.on('finish', common.mustNotCall()); + assert.strictEqual(stream.listenerCount('end'), 0); + stream.resume(); + stream.push(null); +} + +{ + const stream = new Duplex({ + read() {}, + allowHalfOpen: false + }); + assert.strictEqual(stream.allowHalfOpen, false); + stream.on('finish', common.mustCall()); + assert.strictEqual(stream.listenerCount('end'), 0); + stream.resume(); + stream.push(null); +} + +{ + const stream = new Duplex({ + read() {}, + allowHalfOpen: false + }); + assert.strictEqual(stream.allowHalfOpen, false); + stream._writableState.ended = true; + stream.on('finish', common.mustNotCall()); + assert.strictEqual(stream.listenerCount('end'), 0); + stream.resume(); + stream.push(null); +} diff --git a/tests/node_compat/test/parallel/test-stream-duplex-from.js b/tests/node_compat/test/parallel/test-stream-duplex-from.js new file mode 100644 index 000000000..c91a040c5 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-duplex-from.js @@ -0,0 +1,413 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const { Duplex, Readable, Writable, pipeline, PassThrough } = require('stream'); +const { ReadableStream, WritableStream } = require('stream/web'); +const { Blob } = require('buffer'); + +{ + const d = Duplex.from({ + readable: new Readable({ + read() { + this.push('asd'); + this.push(null); + } + }) + }); + assert.strictEqual(d.readable, true); + assert.strictEqual(d.writable, false); + d.once('readable', common.mustCall(function() { + assert.strictEqual(d.read().toString(), 'asd'); + })); + d.once('end', common.mustCall(function() { + assert.strictEqual(d.readable, false); + })); +} + +{ + const d = Duplex.from(new Readable({ + read() { + this.push('asd'); + this.push(null); + } + })); + assert.strictEqual(d.readable, true); + assert.strictEqual(d.writable, false); + d.once('readable', common.mustCall(function() { + assert.strictEqual(d.read().toString(), 'asd'); + })); + d.once('end', common.mustCall(function() { + assert.strictEqual(d.readable, false); + })); +} + +{ + let ret = ''; + const d = Duplex.from(new Writable({ + write(chunk, encoding, callback) { + ret += chunk; + callback(); + } + })); + assert.strictEqual(d.readable, false); + assert.strictEqual(d.writable, true); + d.end('asd'); + d.on('finish', common.mustCall(function() { + assert.strictEqual(d.writable, false); + assert.strictEqual(ret, 'asd'); + })); +} + +{ + let ret = ''; + const d = Duplex.from({ + writable: new Writable({ + write(chunk, encoding, callback) { + ret += chunk; + callback(); + } + }) + }); + assert.strictEqual(d.readable, false); + assert.strictEqual(d.writable, true); + d.end('asd'); + d.on('finish', common.mustCall(function() { + assert.strictEqual(d.writable, false); + assert.strictEqual(ret, 'asd'); + })); +} + +{ + let ret = ''; + const d = Duplex.from({ + readable: new Readable({ + read() { + this.push('asd'); + this.push(null); + } + }), + writable: new Writable({ + write(chunk, encoding, callback) { + ret += chunk; + callback(); + } + }) + }); + assert.strictEqual(d.readable, true); + assert.strictEqual(d.writable, true); + d.once('readable', common.mustCall(function() { + assert.strictEqual(d.read().toString(), 'asd'); + })); + d.once('end', common.mustCall(function() { + assert.strictEqual(d.readable, false); + })); + d.end('asd'); + d.once('finish', common.mustCall(function() { + assert.strictEqual(d.writable, false); + assert.strictEqual(ret, 'asd'); + })); +} + +{ + const d = Duplex.from(Promise.resolve('asd')); + assert.strictEqual(d.readable, true); + assert.strictEqual(d.writable, false); + d.once('readable', common.mustCall(function() { + assert.strictEqual(d.read().toString(), 'asd'); + })); + d.once('end', common.mustCall(function() { + assert.strictEqual(d.readable, false); + })); +} + +{ + // https://github.com/nodejs/node/issues/40497 + pipeline( + ['abc\ndef\nghi'], + Duplex.from(async function * (source) { + let rest = ''; + for await (const chunk of source) { + const lines = (rest + chunk.toString()).split('\n'); + rest = lines.pop(); + for (const line of lines) { + yield line; + } + } + yield rest; + }), + async function * (source) { // eslint-disable-line require-yield + let ret = ''; + for await (const x of source) { + ret += x; + } + assert.strictEqual(ret, 'abcdefghi'); + }, + common.mustSucceed(), + ); +} + +// Ensure that isDuplexNodeStream was called +{ + const duplex = new Duplex(); + assert.strictEqual(Duplex.from(duplex), duplex); +} + +// Ensure that Duplex.from works for blobs +{ + const blob = new Blob(['blob']); + const expectedByteLength = blob.size; + const duplex = Duplex.from(blob); + duplex.on('data', common.mustCall((arrayBuffer) => { + assert.strictEqual(arrayBuffer.byteLength, expectedByteLength); + })); +} + +// Ensure that given a promise rejection it emits an error +{ + const myErrorMessage = 'myCustomError'; + Duplex.from(Promise.reject(myErrorMessage)) + .on('error', common.mustCall((error) => { + assert.strictEqual(error, myErrorMessage); + })); +} + +// Ensure that given a promise rejection on an async function it emits an error +{ + const myErrorMessage = 'myCustomError'; + async function asyncFn() { + return Promise.reject(myErrorMessage); + } + + Duplex.from(asyncFn) + .on('error', common.mustCall((error) => { + assert.strictEqual(error, myErrorMessage); + })); +} + +// Ensure that Duplex.from throws an Invalid return value when function is void +{ + assert.throws(() => Duplex.from(() => {}), { + code: 'ERR_INVALID_RETURN_VALUE', + }); +} + +// Ensure data if a sub object has a readable stream it's duplexified +{ + const msg = Buffer.from('hello'); + const duplex = Duplex.from({ + readable: Readable({ + read() { + this.push(msg); + this.push(null); + } + }) + }).on('data', common.mustCall((data) => { + assert.strictEqual(data, msg); + })); + + assert.strictEqual(duplex.writable, false); +} + +// Ensure data if a sub object has a writable stream it's duplexified +{ + const msg = Buffer.from('hello'); + const duplex = Duplex.from({ + writable: Writable({ + write: common.mustCall((data) => { + assert.strictEqual(data, msg); + }) + }) + }); + + duplex.write(msg); + assert.strictEqual(duplex.readable, false); +} + +// Ensure data if a sub object has a writable and readable stream it's duplexified +{ + const msg = Buffer.from('hello'); + + const duplex = Duplex.from({ + readable: Readable({ + read() { + this.push(msg); + this.push(null); + } + }), + writable: Writable({ + write: common.mustCall((data) => { + assert.strictEqual(data, msg); + }) + }) + }); + + duplex.pipe(duplex) + .on('data', common.mustCall((data) => { + assert.strictEqual(data, msg); + assert.strictEqual(duplex.readable, true); + assert.strictEqual(duplex.writable, true); + })) + .on('end', common.mustCall()); +} + +// Ensure that given readable stream that throws an error it calls destroy +{ + const myErrorMessage = 'error!'; + const duplex = Duplex.from(Readable({ + read() { + throw new Error(myErrorMessage); + } + })); + duplex.on('error', common.mustCall((msg) => { + assert.strictEqual(msg.message, myErrorMessage); + })); +} + +// Ensure that given writable stream that throws an error it calls destroy +{ + const myErrorMessage = 'error!'; + const duplex = Duplex.from(Writable({ + write(chunk, enc, cb) { + cb(myErrorMessage); + } + })); + + duplex.on('error', common.mustCall((msg) => { + assert.strictEqual(msg, myErrorMessage); + })); + + duplex.write('test'); +} + +{ + const through = new PassThrough({ objectMode: true }); + + let res = ''; + const d = Readable.from(['foo', 'bar'], { objectMode: true }) + .pipe(Duplex.from({ + writable: through, + readable: through + })); + + d.on('data', (data) => { + d.pause(); + setImmediate(() => { + d.resume(); + }); + res += data; + }).on('end', common.mustCall(() => { + assert.strictEqual(res, 'foobar'); + })).on('close', common.mustCall()); +} + +function makeATestReadableStream(value) { + return new ReadableStream({ + start(controller) { + controller.enqueue(value); + controller.close(); + } + }); +} + +function makeATestWritableStream(writeFunc) { + return new WritableStream({ + write(chunk) { + writeFunc(chunk); + } + }); +} + +{ + const d = Duplex.from({ + readable: makeATestReadableStream('foo'), + }); + assert.strictEqual(d.readable, true); + assert.strictEqual(d.writable, false); + + d.on('data', common.mustCall((data) => { + assert.strictEqual(data.toString(), 'foo'); + })); + + d.on('end', common.mustCall(() => { + assert.strictEqual(d.readable, false); + })); +} + +{ + const d = Duplex.from(makeATestReadableStream('foo')); + + assert.strictEqual(d.readable, true); + assert.strictEqual(d.writable, false); + + d.on('data', common.mustCall((data) => { + assert.strictEqual(data.toString(), 'foo'); + })); + + d.on('end', common.mustCall(() => { + assert.strictEqual(d.readable, false); + })); +} + +/* +TODO(kt3k): Enable this test case +{ + let ret = ''; + const d = Duplex.from({ + writable: makeATestWritableStream((chunk) => ret += chunk), + }); + + assert.strictEqual(d.readable, false); + assert.strictEqual(d.writable, true); + + d.end('foo'); + d.on('finish', common.mustCall(() => { + assert.strictEqual(ret, 'foo'); + assert.strictEqual(d.writable, false); + })); +} + +{ + let ret = ''; + const d = Duplex.from(makeATestWritableStream((chunk) => ret += chunk)); + + assert.strictEqual(d.readable, false); + assert.strictEqual(d.writable, true); + + d.end('foo'); + d.on('finish', common.mustCall(() => { + assert.strictEqual(ret, 'foo'); + assert.strictEqual(d.writable, false); + })); +} + +{ + let ret = ''; + const d = Duplex.from({ + readable: makeATestReadableStream('foo'), + writable: makeATestWritableStream((chunk) => ret += chunk), + }); + + d.end('bar'); + + d.on('data', common.mustCall((data) => { + assert.strictEqual(data.toString(), 'foo'); + })); + + d.on('end', common.mustCall(() => { + assert.strictEqual(d.readable, false); + })); + + d.on('finish', common.mustCall(() => { + assert.strictEqual(ret, 'bar'); + assert.strictEqual(d.writable, false); + })); +} +*/ diff --git a/tests/node_compat/test/parallel/test-stream-duplex-props.js b/tests/node_compat/test/parallel/test-stream-duplex-props.js new file mode 100644 index 000000000..1eedc9404 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-duplex-props.js @@ -0,0 +1,38 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); +const { Duplex } = require('stream'); + +{ + const d = new Duplex({ + objectMode: true, + highWaterMark: 100 + }); + + assert.strictEqual(d.writableObjectMode, true); + assert.strictEqual(d.writableHighWaterMark, 100); + assert.strictEqual(d.readableObjectMode, true); + assert.strictEqual(d.readableHighWaterMark, 100); +} + +{ + const d = new Duplex({ + readableObjectMode: false, + readableHighWaterMark: 10, + writableObjectMode: true, + writableHighWaterMark: 100 + }); + + assert.strictEqual(d.writableObjectMode, true); + assert.strictEqual(d.writableHighWaterMark, 100); + assert.strictEqual(d.readableObjectMode, false); + assert.strictEqual(d.readableHighWaterMark, 10); +} diff --git a/tests/node_compat/test/parallel/test-stream-duplex-readable-end.js b/tests/node_compat/test/parallel/test-stream-duplex-readable-end.js new file mode 100644 index 000000000..87327814c --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-duplex-readable-end.js @@ -0,0 +1,36 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +// https://github.com/nodejs/node/issues/35926 +const common = require('../common'); +const assert = require('assert'); +const stream = require('stream'); + +let loops = 5; + +const src = new stream.Readable({ + read() { + if (loops--) + this.push(Buffer.alloc(20000)); + } +}); + +const dst = new stream.Transform({ + transform(chunk, output, fn) { + this.push(null); + fn(); + } +}); + +src.pipe(dst); + +dst.on('data', () => { }); +dst.on('end', common.mustCall(() => { + assert.strictEqual(loops, 3); + assert.ok(src.isPaused()); +})); diff --git a/tests/node_compat/test/parallel/test-stream-duplex-writable-finished.js b/tests/node_compat/test/parallel/test-stream-duplex-writable-finished.js new file mode 100644 index 000000000..c556d14ef --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-duplex-writable-finished.js @@ -0,0 +1,37 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const { Duplex } = require('stream'); +const assert = require('assert'); + +// basic +{ + // Find it on Duplex.prototype + assert(Object.hasOwn(Duplex.prototype, 'writableFinished')); +} + +// event +{ + const duplex = new Duplex(); + + duplex._write = (chunk, encoding, cb) => { + // The state finished should start in false. + assert.strictEqual(duplex.writableFinished, false); + cb(); + }; + + duplex.on('finish', common.mustCall(() => { + assert.strictEqual(duplex.writableFinished, true); + })); + + duplex.end('testing finished state', common.mustCall(() => { + assert.strictEqual(duplex.writableFinished, true); + })); +} diff --git a/tests/node_compat/test/parallel/test-stream-duplex.js b/tests/node_compat/test/parallel/test-stream-duplex.js new file mode 100644 index 000000000..d7210e49e --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-duplex.js @@ -0,0 +1,140 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const Duplex = require('stream').Duplex; +const { ReadableStream, WritableStream } = require('stream/web'); + +const stream = new Duplex({ objectMode: true }); + +assert(Duplex() instanceof Duplex); +assert(stream._readableState.objectMode); +assert(stream._writableState.objectMode); +assert(stream.allowHalfOpen); +assert.strictEqual(stream.listenerCount('end'), 0); + +let written; +let read; + +stream._write = (obj, _, cb) => { + written = obj; + cb(); +}; + +stream._read = () => {}; + +stream.on('data', (obj) => { + read = obj; +}); + +stream.push({ val: 1 }); +stream.end({ val: 2 }); + +process.on('exit', () => { + assert.strictEqual(read.val, 1); + assert.strictEqual(written.val, 2); +}); + +// Duplex.fromWeb +{ + const dataToRead = Buffer.from('hello'); + const dataToWrite = Buffer.from('world'); + + const readable = new ReadableStream({ + start(controller) { + controller.enqueue(dataToRead); + }, + }); + + const writable = new WritableStream({ + write: common.mustCall((chunk) => { + assert.strictEqual(chunk, dataToWrite); + }) + }); + + const pair = { readable, writable }; + const duplex = Duplex.fromWeb(pair); + + duplex.write(dataToWrite); + duplex.once('data', common.mustCall((chunk) => { + assert.strictEqual(chunk, dataToRead); + })); +} + +// Duplex.fromWeb - using utf8 and objectMode +{ + const dataToRead = 'hello'; + const dataToWrite = 'world'; + + const readable = new ReadableStream({ + start(controller) { + controller.enqueue(dataToRead); + }, + }); + + const writable = new WritableStream({ + write: common.mustCall((chunk) => { + assert.strictEqual(chunk, dataToWrite); + }) + }); + + const pair = { + readable, + writable + }; + const duplex = Duplex.fromWeb(pair, { encoding: 'utf8', objectMode: true }); + + duplex.write(dataToWrite); + duplex.once('data', common.mustCall((chunk) => { + assert.strictEqual(chunk, dataToRead); + })); +} +// Duplex.toWeb +{ + const dataToRead = Buffer.from('hello'); + const dataToWrite = Buffer.from('world'); + + const duplex = Duplex({ + read() { + this.push(dataToRead); + this.push(null); + }, + write: common.mustCall((chunk) => { + assert.strictEqual(chunk, dataToWrite); + }) + }); + + const { writable, readable } = Duplex.toWeb(duplex); + writable.getWriter().write(dataToWrite); + + readable.getReader().read().then(common.mustCall((result) => { + assert.deepStrictEqual(Buffer.from(result.value), dataToRead); + })); +} diff --git a/tests/node_compat/test/parallel/test-stream-end-paused.js b/tests/node_compat/test/parallel/test-stream-end-paused.js new file mode 100644 index 000000000..12c05243d --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-end-paused.js @@ -0,0 +1,57 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +// Make sure we don't miss the end event for paused 0-length streams + +const Readable = require('stream').Readable; +const stream = new Readable(); +let calledRead = false; +stream._read = function() { + assert(!calledRead); + calledRead = true; + this.push(null); +}; + +stream.on('data', function() { + throw new Error('should not ever get data'); +}); +stream.pause(); + +setTimeout(common.mustCall(function() { + stream.on('end', common.mustCall()); + stream.resume(); +}), 1); + +process.on('exit', function() { + assert(calledRead); + console.log('ok'); +}); diff --git a/tests/node_compat/test/parallel/test-stream-error-once.js b/tests/node_compat/test/parallel/test-stream-error-once.js new file mode 100644 index 000000000..592788d4f --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-error-once.js @@ -0,0 +1,26 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const { Writable, Readable } = require('stream'); + +{ + const writable = new Writable(); + writable.on('error', common.mustCall()); + writable.end(); + writable.write('h'); + writable.write('h'); +} + +{ + const readable = new Readable(); + readable.on('error', common.mustCall()); + readable.push(null); + readable.push('h'); + readable.push('h'); +} diff --git a/tests/node_compat/test/parallel/test-stream-events-prepend.js b/tests/node_compat/test/parallel/test-stream-events-prepend.js new file mode 100644 index 000000000..7245977f1 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-events-prepend.js @@ -0,0 +1,33 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const stream = require('stream'); + +class Writable extends stream.Writable { + constructor() { + super(); + this.prependListener = undefined; + } + + _write(chunk, end, cb) { + cb(); + } +} + +class Readable extends stream.Readable { + _read() { + this.push(null); + } +} + +const w = new Writable(); +w.on('pipe', common.mustCall()); + +const r = new Readable(); +r.pipe(w); diff --git a/tests/node_compat/test/parallel/test-stream-inheritance.js b/tests/node_compat/test/parallel/test-stream-inheritance.js new file mode 100644 index 000000000..296e12996 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-inheritance.js @@ -0,0 +1,70 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const assert = require('assert'); +const { Readable, Writable, Duplex, Transform } = require('stream'); + +const readable = new Readable({ read() {} }); +const writable = new Writable({ write() {} }); +const duplex = new Duplex({ read() {}, write() {} }); +const transform = new Transform({ transform() {} }); + +assert.ok(readable instanceof Readable); +assert.ok(!(writable instanceof Readable)); +assert.ok(duplex instanceof Readable); +assert.ok(transform instanceof Readable); + +assert.ok(!(readable instanceof Writable)); +assert.ok(writable instanceof Writable); +assert.ok(duplex instanceof Writable); +assert.ok(transform instanceof Writable); + +assert.ok(!(readable instanceof Duplex)); +assert.ok(!(writable instanceof Duplex)); +assert.ok(duplex instanceof Duplex); +assert.ok(transform instanceof Duplex); + +assert.ok(!(readable instanceof Transform)); +assert.ok(!(writable instanceof Transform)); +assert.ok(!(duplex instanceof Transform)); +assert.ok(transform instanceof Transform); + +assert.ok(!(null instanceof Writable)); +assert.ok(!(undefined instanceof Writable)); + +// Simple inheritance check for `Writable` works fine in a subclass constructor. +function CustomWritable() { + assert.ok( + this instanceof CustomWritable, + `${this} does not inherit from CustomWritable` + ); + assert.ok( + this instanceof Writable, + `${this} does not inherit from Writable` + ); +} + +Object.setPrototypeOf(CustomWritable, Writable); +Object.setPrototypeOf(CustomWritable.prototype, Writable.prototype); + +new CustomWritable(); + +assert.throws( + CustomWritable, + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + message: 'undefined does not inherit from CustomWritable' + } +); + +class OtherCustomWritable extends Writable {} + +assert(!(new OtherCustomWritable() instanceof CustomWritable)); +assert(!(new CustomWritable() instanceof OtherCustomWritable)); diff --git a/tests/node_compat/test/parallel/test-stream-ispaused.js b/tests/node_compat/test/parallel/test-stream-ispaused.js new file mode 100644 index 000000000..8f4897047 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-ispaused.js @@ -0,0 +1,51 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const stream = require('stream'); + +const readable = new stream.Readable(); + +// _read is a noop, here. +readable._read = Function(); + +// Default state of a stream is not "paused" +assert.ok(!readable.isPaused()); + +// Make the stream start flowing... +readable.on('data', Function()); + +// still not paused. +assert.ok(!readable.isPaused()); + +readable.pause(); +assert.ok(readable.isPaused()); +readable.resume(); +assert.ok(!readable.isPaused()); diff --git a/tests/node_compat/test/parallel/test-stream-objectmode-undefined.js b/tests/node_compat/test/parallel/test-stream-objectmode-undefined.js new file mode 100644 index 000000000..0478b0ee7 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-objectmode-undefined.js @@ -0,0 +1,51 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const { Readable, Writable, Transform } = require('stream'); + +{ + const stream = new Readable({ + objectMode: true, + read: common.mustCall(() => { + stream.push(undefined); + stream.push(null); + }) + }); + + stream.on('data', common.mustCall((chunk) => { + assert.strictEqual(chunk, undefined); + })); +} + +{ + const stream = new Writable({ + objectMode: true, + write: common.mustCall((chunk) => { + assert.strictEqual(chunk, undefined); + }) + }); + + stream.write(undefined); +} + +{ + const stream = new Transform({ + objectMode: true, + transform: common.mustCall((chunk) => { + stream.push(chunk); + }) + }); + + stream.on('data', common.mustCall((chunk) => { + assert.strictEqual(chunk, undefined); + })); + + stream.write(undefined); +} diff --git a/tests/node_compat/test/parallel/test-stream-once-readable-pipe.js b/tests/node_compat/test/parallel/test-stream-once-readable-pipe.js new file mode 100644 index 000000000..f273b9602 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-once-readable-pipe.js @@ -0,0 +1,68 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const { Readable, Writable } = require('stream'); + +// This test ensures that if have 'readable' listener +// on Readable instance it will not disrupt the pipe. + +{ + let receivedData = ''; + const w = new Writable({ + write: (chunk, env, callback) => { + receivedData += chunk; + callback(); + }, + }); + + const data = ['foo', 'bar', 'baz']; + const r = new Readable({ + read: () => {}, + }); + + r.once('readable', common.mustCall()); + + r.pipe(w); + r.push(data[0]); + r.push(data[1]); + r.push(data[2]); + r.push(null); + + w.on('finish', common.mustCall(() => { + assert.strictEqual(receivedData, data.join('')); + })); +} + +{ + let receivedData = ''; + const w = new Writable({ + write: (chunk, env, callback) => { + receivedData += chunk; + callback(); + }, + }); + + const data = ['foo', 'bar', 'baz']; + const r = new Readable({ + read: () => {}, + }); + + r.pipe(w); + r.push(data[0]); + r.push(data[1]); + r.push(data[2]); + r.push(null); + r.once('readable', common.mustCall()); + + w.on('finish', common.mustCall(() => { + assert.strictEqual(receivedData, data.join('')); + })); +} diff --git a/tests/node_compat/test/parallel/test-stream-pipe-after-end.js b/tests/node_compat/test/parallel/test-stream-pipe-after-end.js new file mode 100644 index 000000000..a7af22b94 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-pipe-after-end.js @@ -0,0 +1,76 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const { Readable, Writable } = require('stream'); + +class TestReadable extends Readable { + constructor(opt) { + super(opt); + this._ended = false; + } + + _read() { + if (this._ended) + this.emit('error', new Error('_read called twice')); + this._ended = true; + this.push(null); + } +} + +class TestWritable extends Writable { + constructor(opt) { + super(opt); + this._written = []; + } + + _write(chunk, encoding, cb) { + this._written.push(chunk); + cb(); + } +} + +// This one should not emit 'end' until we read() from it later. +const ender = new TestReadable(); + +// What happens when you pipe() a Readable that's already ended? +const piper = new TestReadable(); +// pushes EOF null, and length=0, so this will trigger 'end' +piper.read(); + +setTimeout(common.mustCall(function() { + ender.on('end', common.mustCall()); + const c = ender.read(); + assert.strictEqual(c, null); + + const w = new TestWritable(); + w.on('finish', common.mustCall()); + piper.pipe(w); +}), 1); diff --git a/tests/node_compat/test/parallel/test-stream-pipe-await-drain-manual-resume.js b/tests/node_compat/test/parallel/test-stream-pipe-await-drain-manual-resume.js new file mode 100644 index 000000000..e49c99033 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-pipe-await-drain-manual-resume.js @@ -0,0 +1,82 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const stream = require('stream'); +const assert = require('assert'); + +// A consumer stream with a very low highWaterMark, which starts in a state +// where it buffers the chunk it receives rather than indicating that they +// have been consumed. +const writable = new stream.Writable({ + highWaterMark: 5 +}); + +let isCurrentlyBufferingWrites = true; +const queue = []; + +writable._write = (chunk, encoding, cb) => { + if (isCurrentlyBufferingWrites) + queue.push({ chunk, cb }); + else + cb(); +}; + +const readable = new stream.Readable({ + read() {} +}); + +readable.pipe(writable); + +readable.once('pause', common.mustCall(() => { + assert.strictEqual( + readable._readableState.awaitDrainWriters, + writable, + 'Expected awaitDrainWriters to be a Writable but instead got ' + + `${readable._readableState.awaitDrainWriters}` + ); + // First pause, resume manually. The next write() to writable will still + // return false, because chunks are still being buffered, so it will increase + // the awaitDrain counter again. + + process.nextTick(common.mustCall(() => { + readable.resume(); + })); + + readable.once('pause', common.mustCall(() => { + assert.strictEqual( + readable._readableState.awaitDrainWriters, + writable, + '.resume() should not reset the awaitDrainWriters, but instead got ' + + `${readable._readableState.awaitDrainWriters}` + ); + // Second pause, handle all chunks from now on. Once all callbacks that + // are currently queued up are handled, the awaitDrain drain counter should + // fall back to 0 and all chunks that are pending on the readable side + // should be flushed. + isCurrentlyBufferingWrites = false; + for (const queued of queue) + queued.cb(); + })); +})); + +readable.push(Buffer.alloc(100)); // Fill the writable HWM, first 'pause'. +readable.push(Buffer.alloc(100)); // Second 'pause'. +readable.push(Buffer.alloc(100)); // Should get through to the writable. +readable.push(null); + +writable.on('finish', common.mustCall(() => { + assert.strictEqual( + readable._readableState.awaitDrainWriters, + null, + `awaitDrainWriters should be reset to null + after all chunks are written but instead got + ${readable._readableState.awaitDrainWriters}` + ); + // Everything okay, all chunks were written. +})); diff --git a/tests/node_compat/test/parallel/test-stream-pipe-await-drain-push-while-write.js b/tests/node_compat/test/parallel/test-stream-pipe-await-drain-push-while-write.js new file mode 100644 index 000000000..54fbe9e89 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-pipe-await-drain-push-while-write.js @@ -0,0 +1,43 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const stream = require('stream'); +const assert = require('assert'); + +const writable = new stream.Writable({ + write: common.mustCall(function(chunk, encoding, cb) { + assert.strictEqual( + readable._readableState.awaitDrainWriters, + null, + ); + + if (chunk.length === 32 * 1024) { // first chunk + readable.push(Buffer.alloc(34 * 1024)); // above hwm + // We should check if awaitDrain counter is increased in the next + // tick, because awaitDrain is incremented after this method finished + process.nextTick(() => { + assert.strictEqual(readable._readableState.awaitDrainWriters, writable); + }); + } + + process.nextTick(cb); + }, 3) +}); + +// A readable stream which produces two buffers. +const bufs = [Buffer.alloc(32 * 1024), Buffer.alloc(33 * 1024)]; // above hwm +const readable = new stream.Readable({ + read: function() { + while (bufs.length > 0) { + this.push(bufs.shift()); + } + } +}); + +readable.pipe(writable); diff --git a/tests/node_compat/test/parallel/test-stream-pipe-await-drain.js b/tests/node_compat/test/parallel/test-stream-pipe-await-drain.js new file mode 100644 index 000000000..49062fe0b --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-pipe-await-drain.js @@ -0,0 +1,74 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const stream = require('stream'); +const assert = require('assert'); + +// This is very similar to test-stream-pipe-cleanup-pause.js. + +const reader = new stream.Readable(); +const writer1 = new stream.Writable(); +const writer2 = new stream.Writable(); +const writer3 = new stream.Writable(); + +// 560000 is chosen here because it is larger than the (default) highWaterMark +// and will cause `.write()` to return false +// See: https://github.com/nodejs/node/issues/5820 +const buffer = Buffer.allocUnsafe(560000); + +reader._read = () => {}; + +writer1._write = common.mustCall(function(chunk, encoding, cb) { + this.emit('chunk-received'); + process.nextTick(cb); +}, 1); + +writer1.once('chunk-received', () => { + assert.strictEqual( + reader._readableState.awaitDrainWriters.size, + 0, + 'awaitDrain initial value should be 0, actual is ' + + reader._readableState.awaitDrainWriters.size + ); + setImmediate(() => { + // This one should *not* get through to writer1 because writer2 is not + // "done" processing. + reader.push(buffer); + }); +}); + +// A "slow" consumer: +writer2._write = common.mustCall((chunk, encoding, cb) => { + assert.strictEqual( + reader._readableState.awaitDrainWriters.size, + 1, + 'awaitDrain should be 1 after first push, actual is ' + + reader._readableState.awaitDrainWriters.size + ); + // Not calling cb here to "simulate" slow stream. + // This should be called exactly once, since the first .write() call + // will return false. +}, 1); + +writer3._write = common.mustCall((chunk, encoding, cb) => { + assert.strictEqual( + reader._readableState.awaitDrainWriters.size, + 2, + 'awaitDrain should be 2 after second push, actual is ' + + reader._readableState.awaitDrainWriters.size + ); + // Not calling cb here to "simulate" slow stream. + // This should be called exactly once, since the first .write() call + // will return false. +}, 1); + +reader.pipe(writer1); +reader.pipe(writer2); +reader.pipe(writer3); +reader.push(buffer); diff --git a/tests/node_compat/test/parallel/test-stream-pipe-cleanup-pause.js b/tests/node_compat/test/parallel/test-stream-pipe-cleanup-pause.js new file mode 100644 index 000000000..279ce10d5 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-pipe-cleanup-pause.js @@ -0,0 +1,44 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const stream = require('stream'); + +const reader = new stream.Readable(); +const writer1 = new stream.Writable(); +const writer2 = new stream.Writable(); + +// 560000 is chosen here because it is larger than the (default) highWaterMark +// and will cause `.write()` to return false +// See: https://github.com/nodejs/node/issues/2323 +const buffer = Buffer.allocUnsafe(560000); + +reader._read = () => {}; + +writer1._write = common.mustCall(function(chunk, encoding, cb) { + this.emit('chunk-received'); + cb(); +}, 1); +writer1.once('chunk-received', function() { + reader.unpipe(writer1); + reader.pipe(writer2); + reader.push(buffer); + setImmediate(function() { + reader.push(buffer); + setImmediate(function() { + reader.push(buffer); + }); + }); +}); + +writer2._write = common.mustCall(function(chunk, encoding, cb) { + cb(); +}, 3); + +reader.pipe(writer1); +reader.push(buffer); diff --git a/tests/node_compat/test/parallel/test-stream-pipe-cleanup.js b/tests/node_compat/test/parallel/test-stream-pipe-cleanup.js new file mode 100644 index 000000000..8106ab4f1 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-pipe-cleanup.js @@ -0,0 +1,132 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +// This test asserts that Stream.prototype.pipe does not leave listeners +// hanging on the source or dest. +require('../common'); +const stream = require('stream'); +const assert = require('assert'); + +function Writable() { + this.writable = true; + this.endCalls = 0; + stream.Stream.call(this); +} +Object.setPrototypeOf(Writable.prototype, stream.Stream.prototype); +Object.setPrototypeOf(Writable, stream.Stream); +Writable.prototype.end = function() { + this.endCalls++; +}; + +Writable.prototype.destroy = function() { + this.endCalls++; +}; + +function Readable() { + this.readable = true; + stream.Stream.call(this); +} +Object.setPrototypeOf(Readable.prototype, stream.Stream.prototype); +Object.setPrototypeOf(Readable, stream.Stream); + +function Duplex() { + this.readable = true; + Writable.call(this); +} +Object.setPrototypeOf(Duplex.prototype, Writable.prototype); +Object.setPrototypeOf(Duplex, Writable); + +let i = 0; +const limit = 100; + +let w = new Writable(); + +let r; + +for (i = 0; i < limit; i++) { + r = new Readable(); + r.pipe(w); + r.emit('end'); +} +assert.strictEqual(r.listeners('end').length, 0); +assert.strictEqual(w.endCalls, limit); + +w.endCalls = 0; + +for (i = 0; i < limit; i++) { + r = new Readable(); + r.pipe(w); + r.emit('close'); +} +assert.strictEqual(r.listeners('close').length, 0); +assert.strictEqual(w.endCalls, limit); + +w.endCalls = 0; + +r = new Readable(); + +for (i = 0; i < limit; i++) { + w = new Writable(); + r.pipe(w); + w.emit('close'); +} +assert.strictEqual(w.listeners('close').length, 0); + +r = new Readable(); +w = new Writable(); +const d = new Duplex(); +r.pipe(d); // pipeline A +d.pipe(w); // pipeline B +assert.strictEqual(r.listeners('end').length, 2); // A.onend, A.cleanup +assert.strictEqual(r.listeners('close').length, 2); // A.onclose, A.cleanup +assert.strictEqual(d.listeners('end').length, 2); // B.onend, B.cleanup +// A.cleanup, B.onclose, B.cleanup +assert.strictEqual(d.listeners('close').length, 3); +assert.strictEqual(w.listeners('end').length, 0); +assert.strictEqual(w.listeners('close').length, 1); // B.cleanup + +r.emit('end'); +assert.strictEqual(d.endCalls, 1); +assert.strictEqual(w.endCalls, 0); +assert.strictEqual(r.listeners('end').length, 0); +assert.strictEqual(r.listeners('close').length, 0); +assert.strictEqual(d.listeners('end').length, 2); // B.onend, B.cleanup +assert.strictEqual(d.listeners('close').length, 2); // B.onclose, B.cleanup +assert.strictEqual(w.listeners('end').length, 0); +assert.strictEqual(w.listeners('close').length, 1); // B.cleanup + +d.emit('end'); +assert.strictEqual(d.endCalls, 1); +assert.strictEqual(w.endCalls, 1); +assert.strictEqual(r.listeners('end').length, 0); +assert.strictEqual(r.listeners('close').length, 0); +assert.strictEqual(d.listeners('end').length, 0); +assert.strictEqual(d.listeners('close').length, 0); +assert.strictEqual(w.listeners('end').length, 0); +assert.strictEqual(w.listeners('close').length, 0); diff --git a/tests/node_compat/test/parallel/test-stream-pipe-error-handling.js b/tests/node_compat/test/parallel/test-stream-pipe-error-handling.js new file mode 100644 index 000000000..356bb1cd9 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-pipe-error-handling.js @@ -0,0 +1,131 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const { Stream, PassThrough } = require('stream'); + +{ + const source = new Stream(); + const dest = new Stream(); + + source.pipe(dest); + + let gotErr = null; + source.on('error', function(err) { + gotErr = err; + }); + + const err = new Error('This stream turned into bacon.'); + source.emit('error', err); + assert.strictEqual(gotErr, err); +} + +{ + const source = new Stream(); + const dest = new Stream(); + + source.pipe(dest); + + const err = new Error('This stream turned into bacon.'); + + let gotErr = null; + try { + source.emit('error', err); + } catch (e) { + gotErr = e; + } + + assert.strictEqual(gotErr, err); +} + +{ + const R = Stream.Readable; + const W = Stream.Writable; + + const r = new R({ autoDestroy: false }); + const w = new W({ autoDestroy: false }); + let removed = false; + + r._read = common.mustCall(function() { + setTimeout(common.mustCall(function() { + assert(removed); + assert.throws(function() { + w.emit('error', new Error('fail')); + }, /^Error: fail$/); + }), 1); + }); + + w.on('error', myOnError); + r.pipe(w); + w.removeListener('error', myOnError); + removed = true; + + function myOnError() { + throw new Error('this should not happen'); + } +} + +{ + const R = Stream.Readable; + const W = Stream.Writable; + + const r = new R(); + const w = new W(); + let removed = false; + + r._read = common.mustCall(function() { + setTimeout(common.mustCall(function() { + assert(removed); + w.emit('error', new Error('fail')); + }), 1); + }); + + w.on('error', common.mustCall()); + w._write = () => {}; + + r.pipe(w); + // Removing some OTHER random listener should not do anything + w.removeListener('error', () => {}); + removed = true; +} + +{ + const _err = new Error('this should be handled'); + const destination = new PassThrough(); + destination.once('error', common.mustCall((err) => { + assert.strictEqual(err, _err); + })); + + const stream = new Stream(); + stream + .pipe(destination); + + destination.destroy(_err); +} diff --git a/tests/node_compat/test/parallel/test-stream-pipe-event.js b/tests/node_compat/test/parallel/test-stream-pipe-event.js new file mode 100644 index 000000000..a2721c053 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-pipe-event.js @@ -0,0 +1,58 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const stream = require('stream'); +const assert = require('assert'); + +function Writable() { + this.writable = true; + stream.Stream.call(this); +} +Object.setPrototypeOf(Writable.prototype, stream.Stream.prototype); +Object.setPrototypeOf(Writable, stream.Stream); + +function Readable() { + this.readable = true; + stream.Stream.call(this); +} +Object.setPrototypeOf(Readable.prototype, stream.Stream.prototype); +Object.setPrototypeOf(Readable, stream.Stream); + +let passed = false; + +const w = new Writable(); +w.on('pipe', function(src) { + passed = true; +}); + +const r = new Readable(); +r.pipe(w); + +assert.ok(passed); diff --git a/tests/node_compat/test/parallel/test-stream-pipe-flow-after-unpipe.js b/tests/node_compat/test/parallel/test-stream-pipe-flow-after-unpipe.js new file mode 100644 index 000000000..c0b144c18 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-pipe-flow-after-unpipe.js @@ -0,0 +1,36 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const { Readable, Writable } = require('stream'); + +// Tests that calling .unpipe() un-blocks a stream that is paused because +// it is waiting on the writable side to finish a write(). + +const rs = new Readable({ + highWaterMark: 1, + // That this gets called at least 20 times is the real test here. + read: common.mustCallAtLeast(() => rs.push('foo'), 20) +}); + +const ws = new Writable({ + highWaterMark: 1, + write: common.mustCall(() => { + // Ignore the callback, this write() simply never finishes. + setImmediate(() => rs.unpipe(ws)); + }) +}); + +let chunks = 0; +rs.on('data', common.mustCallAtLeast(() => { + chunks++; + if (chunks >= 20) + rs.pause(); // Finish this test. +})); + +rs.pipe(ws); diff --git a/tests/node_compat/test/parallel/test-stream-pipe-flow.js b/tests/node_compat/test/parallel/test-stream-pipe-flow.js new file mode 100644 index 000000000..8e877312f --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-pipe-flow.js @@ -0,0 +1,97 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const { Readable, Writable, PassThrough } = require('stream'); + +{ + let ticks = 17; + + const rs = new Readable({ + objectMode: true, + read: () => { + if (ticks-- > 0) + return process.nextTick(() => rs.push({})); + rs.push({}); + rs.push(null); + } + }); + + const ws = new Writable({ + highWaterMark: 0, + objectMode: true, + write: (data, end, cb) => setImmediate(cb) + }); + + rs.on('end', common.mustCall()); + ws.on('finish', common.mustCall()); + rs.pipe(ws); +} + +{ + let missing = 8; + + const rs = new Readable({ + objectMode: true, + read: () => { + if (missing--) rs.push({}); + else rs.push(null); + } + }); + + const pt = rs + .pipe(new PassThrough({ objectMode: true, highWaterMark: 2 })) + .pipe(new PassThrough({ objectMode: true, highWaterMark: 2 })); + + pt.on('end', () => { + wrapper.push(null); + }); + + const wrapper = new Readable({ + objectMode: true, + read: () => { + process.nextTick(() => { + let data = pt.read(); + if (data === null) { + pt.once('readable', () => { + data = pt.read(); + if (data !== null) wrapper.push(data); + }); + } else { + wrapper.push(data); + } + }); + } + }); + + wrapper.resume(); + wrapper.on('end', common.mustCall()); +} + +{ + // Only register drain if there is backpressure. + const rs = new Readable({ read() {} }); + + const pt = rs + .pipe(new PassThrough({ objectMode: true, highWaterMark: 2 })); + assert.strictEqual(pt.listenerCount('drain'), 0); + pt.on('finish', () => { + assert.strictEqual(pt.listenerCount('drain'), 0); + }); + + rs.push('asd'); + assert.strictEqual(pt.listenerCount('drain'), 0); + + process.nextTick(() => { + rs.push('asd'); + assert.strictEqual(pt.listenerCount('drain'), 0); + rs.push(null); + assert.strictEqual(pt.listenerCount('drain'), 0); + }); +} diff --git a/tests/node_compat/test/parallel/test-stream-pipe-manual-resume.js b/tests/node_compat/test/parallel/test-stream-pipe-manual-resume.js new file mode 100644 index 000000000..0666e44d6 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-pipe-manual-resume.js @@ -0,0 +1,42 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const stream = require('stream'); + +function test(throwCodeInbetween) { + // Check that a pipe does not stall if .read() is called unexpectedly + // (i.e. the stream is not resumed by the pipe). + + const n = 1000; + let counter = n; + const rs = stream.Readable({ + objectMode: true, + read: common.mustCallAtLeast(() => { + if (--counter >= 0) + rs.push({ counter }); + else + rs.push(null); + }, n) + }); + + const ws = stream.Writable({ + objectMode: true, + write: common.mustCall((data, enc, cb) => { + setImmediate(cb); + }, n) + }); + + setImmediate(() => throwCodeInbetween(rs, ws)); + + rs.pipe(ws); +} + +test((rs) => rs.read()); +test((rs) => rs.resume()); +test(() => 0); diff --git a/tests/node_compat/test/parallel/test-stream-pipe-multiple-pipes.js b/tests/node_compat/test/parallel/test-stream-pipe-multiple-pipes.js new file mode 100644 index 000000000..cd24dd4ca --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-pipe-multiple-pipes.js @@ -0,0 +1,58 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const stream = require('stream'); +const assert = require('assert'); + +const readable = new stream.Readable({ + read: () => {} +}); + +const writables = []; + +for (let i = 0; i < 5; i++) { + const target = new stream.Writable({ + write: common.mustCall((chunk, encoding, callback) => { + target.output.push(chunk); + callback(); + }, 1) + }); + target.output = []; + + target.on('pipe', common.mustCall()); + readable.pipe(target); + + + writables.push(target); +} + +const input = Buffer.from([1, 2, 3, 4, 5]); + +readable.push(input); + +// The pipe() calls will postpone emission of the 'resume' event using nextTick, +// so no data will be available to the writable streams until then. +process.nextTick(common.mustCall(() => { + for (const target of writables) { + assert.deepStrictEqual(target.output, [input]); + + target.on('unpipe', common.mustCall()); + readable.unpipe(target); + } + + readable.push('something else'); // This does not get through. + readable.push(null); + readable.resume(); // Make sure the 'end' event gets emitted. +})); + +readable.on('end', common.mustCall(() => { + for (const target of writables) { + assert.deepStrictEqual(target.output, [input]); + } +})); diff --git a/tests/node_compat/test/parallel/test-stream-pipe-needDrain.js b/tests/node_compat/test/parallel/test-stream-pipe-needDrain.js new file mode 100644 index 000000000..f8b724de9 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-pipe-needDrain.js @@ -0,0 +1,38 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const { Readable, Writable } = require('stream'); + +// Pipe should pause temporarily if writable needs drain. +{ + const w = new Writable({ + write(buf, encoding, callback) { + process.nextTick(callback); + }, + highWaterMark: 1 + }); + + while (w.write('asd')); + + assert.strictEqual(w.writableNeedDrain, true); + + const r = new Readable({ + read() { + this.push('asd'); + this.push(null); + } + }); + + r.on('pause', common.mustCall(2)); + r.on('end', common.mustCall()); + + r.pipe(w); +} diff --git a/tests/node_compat/test/parallel/test-stream-pipe-same-destination-twice.js b/tests/node_compat/test/parallel/test-stream-pipe-same-destination-twice.js new file mode 100644 index 000000000..7e1215733 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-pipe-same-destination-twice.js @@ -0,0 +1,85 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); + +// Regression test for https://github.com/nodejs/node/issues/12718. +// Tests that piping a source stream twice to the same destination stream +// works, and that a subsequent unpipe() call only removes the pipe *once*. +const assert = require('assert'); +const { PassThrough, Writable } = require('stream'); + +{ + const passThrough = new PassThrough(); + const dest = new Writable({ + write: common.mustCall((chunk, encoding, cb) => { + assert.strictEqual(`${chunk}`, 'foobar'); + cb(); + }) + }); + + passThrough.pipe(dest); + passThrough.pipe(dest); + + assert.strictEqual(passThrough._events.data.length, 2); + assert.strictEqual(passThrough._readableState.pipes.length, 2); + assert.strictEqual(passThrough._readableState.pipes[0], dest); + assert.strictEqual(passThrough._readableState.pipes[1], dest); + + passThrough.unpipe(dest); + + assert.strictEqual(passThrough._events.data.length, 1); + assert.strictEqual(passThrough._readableState.pipes.length, 1); + assert.deepStrictEqual(passThrough._readableState.pipes, [dest]); + + passThrough.write('foobar'); + passThrough.pipe(dest); +} + +{ + const passThrough = new PassThrough(); + const dest = new Writable({ + write: common.mustCall((chunk, encoding, cb) => { + assert.strictEqual(`${chunk}`, 'foobar'); + cb(); + }, 2) + }); + + passThrough.pipe(dest); + passThrough.pipe(dest); + + assert.strictEqual(passThrough._events.data.length, 2); + assert.strictEqual(passThrough._readableState.pipes.length, 2); + assert.strictEqual(passThrough._readableState.pipes[0], dest); + assert.strictEqual(passThrough._readableState.pipes[1], dest); + + passThrough.write('foobar'); +} + +{ + const passThrough = new PassThrough(); + const dest = new Writable({ + write: common.mustNotCall() + }); + + passThrough.pipe(dest); + passThrough.pipe(dest); + + assert.strictEqual(passThrough._events.data.length, 2); + assert.strictEqual(passThrough._readableState.pipes.length, 2); + assert.strictEqual(passThrough._readableState.pipes[0], dest); + assert.strictEqual(passThrough._readableState.pipes[1], dest); + + passThrough.unpipe(dest); + passThrough.unpipe(dest); + + assert.strictEqual(passThrough._events.data, undefined); + assert.strictEqual(passThrough._readableState.pipes.length, 0); + + passThrough.write('foobar'); +} diff --git a/tests/node_compat/test/parallel/test-stream-pipe-unpipe-streams.js b/tests/node_compat/test/parallel/test-stream-pipe-unpipe-streams.js new file mode 100644 index 000000000..a51dcfbad --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-pipe-unpipe-streams.js @@ -0,0 +1,103 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const { Readable, Writable } = require('stream'); + +const source = Readable({ read: () => {} }); +const dest1 = Writable({ write: () => {} }); +const dest2 = Writable({ write: () => {} }); + +source.pipe(dest1); +source.pipe(dest2); + +dest1.on('unpipe', common.mustCall()); +dest2.on('unpipe', common.mustCall()); + +assert.strictEqual(source._readableState.pipes[0], dest1); +assert.strictEqual(source._readableState.pipes[1], dest2); +assert.strictEqual(source._readableState.pipes.length, 2); + +// Should be able to unpipe them in the reverse order that they were piped. + +source.unpipe(dest2); + +assert.deepStrictEqual(source._readableState.pipes, [dest1]); +assert.notStrictEqual(source._readableState.pipes, dest2); + +dest2.on('unpipe', common.mustNotCall()); +source.unpipe(dest2); + +source.unpipe(dest1); + +assert.strictEqual(source._readableState.pipes.length, 0); + +{ + // Test `cleanup()` if we unpipe all streams. + const source = Readable({ read: () => {} }); + const dest1 = Writable({ write: () => {} }); + const dest2 = Writable({ write: () => {} }); + + let destCount = 0; + const srcCheckEventNames = ['end', 'data']; + const destCheckEventNames = ['close', 'finish', 'drain', 'error', 'unpipe']; + + const checkSrcCleanup = common.mustCall(() => { + assert.strictEqual(source._readableState.pipes.length, 0); + assert.strictEqual(source._readableState.flowing, false); + + srcCheckEventNames.forEach((eventName) => { + assert.strictEqual( + source.listenerCount(eventName), 0, + `source's '${eventName}' event listeners not removed` + ); + }); + }); + + function checkDestCleanup(dest) { + const currentDestId = ++destCount; + source.pipe(dest); + + const unpipeChecker = common.mustCall(() => { + assert.deepStrictEqual( + dest.listeners('unpipe'), [unpipeChecker], + `destination{${currentDestId}} should have a 'unpipe' event ` + + 'listener which is `unpipeChecker`' + ); + dest.removeListener('unpipe', unpipeChecker); + destCheckEventNames.forEach((eventName) => { + assert.strictEqual( + dest.listenerCount(eventName), 0, + `destination{${currentDestId}}'s '${eventName}' event ` + + 'listeners not removed' + ); + }); + + if (--destCount === 0) + checkSrcCleanup(); + }); + + dest.on('unpipe', unpipeChecker); + } + + checkDestCleanup(dest1); + checkDestCleanup(dest2); + source.unpipe(); +} + +{ + const src = Readable({ read: () => {} }); + const dst = Writable({ write: () => {} }); + src.pipe(dst); + src.on('resume', common.mustCall(() => { + src.on('pause', common.mustCall()); + src.unpipe(dst); + })); +} diff --git a/tests/node_compat/test/parallel/test-stream-pipe-without-listenerCount.js b/tests/node_compat/test/parallel/test-stream-pipe-without-listenerCount.js new file mode 100644 index 000000000..7a1719be3 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-pipe-without-listenerCount.js @@ -0,0 +1,24 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const stream = require('stream'); + +const r = new stream.Stream(); +r.listenerCount = undefined; + +const w = new stream.Stream(); +w.listenerCount = undefined; + +w.on('pipe', function() { + r.emit('error', new Error('Readable Error')); + w.emit('error', new Error('Writable Error')); +}); +r.on('error', common.mustCall()); +w.on('error', common.mustCall()); +r.pipe(w); diff --git a/tests/node_compat/test/parallel/test-stream-pipeline-async-iterator.js b/tests/node_compat/test/parallel/test-stream-pipeline-async-iterator.js new file mode 100644 index 000000000..3d3ce96cc --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-pipeline-async-iterator.js @@ -0,0 +1,38 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const { Readable, PassThrough, pipeline } = require('stream'); +const assert = require('assert'); + +const _err = new Error('kaboom'); + +async function run() { + const source = new Readable({ + read() { + } + }); + source.push('hello'); + source.push('world'); + + setImmediate(() => { source.destroy(_err); }); + + const iterator = pipeline( + source, + new PassThrough(), + () => {}); + + iterator.setEncoding('utf8'); + + for await (const k of iterator) { + assert.strictEqual(k, 'helloworld'); + } +} + +run().catch(common.mustCall((err) => assert.strictEqual(err, _err))); diff --git a/tests/node_compat/test/parallel/test-stream-pipeline-queued-end-in-destroy.js b/tests/node_compat/test/parallel/test-stream-pipeline-queued-end-in-destroy.js new file mode 100644 index 000000000..e785a0008 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-pipeline-queued-end-in-destroy.js @@ -0,0 +1,46 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const { Readable, Duplex, pipeline } = require('stream'); + +// Test that the callback for pipeline() is called even when the ._destroy() +// method of the stream places an .end() request to itself that does not +// get processed before the destruction of the stream (i.e. the 'close' event). +// Refs: https://github.com/nodejs/node/issues/24456 + +const readable = new Readable({ + read: common.mustCall() +}); + +const duplex = new Duplex({ + write(chunk, enc, cb) { + // Simulate messages queueing up. + }, + read() {}, + destroy(err, cb) { + // Call end() from inside the destroy() method, like HTTP/2 streams + // do at the time of writing. + this.end(); + cb(err); + } +}); + +duplex.on('finished', common.mustNotCall()); + +pipeline(readable, duplex, common.mustCall((err) => { + assert.strictEqual(err.code, 'ERR_STREAM_PREMATURE_CLOSE'); +})); + +// Write one chunk of data, and destroy the stream later. +// That should trigger the pipeline destruction. +readable.push('foo'); +setImmediate(() => { + readable.destroy(); +}); diff --git a/tests/node_compat/test/parallel/test-stream-pipeline-with-empty-string.js b/tests/node_compat/test/parallel/test-stream-pipeline-with-empty-string.js new file mode 100644 index 000000000..a03fe17dd --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-pipeline-with-empty-string.js @@ -0,0 +1,25 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const { + pipeline, + PassThrough +} = require('stream'); + + +async function runTest() { + await pipeline( + '', + new PassThrough({ objectMode: true }), + common.mustCall(), + ); +} + +runTest().then(common.mustCall()); diff --git a/tests/node_compat/test/parallel/test-stream-push-strings.js b/tests/node_compat/test/parallel/test-stream-push-strings.js new file mode 100644 index 000000000..4d88e082b --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-push-strings.js @@ -0,0 +1,74 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); + +const Readable = require('stream').Readable; + +class MyStream extends Readable { + constructor(options) { + super(options); + this._chunks = 3; + } + + _read(n) { + switch (this._chunks--) { + case 0: + return this.push(null); + case 1: + return setTimeout(() => { + this.push('last chunk'); + }, 100); + case 2: + return this.push('second to last chunk'); + case 3: + return process.nextTick(() => { + this.push('first chunk'); + }); + default: + throw new Error('?'); + } + } +} + +const ms = new MyStream(); +const results = []; +ms.on('readable', function() { + let chunk; + while (null !== (chunk = ms.read())) + results.push(String(chunk)); +}); + +const expect = [ 'first chunksecond to last chunk', 'last chunk' ]; +process.on('exit', function() { + assert.strictEqual(ms._chunks, -1); + assert.deepStrictEqual(results, expect); + console.log('ok'); +}); diff --git a/tests/node_compat/test/parallel/test-stream-readable-aborted.js b/tests/node_compat/test/parallel/test-stream-readable-aborted.js new file mode 100644 index 000000000..3e6550e7e --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readable-aborted.js @@ -0,0 +1,73 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const { Readable, Duplex } = require('stream'); + +{ + const readable = new Readable({ + read() { + } + }); + assert.strictEqual(readable.readableAborted, false); + readable.destroy(); + assert.strictEqual(readable.readableAborted, true); +} + +{ + const readable = new Readable({ + read() { + } + }); + assert.strictEqual(readable.readableAborted, false); + readable.push(null); + readable.destroy(); + assert.strictEqual(readable.readableAborted, true); +} + +{ + const readable = new Readable({ + read() { + } + }); + assert.strictEqual(readable.readableAborted, false); + readable.push('asd'); + readable.destroy(); + assert.strictEqual(readable.readableAborted, true); +} + +{ + const readable = new Readable({ + read() { + } + }); + assert.strictEqual(readable.readableAborted, false); + readable.push('asd'); + readable.push(null); + assert.strictEqual(readable.readableAborted, false); + readable.on('end', common.mustCall(() => { + assert.strictEqual(readable.readableAborted, false); + readable.destroy(); + assert.strictEqual(readable.readableAborted, false); + queueMicrotask(() => { + assert.strictEqual(readable.readableAborted, false); + }); + })); + readable.resume(); +} + +{ + const duplex = new Duplex({ + readable: false, + write() {} + }); + duplex.destroy(); + assert.strictEqual(duplex.readableAborted, false); +} diff --git a/tests/node_compat/test/parallel/test-stream-readable-add-chunk-during-data.js b/tests/node_compat/test/parallel/test-stream-readable-add-chunk-during-data.js new file mode 100644 index 000000000..50939ac81 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readable-add-chunk-during-data.js @@ -0,0 +1,28 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const { Readable } = require('stream'); + +// Verify that .push() and .unshift() can be called from 'data' listeners. + +for (const method of ['push', 'unshift']) { + const r = new Readable({ read() {} }); + r.once('data', common.mustCall((chunk) => { + assert.strictEqual(r.readableLength, 0); + r[method](chunk); + assert.strictEqual(r.readableLength, chunk.length); + + r.on('data', common.mustCall((chunk) => { + assert.strictEqual(chunk.toString(), 'Hello, world'); + })); + })); + + r.push('Hello, world'); +} diff --git a/tests/node_compat/test/parallel/test-stream-readable-constructor-set-methods.js b/tests/node_compat/test/parallel/test-stream-readable-constructor-set-methods.js new file mode 100644 index 000000000..b11ae8fca --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readable-constructor-set-methods.js @@ -0,0 +1,18 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); + +const Readable = require('stream').Readable; + +const _read = common.mustCall(function _read(n) { + this.push(null); +}); + +const r = new Readable({ read: _read }); +r.resume(); diff --git a/tests/node_compat/test/parallel/test-stream-readable-data.js b/tests/node_compat/test/parallel/test-stream-readable-data.js new file mode 100644 index 000000000..d33f9f248 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readable-data.js @@ -0,0 +1,26 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); + +const { Readable } = require('stream'); + +const readable = new Readable({ + read() {} +}); + +function read() {} + +readable.setEncoding('utf8'); +readable.on('readable', read); +readable.removeListener('readable', read); + +process.nextTick(function() { + readable.on('data', common.mustCall()); + readable.push('hello'); +}); diff --git a/tests/node_compat/test/parallel/test-stream-readable-destroy.js b/tests/node_compat/test/parallel/test-stream-readable-destroy.js new file mode 100644 index 000000000..0a780c98e --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readable-destroy.js @@ -0,0 +1,412 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const { Readable, addAbortSignal } = require('stream'); +const assert = require('assert'); + +{ + const read = new Readable({ + read() {} + }); + read.resume(); + + read.on('close', common.mustCall()); + + read.destroy(); + assert.strictEqual(read.errored, null); + assert.strictEqual(read.destroyed, true); +} + +{ + const read = new Readable({ + read() {} + }); + read.resume(); + + const expected = new Error('kaboom'); + + read.on('end', common.mustNotCall('no end event')); + read.on('close', common.mustCall()); + read.on('error', common.mustCall((err) => { + assert.strictEqual(err, expected); + })); + + read.destroy(expected); + assert.strictEqual(read.errored, expected); + assert.strictEqual(read.destroyed, true); +} + +{ + const read = new Readable({ + read() {} + }); + + read._destroy = common.mustCall(function(err, cb) { + assert.strictEqual(err, expected); + cb(err); + }); + + const expected = new Error('kaboom'); + + read.on('end', common.mustNotCall('no end event')); + read.on('close', common.mustCall()); + read.on('error', common.mustCall((err) => { + assert.strictEqual(err, expected); + })); + + read.destroy(expected); + assert.strictEqual(read.destroyed, true); +} + +{ + const read = new Readable({ + read() {}, + destroy: common.mustCall(function(err, cb) { + assert.strictEqual(err, expected); + cb(); + }) + }); + + const expected = new Error('kaboom'); + + read.on('end', common.mustNotCall('no end event')); + + // Error is swallowed by the custom _destroy + read.on('error', common.mustNotCall('no error event')); + read.on('close', common.mustCall()); + + read.destroy(expected); + assert.strictEqual(read.destroyed, true); +} + +{ + const read = new Readable({ + read() {} + }); + + read._destroy = common.mustCall(function(err, cb) { + assert.strictEqual(err, null); + cb(); + }); + + read.destroy(); + assert.strictEqual(read.destroyed, true); +} + +{ + const read = new Readable({ + read() {} + }); + read.resume(); + + read._destroy = common.mustCall(function(err, cb) { + assert.strictEqual(err, null); + process.nextTick(() => { + this.push(null); + cb(); + }); + }); + + const fail = common.mustNotCall('no end event'); + + read.on('end', fail); + read.on('close', common.mustCall()); + + read.destroy(); + + read.removeListener('end', fail); + read.on('end', common.mustNotCall()); + assert.strictEqual(read.destroyed, true); +} + +{ + const read = new Readable({ + read() {} + }); + + const expected = new Error('kaboom'); + + read._destroy = common.mustCall(function(err, cb) { + assert.strictEqual(err, null); + cb(expected); + }); + + let ticked = false; + read.on('end', common.mustNotCall('no end event')); + read.on('error', common.mustCall((err) => { + assert.strictEqual(ticked, true); + assert.strictEqual(read._readableState.errorEmitted, true); + assert.strictEqual(read._readableState.errored, expected); + assert.strictEqual(err, expected); + })); + + read.destroy(); + assert.strictEqual(read._readableState.errorEmitted, false); + assert.strictEqual(read._readableState.errored, expected); + assert.strictEqual(read.destroyed, true); + ticked = true; +} + +{ + const read = new Readable({ + read() {} + }); + read.resume(); + + read.destroyed = true; + assert.strictEqual(read.destroyed, true); + + // The internal destroy() mechanism should not be triggered + read.on('end', common.mustNotCall()); + read.destroy(); +} + +{ + function MyReadable() { + assert.strictEqual(this.destroyed, false); + this.destroyed = false; + Readable.call(this); + } + + Object.setPrototypeOf(MyReadable.prototype, Readable.prototype); + Object.setPrototypeOf(MyReadable, Readable); + + new MyReadable(); +} + +{ + // Destroy and destroy callback + const read = new Readable({ + read() {} + }); + read.resume(); + + const expected = new Error('kaboom'); + + let ticked = false; + read.on('close', common.mustCall(() => { + assert.strictEqual(read._readableState.errorEmitted, true); + assert.strictEqual(ticked, true); + })); + read.on('error', common.mustCall((err) => { + assert.strictEqual(err, expected); + })); + + assert.strictEqual(read._readableState.errored, null); + assert.strictEqual(read._readableState.errorEmitted, false); + + read.destroy(expected, common.mustCall(function(err) { + assert.strictEqual(read._readableState.errored, expected); + assert.strictEqual(err, expected); + })); + assert.strictEqual(read._readableState.errorEmitted, false); + assert.strictEqual(read._readableState.errored, expected); + ticked = true; +} + +{ + const readable = new Readable({ + destroy: common.mustCall(function(err, cb) { + process.nextTick(cb, new Error('kaboom 1')); + }), + read() {} + }); + + let ticked = false; + readable.on('close', common.mustCall(() => { + assert.strictEqual(ticked, true); + assert.strictEqual(readable._readableState.errorEmitted, true); + })); + readable.on('error', common.mustCall((err) => { + assert.strictEqual(ticked, true); + assert.strictEqual(err.message, 'kaboom 1'); + assert.strictEqual(readable._readableState.errorEmitted, true); + })); + + readable.destroy(); + assert.strictEqual(readable.destroyed, true); + assert.strictEqual(readable._readableState.errored, null); + assert.strictEqual(readable._readableState.errorEmitted, false); + + // Test case where `readable.destroy()` is called again with an error before + // the `_destroy()` callback is called. + readable.destroy(new Error('kaboom 2')); + assert.strictEqual(readable._readableState.errorEmitted, false); + assert.strictEqual(readable._readableState.errored, null); + + ticked = true; +} + +{ + const read = new Readable({ + read() {} + }); + + read.destroy(); + read.push('hi'); + read.on('data', common.mustNotCall()); +} + +{ + const read = new Readable({ + read: common.mustNotCall() + }); + read.destroy(); + assert.strictEqual(read.destroyed, true); + read.read(); +} + +{ + const read = new Readable({ + autoDestroy: false, + read() { + this.push(null); + this.push('asd'); + } + }); + + read.on('error', common.mustCall(() => { + assert(read._readableState.errored); + })); + read.resume(); +} + +{ + const controller = new AbortController(); + const read = addAbortSignal(controller.signal, new Readable({ + read() { + this.push('asd'); + }, + })); + + read.on('error', common.mustCall((e) => { + assert.strictEqual(e.name, 'AbortError'); + })); + controller.abort(); + read.on('data', common.mustNotCall()); +} + +{ + const controller = new AbortController(); + const read = new Readable({ + signal: controller.signal, + read() { + this.push('asd'); + }, + }); + + read.on('error', common.mustCall((e) => { + assert.strictEqual(e.name, 'AbortError'); + })); + controller.abort(); + read.on('data', common.mustNotCall()); +} + +{ + const controller = new AbortController(); + const read = addAbortSignal(controller.signal, new Readable({ + objectMode: true, + read() { + return false; + } + })); + read.push('asd'); + + read.on('error', common.mustCall((e) => { + assert.strictEqual(e.name, 'AbortError'); + })); + assert.rejects((async () => { + // eslint-disable-next-line no-unused-vars, no-empty + for await (const chunk of read) { } + })(), /AbortError/); + setTimeout(() => controller.abort(), 0); +} + +{ + const read = new Readable({ + read() { + }, + }); + + read.on('data', common.mustNotCall()); + read.on('error', common.mustCall((e) => { + read.push('asd'); + read.read(); + })); + read.on('close', common.mustCall((e) => { + read.push('asd'); + read.read(); + })); + read.destroy(new Error('asd')); +} + +{ + const read = new Readable({ + read() { + }, + }); + + read.on('data', common.mustNotCall()); + read.on('close', common.mustCall((e) => { + read.push('asd'); + read.read(); + })); + read.destroy(); +} + +{ + const read = new Readable({ + read() { + }, + }); + + read.on('data', common.mustNotCall()); + read.on('close', common.mustCall((e) => { + read.push('asd'); + read.unshift('asd'); + })); + read.destroy(); +} + +{ + const read = new Readable({ + read() { + }, + }); + + read.on('data', common.mustNotCall()); + read.destroy(); + read.unshift('asd'); +} + +{ + const read = new Readable({ + read() { + }, + }); + + read.resume(); + read.on('data', common.mustNotCall()); + read.on('close', common.mustCall((e) => { + read.push('asd'); + })); + read.destroy(); +} + +{ + const read = new Readable({ + read() { + }, + }); + + read.on('data', common.mustNotCall()); + read.destroy(); + read.push('asd'); +} diff --git a/tests/node_compat/test/parallel/test-stream-readable-didRead.js b/tests/node_compat/test/parallel/test-stream-readable-didRead.js new file mode 100644 index 000000000..2d9cfa40f --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readable-didRead.js @@ -0,0 +1,118 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const { isDisturbed, isErrored, Readable } = require('stream'); + +function noop() {} + +function check(readable, data, fn) { + assert.strictEqual(readable.readableDidRead, false); + assert.strictEqual(isDisturbed(readable), false); + assert.strictEqual(isErrored(readable), false); + if (data === -1) { + readable.on('error', common.mustCall(() => { + assert.strictEqual(isErrored(readable), true); + })); + readable.on('data', common.mustNotCall()); + readable.on('end', common.mustNotCall()); + } else { + readable.on('error', common.mustNotCall()); + if (data === -2) { + readable.on('end', common.mustNotCall()); + } else { + readable.on('end', common.mustCall()); + } + if (data > 0) { + readable.on('data', common.mustCallAtLeast(data)); + } else { + readable.on('data', common.mustNotCall()); + } + } + readable.on('close', common.mustCall()); + fn(); + setImmediate(() => { + assert.strictEqual(readable.readableDidRead, data > 0); + if (data > 0) { + assert.strictEqual(isDisturbed(readable), true); + } + }); +} + +{ + const readable = new Readable({ + read() { + this.push(null); + } + }); + check(readable, 0, () => { + readable.read(); + }); +} + +{ + const readable = new Readable({ + read() { + this.push(null); + } + }); + check(readable, 0, () => { + readable.resume(); + }); +} + +{ + const readable = new Readable({ + read() { + this.push(null); + } + }); + check(readable, -2, () => { + readable.destroy(); + }); +} + +{ + const readable = new Readable({ + read() { + this.push(null); + } + }); + + check(readable, -1, () => { + readable.destroy(new Error()); + }); +} + +{ + const readable = new Readable({ + read() { + this.push('data'); + this.push(null); + } + }); + + check(readable, 1, () => { + readable.on('data', noop); + }); +} + +{ + const readable = new Readable({ + read() { + this.push('data'); + this.push(null); + } + }); + + check(readable, 1, () => { + readable.on('data', noop); + readable.off('data', noop); + }); +} diff --git a/tests/node_compat/test/parallel/test-stream-readable-emit-readable-short-stream.js b/tests/node_compat/test/parallel/test-stream-readable-emit-readable-short-stream.js new file mode 100644 index 000000000..fac562092 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readable-emit-readable-short-stream.js @@ -0,0 +1,153 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const stream = require('stream'); +const assert = require('assert'); + +{ + const r = new stream.Readable({ + read: common.mustCall(function() { + this.push('content'); + this.push(null); + }) + }); + + const t = new stream.Transform({ + transform: common.mustCall(function(chunk, encoding, callback) { + this.push(chunk); + return callback(); + }), + flush: common.mustCall(function(callback) { + return callback(); + }) + }); + + r.pipe(t); + t.on('readable', common.mustCall(function() { + while (true) { + const chunk = t.read(); + if (!chunk) + break; + + assert.strictEqual(chunk.toString(), 'content'); + } + }, 2)); +} + +{ + const t = new stream.Transform({ + transform: common.mustCall(function(chunk, encoding, callback) { + this.push(chunk); + return callback(); + }), + flush: common.mustCall(function(callback) { + return callback(); + }) + }); + + t.end('content'); + + t.on('readable', common.mustCall(function() { + while (true) { + const chunk = t.read(); + if (!chunk) + break; + assert.strictEqual(chunk.toString(), 'content'); + } + })); +} + +{ + const t = new stream.Transform({ + transform: common.mustCall(function(chunk, encoding, callback) { + this.push(chunk); + return callback(); + }), + flush: common.mustCall(function(callback) { + return callback(); + }) + }); + + t.write('content'); + t.end(); + + t.on('readable', common.mustCall(function() { + while (true) { + const chunk = t.read(); + if (!chunk) + break; + assert.strictEqual(chunk.toString(), 'content'); + } + })); +} + +{ + const t = new stream.Readable({ + read() { + } + }); + + t.on('readable', common.mustCall(function() { + while (true) { + const chunk = t.read(); + if (!chunk) + break; + assert.strictEqual(chunk.toString(), 'content'); + } + })); + + t.push('content'); + t.push(null); +} + +{ + const t = new stream.Readable({ + read() { + } + }); + + t.on('readable', common.mustCall(function() { + while (true) { + const chunk = t.read(); + if (!chunk) + break; + assert.strictEqual(chunk.toString(), 'content'); + } + }, 2)); + + process.nextTick(() => { + t.push('content'); + t.push(null); + }); +} + +{ + const t = new stream.Transform({ + transform: common.mustCall(function(chunk, encoding, callback) { + this.push(chunk); + return callback(); + }), + flush: common.mustCall(function(callback) { + return callback(); + }) + }); + + t.on('readable', common.mustCall(function() { + while (true) { + const chunk = t.read(); + if (!chunk) + break; + assert.strictEqual(chunk.toString(), 'content'); + } + }, 2)); + + t.write('content'); + t.end(); +} diff --git a/tests/node_compat/test/parallel/test-stream-readable-emittedReadable.js b/tests/node_compat/test/parallel/test-stream-readable-emittedReadable.js new file mode 100644 index 000000000..a05130737 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readable-emittedReadable.js @@ -0,0 +1,80 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const Readable = require('stream').Readable; + +const readable = new Readable({ + read: () => {} +}); + +// Initialized to false. +assert.strictEqual(readable._readableState.emittedReadable, false); + +const expected = [Buffer.from('foobar'), Buffer.from('quo'), null]; +readable.on('readable', common.mustCall(() => { + // emittedReadable should be true when the readable event is emitted + assert.strictEqual(readable._readableState.emittedReadable, true); + assert.deepStrictEqual(readable.read(), expected.shift()); + // emittedReadable is reset to false during read() + assert.strictEqual(readable._readableState.emittedReadable, false); +}, 3)); + +// When the first readable listener is just attached, +// emittedReadable should be false +assert.strictEqual(readable._readableState.emittedReadable, false); + +// These trigger a single 'readable', as things are batched up +process.nextTick(common.mustCall(() => { + readable.push('foo'); +})); +process.nextTick(common.mustCall(() => { + readable.push('bar'); +})); + +// These triggers two readable events +setImmediate(common.mustCall(() => { + readable.push('quo'); + process.nextTick(common.mustCall(() => { + readable.push(null); + })); +})); + +const noRead = new Readable({ + read: () => {} +}); + +noRead.on('readable', common.mustCall(() => { + // emittedReadable should be true when the readable event is emitted + assert.strictEqual(noRead._readableState.emittedReadable, true); + noRead.read(0); + // emittedReadable is not reset during read(0) + assert.strictEqual(noRead._readableState.emittedReadable, true); +})); + +noRead.push('foo'); +noRead.push(null); + +const flowing = new Readable({ + read: () => {} +}); + +flowing.on('data', common.mustCall(() => { + // When in flowing mode, emittedReadable is always false. + assert.strictEqual(flowing._readableState.emittedReadable, false); + flowing.read(); + assert.strictEqual(flowing._readableState.emittedReadable, false); +}, 3)); + +flowing.push('foooo'); +flowing.push('bar'); +flowing.push('quo'); +process.nextTick(common.mustCall(() => { + flowing.push(null); +})); diff --git a/tests/node_compat/test/parallel/test-stream-readable-end-destroyed.js b/tests/node_compat/test/parallel/test-stream-readable-end-destroyed.js new file mode 100644 index 000000000..7c542f330 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readable-end-destroyed.js @@ -0,0 +1,24 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const { Readable } = require('stream'); + +{ + // Don't emit 'end' after 'close'. + + const r = new Readable(); + + r.on('end', common.mustNotCall()); + r.resume(); + r.destroy(); + r.on('close', common.mustCall(() => { + r.push(null); + })); +} diff --git a/tests/node_compat/test/parallel/test-stream-readable-ended.js b/tests/node_compat/test/parallel/test-stream-readable-ended.js new file mode 100644 index 000000000..b8f59e2df --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readable-ended.js @@ -0,0 +1,53 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const { Readable } = require('stream'); +const assert = require('assert'); + +// basic +{ + // Find it on Readable.prototype + assert(Object.hasOwn(Readable.prototype, 'readableEnded')); +} + +// event +{ + const readable = new Readable(); + + readable._read = () => { + // The state ended should start in false. + assert.strictEqual(readable.readableEnded, false); + readable.push('asd'); + assert.strictEqual(readable.readableEnded, false); + readable.push(null); + assert.strictEqual(readable.readableEnded, false); + }; + + readable.on('end', common.mustCall(() => { + assert.strictEqual(readable.readableEnded, true); + })); + + readable.on('data', common.mustCall(() => { + assert.strictEqual(readable.readableEnded, false); + })); +} + +// Verifies no `error` triggered on multiple .push(null) invocations +{ + const readable = new Readable(); + + readable.on('readable', () => { readable.read(); }); + readable.on('error', common.mustNotCall()); + readable.on('end', common.mustCall()); + + readable.push('a'); + readable.push(null); + readable.push(null); +} diff --git a/tests/node_compat/test/parallel/test-stream-readable-error-end.js b/tests/node_compat/test/parallel/test-stream-readable-error-end.js new file mode 100644 index 000000000..821a5f458 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readable-error-end.js @@ -0,0 +1,22 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const { Readable } = require('stream'); + +{ + const r = new Readable({ read() {} }); + + r.on('end', common.mustNotCall()); + r.on('data', common.mustCall()); + r.on('error', common.mustCall()); + r.push('asd'); + r.push(null); + r.destroy(new Error('kaboom')); +} diff --git a/tests/node_compat/test/parallel/test-stream-readable-event.js b/tests/node_compat/test/parallel/test-stream-readable-event.js new file mode 100644 index 000000000..87a4e0feb --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readable-event.js @@ -0,0 +1,135 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const Readable = require('stream').Readable; + +{ + // First test, not reading when the readable is added. + // make sure that on('readable', ...) triggers a readable event. + const r = new Readable({ + highWaterMark: 3 + }); + + r._read = common.mustNotCall(); + + // This triggers a 'readable' event, which is lost. + r.push(Buffer.from('blerg')); + + setTimeout(function() { + // We're testing what we think we are + assert(!r._readableState.reading); + r.on('readable', common.mustCall()); + }, 1); +} + +{ + // Second test, make sure that readable is re-emitted if there's + // already a length, while it IS reading. + + const r = new Readable({ + highWaterMark: 3 + }); + + r._read = common.mustCall(); + + // This triggers a 'readable' event, which is lost. + r.push(Buffer.from('bl')); + + setTimeout(function() { + // Assert we're testing what we think we are + assert(r._readableState.reading); + r.on('readable', common.mustCall()); + }, 1); +} + +{ + // Third test, not reading when the stream has not passed + // the highWaterMark but *has* reached EOF. + const r = new Readable({ + highWaterMark: 30 + }); + + r._read = common.mustNotCall(); + + // This triggers a 'readable' event, which is lost. + r.push(Buffer.from('blerg')); + r.push(null); + + setTimeout(function() { + // Assert we're testing what we think we are + assert(!r._readableState.reading); + r.on('readable', common.mustCall()); + }, 1); +} + +{ + // Pushing an empty string in non-objectMode should + // trigger next `read()`. + const underlyingData = ['', 'x', 'y', '', 'z']; + const expected = underlyingData.filter((data) => data); + const result = []; + + const r = new Readable({ + encoding: 'utf8', + }); + r._read = function() { + process.nextTick(() => { + if (!underlyingData.length) { + this.push(null); + } else { + this.push(underlyingData.shift()); + } + }); + }; + + r.on('readable', () => { + const data = r.read(); + if (data !== null) result.push(data); + }); + + r.on('end', common.mustCall(() => { + assert.deepStrictEqual(result, expected); + })); +} + +{ + // #20923 + const r = new Readable(); + r._read = function() { + // Actually doing thing here + }; + r.on('data', function() {}); + + r.removeAllListeners(); + + assert.strictEqual(r.eventNames().length, 0); +} diff --git a/tests/node_compat/test/parallel/test-stream-readable-flow-recursion.js b/tests/node_compat/test/parallel/test-stream-readable-flow-recursion.js new file mode 100644 index 000000000..1ac657197 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readable-flow-recursion.js @@ -0,0 +1,84 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); + +// This test verifies that passing a huge number to read(size) +// will push up the highWaterMark, and cause the stream to read +// more data continuously, but without triggering a nextTick +// warning or RangeError. + +const Readable = require('stream').Readable; + +// Throw an error if we trigger a nextTick warning. +process.throwDeprecation = true; + +const stream = new Readable({ highWaterMark: 2 }); +let reads = 0; +let total = 5000; +stream._read = function(size) { + reads++; + size = Math.min(size, total); + total -= size; + if (size === 0) + stream.push(null); + else + stream.push(Buffer.allocUnsafe(size)); +}; + +let depth = 0; + +function flow(stream, size, callback) { + depth += 1; + const chunk = stream.read(size); + + if (!chunk) + stream.once('readable', flow.bind(null, stream, size, callback)); + else + callback(chunk); + + depth -= 1; + console.log(`flow(${depth}): exit`); +} + +flow(stream, 5000, function() { + console.log(`complete (${depth})`); +}); + +process.on('exit', function(code) { + assert.strictEqual(reads, 2); + // We pushed up the high water mark + assert.strictEqual(stream.readableHighWaterMark, 8192); + // Length is 0 right now, because we pulled it all out. + assert.strictEqual(stream.readableLength, 0); + assert(!code); + assert.strictEqual(depth, 0); + console.log('ok'); +}); diff --git a/tests/node_compat/test/parallel/test-stream-readable-hwm-0-async.js b/tests/node_compat/test/parallel/test-stream-readable-hwm-0-async.js new file mode 100644 index 000000000..c797129ee --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readable-hwm-0-async.js @@ -0,0 +1,34 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); + +// This test ensures that Readable stream will continue to call _read +// for streams with highWaterMark === 0 once the stream returns data +// by calling push() asynchronously. + +const { Readable } = require('stream'); + +let count = 5; + +const r = new Readable({ + // Called 6 times: First 5 return data, last one signals end of stream. + read: common.mustCall(() => { + process.nextTick(common.mustCall(() => { + if (count--) + r.push('a'); + else + r.push(null); + })); + }, 6), + highWaterMark: 0, +}); + +r.on('end', common.mustCall()); +r.on('data', common.mustCall(5)); diff --git a/tests/node_compat/test/parallel/test-stream-readable-hwm-0-no-flow-data.js b/tests/node_compat/test/parallel/test-stream-readable-hwm-0-no-flow-data.js new file mode 100644 index 000000000..3d9c0507a --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readable-hwm-0-no-flow-data.js @@ -0,0 +1,111 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); + +// Ensure that subscribing the 'data' event will not make the stream flow. +// The 'data' event will require calling read() by hand. +// +// The test is written for the (somewhat rare) highWaterMark: 0 streams to +// specifically catch any regressions that might occur with these streams. + +const assert = require('assert'); +const { Readable } = require('stream'); + +const streamData = [ 'a', null ]; + +// Track the calls so we can assert their order later. +const calls = []; +const r = new Readable({ + read: common.mustCall(() => { + calls.push('_read:' + streamData[0]); + process.nextTick(() => { + calls.push('push:' + streamData[0]); + r.push(streamData.shift()); + }); + }, streamData.length), + highWaterMark: 0, + + // Object mode is used here just for testing convenience. It really + // shouldn't affect the order of events. Just the data and its format. + objectMode: true, +}); + +assert.strictEqual(r.readableFlowing, null); +r.on('readable', common.mustCall(() => { + calls.push('readable'); +}, 2)); +assert.strictEqual(r.readableFlowing, false); +r.on('data', common.mustCall((data) => { + calls.push('data:' + data); +}, 1)); +r.on('end', common.mustCall(() => { + calls.push('end'); +})); +assert.strictEqual(r.readableFlowing, false); + +// The stream emits the events asynchronously but that's not guaranteed to +// happen on the next tick (especially since the _read implementation above +// uses process.nextTick). +// +// We use setImmediate here to give the stream enough time to emit all the +// events it's about to emit. +setImmediate(() => { + + // Only the _read, push, readable calls have happened. No data must be + // emitted yet. + assert.deepStrictEqual(calls, ['_read:a', 'push:a', 'readable']); + + // Calling 'r.read()' should trigger the data event. + assert.strictEqual(r.read(), 'a'); + assert.deepStrictEqual( + calls, + ['_read:a', 'push:a', 'readable', 'data:a']); + + // The next 'read()' will return null because hwm: 0 does not buffer any + // data and the _read implementation above does the push() asynchronously. + // + // Note: This 'null' signals "no data available". It isn't the end-of-stream + // null value as the stream doesn't know yet that it is about to reach the + // end. + // + // Using setImmediate again to give the stream enough time to emit all the + // events it wants to emit. + assert.strictEqual(r.read(), null); + setImmediate(() => { + + // There's a new 'readable' event after the data has been pushed. + // The 'end' event will be emitted only after a 'read()'. + // + // This is somewhat special for the case where the '_read' implementation + // calls 'push' asynchronously. If 'push' was synchronous, the 'end' event + // would be emitted here _before_ we call read(). + assert.deepStrictEqual( + calls, + ['_read:a', 'push:a', 'readable', 'data:a', + '_read:null', 'push:null', 'readable']); + + assert.strictEqual(r.read(), null); + + // While it isn't really specified whether the 'end' event should happen + // synchronously with read() or not, we'll assert the current behavior + // ('end' event happening on the next tick after read()) so any changes + // to it are noted and acknowledged in the future. + assert.deepStrictEqual( + calls, + ['_read:a', 'push:a', 'readable', 'data:a', + '_read:null', 'push:null', 'readable']); + process.nextTick(() => { + assert.deepStrictEqual( + calls, + ['_read:a', 'push:a', 'readable', 'data:a', + '_read:null', 'push:null', 'readable', 'end']); + }); + }); +}); diff --git a/tests/node_compat/test/parallel/test-stream-readable-hwm-0.js b/tests/node_compat/test/parallel/test-stream-readable-hwm-0.js new file mode 100644 index 000000000..cfbfac8ab --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readable-hwm-0.js @@ -0,0 +1,37 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); + +// This test ensures that Readable stream will call _read() for streams +// with highWaterMark === 0 upon .read(0) instead of just trying to +// emit 'readable' event. + +const assert = require('assert'); +const { Readable } = require('stream'); + +const r = new Readable({ + // Must be called only once upon setting 'readable' listener + read: common.mustCall(), + highWaterMark: 0, +}); + +let pushedNull = false; +// This will trigger read(0) but must only be called after push(null) +// because the we haven't pushed any data +r.on('readable', common.mustCall(() => { + assert.strictEqual(r.read(), null); + assert.strictEqual(pushedNull, true); +})); +r.on('end', common.mustCall()); +process.nextTick(() => { + assert.strictEqual(r.read(), null); + pushedNull = true; + r.push(null); +}); diff --git a/tests/node_compat/test/parallel/test-stream-readable-infinite-read.js b/tests/node_compat/test/parallel/test-stream-readable-infinite-read.js new file mode 100644 index 000000000..e3819cad9 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readable-infinite-read.js @@ -0,0 +1,39 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const { Readable } = require('stream'); + +const buf = Buffer.alloc(8192); + +const readable = new Readable({ + read: common.mustCall(function() { + this.push(buf); + }, 31) +}); + +let i = 0; + +readable.on('readable', common.mustCall(function() { + if (i++ === 10) { + // We will just terminate now. + process.removeAllListeners('readable'); + return; + } + + const data = readable.read(); + // TODO(mcollina): there is something odd in the highWaterMark logic + // investigate. + if (i === 1) { + assert.strictEqual(data.length, 8192 * 2); + } else { + assert.strictEqual(data.length, 8192 * 3); + } +}, 11)); diff --git a/tests/node_compat/test/parallel/test-stream-readable-invalid-chunk.js b/tests/node_compat/test/parallel/test-stream-readable-invalid-chunk.js new file mode 100644 index 000000000..a40526389 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readable-invalid-chunk.js @@ -0,0 +1,41 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const stream = require('stream'); + +function testPushArg(val) { + const readable = new stream.Readable({ + read: () => {} + }); + readable.on('error', common.expectsError({ + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + })); + readable.push(val); +} + +testPushArg([]); +testPushArg({}); +testPushArg(0); + +function testUnshiftArg(val) { + const readable = new stream.Readable({ + read: () => {} + }); + readable.on('error', common.expectsError({ + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + })); + readable.unshift(val); +} + +testUnshiftArg([]); +testUnshiftArg({}); +testUnshiftArg(0); diff --git a/tests/node_compat/test/parallel/test-stream-readable-needReadable.js b/tests/node_compat/test/parallel/test-stream-readable-needReadable.js new file mode 100644 index 000000000..675e5e872 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readable-needReadable.js @@ -0,0 +1,106 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const Readable = require('stream').Readable; + +const readable = new Readable({ + read: () => {} +}); + +// Initialized to false. +assert.strictEqual(readable._readableState.needReadable, false); + +readable.on('readable', common.mustCall(() => { + // When the readable event fires, needReadable is reset. + assert.strictEqual(readable._readableState.needReadable, false); + readable.read(); +})); + +// If a readable listener is attached, then a readable event is needed. +assert.strictEqual(readable._readableState.needReadable, true); + +readable.push('foo'); +readable.push(null); + +readable.on('end', common.mustCall(() => { + // No need to emit readable anymore when the stream ends. + assert.strictEqual(readable._readableState.needReadable, false); +})); + +const asyncReadable = new Readable({ + read: () => {} +}); + +asyncReadable.on('readable', common.mustCall(() => { + if (asyncReadable.read() !== null) { + // After each read(), the buffer is empty. + // If the stream doesn't end now, + // then we need to notify the reader on future changes. + assert.strictEqual(asyncReadable._readableState.needReadable, true); + } +}, 2)); + +process.nextTick(common.mustCall(() => { + asyncReadable.push('foooo'); +})); +process.nextTick(common.mustCall(() => { + asyncReadable.push('bar'); +})); +setImmediate(common.mustCall(() => { + asyncReadable.push(null); + assert.strictEqual(asyncReadable._readableState.needReadable, false); +})); + +const flowing = new Readable({ + read: () => {} +}); + +// Notice this must be above the on('data') call. +flowing.push('foooo'); +flowing.push('bar'); +flowing.push('quo'); +process.nextTick(common.mustCall(() => { + flowing.push(null); +})); + +// When the buffer already has enough data, and the stream is +// in flowing mode, there is no need for the readable event. +flowing.on('data', common.mustCall(function(data) { + assert.strictEqual(flowing._readableState.needReadable, false); +}, 3)); + +const slowProducer = new Readable({ + read: () => {} +}); + +slowProducer.on('readable', common.mustCall(() => { + const chunk = slowProducer.read(8); + const state = slowProducer._readableState; + if (chunk === null) { + // The buffer doesn't have enough data, and the stream is not need, + // we need to notify the reader when data arrives. + assert.strictEqual(state.needReadable, true); + } else { + assert.strictEqual(state.needReadable, false); + } +}, 4)); + +process.nextTick(common.mustCall(() => { + slowProducer.push('foo'); + process.nextTick(common.mustCall(() => { + slowProducer.push('foo'); + process.nextTick(common.mustCall(() => { + slowProducer.push('foo'); + process.nextTick(common.mustCall(() => { + slowProducer.push(null); + })); + })); + })); +})); diff --git a/tests/node_compat/test/parallel/test-stream-readable-next-no-null.js b/tests/node_compat/test/parallel/test-stream-readable-next-no-null.js new file mode 100644 index 000000000..06f06f41d --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readable-next-no-null.js @@ -0,0 +1,26 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const { mustNotCall, expectsError } = require('../common'); +const { Readable } = require('stream'); + +async function* generate() { + yield null; +} + +const stream = Readable.from(generate()); + +stream.on('error', expectsError({ + code: 'ERR_STREAM_NULL_VALUES', + name: 'TypeError', + message: 'May not write null values to stream' +})); + +stream.on('data', mustNotCall()); + +stream.on('end', mustNotCall()); diff --git a/tests/node_compat/test/parallel/test-stream-readable-no-unneeded-readable.js b/tests/node_compat/test/parallel/test-stream-readable-no-unneeded-readable.js new file mode 100644 index 000000000..9a96db87d --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readable-no-unneeded-readable.js @@ -0,0 +1,69 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const { Readable, PassThrough } = require('stream'); + +function test(r) { + const wrapper = new Readable({ + read: () => { + let data = r.read(); + + if (data) { + wrapper.push(data); + return; + } + + r.once('readable', function() { + data = r.read(); + if (data) { + wrapper.push(data); + } + // else: the end event should fire + }); + }, + }); + + r.once('end', function() { + wrapper.push(null); + }); + + wrapper.resume(); + wrapper.once('end', common.mustCall()); +} + +{ + const source = new Readable({ + read: () => {} + }); + source.push('foo'); + source.push('bar'); + source.push(null); + + const pt = source.pipe(new PassThrough()); + test(pt); +} + +{ + // This is the underlying cause of the above test case. + const pushChunks = ['foo', 'bar']; + const r = new Readable({ + read: () => { + const chunk = pushChunks.shift(); + if (chunk) { + // synchronous call + r.push(chunk); + } else { + // asynchronous call + process.nextTick(() => r.push(null)); + } + }, + }); + + test(r); +} diff --git a/tests/node_compat/test/parallel/test-stream-readable-object-multi-push-async.js b/tests/node_compat/test/parallel/test-stream-readable-object-multi-push-async.js new file mode 100644 index 000000000..4ab7f3adb --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readable-object-multi-push-async.js @@ -0,0 +1,190 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const { Readable } = require('stream'); + +const MAX = 42; +const BATCH = 10; + +{ + const readable = new Readable({ + objectMode: true, + read: common.mustCall(function() { + console.log('>> READ'); + fetchData((err, data) => { + if (err) { + this.destroy(err); + return; + } + + if (data.length === 0) { + console.log('pushing null'); + this.push(null); + return; + } + + console.log('pushing'); + data.forEach((d) => this.push(d)); + }); + }, Math.floor(MAX / BATCH) + 2) + }); + + let i = 0; + function fetchData(cb) { + if (i > MAX) { + setTimeout(cb, 10, null, []); + } else { + const array = []; + const max = i + BATCH; + for (; i < max; i++) { + array.push(i); + } + setTimeout(cb, 10, null, array); + } + } + + readable.on('readable', () => { + let data; + console.log('readable emitted'); + while ((data = readable.read()) !== null) { + console.log(data); + } + }); + + readable.on('end', common.mustCall(() => { + assert.strictEqual(i, (Math.floor(MAX / BATCH) + 1) * BATCH); + })); +} + +{ + const readable = new Readable({ + objectMode: true, + read: common.mustCall(function() { + console.log('>> READ'); + fetchData((err, data) => { + if (err) { + this.destroy(err); + return; + } + + if (data.length === 0) { + console.log('pushing null'); + this.push(null); + return; + } + + console.log('pushing'); + data.forEach((d) => this.push(d)); + }); + }, Math.floor(MAX / BATCH) + 2) + }); + + let i = 0; + function fetchData(cb) { + if (i > MAX) { + setTimeout(cb, 10, null, []); + } else { + const array = []; + const max = i + BATCH; + for (; i < max; i++) { + array.push(i); + } + setTimeout(cb, 10, null, array); + } + } + + readable.on('data', (data) => { + console.log('data emitted', data); + }); + + readable.on('end', common.mustCall(() => { + assert.strictEqual(i, (Math.floor(MAX / BATCH) + 1) * BATCH); + })); +} + +{ + const readable = new Readable({ + objectMode: true, + read: common.mustCall(function() { + console.log('>> READ'); + fetchData((err, data) => { + if (err) { + this.destroy(err); + return; + } + + console.log('pushing'); + data.forEach((d) => this.push(d)); + + if (data[BATCH - 1] >= MAX) { + console.log('pushing null'); + this.push(null); + } + }); + }, Math.floor(MAX / BATCH) + 1) + }); + + let i = 0; + function fetchData(cb) { + const array = []; + const max = i + BATCH; + for (; i < max; i++) { + array.push(i); + } + setTimeout(cb, 10, null, array); + } + + readable.on('data', (data) => { + console.log('data emitted', data); + }); + + readable.on('end', common.mustCall(() => { + assert.strictEqual(i, (Math.floor(MAX / BATCH) + 1) * BATCH); + })); +} + +{ + const readable = new Readable({ + objectMode: true, + read: common.mustNotCall() + }); + + readable.on('data', common.mustNotCall()); + + readable.push(null); + + let nextTickPassed = false; + process.nextTick(() => { + nextTickPassed = true; + }); + + readable.on('end', common.mustCall(() => { + assert.strictEqual(nextTickPassed, true); + })); +} + +{ + const readable = new Readable({ + objectMode: true, + read: common.mustCall() + }); + + readable.on('data', (data) => { + console.log('data emitted', data); + }); + + readable.on('end', common.mustCall()); + + setImmediate(() => { + readable.push('aaa'); + readable.push(null); + }); +} diff --git a/tests/node_compat/test/parallel/test-stream-readable-pause-and-resume.js b/tests/node_compat/test/parallel/test-stream-readable-pause-and-resume.js new file mode 100644 index 000000000..923349ef4 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readable-pause-and-resume.js @@ -0,0 +1,81 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const { Readable } = require('stream'); + +let ticks = 18; +let expectedData = 19; + +const rs = new Readable({ + objectMode: true, + read: () => { + if (ticks-- > 0) + return process.nextTick(() => rs.push({})); + rs.push({}); + rs.push(null); + } +}); + +rs.on('end', common.mustCall()); +readAndPause(); + +function readAndPause() { + // Does a on(data) -> pause -> wait -> resume -> on(data) ... loop. + // Expects on(data) to never fire if the stream is paused. + const ondata = common.mustCall((data) => { + rs.pause(); + + expectedData--; + if (expectedData <= 0) + return; + + setImmediate(function() { + rs.removeListener('data', ondata); + readAndPause(); + rs.resume(); + }); + }, 1); // Only call ondata once + + rs.on('data', ondata); +} + +{ + const readable = new Readable({ + read() {} + }); + + function read() {} + + readable.setEncoding('utf8'); + readable.on('readable', read); + readable.removeListener('readable', read); + readable.pause(); + + process.nextTick(function() { + assert(readable.isPaused()); + }); +} + +{ + const { PassThrough } = require('stream'); + + const source3 = new PassThrough(); + const target3 = new PassThrough(); + + const chunk = Buffer.allocUnsafe(1000); + while (target3.write(chunk)); + + source3.pipe(target3); + target3.on('drain', common.mustCall(() => { + assert(!source3.isPaused()); + })); + target3.on('data', () => {}); +} diff --git a/tests/node_compat/test/parallel/test-stream-readable-readable-then-resume.js b/tests/node_compat/test/parallel/test-stream-readable-readable-then-resume.js new file mode 100644 index 000000000..3df0bcaaf --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readable-readable-then-resume.js @@ -0,0 +1,38 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const { Readable } = require('stream'); +const assert = require('assert'); + +// This test verifies that a stream could be resumed after +// removing the readable event in the same tick + +check(new Readable({ + objectMode: true, + highWaterMark: 1, + read() { + if (!this.first) { + this.push('hello'); + this.first = true; + return; + } + + this.push(null); + } +})); + +function check(s) { + const readableListener = common.mustNotCall(); + s.on('readable', readableListener); + s.on('end', common.mustCall()); + assert.strictEqual(s.removeListener, s.off); + s.removeListener('readable', readableListener); + s.resume(); +} diff --git a/tests/node_compat/test/parallel/test-stream-readable-readable.js b/tests/node_compat/test/parallel/test-stream-readable-readable.js new file mode 100644 index 000000000..6353ad8d4 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readable-readable.js @@ -0,0 +1,52 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const { Readable } = require('stream'); + +{ + const r = new Readable({ + read() {} + }); + assert.strictEqual(r.readable, true); + r.destroy(); + assert.strictEqual(r.readable, false); +} + +{ + const mustNotCall = common.mustNotCall(); + const r = new Readable({ + read() {} + }); + assert.strictEqual(r.readable, true); + r.on('end', mustNotCall); + r.resume(); + r.push(null); + assert.strictEqual(r.readable, true); + r.off('end', mustNotCall); + r.on('end', common.mustCall(() => { + assert.strictEqual(r.readable, false); + })); +} + +{ + const r = new Readable({ + read: common.mustCall(() => { + process.nextTick(() => { + r.destroy(new Error()); + assert.strictEqual(r.readable, false); + }); + }) + }); + r.resume(); + r.on('error', common.mustCall(() => { + assert.strictEqual(r.readable, false); + })); +} diff --git a/tests/node_compat/test/parallel/test-stream-readable-reading-readingMore.js b/tests/node_compat/test/parallel/test-stream-readable-reading-readingMore.js new file mode 100644 index 000000000..26663b88b --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readable-reading-readingMore.js @@ -0,0 +1,178 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const Readable = require('stream').Readable; + +{ + const readable = new Readable({ + read(size) {} + }); + + const state = readable._readableState; + + // Starting off with false initially. + assert.strictEqual(state.reading, false); + assert.strictEqual(state.readingMore, false); + + readable.on('data', common.mustCall((data) => { + // While in a flowing state with a 'readable' listener + // we should not be reading more + if (readable.readableFlowing) + assert.strictEqual(state.readingMore, true); + + // Reading as long as we've not ended + assert.strictEqual(state.reading, !state.ended); + }, 2)); + + function onStreamEnd() { + // End of stream; state.reading is false + // And so should be readingMore. + assert.strictEqual(state.readingMore, false); + assert.strictEqual(state.reading, false); + } + + const expectedReadingMore = [true, true, false]; + readable.on('readable', common.mustCall(() => { + // There is only one readingMore scheduled from on('data'), + // after which everything is governed by the .read() call + assert.strictEqual(state.readingMore, expectedReadingMore.shift()); + + // If the stream has ended, we shouldn't be reading + assert.strictEqual(state.ended, !state.reading); + + // Consume all the data + while (readable.read() !== null); + + if (expectedReadingMore.length === 0) // Reached end of stream + process.nextTick(common.mustCall(onStreamEnd, 1)); + }, 3)); + + readable.on('end', common.mustCall(onStreamEnd)); + readable.push('pushed'); + + readable.read(6); + + // reading + assert.strictEqual(state.reading, true); + assert.strictEqual(state.readingMore, true); + + // add chunk to front + readable.unshift('unshifted'); + + // end + readable.push(null); +} + +{ + const readable = new Readable({ + read(size) {} + }); + + const state = readable._readableState; + + // Starting off with false initially. + assert.strictEqual(state.reading, false); + assert.strictEqual(state.readingMore, false); + + readable.on('data', common.mustCall((data) => { + // While in a flowing state without a 'readable' listener + // we should be reading more + if (readable.readableFlowing) + assert.strictEqual(state.readingMore, true); + + // Reading as long as we've not ended + assert.strictEqual(state.reading, !state.ended); + }, 2)); + + function onStreamEnd() { + // End of stream; state.reading is false + // And so should be readingMore. + assert.strictEqual(state.readingMore, false); + assert.strictEqual(state.reading, false); + } + + readable.on('end', common.mustCall(onStreamEnd)); + readable.push('pushed'); + + // Stop emitting 'data' events + assert.strictEqual(state.flowing, true); + readable.pause(); + + // paused + assert.strictEqual(state.reading, false); + assert.strictEqual(state.flowing, false); + + readable.resume(); + assert.strictEqual(state.reading, false); + assert.strictEqual(state.flowing, true); + + // add chunk to front + readable.unshift('unshifted'); + + // end + readable.push(null); +} + +{ + const readable = new Readable({ + read(size) {} + }); + + const state = readable._readableState; + + // Starting off with false initially. + assert.strictEqual(state.reading, false); + assert.strictEqual(state.readingMore, false); + + const onReadable = common.mustNotCall(); + + readable.on('readable', onReadable); + + readable.on('data', common.mustCall((data) => { + // Reading as long as we've not ended + assert.strictEqual(state.reading, !state.ended); + }, 2)); + + readable.removeListener('readable', onReadable); + + function onStreamEnd() { + // End of stream; state.reading is false + // And so should be readingMore. + assert.strictEqual(state.readingMore, false); + assert.strictEqual(state.reading, false); + } + + readable.on('end', common.mustCall(onStreamEnd)); + readable.push('pushed'); + + // We are still not flowing, we will be resuming in the next tick + assert.strictEqual(state.flowing, false); + + // Wait for nextTick, so the readableListener flag resets + process.nextTick(function() { + readable.resume(); + + // Stop emitting 'data' events + assert.strictEqual(state.flowing, true); + readable.pause(); + + // paused + assert.strictEqual(state.flowing, false); + + readable.resume(); + assert.strictEqual(state.flowing, true); + + // add chunk to front + readable.unshift('unshifted'); + + // end + readable.push(null); + }); +} diff --git a/tests/node_compat/test/parallel/test-stream-readable-resume-hwm.js b/tests/node_compat/test/parallel/test-stream-readable-resume-hwm.js new file mode 100644 index 000000000..0e490529c --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readable-resume-hwm.js @@ -0,0 +1,28 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const { Readable } = require('stream'); + +// readable.resume() should not lead to a ._read() call being scheduled +// when we exceed the high water mark already. + +const readable = new Readable({ + read: common.mustNotCall(), + highWaterMark: 100 +}); + +// Fill up the internal buffer so that we definitely exceed the HWM: +for (let i = 0; i < 10; i++) + readable.push('a'.repeat(200)); + +// Call resume, and pause after one chunk. +// The .pause() is just so that we don’t empty the buffer fully, which would +// be a valid reason to call ._read(). +readable.resume(); +readable.once('data', common.mustCall(() => readable.pause())); diff --git a/tests/node_compat/test/parallel/test-stream-readable-resumeScheduled.js b/tests/node_compat/test/parallel/test-stream-readable-resumeScheduled.js new file mode 100644 index 000000000..474670264 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readable-resumeScheduled.js @@ -0,0 +1,72 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); + +// Testing Readable Stream resumeScheduled state + +const assert = require('assert'); +const { Readable, Writable } = require('stream'); + +{ + // pipe() test case + const r = new Readable({ read() {} }); + const w = new Writable(); + + // resumeScheduled should start = `false`. + assert.strictEqual(r._readableState.resumeScheduled, false); + + // Calling pipe() should change the state value = true. + r.pipe(w); + assert.strictEqual(r._readableState.resumeScheduled, true); + + process.nextTick(common.mustCall(() => { + assert.strictEqual(r._readableState.resumeScheduled, false); + })); +} + +{ + // 'data' listener test case + const r = new Readable({ read() {} }); + + // resumeScheduled should start = `false`. + assert.strictEqual(r._readableState.resumeScheduled, false); + + r.push(Buffer.from([1, 2, 3])); + + // Adding 'data' listener should change the state value + r.on('data', common.mustCall(() => { + assert.strictEqual(r._readableState.resumeScheduled, false); + })); + assert.strictEqual(r._readableState.resumeScheduled, true); + + process.nextTick(common.mustCall(() => { + assert.strictEqual(r._readableState.resumeScheduled, false); + })); +} + +{ + // resume() test case + const r = new Readable({ read() {} }); + + // resumeScheduled should start = `false`. + assert.strictEqual(r._readableState.resumeScheduled, false); + + // Calling resume() should change the state value. + r.resume(); + assert.strictEqual(r._readableState.resumeScheduled, true); + + r.on('resume', common.mustCall(() => { + // The state value should be `false` again + assert.strictEqual(r._readableState.resumeScheduled, false); + })); + + process.nextTick(common.mustCall(() => { + assert.strictEqual(r._readableState.resumeScheduled, false); + })); +} diff --git a/tests/node_compat/test/parallel/test-stream-readable-setEncoding-existing-buffers.js b/tests/node_compat/test/parallel/test-stream-readable-setEncoding-existing-buffers.js new file mode 100644 index 000000000..c99a39819 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readable-setEncoding-existing-buffers.js @@ -0,0 +1,67 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const { Readable } = require('stream'); +const assert = require('assert'); + +{ + // Call .setEncoding() while there are bytes already in the buffer. + const r = new Readable({ read() {} }); + + r.push(Buffer.from('a')); + r.push(Buffer.from('b')); + + r.setEncoding('utf8'); + const chunks = []; + r.on('data', (chunk) => chunks.push(chunk)); + + process.nextTick(() => { + assert.deepStrictEqual(chunks, ['ab']); + }); +} + +{ + // Call .setEncoding() while the buffer contains a complete, + // but chunked character. + const r = new Readable({ read() {} }); + + r.push(Buffer.from([0xf0])); + r.push(Buffer.from([0x9f])); + r.push(Buffer.from([0x8e])); + r.push(Buffer.from([0x89])); + + r.setEncoding('utf8'); + const chunks = []; + r.on('data', (chunk) => chunks.push(chunk)); + + process.nextTick(() => { + assert.deepStrictEqual(chunks, ['🎉']); + }); +} + +{ + // Call .setEncoding() while the buffer contains an incomplete character, + // and finish the character later. + const r = new Readable({ read() {} }); + + r.push(Buffer.from([0xf0])); + r.push(Buffer.from([0x9f])); + + r.setEncoding('utf8'); + + r.push(Buffer.from([0x8e])); + r.push(Buffer.from([0x89])); + + const chunks = []; + r.on('data', (chunk) => chunks.push(chunk)); + + process.nextTick(() => { + assert.deepStrictEqual(chunks, ['🎉']); + }); +} diff --git a/tests/node_compat/test/parallel/test-stream-readable-setEncoding-null.js b/tests/node_compat/test/parallel/test-stream-readable-setEncoding-null.js new file mode 100644 index 000000000..e6823f7cd --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readable-setEncoding-null.js @@ -0,0 +1,22 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); +const { Readable } = require('stream'); + + +{ + const readable = new Readable({ encoding: 'hex' }); + assert.strictEqual(readable._readableState.encoding, 'hex'); + + readable.setEncoding(null); + + assert.strictEqual(readable._readableState.encoding, 'utf8'); +} diff --git a/tests/node_compat/test/parallel/test-stream-readable-unshift.js b/tests/node_compat/test/parallel/test-stream-readable-unshift.js new file mode 100644 index 000000000..1303befa9 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readable-unshift.js @@ -0,0 +1,177 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const { Readable } = require('stream'); + +{ + // Check that strings are saved as Buffer + const readable = new Readable({ read() {} }); + + const string = 'abc'; + + readable.on('data', common.mustCall((chunk) => { + assert(Buffer.isBuffer(chunk)); + assert.strictEqual(chunk.toString('utf8'), string); + }, 1)); + + readable.unshift(string); + +} + +{ + // Check that data goes at the beginning + const readable = new Readable({ read() {} }); + const unshift = 'front'; + const push = 'back'; + + const expected = [unshift, push]; + readable.on('data', common.mustCall((chunk) => { + assert.strictEqual(chunk.toString('utf8'), expected.shift()); + }, 2)); + + + readable.push(push); + readable.unshift(unshift); +} + +{ + // Check that buffer is saved with correct encoding + const readable = new Readable({ read() {} }); + + const encoding = 'base64'; + const string = Buffer.from('abc').toString(encoding); + + readable.on('data', common.mustCall((chunk) => { + assert.strictEqual(chunk.toString(encoding), string); + }, 1)); + + readable.unshift(string, encoding); + +} + +{ + + const streamEncoding = 'base64'; + + function checkEncoding(readable) { + + // chunk encodings + const encodings = ['utf8', 'binary', 'hex', 'base64']; + const expected = []; + + readable.on('data', common.mustCall((chunk) => { + const { encoding, string } = expected.pop(); + assert.strictEqual(chunk.toString(encoding), string); + }, encodings.length)); + + for (const encoding of encodings) { + const string = 'abc'; + + // If encoding is the same as the state.encoding the string is + // saved as is + const expect = encoding !== streamEncoding ? + Buffer.from(string, encoding).toString(streamEncoding) : string; + + expected.push({ encoding, string: expect }); + + readable.unshift(string, encoding); + } + } + + const r1 = new Readable({ read() {} }); + r1.setEncoding(streamEncoding); + checkEncoding(r1); + + const r2 = new Readable({ read() {}, encoding: streamEncoding }); + checkEncoding(r2); + +} + +{ + // Both .push & .unshift should have the same behaviour + // When setting an encoding, each chunk should be emitted with that encoding + const encoding = 'base64'; + + function checkEncoding(readable) { + const string = 'abc'; + readable.on('data', common.mustCall((chunk) => { + assert.strictEqual(chunk, Buffer.from(string).toString(encoding)); + }, 2)); + + readable.push(string); + readable.unshift(string); + } + + const r1 = new Readable({ read() {} }); + r1.setEncoding(encoding); + checkEncoding(r1); + + const r2 = new Readable({ read() {}, encoding }); + checkEncoding(r2); + +} + +{ + // Check that ObjectMode works + const readable = new Readable({ objectMode: true, read() {} }); + + const chunks = ['a', 1, {}, []]; + + readable.on('data', common.mustCall((chunk) => { + assert.strictEqual(chunk, chunks.pop()); + }, chunks.length)); + + for (const chunk of chunks) { + readable.unshift(chunk); + } +} + +{ + + // Should not throw: https://github.com/nodejs/node/issues/27192 + const highWaterMark = 50; + class ArrayReader extends Readable { + constructor(opt) { + super({ highWaterMark }); + // The error happened only when pushing above hwm + this.buffer = new Array(highWaterMark * 2).fill(0).map(String); + } + _read(size) { + while (this.buffer.length) { + const chunk = this.buffer.shift(); + if (!this.buffer.length) { + this.push(chunk); + this.push(null); + return true; + } + if (!this.push(chunk)) + return; + } + } + } + + function onRead() { + while (null !== (stream.read())) { + // Remove the 'readable' listener before unshifting + stream.removeListener('readable', onRead); + stream.unshift('a'); + stream.on('data', (chunk) => { + console.log(chunk.length); + }); + break; + } + } + + const stream = new ArrayReader(); + stream.once('readable', common.mustCall(onRead)); + stream.on('end', common.mustCall()); + +} diff --git a/tests/node_compat/test/parallel/test-stream-readable-with-unimplemented-_read.js b/tests/node_compat/test/parallel/test-stream-readable-with-unimplemented-_read.js new file mode 100644 index 000000000..a2fe2ac01 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readable-with-unimplemented-_read.js @@ -0,0 +1,20 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const { Readable } = require('stream'); + +const readable = new Readable(); + +readable.read(); +readable.on('error', common.expectsError({ + code: 'ERR_METHOD_NOT_IMPLEMENTED', + name: 'Error', + message: 'The _read() method is not implemented' +})); +readable.on('close', common.mustCall()); diff --git a/tests/node_compat/test/parallel/test-stream-readableListening-state.js b/tests/node_compat/test/parallel/test-stream-readableListening-state.js new file mode 100644 index 000000000..69085ac86 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readableListening-state.js @@ -0,0 +1,41 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const stream = require('stream'); + +const r = new stream.Readable({ + read: () => {} +}); + +// readableListening state should start in `false`. +assert.strictEqual(r._readableState.readableListening, false); + +r.on('readable', common.mustCall(() => { + // Inside the readable event this state should be true. + assert.strictEqual(r._readableState.readableListening, true); +})); + +r.push(Buffer.from('Testing readableListening state')); + +const r2 = new stream.Readable({ + read: () => {} +}); + +// readableListening state should start in `false`. +assert.strictEqual(r2._readableState.readableListening, false); + +r2.on('data', common.mustCall((chunk) => { + // readableListening should be false because we don't have + // a `readable` listener + assert.strictEqual(r2._readableState.readableListening, false); +})); + +r2.push(Buffer.from('Testing readableListening state')); diff --git a/tests/node_compat/test/parallel/test-stream-transform-callback-twice.js b/tests/node_compat/test/parallel/test-stream-transform-callback-twice.js new file mode 100644 index 000000000..3ca0a4c68 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-transform-callback-twice.js @@ -0,0 +1,21 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const { Transform } = require('stream'); +const stream = new Transform({ + transform(chunk, enc, cb) { cb(); cb(); } +}); + +stream.on('error', common.expectsError({ + name: 'Error', + message: 'Callback called multiple times', + code: 'ERR_MULTIPLE_CALLBACK' +})); + +stream.write('foo'); diff --git a/tests/node_compat/test/parallel/test-stream-transform-constructor-set-methods.js b/tests/node_compat/test/parallel/test-stream-transform-constructor-set-methods.js new file mode 100644 index 000000000..4daf199b0 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-transform-constructor-set-methods.js @@ -0,0 +1,50 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); + +const assert = require('assert'); +const { Transform } = require('stream'); + +const t = new Transform(); + +assert.throws( + () => { + t.end(Buffer.from('blerg')); + }, + { + name: 'Error', + code: 'ERR_METHOD_NOT_IMPLEMENTED', + message: 'The _transform() method is not implemented' + } +); + +const _transform = common.mustCall((chunk, _, next) => { + next(); +}); + +const _final = common.mustCall((next) => { + next(); +}); + +const _flush = common.mustCall((next) => { + next(); +}); + +const t2 = new Transform({ + transform: _transform, + flush: _flush, + final: _final +}); + +assert.strictEqual(t2._transform, _transform); +assert.strictEqual(t2._flush, _flush); +assert.strictEqual(t2._final, _final); + +t2.end(Buffer.from('blerg')); +t2.resume(); diff --git a/tests/node_compat/test/parallel/test-stream-transform-destroy.js b/tests/node_compat/test/parallel/test-stream-transform-destroy.js new file mode 100644 index 000000000..e721f848f --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-transform-destroy.js @@ -0,0 +1,150 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const { Transform } = require('stream'); +const assert = require('assert'); + +{ + const transform = new Transform({ + transform(chunk, enc, cb) {} + }); + + transform.resume(); + + transform.on('end', common.mustNotCall()); + transform.on('close', common.mustCall()); + transform.on('finish', common.mustNotCall()); + + transform.destroy(); +} + +{ + const transform = new Transform({ + transform(chunk, enc, cb) {} + }); + transform.resume(); + + const expected = new Error('kaboom'); + + transform.on('end', common.mustNotCall()); + transform.on('finish', common.mustNotCall()); + transform.on('close', common.mustCall()); + transform.on('error', common.mustCall((err) => { + assert.strictEqual(err, expected); + })); + + transform.destroy(expected); +} + +{ + const transform = new Transform({ + transform(chunk, enc, cb) {} + }); + + transform._destroy = common.mustCall(function(err, cb) { + assert.strictEqual(err, expected); + cb(err); + }, 1); + + const expected = new Error('kaboom'); + + transform.on('finish', common.mustNotCall('no finish event')); + transform.on('close', common.mustCall()); + transform.on('error', common.mustCall((err) => { + assert.strictEqual(err, expected); + })); + + transform.destroy(expected); +} + +{ + const expected = new Error('kaboom'); + const transform = new Transform({ + transform(chunk, enc, cb) {}, + destroy: common.mustCall(function(err, cb) { + assert.strictEqual(err, expected); + cb(); + }, 1) + }); + transform.resume(); + + transform.on('end', common.mustNotCall('no end event')); + transform.on('close', common.mustCall()); + transform.on('finish', common.mustNotCall('no finish event')); + + // Error is swallowed by the custom _destroy + transform.on('error', common.mustNotCall('no error event')); + + transform.destroy(expected); +} + +{ + const transform = new Transform({ + transform(chunk, enc, cb) {} + }); + + transform._destroy = common.mustCall(function(err, cb) { + assert.strictEqual(err, null); + cb(); + }, 1); + + transform.destroy(); +} + +{ + const transform = new Transform({ + transform(chunk, enc, cb) {} + }); + transform.resume(); + + transform._destroy = common.mustCall(function(err, cb) { + assert.strictEqual(err, null); + process.nextTick(() => { + this.push(null); + this.end(); + cb(); + }); + }, 1); + + const fail = common.mustNotCall('no event'); + + transform.on('finish', fail); + transform.on('end', fail); + transform.on('close', common.mustCall()); + + transform.destroy(); + + transform.removeListener('end', fail); + transform.removeListener('finish', fail); + transform.on('end', common.mustCall()); + transform.on('finish', common.mustNotCall()); +} + +{ + const transform = new Transform({ + transform(chunk, enc, cb) {} + }); + + const expected = new Error('kaboom'); + + transform._destroy = common.mustCall(function(err, cb) { + assert.strictEqual(err, null); + cb(expected); + }, 1); + + transform.on('close', common.mustCall()); + transform.on('finish', common.mustNotCall('no finish event')); + transform.on('end', common.mustNotCall('no end event')); + transform.on('error', common.mustCall((err) => { + assert.strictEqual(err, expected); + })); + + transform.destroy(); +} diff --git a/tests/node_compat/test/parallel/test-stream-transform-final-sync.js b/tests/node_compat/test/parallel/test-stream-transform-final-sync.js new file mode 100644 index 000000000..5d108097d --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-transform-final-sync.js @@ -0,0 +1,117 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const stream = require('stream'); +let state = 0; + + +// What you do +// +// const stream = new stream.Transform({ +// transform: function transformCallback(chunk, _, next) { +// // part 1 +// this.push(chunk); +// //part 2 +// next(); +// }, +// final: function endCallback(done) { +// // part 1 +// process.nextTick(function () { +// // part 2 +// done(); +// }); +// }, +// flush: function flushCallback(done) { +// // part 1 +// process.nextTick(function () { +// // part 2 +// done(); +// }); +// } +// }); +// t.on('data', dataListener); +// t.on('end', endListener); +// t.on('finish', finishListener); +// t.write(1); +// t.write(4); +// t.end(7, endMethodCallback); +// +// The order things are called +// +// 1. transformCallback part 1 +// 2. dataListener +// 3. transformCallback part 2 +// 4. transformCallback part 1 +// 5. dataListener +// 6. transformCallback part 2 +// 7. transformCallback part 1 +// 8. dataListener +// 9. transformCallback part 2 +// 10. finalCallback part 1 +// 11. finalCallback part 2 +// 12. flushCallback part 1 +// 13. finishListener +// 14. endMethodCallback +// 15. flushCallback part 2 +// 16. endListener + +const t = new stream.Transform({ + objectMode: true, + transform: common.mustCall(function(chunk, _, next) { + // transformCallback part 1 + assert.strictEqual(++state, chunk); + this.push(state); + // transformCallback part 2 + assert.strictEqual(++state, chunk + 2); + process.nextTick(next); + }, 3), + final: common.mustCall(function(done) { + state++; + // finalCallback part 1 + assert.strictEqual(state, 10); + state++; + // finalCallback part 2 + assert.strictEqual(state, 11); + done(); + }, 1), + flush: common.mustCall(function(done) { + state++; + // fluchCallback part 1 + assert.strictEqual(state, 12); + process.nextTick(function() { + state++; + // fluchCallback part 2 + assert.strictEqual(state, 13); + done(); + }); + }, 1) +}); +t.on('finish', common.mustCall(function() { + state++; + // finishListener + assert.strictEqual(state, 15); +}, 1)); +t.on('end', common.mustCall(function() { + state++; + // endEvent + assert.strictEqual(state, 16); +}, 1)); +t.on('data', common.mustCall(function(d) { + // dataListener + assert.strictEqual(++state, d + 1); +}, 3)); +t.write(1); +t.write(4); +t.end(7, common.mustCall(function() { + state++; + // endMethodCallback + assert.strictEqual(state, 14); +}, 1)); diff --git a/tests/node_compat/test/parallel/test-stream-transform-final.js b/tests/node_compat/test/parallel/test-stream-transform-final.js new file mode 100644 index 000000000..1d14adf6b --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-transform-final.js @@ -0,0 +1,119 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const stream = require('stream'); +let state = 0; + + +// What you do: +// +// const stream = new stream.Transform({ +// transform: function transformCallback(chunk, _, next) { +// // part 1 +// this.push(chunk); +// //part 2 +// next(); +// }, +// final: function endCallback(done) { +// // part 1 +// process.nextTick(function () { +// // part 2 +// done(); +// }); +// }, +// flush: function flushCallback(done) { +// // part 1 +// process.nextTick(function () { +// // part 2 +// done(); +// }); +// } +// }); +// t.on('data', dataListener); +// t.on('end', endListener); +// t.on('finish', finishListener); +// t.write(1); +// t.write(4); +// t.end(7, endMethodCallback); +// +// The order things are called + +// 1. transformCallback part 1 +// 2. dataListener +// 3. transformCallback part 2 +// 4. transformCallback part 1 +// 5. dataListener +// 6. transformCallback part 2 +// 7. transformCallback part 1 +// 8. dataListener +// 9. transformCallback part 2 +// 10. finalCallback part 1 +// 11. finalCallback part 2 +// 12. flushCallback part 1 +// 13. finishListener +// 14. endMethodCallback +// 15. flushCallback part 2 +// 16. endListener + +const t = new stream.Transform({ + objectMode: true, + transform: common.mustCall(function(chunk, _, next) { + // transformCallback part 1 + assert.strictEqual(++state, chunk); + this.push(state); + // transformCallback part 2 + assert.strictEqual(++state, chunk + 2); + process.nextTick(next); + }, 3), + final: common.mustCall(function(done) { + state++; + // finalCallback part 1 + assert.strictEqual(state, 10); + setTimeout(function() { + state++; + // finalCallback part 2 + assert.strictEqual(state, 11); + done(); + }, 100); + }, 1), + flush: common.mustCall(function(done) { + state++; + // flushCallback part 1 + assert.strictEqual(state, 12); + process.nextTick(function() { + state++; + // flushCallback part 2 + assert.strictEqual(state, 13); + done(); + }); + }, 1) +}); +t.on('finish', common.mustCall(function() { + state++; + // finishListener + assert.strictEqual(state, 15); +}, 1)); +t.on('end', common.mustCall(function() { + state++; + // end event + assert.strictEqual(state, 16); +}, 1)); +t.on('data', common.mustCall(function(d) { + // dataListener + assert.strictEqual(++state, d + 1); +}, 3)); +t.write(1); +t.write(4); +t.end(7, common.mustCall(function() { + state++; + // endMethodCallback + assert.strictEqual(state, 14); +}, 1)); diff --git a/tests/node_compat/test/parallel/test-stream-transform-flush-data.js b/tests/node_compat/test/parallel/test-stream-transform-flush-data.js new file mode 100644 index 000000000..6b8ba1adc --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-transform-flush-data.js @@ -0,0 +1,35 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); + +const assert = require('assert'); +const Transform = require('stream').Transform; + + +const expected = 'asdf'; + + +function _transform(d, e, n) { + n(); +} + +function _flush(n) { + n(null, expected); +} + +const t = new Transform({ + transform: _transform, + flush: _flush +}); + +t.end(Buffer.from('blerg')); +t.on('data', (data) => { + assert.strictEqual(data.toString(), expected); +}); diff --git a/tests/node_compat/test/parallel/test-stream-transform-objectmode-falsey-value.js b/tests/node_compat/test/parallel/test-stream-transform-objectmode-falsey-value.js new file mode 100644 index 000000000..12390fe36 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-transform-objectmode-falsey-value.js @@ -0,0 +1,58 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const stream = require('stream'); +const PassThrough = stream.PassThrough; + +const src = new PassThrough({ objectMode: true }); +const tx = new PassThrough({ objectMode: true }); +const dest = new PassThrough({ objectMode: true }); + +const expect = [ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]; +const results = []; + +dest.on('data', common.mustCall(function(x) { + results.push(x); +}, expect.length)); + +src.pipe(tx).pipe(dest); + +let i = -1; +const int = setInterval(common.mustCall(function() { + if (results.length === expect.length) { + src.end(); + clearInterval(int); + assert.deepStrictEqual(results, expect); + } else { + src.write(i++); + } +}, expect.length + 1), 1); diff --git a/tests/node_compat/test/parallel/test-stream-transform-split-highwatermark.js b/tests/node_compat/test/parallel/test-stream-transform-split-highwatermark.js new file mode 100644 index 000000000..783ddfc91 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-transform-split-highwatermark.js @@ -0,0 +1,80 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const assert = require('assert'); + +const { Transform, Readable, Writable } = require('stream'); + +const DEFAULT = 16 * 1024; + +function testTransform(expectedReadableHwm, expectedWritableHwm, options) { + const t = new Transform(options); + assert.strictEqual(t._readableState.highWaterMark, expectedReadableHwm); + assert.strictEqual(t._writableState.highWaterMark, expectedWritableHwm); +} + +// Test overriding defaultHwm +testTransform(666, DEFAULT, { readableHighWaterMark: 666 }); +testTransform(DEFAULT, 777, { writableHighWaterMark: 777 }); +testTransform(666, 777, { + readableHighWaterMark: 666, + writableHighWaterMark: 777, +}); + +// Test highWaterMark overriding +testTransform(555, 555, { + highWaterMark: 555, + readableHighWaterMark: 666, +}); +testTransform(555, 555, { + highWaterMark: 555, + writableHighWaterMark: 777, +}); +testTransform(555, 555, { + highWaterMark: 555, + readableHighWaterMark: 666, + writableHighWaterMark: 777, +}); + +// Test undefined, null +[undefined, null].forEach((v) => { + testTransform(DEFAULT, DEFAULT, { readableHighWaterMark: v }); + testTransform(DEFAULT, DEFAULT, { writableHighWaterMark: v }); + testTransform(666, DEFAULT, { highWaterMark: v, readableHighWaterMark: 666 }); + testTransform(DEFAULT, 777, { highWaterMark: v, writableHighWaterMark: 777 }); +}); + +// test NaN +{ + assert.throws(() => { + new Transform({ readableHighWaterMark: NaN }); + }, { + name: 'TypeError', + code: 'ERR_INVALID_ARG_VALUE', + message: "The property 'options.readableHighWaterMark' is invalid. " + + 'Received NaN' + }); + + assert.throws(() => { + new Transform({ writableHighWaterMark: NaN }); + }, { + name: 'TypeError', + code: 'ERR_INVALID_ARG_VALUE', + message: "The property 'options.writableHighWaterMark' is invalid. " + + 'Received NaN' + }); +} + +// Test non Duplex streams ignore the options +{ + const r = new Readable({ readableHighWaterMark: 666 }); + assert.strictEqual(r._readableState.highWaterMark, DEFAULT); + const w = new Writable({ writableHighWaterMark: 777 }); + assert.strictEqual(w._writableState.highWaterMark, DEFAULT); +} diff --git a/tests/node_compat/test/parallel/test-stream-transform-split-objectmode.js b/tests/node_compat/test/parallel/test-stream-transform-split-objectmode.js new file mode 100644 index 000000000..22e2586df --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-transform-split-objectmode.js @@ -0,0 +1,88 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); + +const Transform = require('stream').Transform; + +const parser = new Transform({ readableObjectMode: true }); + +assert(parser._readableState.objectMode); +assert(!parser._writableState.objectMode); +assert.strictEqual(parser.readableHighWaterMark, 16); +assert.strictEqual(parser.writableHighWaterMark, 16 * 1024); +assert.strictEqual(parser.readableHighWaterMark, + parser._readableState.highWaterMark); +assert.strictEqual(parser.writableHighWaterMark, + parser._writableState.highWaterMark); + +parser._transform = function(chunk, enc, callback) { + callback(null, { val: chunk[0] }); +}; + +let parsed; + +parser.on('data', function(obj) { + parsed = obj; +}); + +parser.end(Buffer.from([42])); + +process.on('exit', function() { + assert.strictEqual(parsed.val, 42); +}); + + +const serializer = new Transform({ writableObjectMode: true }); + +assert(!serializer._readableState.objectMode); +assert(serializer._writableState.objectMode); +assert.strictEqual(serializer.readableHighWaterMark, 16 * 1024); +assert.strictEqual(serializer.writableHighWaterMark, 16); +assert.strictEqual(parser.readableHighWaterMark, + parser._readableState.highWaterMark); +assert.strictEqual(parser.writableHighWaterMark, + parser._writableState.highWaterMark); + +serializer._transform = function(obj, _, callback) { + callback(null, Buffer.from([obj.val])); +}; + +let serialized; + +serializer.on('data', function(chunk) { + serialized = chunk; +}); + +serializer.write({ val: 42 }); + +process.on('exit', function() { + assert.strictEqual(serialized[0], 42); +}); diff --git a/tests/node_compat/test/parallel/test-stream-uint8array.js b/tests/node_compat/test/parallel/test-stream-uint8array.js new file mode 100644 index 000000000..c8de2dfe6 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-uint8array.js @@ -0,0 +1,108 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const { Readable, Writable } = require('stream'); + +const ABC = new Uint8Array([0x41, 0x42, 0x43]); +const DEF = new Uint8Array([0x44, 0x45, 0x46]); +const GHI = new Uint8Array([0x47, 0x48, 0x49]); + +{ + // Simple Writable test. + + let n = 0; + const writable = new Writable({ + write: common.mustCall((chunk, encoding, cb) => { + assert(chunk instanceof Buffer); + if (n++ === 0) { + assert.strictEqual(String(chunk), 'ABC'); + } else { + assert.strictEqual(String(chunk), 'DEF'); + } + + cb(); + }, 2) + }); + + writable.write(ABC); + writable.end(DEF); +} + +{ + // Writable test, pass in Uint8Array in object mode. + + const writable = new Writable({ + objectMode: true, + write: common.mustCall((chunk, encoding, cb) => { + assert(!(chunk instanceof Buffer)); + assert(chunk instanceof Uint8Array); + assert.strictEqual(chunk, ABC); + assert.strictEqual(encoding, 'utf8'); + cb(); + }) + }); + + writable.end(ABC); +} + +{ + // Writable test, multiple writes carried out via writev. + let callback; + + const writable = new Writable({ + write: common.mustCall((chunk, encoding, cb) => { + assert(chunk instanceof Buffer); + assert.strictEqual(encoding, 'buffer'); + assert.strictEqual(String(chunk), 'ABC'); + callback = cb; + }), + writev: common.mustCall((chunks, cb) => { + assert.strictEqual(chunks.length, 2); + assert.strictEqual(chunks[0].encoding, 'buffer'); + assert.strictEqual(chunks[1].encoding, 'buffer'); + assert.strictEqual(chunks[0].chunk + chunks[1].chunk, 'DEFGHI'); + }) + }); + + writable.write(ABC); + writable.write(DEF); + writable.end(GHI); + callback(); +} + +{ + // Simple Readable test. + const readable = new Readable({ + read() {} + }); + + readable.push(DEF); + readable.unshift(ABC); + + const buf = readable.read(); + assert(buf instanceof Buffer); + assert.deepStrictEqual([...buf], [...ABC, ...DEF]); +} + +{ + // Readable test, setEncoding. + const readable = new Readable({ + read() {} + }); + + readable.setEncoding('utf8'); + + readable.push(DEF); + readable.unshift(ABC); + + const out = readable.read(); + assert.strictEqual(out, 'ABCDEF'); +} diff --git a/tests/node_compat/test/parallel/test-stream-unpipe-event.js b/tests/node_compat/test/parallel/test-stream-unpipe-event.js new file mode 100644 index 000000000..d0b60f435 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-unpipe-event.js @@ -0,0 +1,92 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const { Writable, Readable } = require('stream'); +class NullWriteable extends Writable { + _write(chunk, encoding, callback) { + return callback(); + } +} +class QuickEndReadable extends Readable { + _read() { + this.push(null); + } +} +class NeverEndReadable extends Readable { + _read() {} +} + +{ + const dest = new NullWriteable(); + const src = new QuickEndReadable(); + dest.on('pipe', common.mustCall()); + dest.on('unpipe', common.mustCall()); + src.pipe(dest); + setImmediate(() => { + assert.strictEqual(src._readableState.pipes.length, 0); + }); +} + +{ + const dest = new NullWriteable(); + const src = new NeverEndReadable(); + dest.on('pipe', common.mustCall()); + dest.on('unpipe', common.mustNotCall('unpipe should not have been emitted')); + src.pipe(dest); + setImmediate(() => { + assert.strictEqual(src._readableState.pipes.length, 1); + }); +} + +{ + const dest = new NullWriteable(); + const src = new NeverEndReadable(); + dest.on('pipe', common.mustCall()); + dest.on('unpipe', common.mustCall()); + src.pipe(dest); + src.unpipe(dest); + setImmediate(() => { + assert.strictEqual(src._readableState.pipes.length, 0); + }); +} + +{ + const dest = new NullWriteable(); + const src = new QuickEndReadable(); + dest.on('pipe', common.mustCall()); + dest.on('unpipe', common.mustCall()); + src.pipe(dest, { end: false }); + setImmediate(() => { + assert.strictEqual(src._readableState.pipes.length, 0); + }); +} + +{ + const dest = new NullWriteable(); + const src = new NeverEndReadable(); + dest.on('pipe', common.mustCall()); + dest.on('unpipe', common.mustNotCall('unpipe should not have been emitted')); + src.pipe(dest, { end: false }); + setImmediate(() => { + assert.strictEqual(src._readableState.pipes.length, 1); + }); +} + +{ + const dest = new NullWriteable(); + const src = new NeverEndReadable(); + dest.on('pipe', common.mustCall()); + dest.on('unpipe', common.mustCall()); + src.pipe(dest, { end: false }); + src.unpipe(dest); + setImmediate(() => { + assert.strictEqual(src._readableState.pipes.length, 0); + }); +} diff --git a/tests/node_compat/test/parallel/test-stream-unshift-empty-chunk.js b/tests/node_compat/test/parallel/test-stream-unshift-empty-chunk.js new file mode 100644 index 000000000..f6c057fd6 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-unshift-empty-chunk.js @@ -0,0 +1,87 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); + +// This test verifies that stream.unshift(Buffer.alloc(0)) or +// stream.unshift('') does not set state.reading=false. +const Readable = require('stream').Readable; + +const r = new Readable(); +let nChunks = 10; +const chunk = Buffer.alloc(10, 'x'); + +r._read = function(n) { + setImmediate(() => { + r.push(--nChunks === 0 ? null : chunk); + }); +}; + +let readAll = false; +const seen = []; +r.on('readable', () => { + let chunk; + while ((chunk = r.read()) !== null) { + seen.push(chunk.toString()); + // Simulate only reading a certain amount of the data, + // and then putting the rest of the chunk back into the + // stream, like a parser might do. We just fill it with + // 'y' so that it's easy to see which bits were touched, + // and which were not. + const putBack = Buffer.alloc(readAll ? 0 : 5, 'y'); + readAll = !readAll; + r.unshift(putBack); + } +}); + +const expect = + [ 'xxxxxxxxxx', + 'yyyyy', + 'xxxxxxxxxx', + 'yyyyy', + 'xxxxxxxxxx', + 'yyyyy', + 'xxxxxxxxxx', + 'yyyyy', + 'xxxxxxxxxx', + 'yyyyy', + 'xxxxxxxxxx', + 'yyyyy', + 'xxxxxxxxxx', + 'yyyyy', + 'xxxxxxxxxx', + 'yyyyy', + 'xxxxxxxxxx', + 'yyyyy' ]; + +r.on('end', () => { + assert.deepStrictEqual(seen, expect); + console.log('ok'); +}); diff --git a/tests/node_compat/test/parallel/test-stream-unshift-read-race.js b/tests/node_compat/test/parallel/test-stream-unshift-read-race.js new file mode 100644 index 000000000..d88850519 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-unshift-read-race.js @@ -0,0 +1,135 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +// This test verifies that: +// 1. unshift() does not cause colliding _read() calls. +// 2. unshift() after the 'end' event is an error, but after the EOF +// signalling null, it is ok, and just creates a new readable chunk. +// 3. push() after the EOF signaling null is an error. +// 4. _read() is not called after pushing the EOF null chunk. + +const stream = require('stream'); +const hwm = 10; +const r = stream.Readable({ highWaterMark: hwm, autoDestroy: false }); +const chunks = 10; + +const data = Buffer.allocUnsafe(chunks * hwm + Math.ceil(hwm / 2)); +for (let i = 0; i < data.length; i++) { + const c = 'asdf'.charCodeAt(i % 4); + data[i] = c; +} + +let pos = 0; +let pushedNull = false; +r._read = function(n) { + assert(!pushedNull, '_read after null push'); + + // Every third chunk is fast + push(!(chunks % 3)); + + function push(fast) { + assert(!pushedNull, 'push() after null push'); + const c = pos >= data.length ? null : data.slice(pos, pos + n); + pushedNull = c === null; + if (fast) { + pos += n; + r.push(c); + if (c === null) pushError(); + } else { + setTimeout(function() { + pos += n; + r.push(c); + if (c === null) pushError(); + }, 1); + } + } +}; + +function pushError() { + r.unshift(Buffer.allocUnsafe(1)); + w.end(); + + assert.throws(() => { + r.push(Buffer.allocUnsafe(1)); + }, { + code: 'ERR_STREAM_PUSH_AFTER_EOF', + name: 'Error', + message: 'stream.push() after EOF' + }); +} + + +const w = stream.Writable(); +const written = []; +w._write = function(chunk, encoding, cb) { + written.push(chunk.toString()); + cb(); +}; + +r.on('end', common.mustNotCall()); + +r.on('readable', function() { + let chunk; + while (null !== (chunk = r.read(10))) { + w.write(chunk); + if (chunk.length > 4) + r.unshift(Buffer.from('1234')); + } +}); + +w.on('finish', common.mustCall(function() { + // Each chunk should start with 1234, and then be asfdasdfasdf... + // The first got pulled out before the first unshift('1234'), so it's + // lacking that piece. + assert.strictEqual(written[0], 'asdfasdfas'); + let asdf = 'd'; + console.error(`0: ${written[0]}`); + for (let i = 1; i < written.length; i++) { + console.error(`${i.toString(32)}: ${written[i]}`); + assert.strictEqual(written[i].slice(0, 4), '1234'); + for (let j = 4; j < written[i].length; j++) { + const c = written[i].charAt(j); + assert.strictEqual(c, asdf); + switch (asdf) { + case 'a': asdf = 's'; break; + case 's': asdf = 'd'; break; + case 'd': asdf = 'f'; break; + case 'f': asdf = 'a'; break; + } + } + } +})); + +process.on('exit', function() { + assert.strictEqual(written.length, 18); + console.log('ok'); +}); diff --git a/tests/node_compat/test/parallel/test-stream-writable-change-default-encoding.js b/tests/node_compat/test/parallel/test-stream-writable-change-default-encoding.js new file mode 100644 index 000000000..547309d70 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-writable-change-default-encoding.js @@ -0,0 +1,85 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); + +const stream = require('stream'); + +class MyWritable extends stream.Writable { + constructor(fn, options) { + super(options); + this.fn = fn; + } + + _write(chunk, encoding, callback) { + this.fn(Buffer.isBuffer(chunk), typeof chunk, encoding); + callback(); + } +} + +(function defaultCondingIsUtf8() { + const m = new MyWritable(function(isBuffer, type, enc) { + assert.strictEqual(enc, 'utf8'); + }, { decodeStrings: false }); + m.write('foo'); + m.end(); +}()); + +(function changeDefaultEncodingToAscii() { + const m = new MyWritable(function(isBuffer, type, enc) { + assert.strictEqual(enc, 'ascii'); + }, { decodeStrings: false }); + m.setDefaultEncoding('ascii'); + m.write('bar'); + m.end(); +}()); + +// Change default encoding to invalid value. +assert.throws(() => { + const m = new MyWritable( + (isBuffer, type, enc) => {}, + { decodeStrings: false }); + m.setDefaultEncoding({}); + m.write('bar'); + m.end(); +}, { + name: 'TypeError', + code: 'ERR_UNKNOWN_ENCODING', + message: 'Unknown encoding: {}' +}); + +(function checkVariableCaseEncoding() { + const m = new MyWritable(function(isBuffer, type, enc) { + assert.strictEqual(enc, 'ascii'); + }, { decodeStrings: false }); + m.setDefaultEncoding('AsCii'); + m.write('bar'); + m.end(); +}()); diff --git a/tests/node_compat/test/parallel/test-stream-writable-clear-buffer.js b/tests/node_compat/test/parallel/test-stream-writable-clear-buffer.js new file mode 100644 index 000000000..ee24da756 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-writable-clear-buffer.js @@ -0,0 +1,42 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +// This test ensures that the _writeableState.bufferedRequestCount and +// the actual buffered request count are the same. + +const common = require('../common'); +const Stream = require('stream'); +const assert = require('assert'); + +class StreamWritable extends Stream.Writable { + constructor() { + super({ objectMode: true }); + } + + // Refs: https://github.com/nodejs/node/issues/6758 + // We need a timer like on the original issue thread. + // Otherwise the code will never reach our test case. + _write(chunk, encoding, cb) { + setImmediate(cb); + } +} + +const testStream = new StreamWritable(); +testStream.cork(); + +for (let i = 1; i <= 5; i++) { + testStream.write(i, common.mustCall(() => { + assert.strictEqual( + testStream._writableState.bufferedRequestCount, + testStream._writableState.getBuffer().length + ); + })); +} + +testStream.end(); diff --git a/tests/node_compat/test/parallel/test-stream-writable-constructor-set-methods.js b/tests/node_compat/test/parallel/test-stream-writable-constructor-set-methods.js new file mode 100644 index 000000000..58e687edd --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-writable-constructor-set-methods.js @@ -0,0 +1,48 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); + +const assert = require('assert'); +const { Writable } = require('stream'); + +const bufferBlerg = Buffer.from('blerg'); +const w = new Writable(); + +assert.throws( + () => { + w.end(bufferBlerg); + }, + { + name: 'Error', + code: 'ERR_METHOD_NOT_IMPLEMENTED', + message: 'The _write() method is not implemented' + } +); + +const _write = common.mustCall((chunk, _, next) => { + next(); +}); + +const _writev = common.mustCall((chunks, next) => { + assert.strictEqual(chunks.length, 2); + next(); +}); + +const w2 = new Writable({ write: _write, writev: _writev }); + +assert.strictEqual(w2._write, _write); +assert.strictEqual(w2._writev, _writev); + +w2.write(bufferBlerg); + +w2.cork(); +w2.write(bufferBlerg); +w2.write(bufferBlerg); + +w2.end(); diff --git a/tests/node_compat/test/parallel/test-stream-writable-decoded-encoding.js b/tests/node_compat/test/parallel/test-stream-writable-decoded-encoding.js new file mode 100644 index 000000000..9bf47bb1a --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-writable-decoded-encoding.js @@ -0,0 +1,65 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); + +const stream = require('stream'); + +class MyWritable extends stream.Writable { + constructor(fn, options) { + super(options); + this.fn = fn; + } + + _write(chunk, encoding, callback) { + this.fn(Buffer.isBuffer(chunk), typeof chunk, encoding); + callback(); + } +} + +{ + const m = new MyWritable(function(isBuffer, type, enc) { + assert(isBuffer); + assert.strictEqual(type, 'object'); + assert.strictEqual(enc, 'buffer'); + }, { decodeStrings: true }); + m.write('some-text', 'utf8'); + m.end(); +} + +{ + const m = new MyWritable(function(isBuffer, type, enc) { + assert(!isBuffer); + assert.strictEqual(type, 'string'); + assert.strictEqual(enc, 'utf8'); + }, { decodeStrings: false }); + m.write('some-text', 'utf8'); + m.end(); +} diff --git a/tests/node_compat/test/parallel/test-stream-writable-destroy.js b/tests/node_compat/test/parallel/test-stream-writable-destroy.js new file mode 100644 index 000000000..bfe145854 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-writable-destroy.js @@ -0,0 +1,496 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const { Writable, addAbortSignal } = require('stream'); +const assert = require('assert'); + +{ + const write = new Writable({ + write(chunk, enc, cb) { cb(); } + }); + + write.on('finish', common.mustNotCall()); + write.on('close', common.mustCall()); + + write.destroy(); + assert.strictEqual(write.destroyed, true); +} + +{ + const write = new Writable({ + write(chunk, enc, cb) { + this.destroy(new Error('asd')); + cb(); + } + }); + + write.on('error', common.mustCall()); + write.on('finish', common.mustNotCall()); + write.end('asd'); + assert.strictEqual(write.destroyed, true); +} + +{ + const write = new Writable({ + write(chunk, enc, cb) { cb(); } + }); + + const expected = new Error('kaboom'); + + write.on('finish', common.mustNotCall()); + write.on('close', common.mustCall()); + write.on('error', common.mustCall((err) => { + assert.strictEqual(err, expected); + })); + + write.destroy(expected); + assert.strictEqual(write.destroyed, true); +} + +{ + const write = new Writable({ + write(chunk, enc, cb) { cb(); } + }); + + write._destroy = function(err, cb) { + assert.strictEqual(err, expected); + cb(err); + }; + + const expected = new Error('kaboom'); + + write.on('finish', common.mustNotCall('no finish event')); + write.on('close', common.mustCall()); + write.on('error', common.mustCall((err) => { + assert.strictEqual(err, expected); + })); + + write.destroy(expected); + assert.strictEqual(write.destroyed, true); +} + +{ + const write = new Writable({ + write(chunk, enc, cb) { cb(); }, + destroy: common.mustCall(function(err, cb) { + assert.strictEqual(err, expected); + cb(); + }) + }); + + const expected = new Error('kaboom'); + + write.on('finish', common.mustNotCall('no finish event')); + write.on('close', common.mustCall()); + + // Error is swallowed by the custom _destroy + write.on('error', common.mustNotCall('no error event')); + + write.destroy(expected); + assert.strictEqual(write.destroyed, true); +} + +{ + const write = new Writable({ + write(chunk, enc, cb) { cb(); } + }); + + write._destroy = common.mustCall(function(err, cb) { + assert.strictEqual(err, null); + cb(); + }); + + write.destroy(); + assert.strictEqual(write.destroyed, true); +} + +{ + const write = new Writable({ + write(chunk, enc, cb) { cb(); } + }); + + write._destroy = common.mustCall(function(err, cb) { + assert.strictEqual(err, null); + process.nextTick(() => { + this.end(); + cb(); + }); + }); + + const fail = common.mustNotCall('no finish event'); + + write.on('finish', fail); + write.on('close', common.mustCall()); + + write.destroy(); + + assert.strictEqual(write.destroyed, true); +} + +{ + const write = new Writable({ + write(chunk, enc, cb) { cb(); } + }); + + const expected = new Error('kaboom'); + + write._destroy = common.mustCall(function(err, cb) { + assert.strictEqual(err, null); + cb(expected); + }); + + write.on('close', common.mustCall()); + write.on('finish', common.mustNotCall('no finish event')); + write.on('error', common.mustCall((err) => { + assert.strictEqual(err, expected); + })); + + write.destroy(); + assert.strictEqual(write.destroyed, true); +} + +{ + // double error case + const write = new Writable({ + write(chunk, enc, cb) { cb(); } + }); + + let ticked = false; + write.on('close', common.mustCall(() => { + assert.strictEqual(ticked, true); + })); + write.on('error', common.mustCall((err) => { + assert.strictEqual(ticked, true); + assert.strictEqual(err.message, 'kaboom 1'); + assert.strictEqual(write._writableState.errorEmitted, true); + })); + + const expected = new Error('kaboom 1'); + write.destroy(expected); + write.destroy(new Error('kaboom 2')); + assert.strictEqual(write._writableState.errored, expected); + assert.strictEqual(write._writableState.errorEmitted, false); + assert.strictEqual(write.destroyed, true); + ticked = true; +} + +{ + const writable = new Writable({ + destroy: common.mustCall(function(err, cb) { + process.nextTick(cb, new Error('kaboom 1')); + }), + write(chunk, enc, cb) { + cb(); + } + }); + + let ticked = false; + writable.on('close', common.mustCall(() => { + writable.on('error', common.mustNotCall()); + writable.destroy(new Error('hello')); + assert.strictEqual(ticked, true); + assert.strictEqual(writable._writableState.errorEmitted, true); + })); + writable.on('error', common.mustCall((err) => { + assert.strictEqual(ticked, true); + assert.strictEqual(err.message, 'kaboom 1'); + assert.strictEqual(writable._writableState.errorEmitted, true); + })); + + writable.destroy(); + assert.strictEqual(writable.destroyed, true); + assert.strictEqual(writable._writableState.errored, null); + assert.strictEqual(writable._writableState.errorEmitted, false); + + // Test case where `writable.destroy()` is called again with an error before + // the `_destroy()` callback is called. + writable.destroy(new Error('kaboom 2')); + assert.strictEqual(writable._writableState.errorEmitted, false); + assert.strictEqual(writable._writableState.errored, null); + + ticked = true; +} + +{ + const write = new Writable({ + write(chunk, enc, cb) { cb(); } + }); + + write.destroyed = true; + assert.strictEqual(write.destroyed, true); + + // The internal destroy() mechanism should not be triggered + write.on('close', common.mustNotCall()); + write.destroy(); +} + +{ + function MyWritable() { + assert.strictEqual(this.destroyed, false); + this.destroyed = false; + Writable.call(this); + } + + Object.setPrototypeOf(MyWritable.prototype, Writable.prototype); + Object.setPrototypeOf(MyWritable, Writable); + + new MyWritable(); +} + +{ + // Destroy and destroy callback + const write = new Writable({ + write(chunk, enc, cb) { cb(); } + }); + + write.destroy(); + + const expected = new Error('kaboom'); + + write.destroy(expected, common.mustCall((err) => { + assert.strictEqual(err, undefined); + })); +} + +{ + // Checks that `._undestroy()` restores the state so that `final` will be + // called again. + const write = new Writable({ + write: common.mustNotCall(), + final: common.mustCall((cb) => cb(), 2), + autoDestroy: true + }); + + write.end(); + write.once('close', common.mustCall(() => { + write._undestroy(); + write.end(); + })); +} + +{ + const write = new Writable(); + + write.destroy(); + write.on('error', common.mustNotCall()); + write.write('asd', common.expectsError({ + name: 'Error', + code: 'ERR_STREAM_DESTROYED', + message: 'Cannot call write after a stream was destroyed' + })); +} + +{ + const write = new Writable({ + write(chunk, enc, cb) { cb(); } + }); + + write.on('error', common.mustNotCall()); + + write.cork(); + write.write('asd', common.mustCall()); + write.uncork(); + + write.cork(); + write.write('asd', common.expectsError({ + name: 'Error', + code: 'ERR_STREAM_DESTROYED', + message: 'Cannot call write after a stream was destroyed' + })); + write.destroy(); + write.write('asd', common.expectsError({ + name: 'Error', + code: 'ERR_STREAM_DESTROYED', + message: 'Cannot call write after a stream was destroyed' + })); + write.uncork(); +} + +{ + // Call end(cb) after error & destroy + + const write = new Writable({ + write(chunk, enc, cb) { cb(new Error('asd')); } + }); + write.on('error', common.mustCall(() => { + write.destroy(); + let ticked = false; + write.end(common.mustCall((err) => { + assert.strictEqual(ticked, true); + assert.strictEqual(err.code, 'ERR_STREAM_DESTROYED'); + })); + ticked = true; + })); + write.write('asd'); +} + +{ + // Call end(cb) after finish & destroy + + const write = new Writable({ + write(chunk, enc, cb) { cb(); } + }); + write.on('finish', common.mustCall(() => { + write.destroy(); + let ticked = false; + write.end(common.mustCall((err) => { + assert.strictEqual(ticked, true); + assert.strictEqual(err.code, 'ERR_STREAM_ALREADY_FINISHED'); + })); + ticked = true; + })); + write.end(); +} + +{ + // Call end(cb) after error & destroy and don't trigger + // unhandled exception. + + const write = new Writable({ + write(chunk, enc, cb) { process.nextTick(cb); } + }); + const _err = new Error('asd'); + write.once('error', common.mustCall((err) => { + assert.strictEqual(err.message, 'asd'); + })); + write.end('asd', common.mustCall((err) => { + assert.strictEqual(err, _err); + })); + write.destroy(_err); +} + +{ + // Call buffered write callback with error + + const _err = new Error('asd'); + const write = new Writable({ + write(chunk, enc, cb) { + process.nextTick(cb, _err); + }, + autoDestroy: false + }); + write.cork(); + write.write('asd', common.mustCall((err) => { + assert.strictEqual(err, _err); + })); + write.write('asd', common.mustCall((err) => { + assert.strictEqual(err, _err); + })); + write.on('error', common.mustCall((err) => { + assert.strictEqual(err, _err); + })); + write.uncork(); +} + +{ + // Ensure callback order. + + let state = 0; + const write = new Writable({ + write(chunk, enc, cb) { + // `setImmediate()` is used on purpose to ensure the callback is called + // after `process.nextTick()` callbacks. + setImmediate(cb); + } + }); + write.write('asd', common.mustCall(() => { + assert.strictEqual(state++, 0); + })); + write.write('asd', common.mustCall((err) => { + assert.strictEqual(err.code, 'ERR_STREAM_DESTROYED'); + assert.strictEqual(state++, 1); + })); + write.destroy(); +} + +{ + const write = new Writable({ + autoDestroy: false, + write(chunk, enc, cb) { + cb(); + cb(); + } + }); + + write.on('error', common.mustCall(() => { + assert(write._writableState.errored); + })); + write.write('asd'); +} + +{ + const ac = new AbortController(); + const write = addAbortSignal(ac.signal, new Writable({ + write(chunk, enc, cb) { cb(); } + })); + + write.on('error', common.mustCall((e) => { + assert.strictEqual(e.name, 'AbortError'); + assert.strictEqual(write.destroyed, true); + })); + write.write('asd'); + ac.abort(); +} + +{ + const ac = new AbortController(); + const write = new Writable({ + signal: ac.signal, + write(chunk, enc, cb) { cb(); } + }); + + write.on('error', common.mustCall((e) => { + assert.strictEqual(e.name, 'AbortError'); + assert.strictEqual(write.destroyed, true); + })); + write.write('asd'); + ac.abort(); +} + +{ + const signal = AbortSignal.abort(); + + const write = new Writable({ + signal, + write(chunk, enc, cb) { cb(); } + }); + + write.on('error', common.mustCall((e) => { + assert.strictEqual(e.name, 'AbortError'); + assert.strictEqual(write.destroyed, true); + })); +} + +{ + // Destroy twice + const write = new Writable({ + write(chunk, enc, cb) { cb(); } + }); + + write.end(common.mustCall()); + write.destroy(); + write.destroy(); +} + +{ + // https://github.com/nodejs/node/issues/39356 + const s = new Writable({ + final() {} + }); + const _err = new Error('oh no'); + // Remove `callback` and it works + s.end(common.mustCall((err) => { + assert.strictEqual(err, _err); + })); + s.on('error', common.mustCall((err) => { + assert.strictEqual(err, _err); + })); + s.destroy(_err); +} diff --git a/tests/node_compat/test/parallel/test-stream-writable-end-cb-error.js b/tests/node_compat/test/parallel/test-stream-writable-end-cb-error.js new file mode 100644 index 000000000..730146db3 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-writable-end-cb-error.js @@ -0,0 +1,85 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const stream = require('stream'); + +{ + // Invoke end callback on failure. + const writable = new stream.Writable(); + + const _err = new Error('kaboom'); + writable._write = (chunk, encoding, cb) => { + process.nextTick(cb, _err); + }; + + writable.on('error', common.mustCall((err) => { + assert.strictEqual(err, _err); + })); + writable.write('asd'); + writable.end(common.mustCall((err) => { + assert.strictEqual(err, _err); + })); + writable.end(common.mustCall((err) => { + assert.strictEqual(err, _err); + })); +} + +{ + // Don't invoke end callback twice + const writable = new stream.Writable(); + + writable._write = (chunk, encoding, cb) => { + process.nextTick(cb); + }; + + let called = false; + writable.end('asd', common.mustCall((err) => { + called = true; + assert.strictEqual(err, undefined); + })); + + writable.on('error', common.mustCall((err) => { + assert.strictEqual(err.message, 'kaboom'); + })); + writable.on('finish', common.mustCall(() => { + assert.strictEqual(called, true); + writable.emit('error', new Error('kaboom')); + })); +} + +{ + const w = new stream.Writable({ + write(chunk, encoding, callback) { + setImmediate(callback); + }, + finish(callback) { + setImmediate(callback); + } + }); + w.end('testing ended state', common.mustCall((err) => { + assert.strictEqual(err.code, 'ERR_STREAM_WRITE_AFTER_END'); + })); + assert.strictEqual(w.destroyed, false); + assert.strictEqual(w.writableEnded, true); + w.end(common.mustCall((err) => { + assert.strictEqual(err.code, 'ERR_STREAM_WRITE_AFTER_END'); + })); + assert.strictEqual(w.destroyed, false); + assert.strictEqual(w.writableEnded, true); + w.end('end', common.mustCall((err) => { + assert.strictEqual(err.code, 'ERR_STREAM_WRITE_AFTER_END'); + })); + assert.strictEqual(w.destroyed, true); + w.on('error', common.mustCall((err) => { + assert.strictEqual(err.code, 'ERR_STREAM_WRITE_AFTER_END'); + })); + w.on('finish', common.mustNotCall()); +} diff --git a/tests/node_compat/test/parallel/test-stream-writable-end-multiple.js b/tests/node_compat/test/parallel/test-stream-writable-end-multiple.js new file mode 100644 index 000000000..ea1759303 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-writable-end-multiple.js @@ -0,0 +1,29 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); + +const assert = require('assert'); +const stream = require('stream'); + +const writable = new stream.Writable(); +writable._write = (chunk, encoding, cb) => { + setTimeout(() => cb(), 10); +}; + +writable.end('testing ended state', common.mustCall()); +writable.end(common.mustCall()); +writable.on('finish', common.mustCall(() => { + let ticked = false; + writable.end(common.mustCall((err) => { + assert.strictEqual(ticked, true); + assert.strictEqual(err.code, 'ERR_STREAM_ALREADY_FINISHED'); + })); + ticked = true; +})); diff --git a/tests/node_compat/test/parallel/test-stream-writable-ended-state.js b/tests/node_compat/test/parallel/test-stream-writable-ended-state.js new file mode 100644 index 000000000..f6f6971a2 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-writable-ended-state.js @@ -0,0 +1,39 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); + +const assert = require('assert'); +const stream = require('stream'); + +const writable = new stream.Writable(); + +writable._write = (chunk, encoding, cb) => { + assert.strictEqual(writable._writableState.ended, false); + assert.strictEqual(writable._writableState.writable, undefined); + assert.strictEqual(writable.writableEnded, false); + cb(); +}; + +assert.strictEqual(writable._writableState.ended, false); +assert.strictEqual(writable._writableState.writable, undefined); +assert.strictEqual(writable.writable, true); +assert.strictEqual(writable.writableEnded, false); + +writable.end('testing ended state', common.mustCall(() => { + assert.strictEqual(writable._writableState.ended, true); + assert.strictEqual(writable._writableState.writable, undefined); + assert.strictEqual(writable.writable, false); + assert.strictEqual(writable.writableEnded, true); +})); + +assert.strictEqual(writable._writableState.ended, true); +assert.strictEqual(writable._writableState.writable, undefined); +assert.strictEqual(writable.writable, false); +assert.strictEqual(writable.writableEnded, true); diff --git a/tests/node_compat/test/parallel/test-stream-writable-finish-destroyed.js b/tests/node_compat/test/parallel/test-stream-writable-finish-destroyed.js new file mode 100644 index 000000000..9d8775dec --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-writable-finish-destroyed.js @@ -0,0 +1,50 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const { Writable } = require('stream'); + +{ + const w = new Writable({ + write: common.mustCall((chunk, encoding, cb) => { + w.on('close', common.mustCall(() => { + cb(); + })); + }) + }); + + w.on('finish', common.mustNotCall()); + w.end('asd'); + w.destroy(); +} + +{ + const w = new Writable({ + write: common.mustCall((chunk, encoding, cb) => { + w.on('close', common.mustCall(() => { + cb(); + w.end(); + })); + }) + }); + + w.on('finish', common.mustNotCall()); + w.write('asd'); + w.destroy(); +} + +{ + const w = new Writable({ + write() { + } + }); + w.on('finish', common.mustNotCall()); + w.end(); + w.destroy(); +} diff --git a/tests/node_compat/test/parallel/test-stream-writable-finished-state.js b/tests/node_compat/test/parallel/test-stream-writable-finished-state.js new file mode 100644 index 000000000..0b7333bf2 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-writable-finished-state.js @@ -0,0 +1,29 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); + +const assert = require('assert'); +const stream = require('stream'); + +const writable = new stream.Writable(); + +writable._write = (chunk, encoding, cb) => { + // The state finished should start in false. + assert.strictEqual(writable._writableState.finished, false); + cb(); +}; + +writable.on('finish', common.mustCall(() => { + assert.strictEqual(writable._writableState.finished, true); +})); + +writable.end('testing finished state', common.mustCall(() => { + assert.strictEqual(writable._writableState.finished, true); +})); diff --git a/tests/node_compat/test/parallel/test-stream-writable-finished.js b/tests/node_compat/test/parallel/test-stream-writable-finished.js new file mode 100644 index 000000000..30ae737f9 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-writable-finished.js @@ -0,0 +1,106 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const { Writable } = require('stream'); +const assert = require('assert'); + +// basic +{ + // Find it on Writable.prototype + assert(Object.hasOwn(Writable.prototype, 'writableFinished')); +} + +// event +{ + const writable = new Writable(); + + writable._write = (chunk, encoding, cb) => { + // The state finished should start in false. + assert.strictEqual(writable.writableFinished, false); + cb(); + }; + + writable.on('finish', common.mustCall(() => { + assert.strictEqual(writable.writableFinished, true); + })); + + writable.end('testing finished state', common.mustCall(() => { + assert.strictEqual(writable.writableFinished, true); + })); +} + +{ + // Emit finish asynchronously. + + const w = new Writable({ + write(chunk, encoding, cb) { + cb(); + } + }); + + w.end(); + w.on('finish', common.mustCall()); +} + +{ + // Emit prefinish synchronously. + + const w = new Writable({ + write(chunk, encoding, cb) { + cb(); + } + }); + + let sync = true; + w.on('prefinish', common.mustCall(() => { + assert.strictEqual(sync, true); + })); + w.end(); + sync = false; +} + +{ + // Emit prefinish synchronously w/ final. + + const w = new Writable({ + write(chunk, encoding, cb) { + cb(); + }, + final(cb) { + cb(); + } + }); + + let sync = true; + w.on('prefinish', common.mustCall(() => { + assert.strictEqual(sync, true); + })); + w.end(); + sync = false; +} + + +{ + // Call _final synchronously. + + let sync = true; + const w = new Writable({ + write(chunk, encoding, cb) { + cb(); + }, + final: common.mustCall((cb) => { + assert.strictEqual(sync, true); + cb(); + }) + }); + + w.end(); + sync = false; +} diff --git a/tests/node_compat/test/parallel/test-stream-writable-invalid-chunk.js b/tests/node_compat/test/parallel/test-stream-writable-invalid-chunk.js new file mode 100644 index 000000000..82912adb8 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-writable-invalid-chunk.js @@ -0,0 +1,43 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const stream = require('stream'); +const assert = require('assert'); + +function testWriteType(val, objectMode, code) { + const writable = new stream.Writable({ + objectMode, + write: () => {} + }); + writable.on('error', common.mustNotCall()); + if (code) { + assert.throws(() => { + writable.write(val); + }, { code }); + } else { + writable.write(val); + } +} + +testWriteType([], false, 'ERR_INVALID_ARG_TYPE'); +testWriteType({}, false, 'ERR_INVALID_ARG_TYPE'); +testWriteType(0, false, 'ERR_INVALID_ARG_TYPE'); +testWriteType(true, false, 'ERR_INVALID_ARG_TYPE'); +testWriteType(0.0, false, 'ERR_INVALID_ARG_TYPE'); +testWriteType(undefined, false, 'ERR_INVALID_ARG_TYPE'); +testWriteType(null, false, 'ERR_STREAM_NULL_VALUES'); + +testWriteType([], true); +testWriteType({}, true); +testWriteType(0, true); +testWriteType(true, true); +testWriteType(0.0, true); +testWriteType(undefined, true); +testWriteType(null, true, 'ERR_STREAM_NULL_VALUES'); diff --git a/tests/node_compat/test/parallel/test-stream-writable-needdrain-state.js b/tests/node_compat/test/parallel/test-stream-writable-needdrain-state.js new file mode 100644 index 000000000..fe8c28921 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-writable-needdrain-state.js @@ -0,0 +1,32 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const stream = require('stream'); +const assert = require('assert'); + +const transform = new stream.Transform({ + transform: _transform, + highWaterMark: 1 +}); + +function _transform(chunk, encoding, cb) { + process.nextTick(() => { + assert.strictEqual(transform._writableState.needDrain, true); + cb(); + }); +} + +assert.strictEqual(transform._writableState.needDrain, false); + +transform.write('asdasd', common.mustCall(() => { + assert.strictEqual(transform._writableState.needDrain, false); +})); + +assert.strictEqual(transform._writableState.needDrain, true); diff --git a/tests/node_compat/test/parallel/test-stream-writable-null.js b/tests/node_compat/test/parallel/test-stream-writable-null.js new file mode 100644 index 000000000..e2ddd7d0a --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-writable-null.js @@ -0,0 +1,54 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const stream = require('stream'); + +class MyWritable extends stream.Writable { + constructor(options) { + super({ autoDestroy: false, ...options }); + } + _write(chunk, encoding, callback) { + assert.notStrictEqual(chunk, null); + callback(); + } +} + +{ + const m = new MyWritable({ objectMode: true }); + m.on('error', common.mustNotCall()); + assert.throws(() => { + m.write(null); + }, { + code: 'ERR_STREAM_NULL_VALUES' + }); +} + +{ + const m = new MyWritable(); + m.on('error', common.mustNotCall()); + assert.throws(() => { + m.write(false); + }, { + code: 'ERR_INVALID_ARG_TYPE' + }); +} + +{ // Should not throw. + const m = new MyWritable({ objectMode: true }); + m.write(false, assert.ifError); +} + +{ // Should not throw. + const m = new MyWritable({ objectMode: true }).on('error', (e) => { + assert.ifError(e || new Error('should not get here')); + }); + m.write(false, assert.ifError); +} diff --git a/tests/node_compat/test/parallel/test-stream-writable-properties.js b/tests/node_compat/test/parallel/test-stream-writable-properties.js new file mode 100644 index 000000000..ef19b3a01 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-writable-properties.js @@ -0,0 +1,29 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const assert = require('assert'); + +const { Writable } = require('stream'); + +{ + const w = new Writable(); + assert.strictEqual(w.writableCorked, 0); + w.uncork(); + assert.strictEqual(w.writableCorked, 0); + w.cork(); + assert.strictEqual(w.writableCorked, 1); + w.cork(); + assert.strictEqual(w.writableCorked, 2); + w.uncork(); + assert.strictEqual(w.writableCorked, 1); + w.uncork(); + assert.strictEqual(w.writableCorked, 0); + w.uncork(); + assert.strictEqual(w.writableCorked, 0); +} diff --git a/tests/node_compat/test/parallel/test-stream-writable-writable.js b/tests/node_compat/test/parallel/test-stream-writable-writable.js new file mode 100644 index 000000000..63be4b3ca --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-writable-writable.js @@ -0,0 +1,55 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const { Writable } = require('stream'); + +{ + const w = new Writable({ + write() {} + }); + assert.strictEqual(w.writable, true); + w.destroy(); + assert.strictEqual(w.writable, false); +} + +{ + const w = new Writable({ + write: common.mustCall((chunk, encoding, callback) => { + callback(new Error()); + }) + }); + assert.strictEqual(w.writable, true); + w.write('asd'); + assert.strictEqual(w.writable, false); + w.on('error', common.mustCall()); +} + +{ + const w = new Writable({ + write: common.mustCall((chunk, encoding, callback) => { + process.nextTick(() => { + callback(new Error()); + assert.strictEqual(w.writable, false); + }); + }) + }); + w.write('asd'); + w.on('error', common.mustCall()); +} + +{ + const w = new Writable({ + write: common.mustNotCall() + }); + assert.strictEqual(w.writable, true); + w.end(); + assert.strictEqual(w.writable, false); +} diff --git a/tests/node_compat/test/parallel/test-stream-writable-write-cb-error.js b/tests/node_compat/test/parallel/test-stream-writable-write-cb-error.js new file mode 100644 index 000000000..c4df3233a --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-writable-write-cb-error.js @@ -0,0 +1,65 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const { Writable } = require('stream'); +const assert = require('assert'); + +// Ensure callback is always invoked before +// error is emitted. Regardless if error was +// sync or async. + +{ + let callbackCalled = false; + // Sync Error + const writable = new Writable({ + write: common.mustCall((buf, enc, cb) => { + cb(new Error()); + }) + }); + writable.on('error', common.mustCall(() => { + assert.strictEqual(callbackCalled, true); + })); + writable.write('hi', common.mustCall(() => { + callbackCalled = true; + })); +} + +{ + let callbackCalled = false; + // Async Error + const writable = new Writable({ + write: common.mustCall((buf, enc, cb) => { + process.nextTick(cb, new Error()); + }) + }); + writable.on('error', common.mustCall(() => { + assert.strictEqual(callbackCalled, true); + })); + writable.write('hi', common.mustCall(() => { + callbackCalled = true; + })); +} + +{ + // Sync Error + const writable = new Writable({ + write: common.mustCall((buf, enc, cb) => { + cb(new Error()); + }) + }); + + writable.on('error', common.mustCall()); + + let cnt = 0; + // Ensure we don't live lock on sync error + while (writable.write('a')) + cnt++; + + assert.strictEqual(cnt, 0); +} diff --git a/tests/node_compat/test/parallel/test-stream-writable-write-cb-twice.js b/tests/node_compat/test/parallel/test-stream-writable-write-cb-twice.js new file mode 100644 index 000000000..ab2408fd9 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-writable-write-cb-twice.js @@ -0,0 +1,59 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const { Writable } = require('stream'); + +{ + // Sync + Sync + const writable = new Writable({ + write: common.mustCall((buf, enc, cb) => { + cb(); + cb(); + }) + }); + writable.write('hi'); + writable.on('error', common.expectsError({ + code: 'ERR_MULTIPLE_CALLBACK', + name: 'Error' + })); +} + +{ + // Sync + Async + const writable = new Writable({ + write: common.mustCall((buf, enc, cb) => { + cb(); + process.nextTick(() => { + cb(); + }); + }) + }); + writable.write('hi'); + writable.on('error', common.expectsError({ + code: 'ERR_MULTIPLE_CALLBACK', + name: 'Error' + })); +} + +{ + // Async + Async + const writable = new Writable({ + write: common.mustCall((buf, enc, cb) => { + process.nextTick(cb); + process.nextTick(() => { + cb(); + }); + }) + }); + writable.write('hi'); + writable.on('error', common.expectsError({ + code: 'ERR_MULTIPLE_CALLBACK', + name: 'Error' + })); +} diff --git a/tests/node_compat/test/parallel/test-stream-writable-write-error.js b/tests/node_compat/test/parallel/test-stream-writable-write-error.js new file mode 100644 index 000000000..2bb91f821 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-writable-write-error.js @@ -0,0 +1,82 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const { Writable } = require('stream'); + +function expectError(w, args, code, sync) { + if (sync) { + if (code) { + assert.throws(() => w.write(...args), { code }); + } else { + w.write(...args); + } + } else { + let errorCalled = false; + let ticked = false; + w.write(...args, common.mustCall((err) => { + assert.strictEqual(ticked, true); + assert.strictEqual(errorCalled, false); + assert.strictEqual(err.code, code); + })); + ticked = true; + w.on('error', common.mustCall((err) => { + errorCalled = true; + assert.strictEqual(err.code, code); + })); + } +} + +function test(autoDestroy) { + { + const w = new Writable({ + autoDestroy, + _write() {} + }); + w.end(); + expectError(w, ['asd'], 'ERR_STREAM_WRITE_AFTER_END'); + } + + { + const w = new Writable({ + autoDestroy, + _write() {} + }); + w.destroy(); + } + + { + const w = new Writable({ + autoDestroy, + _write() {} + }); + expectError(w, [null], 'ERR_STREAM_NULL_VALUES', true); + } + + { + const w = new Writable({ + autoDestroy, + _write() {} + }); + expectError(w, [{}], 'ERR_INVALID_ARG_TYPE', true); + } + + { + const w = new Writable({ + decodeStrings: false, + autoDestroy, + _write() {} + }); + expectError(w, ['asd', 'noencoding'], 'ERR_UNKNOWN_ENCODING', true); + } +} + +test(false); +test(true); diff --git a/tests/node_compat/test/parallel/test-stream-writable-write-writev-finish.js b/tests/node_compat/test/parallel/test-stream-writable-write-writev-finish.js new file mode 100644 index 000000000..ff34a83c1 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-writable-write-writev-finish.js @@ -0,0 +1,159 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const stream = require('stream'); + +// Ensure consistency between the finish event when using cork() +// and writev and when not using them + +{ + const writable = new stream.Writable(); + + writable._write = (chunks, encoding, cb) => { + cb(new Error('write test error')); + }; + + writable.on('finish', common.mustNotCall()); + writable.on('prefinish', common.mustNotCall()); + writable.on('error', common.mustCall((er) => { + assert.strictEqual(er.message, 'write test error'); + })); + + writable.end('test'); +} + +{ + const writable = new stream.Writable(); + + writable._write = (chunks, encoding, cb) => { + setImmediate(cb, new Error('write test error')); + }; + + writable.on('finish', common.mustNotCall()); + writable.on('prefinish', common.mustNotCall()); + writable.on('error', common.mustCall((er) => { + assert.strictEqual(er.message, 'write test error'); + })); + + writable.end('test'); +} + +{ + const writable = new stream.Writable(); + + writable._write = (chunks, encoding, cb) => { + cb(new Error('write test error')); + }; + + writable._writev = (chunks, cb) => { + cb(new Error('writev test error')); + }; + + writable.on('finish', common.mustNotCall()); + writable.on('prefinish', common.mustNotCall()); + writable.on('error', common.mustCall((er) => { + assert.strictEqual(er.message, 'writev test error'); + })); + + writable.cork(); + writable.write('test'); + + setImmediate(function() { + writable.end('test'); + }); +} + +{ + const writable = new stream.Writable(); + + writable._write = (chunks, encoding, cb) => { + setImmediate(cb, new Error('write test error')); + }; + + writable._writev = (chunks, cb) => { + setImmediate(cb, new Error('writev test error')); + }; + + writable.on('finish', common.mustNotCall()); + writable.on('prefinish', common.mustNotCall()); + writable.on('error', common.mustCall((er) => { + assert.strictEqual(er.message, 'writev test error'); + })); + + writable.cork(); + writable.write('test'); + + setImmediate(function() { + writable.end('test'); + }); +} + +// Regression test for +// https://github.com/nodejs/node/issues/13812 + +{ + const rs = new stream.Readable(); + rs.push('ok'); + rs.push(null); + rs._read = () => {}; + + const ws = new stream.Writable(); + + ws.on('finish', common.mustNotCall()); + ws.on('error', common.mustCall()); + + ws._write = (chunk, encoding, done) => { + setImmediate(done, new Error()); + }; + rs.pipe(ws); +} + +{ + const rs = new stream.Readable(); + rs.push('ok'); + rs.push(null); + rs._read = () => {}; + + const ws = new stream.Writable(); + + ws.on('finish', common.mustNotCall()); + ws.on('error', common.mustCall()); + + ws._write = (chunk, encoding, done) => { + done(new Error()); + }; + rs.pipe(ws); +} + +{ + const w = new stream.Writable(); + w._write = (chunk, encoding, cb) => { + process.nextTick(cb); + }; + w.on('error', common.mustCall()); + w.on('finish', common.mustNotCall()); + w.on('prefinish', () => { + w.write("shouldn't write in prefinish listener"); + }); + w.end(); +} + +{ + const w = new stream.Writable(); + w._write = (chunk, encoding, cb) => { + process.nextTick(cb); + }; + w.on('error', common.mustCall()); + w.on('finish', () => { + w.write("shouldn't write in finish listener"); + }); + w.end(); +} diff --git a/tests/node_compat/test/parallel/test-stream-writableState-ending.js b/tests/node_compat/test/parallel/test-stream-writableState-ending.js new file mode 100644 index 000000000..a477e63b6 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-writableState-ending.js @@ -0,0 +1,44 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); + +const assert = require('assert'); +const stream = require('stream'); + +const writable = new stream.Writable(); + +function testStates(ending, finished, ended) { + assert.strictEqual(writable._writableState.ending, ending); + assert.strictEqual(writable._writableState.finished, finished); + assert.strictEqual(writable._writableState.ended, ended); +} + +writable._write = (chunk, encoding, cb) => { + // Ending, finished, ended start in false. + testStates(false, false, false); + cb(); +}; + +writable.on('finish', () => { + // Ending, finished, ended = true. + testStates(true, true, true); +}); + +const result = writable.end('testing function end()', () => { + // Ending, finished, ended = true. + testStates(true, true, true); +}); + +// End returns the writable instance +assert.strictEqual(result, writable); + +// Ending, ended = true. +// finished = false. +testStates(true, false, true); diff --git a/tests/node_compat/test/parallel/test-stream-writableState-uncorked-bufferedRequestCount.js b/tests/node_compat/test/parallel/test-stream-writableState-uncorked-bufferedRequestCount.js new file mode 100644 index 000000000..0320d1a5d --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-writableState-uncorked-bufferedRequestCount.js @@ -0,0 +1,64 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const stream = require('stream'); + +const writable = new stream.Writable(); + +writable._writev = common.mustCall((chunks, cb) => { + assert.strictEqual(chunks.length, 2); + cb(); +}, 1); + +writable._write = common.mustCall((chunk, encoding, cb) => { + cb(); +}, 1); + +// first cork +writable.cork(); +assert.strictEqual(writable._writableState.corked, 1); +assert.strictEqual(writable._writableState.bufferedRequestCount, 0); + +// cork again +writable.cork(); +assert.strictEqual(writable._writableState.corked, 2); + +// The first chunk is buffered +writable.write('first chunk'); +assert.strictEqual(writable._writableState.bufferedRequestCount, 1); + +// First uncork does nothing +writable.uncork(); +assert.strictEqual(writable._writableState.corked, 1); +assert.strictEqual(writable._writableState.bufferedRequestCount, 1); + +process.nextTick(uncork); + +// The second chunk is buffered, because we uncork at the end of tick +writable.write('second chunk'); +assert.strictEqual(writable._writableState.corked, 1); +assert.strictEqual(writable._writableState.bufferedRequestCount, 2); + +function uncork() { + // Second uncork flushes the buffer + writable.uncork(); + assert.strictEqual(writable._writableState.corked, 0); + assert.strictEqual(writable._writableState.bufferedRequestCount, 0); + + // Verify that end() uncorks correctly + writable.cork(); + writable.write('third chunk'); + writable.end(); + + // End causes an uncork() as well + assert.strictEqual(writable._writableState.corked, 0); + assert.strictEqual(writable._writableState.bufferedRequestCount, 0); +} diff --git a/tests/node_compat/test/parallel/test-stream-write-destroy.js b/tests/node_compat/test/parallel/test-stream-write-destroy.js new file mode 100644 index 000000000..a4f103547 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-write-destroy.js @@ -0,0 +1,69 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const assert = require('assert'); +const { Writable } = require('stream'); + +// Test interaction between calling .destroy() on a writable and pending +// writes. + +for (const withPendingData of [ false, true ]) { + for (const useEnd of [ false, true ]) { + const callbacks = []; + + const w = new Writable({ + write(data, enc, cb) { + callbacks.push(cb); + }, + // Effectively disable the HWM to observe 'drain' events more easily. + highWaterMark: 1 + }); + + let chunksWritten = 0; + let drains = 0; + w.on('drain', () => drains++); + + function onWrite(err) { + if (err) { + assert.strictEqual(w.destroyed, true); + assert.strictEqual(err.code, 'ERR_STREAM_DESTROYED'); + } else { + chunksWritten++; + } + } + + w.write('abc', onWrite); + assert.strictEqual(chunksWritten, 0); + assert.strictEqual(drains, 0); + callbacks.shift()(); + assert.strictEqual(chunksWritten, 1); + assert.strictEqual(drains, 1); + + if (withPendingData) { + // Test 2 cases: There either is or is not data still in the write queue. + // (The second write will never actually get executed either way.) + w.write('def', onWrite); + } + if (useEnd) { + // Again, test 2 cases: Either we indicate that we want to end the + // writable or not. + w.end('ghi', onWrite); + } else { + w.write('ghi', onWrite); + } + + assert.strictEqual(chunksWritten, 1); + w.destroy(); + assert.strictEqual(chunksWritten, 1); + callbacks.shift()(); + assert.strictEqual(chunksWritten, useEnd && !withPendingData ? 1 : 2); + assert.strictEqual(callbacks.length, 0); + assert.strictEqual(drains, 1); + } +} diff --git a/tests/node_compat/test/parallel/test-stream-write-drain.js b/tests/node_compat/test/parallel/test-stream-write-drain.js new file mode 100644 index 000000000..008b2b34b --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-write-drain.js @@ -0,0 +1,23 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const { Writable } = require('stream'); + +// Don't emit 'drain' if ended + +const w = new Writable({ + write(data, enc, cb) { + process.nextTick(cb); + }, + highWaterMark: 1 +}); + +w.on('drain', common.mustNotCall()); +w.write('asd'); +w.end(); diff --git a/tests/node_compat/test/parallel/test-stream-write-final.js b/tests/node_compat/test/parallel/test-stream-write-final.js new file mode 100644 index 000000000..527f515eb --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-write-final.js @@ -0,0 +1,31 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const stream = require('stream'); +let shutdown = false; + +const w = new stream.Writable({ + final: common.mustCall(function(cb) { + assert.strictEqual(this, w); + setTimeout(function() { + shutdown = true; + cb(); + }, 100); + }), + write: function(chunk, e, cb) { + process.nextTick(cb); + } +}); +w.on('finish', common.mustCall(function() { + assert(shutdown); +})); +w.write(Buffer.allocUnsafe(1)); +w.end(Buffer.allocUnsafe(0)); diff --git a/tests/node_compat/test/parallel/test-stream-writev.js b/tests/node_compat/test/parallel/test-stream-writev.js new file mode 100644 index 000000000..050546646 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-writev.js @@ -0,0 +1,137 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const stream = require('stream'); + +const queue = []; +for (let decode = 0; decode < 2; decode++) { + for (let uncork = 0; uncork < 2; uncork++) { + for (let multi = 0; multi < 2; multi++) { + queue.push([!!decode, !!uncork, !!multi]); + } + } +} + +run(); + +function run() { + const t = queue.pop(); + if (t) + test(t[0], t[1], t[2], run); + else + console.log('ok'); +} + +function test(decode, uncork, multi, next) { + console.log(`# decode=${decode} uncork=${uncork} multi=${multi}`); + let counter = 0; + let expectCount = 0; + function cnt(msg) { + expectCount++; + const expect = expectCount; + return function(er) { + assert.ifError(er); + counter++; + assert.strictEqual(counter, expect); + }; + } + + const w = new stream.Writable({ decodeStrings: decode }); + w._write = common.mustNotCall('Should not call _write'); + + const expectChunks = decode ? [ + { encoding: 'buffer', + chunk: [104, 101, 108, 108, 111, 44, 32] }, + { encoding: 'buffer', + chunk: [119, 111, 114, 108, 100] }, + { encoding: 'buffer', + chunk: [33] }, + { encoding: 'buffer', + chunk: [10, 97, 110, 100, 32, 116, 104, 101, 110, 46, 46, 46] }, + { encoding: 'buffer', + chunk: [250, 206, 190, 167, 222, 173, 190, 239, 222, 202, 251, 173] }, + ] : [ + { encoding: 'ascii', chunk: 'hello, ' }, + { encoding: 'utf8', chunk: 'world' }, + { encoding: 'buffer', chunk: [33] }, + { encoding: 'latin1', chunk: '\nand then...' }, + { encoding: 'hex', chunk: 'facebea7deadbeefdecafbad' }, + ]; + + let actualChunks; + w._writev = function(chunks, cb) { + actualChunks = chunks.map(function(chunk) { + return { + encoding: chunk.encoding, + chunk: Buffer.isBuffer(chunk.chunk) ? + Array.prototype.slice.call(chunk.chunk) : chunk.chunk + }; + }); + cb(); + }; + + w.cork(); + w.write('hello, ', 'ascii', cnt('hello')); + w.write('world', 'utf8', cnt('world')); + + if (multi) + w.cork(); + + w.write(Buffer.from('!'), 'buffer', cnt('!')); + w.write('\nand then...', 'latin1', cnt('and then')); + + if (multi) + w.uncork(); + + w.write('facebea7deadbeefdecafbad', 'hex', cnt('hex')); + + if (uncork) + w.uncork(); + + w.end(cnt('end')); + + w.on('finish', function() { + // Make sure finish comes after all the write cb + cnt('finish')(); + assert.deepStrictEqual(actualChunks, expectChunks); + next(); + }); +} + +{ + const w = new stream.Writable({ + writev: common.mustCall(function(chunks, cb) { + cb(); + }) + }); + w.write('asd', common.mustCall()); +} diff --git a/tests/node_compat/test/parallel/test-stream2-base64-single-char-read-end.js b/tests/node_compat/test/parallel/test-stream2-base64-single-char-read-end.js new file mode 100644 index 000000000..34a1f7240 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream2-base64-single-char-read-end.js @@ -0,0 +1,63 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const { Readable: R, Writable: W } = require('stream'); +const assert = require('assert'); + +const src = new R({ encoding: 'base64' }); +const dst = new W(); +let hasRead = false; +const accum = []; + +src._read = function(n) { + if (!hasRead) { + hasRead = true; + process.nextTick(function() { + src.push(Buffer.from('1')); + src.push(null); + }); + } +}; + +dst._write = function(chunk, enc, cb) { + accum.push(chunk); + cb(); +}; + +src.on('end', function() { + assert.strictEqual(String(Buffer.concat(accum)), 'MQ=='); + clearTimeout(timeout); +}); + +src.pipe(dst); + +const timeout = setTimeout(function() { + assert.fail('timed out waiting for _write'); +}, 100); diff --git a/tests/node_compat/test/parallel/test-stream2-basic.js b/tests/node_compat/test/parallel/test-stream2-basic.js new file mode 100644 index 000000000..b820d5287 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream2-basic.js @@ -0,0 +1,452 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; + +const common = require('../common'); +const { Readable: R, Writable: W } = require('stream'); +const assert = require('assert'); + +const EE = require('events').EventEmitter; + +class TestReader extends R { + constructor(n) { + super(); + this._buffer = Buffer.alloc(n || 100, 'x'); + this._pos = 0; + this._bufs = 10; + } + + _read(n) { + const max = this._buffer.length - this._pos; + n = Math.max(n, 0); + const toRead = Math.min(n, max); + if (toRead === 0) { + // Simulate the read buffer filling up with some more bytes some time + // in the future. + setTimeout(() => { + this._pos = 0; + this._bufs -= 1; + if (this._bufs <= 0) { + // read them all! + if (!this.ended) + this.push(null); + } else { + // now we have more. + // kinda cheating by calling _read, but whatever, + // it's just fake anyway. + this._read(n); + } + }, 10); + return; + } + + const ret = this._buffer.slice(this._pos, this._pos + toRead); + this._pos += toRead; + this.push(ret); + } +} + +class TestWriter extends EE { + constructor() { + super(); + this.received = []; + this.flush = false; + } + + write(c) { + this.received.push(c.toString()); + this.emit('write', c); + return true; + } + + end(c) { + if (c) this.write(c); + this.emit('end', this.received); + } +} + +{ + // Test basic functionality + const r = new TestReader(20); + + const reads = []; + const expect = [ 'x', + 'xx', + 'xxx', + 'xxxx', + 'xxxxx', + 'xxxxxxxxx', + 'xxxxxxxxxx', + 'xxxxxxxxxxxx', + 'xxxxxxxxxxxxx', + 'xxxxxxxxxxxxxxx', + 'xxxxxxxxxxxxxxxxx', + 'xxxxxxxxxxxxxxxxxxx', + 'xxxxxxxxxxxxxxxxxxxxx', + 'xxxxxxxxxxxxxxxxxxxxxxx', + 'xxxxxxxxxxxxxxxxxxxxxxxxx', + 'xxxxxxxxxxxxxxxxxxxxx' ]; + + r.on('end', common.mustCall(function() { + assert.deepStrictEqual(reads, expect); + })); + + let readSize = 1; + function flow() { + let res; + while (null !== (res = r.read(readSize++))) { + reads.push(res.toString()); + } + r.once('readable', flow); + } + + flow(); +} + +{ + // Verify pipe + const r = new TestReader(5); + + const expect = [ 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx' ]; + + const w = new TestWriter(); + + w.on('end', common.mustCall(function(received) { + assert.deepStrictEqual(received, expect); + })); + + r.pipe(w); +} + + +[1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(function(SPLIT) { + // Verify unpipe + const r = new TestReader(5); + + // Unpipe after 3 writes, then write to another stream instead. + let expect = [ 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx' ]; + expect = [ expect.slice(0, SPLIT), expect.slice(SPLIT) ]; + + const w = [ new TestWriter(), new TestWriter() ]; + + let writes = SPLIT; + w[0].on('write', function() { + if (--writes === 0) { + r.unpipe(); + assert.deepStrictEqual(r._readableState.pipes, []); + w[0].end(); + r.pipe(w[1]); + assert.deepStrictEqual(r._readableState.pipes, [w[1]]); + } + }); + + let ended = 0; + + w[0].on('end', common.mustCall(function(results) { + ended++; + assert.strictEqual(ended, 1); + assert.deepStrictEqual(results, expect[0]); + })); + + w[1].on('end', common.mustCall(function(results) { + ended++; + assert.strictEqual(ended, 2); + assert.deepStrictEqual(results, expect[1]); + })); + + r.pipe(w[0]); +}); + + +{ + // Verify both writers get the same data when piping to destinations + const r = new TestReader(5); + const w = [ new TestWriter(), new TestWriter() ]; + + const expect = [ 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx' ]; + + w[0].on('end', common.mustCall(function(received) { + assert.deepStrictEqual(received, expect); + })); + w[1].on('end', common.mustCall(function(received) { + assert.deepStrictEqual(received, expect); + })); + + r.pipe(w[0]); + r.pipe(w[1]); +} + + +[1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(function(SPLIT) { + // Verify multi-unpipe + const r = new TestReader(5); + + // Unpipe after 3 writes, then write to another stream instead. + let expect = [ 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx' ]; + expect = [ expect.slice(0, SPLIT), expect.slice(SPLIT) ]; + + const w = [ new TestWriter(), new TestWriter(), new TestWriter() ]; + + let writes = SPLIT; + w[0].on('write', function() { + if (--writes === 0) { + r.unpipe(); + w[0].end(); + r.pipe(w[1]); + } + }); + + let ended = 0; + + w[0].on('end', common.mustCall(function(results) { + ended++; + assert.strictEqual(ended, 1); + assert.deepStrictEqual(results, expect[0]); + })); + + w[1].on('end', common.mustCall(function(results) { + ended++; + assert.strictEqual(ended, 2); + assert.deepStrictEqual(results, expect[1]); + })); + + r.pipe(w[0]); + r.pipe(w[2]); +}); + +{ + // Verify that back pressure is respected + const r = new R({ objectMode: true }); + r._read = common.mustNotCall(); + let counter = 0; + r.push(['one']); + r.push(['two']); + r.push(['three']); + r.push(['four']); + r.push(null); + + const w1 = new R(); + w1.write = function(chunk) { + assert.strictEqual(chunk[0], 'one'); + w1.emit('close'); + process.nextTick(function() { + r.pipe(w2); + r.pipe(w3); + }); + }; + w1.end = common.mustNotCall(); + + r.pipe(w1); + + const expected = ['two', 'two', 'three', 'three', 'four', 'four']; + + const w2 = new R(); + w2.write = function(chunk) { + assert.strictEqual(chunk[0], expected.shift()); + assert.strictEqual(counter, 0); + + counter++; + + if (chunk[0] === 'four') { + return true; + } + + setTimeout(function() { + counter--; + w2.emit('drain'); + }, 10); + + return false; + }; + w2.end = common.mustCall(); + + const w3 = new R(); + w3.write = function(chunk) { + assert.strictEqual(chunk[0], expected.shift()); + assert.strictEqual(counter, 1); + + counter++; + + if (chunk[0] === 'four') { + return true; + } + + setTimeout(function() { + counter--; + w3.emit('drain'); + }, 50); + + return false; + }; + w3.end = common.mustCall(function() { + assert.strictEqual(counter, 2); + assert.strictEqual(expected.length, 0); + }); +} + +{ + // Verify read(0) behavior for ended streams + const r = new R(); + let written = false; + let ended = false; + r._read = common.mustNotCall(); + + r.push(Buffer.from('foo')); + r.push(null); + + const v = r.read(0); + + assert.strictEqual(v, null); + + const w = new R(); + w.write = function(buffer) { + written = true; + assert.strictEqual(ended, false); + assert.strictEqual(buffer.toString(), 'foo'); + }; + + w.end = common.mustCall(function() { + ended = true; + assert.strictEqual(written, true); + }); + + r.pipe(w); +} + +{ + // Verify synchronous _read ending + const r = new R(); + let called = false; + r._read = function(n) { + r.push(null); + }; + + r.once('end', function() { + // Verify that this is called before the next tick + called = true; + }); + + r.read(); + + process.nextTick(function() { + assert.strictEqual(called, true); + }); +} + +{ + // Verify that adding readable listeners trigger data flow + const r = new R({ highWaterMark: 5 }); + let onReadable = false; + let readCalled = 0; + + r._read = function(n) { + if (readCalled++ === 2) + r.push(null); + else + r.push(Buffer.from('asdf')); + }; + + r.on('readable', function() { + onReadable = true; + r.read(); + }); + + r.on('end', common.mustCall(function() { + assert.strictEqual(readCalled, 3); + assert.ok(onReadable); + })); +} + +{ + // Verify that streams are chainable + const r = new R(); + r._read = common.mustCall(); + const r2 = r.setEncoding('utf8').pause().resume().pause(); + assert.strictEqual(r, r2); +} + +{ + // Verify readableEncoding property + assert(Object.hasOwn(R.prototype, 'readableEncoding')); + + const r = new R({ encoding: 'utf8' }); + assert.strictEqual(r.readableEncoding, 'utf8'); +} + +{ + // Verify readableObjectMode property + assert(Object.hasOwn(R.prototype, 'readableObjectMode')); + + const r = new R({ objectMode: true }); + assert.strictEqual(r.readableObjectMode, true); +} + +{ + // Verify writableObjectMode property + assert(Object.hasOwn(W.prototype, 'writableObjectMode')); + + const w = new W({ objectMode: true }); + assert.strictEqual(w.writableObjectMode, true); +} diff --git a/tests/node_compat/test/parallel/test-stream2-compatibility.js b/tests/node_compat/test/parallel/test-stream2-compatibility.js new file mode 100644 index 000000000..c228366c3 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream2-compatibility.js @@ -0,0 +1,77 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const { Readable: R, Writable: W } = require('stream'); +const assert = require('assert'); + +let ondataCalled = 0; + +class TestReader extends R { + constructor() { + super(); + this._buffer = Buffer.alloc(100, 'x'); + + this.on('data', () => { + ondataCalled++; + }); + } + + _read(n) { + this.push(this._buffer); + this._buffer = Buffer.alloc(0); + } +} + +const reader = new TestReader(); +setImmediate(function() { + assert.strictEqual(ondataCalled, 1); + console.log('ok'); + reader.push(null); +}); + +class TestWriter extends W { + constructor() { + super(); + this.write('foo'); + this.end(); + } + + _write(chunk, enc, cb) { + cb(); + } +} + +const writer = new TestWriter(); + +process.on('exit', function() { + assert.strictEqual(reader.readable, false); + assert.strictEqual(writer.writable, false); + console.log('ok'); +}); diff --git a/tests/node_compat/test/parallel/test-stream2-decode-partial.js b/tests/node_compat/test/parallel/test-stream2-decode-partial.js new file mode 100644 index 000000000..f3a9ec15d --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream2-decode-partial.js @@ -0,0 +1,30 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const { Readable } = require('stream'); +const assert = require('assert'); + +let buf = ''; +const euro = Buffer.from([0xE2, 0x82, 0xAC]); +const cent = Buffer.from([0xC2, 0xA2]); +const source = Buffer.concat([euro, cent]); + +const readable = Readable({ encoding: 'utf8' }); +readable.push(source.slice(0, 2)); +readable.push(source.slice(2, 4)); +readable.push(source.slice(4, 6)); +readable.push(null); + +readable.on('data', function(data) { + buf += data; +}); + +process.on('exit', function() { + assert.strictEqual(buf, '€¢'); +}); diff --git a/tests/node_compat/test/parallel/test-stream2-finish-pipe.js b/tests/node_compat/test/parallel/test-stream2-finish-pipe.js new file mode 100644 index 000000000..c98812ff8 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream2-finish-pipe.js @@ -0,0 +1,51 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const stream = require('stream'); + +const r = new stream.Readable(); +r._read = function(size) { + r.push(Buffer.allocUnsafe(size)); +}; + +const w = new stream.Writable(); +w._write = function(data, encoding, cb) { + process.nextTick(cb, null); +}; + +r.pipe(w); + +// end() must be called in nextTick or a WRITE_AFTER_END error occurs. +process.nextTick(() => { + // This might sound unrealistic, but it happens in net.js. When + // socket.allowHalfOpen === false, EOF will cause .destroySoon() call which + // ends the writable side of net.Socket. + w.end(); +}); diff --git a/tests/node_compat/test/parallel/test-stream2-large-read-stall.js b/tests/node_compat/test/parallel/test-stream2-large-read-stall.js new file mode 100644 index 000000000..e13b53711 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream2-large-read-stall.js @@ -0,0 +1,81 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +// If everything aligns so that you do a read(n) of exactly the +// remaining buffer, then make sure that 'end' still emits. + +const READSIZE = 100; +const PUSHSIZE = 20; +const PUSHCOUNT = 1000; +const HWM = 50; + +const Readable = require('stream').Readable; +const r = new Readable({ + highWaterMark: HWM +}); +const rs = r._readableState; + +r._read = push; + +r.on('readable', function() { + console.error('>> readable'); + let ret; + do { + console.error(` > read(${READSIZE})`); + ret = r.read(READSIZE); + console.error(` < ${ret && ret.length} (${rs.length} remain)`); + } while (ret && ret.length === READSIZE); + + console.error('<< after read()', + ret && ret.length, + rs.needReadable, + rs.length); +}); + +r.on('end', common.mustCall(function() { + assert.strictEqual(pushes, PUSHCOUNT + 1); +})); + +let pushes = 0; +function push() { + if (pushes > PUSHCOUNT) + return; + + if (pushes++ === PUSHCOUNT) { + console.error(' push(EOF)'); + return r.push(null); + } + + console.error(` push #${pushes}`); + if (r.push(Buffer.allocUnsafe(PUSHSIZE))) + setTimeout(push, 1); +} diff --git a/tests/node_compat/test/parallel/test-stream2-objects.js b/tests/node_compat/test/parallel/test-stream2-objects.js new file mode 100644 index 000000000..c5b2c981e --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream2-objects.js @@ -0,0 +1,304 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; + +const common = require('../common'); +const { Readable, Writable } = require('stream'); +const assert = require('assert'); + +function toArray(callback) { + const stream = new Writable({ objectMode: true }); + const list = []; + stream.write = function(chunk) { + list.push(chunk); + }; + + stream.end = common.mustCall(function() { + callback(list); + }); + + return stream; +} + +function fromArray(list) { + const r = new Readable({ objectMode: true }); + r._read = common.mustNotCall(); + list.forEach(function(chunk) { + r.push(chunk); + }); + r.push(null); + + return r; +} + +{ + // Verify that objects can be read from the stream + const r = fromArray([{ one: '1' }, { two: '2' }]); + + const v1 = r.read(); + const v2 = r.read(); + const v3 = r.read(); + + assert.deepStrictEqual(v1, { one: '1' }); + assert.deepStrictEqual(v2, { two: '2' }); + assert.strictEqual(v3, null); +} + +{ + // Verify that objects can be piped into the stream + const r = fromArray([{ one: '1' }, { two: '2' }]); + + r.pipe(toArray(common.mustCall(function(list) { + assert.deepStrictEqual(list, [ + { one: '1' }, + { two: '2' }, + ]); + }))); +} + +{ + // Verify that read(n) is ignored + const r = fromArray([{ one: '1' }, { two: '2' }]); + const value = r.read(2); + + assert.deepStrictEqual(value, { one: '1' }); +} + +{ + // Verify that objects can be synchronously read + const r = new Readable({ objectMode: true }); + const list = [{ one: '1' }, { two: '2' }]; + r._read = function(n) { + const item = list.shift(); + r.push(item || null); + }; + + r.pipe(toArray(common.mustCall(function(list) { + assert.deepStrictEqual(list, [ + { one: '1' }, + { two: '2' }, + ]); + }))); +} + +{ + // Verify that objects can be asynchronously read + const r = new Readable({ objectMode: true }); + const list = [{ one: '1' }, { two: '2' }]; + r._read = function(n) { + const item = list.shift(); + process.nextTick(function() { + r.push(item || null); + }); + }; + + r.pipe(toArray(common.mustCall(function(list) { + assert.deepStrictEqual(list, [ + { one: '1' }, + { two: '2' }, + ]); + }))); +} + +{ + // Verify that strings can be read as objects + const r = new Readable({ + objectMode: true + }); + r._read = common.mustNotCall(); + const list = ['one', 'two', 'three']; + list.forEach(function(str) { + r.push(str); + }); + r.push(null); + + r.pipe(toArray(common.mustCall(function(array) { + assert.deepStrictEqual(array, list); + }))); +} + +{ + // Verify read(0) behavior for object streams + const r = new Readable({ + objectMode: true + }); + r._read = common.mustNotCall(); + + r.push('foobar'); + r.push(null); + + r.pipe(toArray(common.mustCall(function(array) { + assert.deepStrictEqual(array, ['foobar']); + }))); +} + +{ + // Verify the behavior of pushing falsey values + const r = new Readable({ + objectMode: true + }); + r._read = common.mustNotCall(); + + r.push(false); + r.push(0); + r.push(''); + r.push(null); + + r.pipe(toArray(common.mustCall(function(array) { + assert.deepStrictEqual(array, [false, 0, '']); + }))); +} + +{ + // Verify high watermark _read() behavior + const r = new Readable({ + highWaterMark: 6, + objectMode: true + }); + let calls = 0; + const list = ['1', '2', '3', '4', '5', '6', '7', '8']; + + r._read = function(n) { + calls++; + }; + + list.forEach(function(c) { + r.push(c); + }); + + const v = r.read(); + + assert.strictEqual(calls, 0); + assert.strictEqual(v, '1'); + + const v2 = r.read(); + assert.strictEqual(v2, '2'); + + const v3 = r.read(); + assert.strictEqual(v3, '3'); + + assert.strictEqual(calls, 1); +} + +{ + // Verify high watermark push behavior + const r = new Readable({ + highWaterMark: 6, + objectMode: true + }); + r._read = common.mustNotCall(); + for (let i = 0; i < 6; i++) { + const bool = r.push(i); + assert.strictEqual(bool, i !== 5); + } +} + +{ + // Verify that objects can be written to stream + const w = new Writable({ objectMode: true }); + + w._write = function(chunk, encoding, cb) { + assert.deepStrictEqual(chunk, { foo: 'bar' }); + cb(); + }; + + w.on('finish', common.mustCall()); + w.write({ foo: 'bar' }); + w.end(); +} + +{ + // Verify that multiple objects can be written to stream + const w = new Writable({ objectMode: true }); + const list = []; + + w._write = function(chunk, encoding, cb) { + list.push(chunk); + cb(); + }; + + w.on('finish', common.mustCall(function() { + assert.deepStrictEqual(list, [0, 1, 2, 3, 4]); + })); + + w.write(0); + w.write(1); + w.write(2); + w.write(3); + w.write(4); + w.end(); +} + +{ + // Verify that strings can be written as objects + const w = new Writable({ + objectMode: true + }); + const list = []; + + w._write = function(chunk, encoding, cb) { + list.push(chunk); + process.nextTick(cb); + }; + + w.on('finish', common.mustCall(function() { + assert.deepStrictEqual(list, ['0', '1', '2', '3', '4']); + })); + + w.write('0'); + w.write('1'); + w.write('2'); + w.write('3'); + w.write('4'); + w.end(); +} + +{ + // Verify that stream buffers finish until callback is called + const w = new Writable({ + objectMode: true + }); + let called = false; + + w._write = function(chunk, encoding, cb) { + assert.strictEqual(chunk, 'foo'); + + process.nextTick(function() { + called = true; + cb(); + }); + }; + + w.on('finish', common.mustCall(function() { + assert.strictEqual(called, true); + })); + + w.write('foo'); + w.end(); +} diff --git a/tests/node_compat/test/parallel/test-stream2-pipe-error-handling.js b/tests/node_compat/test/parallel/test-stream2-pipe-error-handling.js new file mode 100644 index 000000000..ee8b0d656 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream2-pipe-error-handling.js @@ -0,0 +1,113 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const stream = require('stream'); + +{ + let count = 1000; + + const source = new stream.Readable(); + source._read = function(n) { + n = Math.min(count, n); + count -= n; + source.push(Buffer.allocUnsafe(n)); + }; + + let unpipedDest; + source.unpipe = function(dest) { + unpipedDest = dest; + stream.Readable.prototype.unpipe.call(this, dest); + }; + + const dest = new stream.Writable(); + dest._write = function(chunk, encoding, cb) { + cb(); + }; + + source.pipe(dest); + + let gotErr = null; + dest.on('error', function(err) { + gotErr = err; + }); + + let unpipedSource; + dest.on('unpipe', function(src) { + unpipedSource = src; + }); + + const err = new Error('This stream turned into bacon.'); + dest.emit('error', err); + assert.strictEqual(gotErr, err); + assert.strictEqual(unpipedSource, source); + assert.strictEqual(unpipedDest, dest); +} + +{ + let count = 1000; + + const source = new stream.Readable(); + source._read = function(n) { + n = Math.min(count, n); + count -= n; + source.push(Buffer.allocUnsafe(n)); + }; + + let unpipedDest; + source.unpipe = function(dest) { + unpipedDest = dest; + stream.Readable.prototype.unpipe.call(this, dest); + }; + + const dest = new stream.Writable({ autoDestroy: false }); + dest._write = function(chunk, encoding, cb) { + cb(); + }; + + source.pipe(dest); + + let unpipedSource; + dest.on('unpipe', function(src) { + unpipedSource = src; + }); + + const err = new Error('This stream turned into bacon.'); + + let gotErr = null; + try { + dest.emit('error', err); + } catch (e) { + gotErr = e; + } + assert.strictEqual(gotErr, err); + assert.strictEqual(unpipedSource, source); + assert.strictEqual(unpipedDest, dest); +} diff --git a/tests/node_compat/test/parallel/test-stream2-pipe-error-once-listener.js b/tests/node_compat/test/parallel/test-stream2-pipe-error-once-listener.js new file mode 100644 index 000000000..990dfc67d --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream2-pipe-error-once-listener.js @@ -0,0 +1,60 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; + +require('../common'); +const stream = require('stream'); + +class Read extends stream.Readable { + _read(size) { + this.push('x'); + this.push(null); + } +} + +class Write extends stream.Writable { + _write(buffer, encoding, cb) { + this.emit('error', new Error('boom')); + this.emit('alldone'); + } +} + +const read = new Read(); +const write = new Write(); + +write.once('error', () => {}); +write.once('alldone', function(err) { + console.log('ok'); +}); + +process.on('exit', function(c) { + console.error('error thrown even with listener'); +}); + +read.pipe(write); diff --git a/tests/node_compat/test/parallel/test-stream2-push.js b/tests/node_compat/test/parallel/test-stream2-push.js new file mode 100644 index 000000000..e1dcdec95 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream2-push.js @@ -0,0 +1,143 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const { Readable, Writable } = require('stream'); + +const EE = require('events').EventEmitter; + + +// A mock thing a bit like the net.Socket/tcp_wrap.handle interaction + +const stream = new Readable({ + highWaterMark: 16, + encoding: 'utf8' +}); + +const source = new EE(); + +stream._read = function() { + console.error('stream._read'); + readStart(); +}; + +let ended = false; +stream.on('end', function() { + ended = true; +}); + +source.on('data', function(chunk) { + const ret = stream.push(chunk); + console.error('data', stream.readableLength); + if (!ret) + readStop(); +}); + +source.on('end', function() { + stream.push(null); +}); + +let reading = false; + +function readStart() { + console.error('readStart'); + reading = true; +} + +function readStop() { + console.error('readStop'); + reading = false; + process.nextTick(function() { + const r = stream.read(); + if (r !== null) + writer.write(r); + }); +} + +const writer = new Writable({ + decodeStrings: false +}); + +const written = []; + +const expectWritten = + [ 'asdfgasdfgasdfgasdfg', + 'asdfgasdfgasdfgasdfg', + 'asdfgasdfgasdfgasdfg', + 'asdfgasdfgasdfgasdfg', + 'asdfgasdfgasdfgasdfg', + 'asdfgasdfgasdfgasdfg' ]; + +writer._write = function(chunk, encoding, cb) { + console.error(`WRITE ${chunk}`); + written.push(chunk); + process.nextTick(cb); +}; + +writer.on('finish', finish); + + +// Now emit some chunks. + +const chunk = 'asdfg'; + +let set = 0; +readStart(); +data(); +function data() { + assert(reading); + source.emit('data', chunk); + assert(reading); + source.emit('data', chunk); + assert(reading); + source.emit('data', chunk); + assert(reading); + source.emit('data', chunk); + assert(!reading); + if (set++ < 5) + setTimeout(data, 10); + else + end(); +} + +function finish() { + console.error('finish'); + assert.deepStrictEqual(written, expectWritten); + console.log('ok'); +} + +function end() { + source.emit('end'); + assert(!reading); + writer.end(stream.read()); + setImmediate(function() { + assert(ended); + }); +} diff --git a/tests/node_compat/test/parallel/test-stream2-read-sync-stack.js b/tests/node_compat/test/parallel/test-stream2-read-sync-stack.js new file mode 100644 index 000000000..0d291ac08 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream2-read-sync-stack.js @@ -0,0 +1,53 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const Readable = require('stream').Readable; + +// This tests synchronous read callbacks and verifies that even if they nest +// heavily the process handles it without an error + +const r = new Readable(); +const N = 256 * 1024; + +let reads = 0; +r._read = function(n) { + const chunk = reads++ === N ? null : Buffer.allocUnsafe(1); + r.push(chunk); +}; + +r.on('readable', function onReadable() { + if (!(r.readableLength % 256)) + console.error('readable', r.readableLength); + r.read(N * 2); +}); + +r.on('end', common.mustCall()); + +r.read(0); diff --git a/tests/node_compat/test/parallel/test-stream2-readable-empty-buffer-no-eof.js b/tests/node_compat/test/parallel/test-stream2-readable-empty-buffer-no-eof.js new file mode 100644 index 000000000..fca3b11f2 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream2-readable-empty-buffer-no-eof.js @@ -0,0 +1,124 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); + +const Readable = require('stream').Readable; + +test1(); +test2(); + +function test1() { + const r = new Readable(); + + // Should not end when we get a Buffer.alloc(0) or '' as the _read + // result that just means that there is *temporarily* no data, but to + // go ahead and try again later. + // + // note that this is very unusual. it only works for crypto streams + // because the other side of the stream will call read(0) to cycle + // data through openssl. that's why setImmediate() is used to call + // r.read(0) again later, otherwise there is no more work being done + // and the process just exits. + + const buf = Buffer.alloc(5, 'x'); + let reads = 5; + r._read = function(n) { + switch (reads--) { + case 5: + return setImmediate(() => { + return r.push(buf); + }); + case 4: + setImmediate(() => { + return r.push(Buffer.alloc(0)); + }); + return setImmediate(r.read.bind(r, 0)); + case 3: + setImmediate(r.read.bind(r, 0)); + return process.nextTick(() => { + return r.push(Buffer.alloc(0)); + }); + case 2: + setImmediate(r.read.bind(r, 0)); + return r.push(Buffer.alloc(0)); // Not-EOF! + case 1: + return r.push(buf); + case 0: + return r.push(null); // EOF + default: + throw new Error('unreachable'); + } + }; + + const results = []; + function flow() { + let chunk; + while (null !== (chunk = r.read())) + results.push(String(chunk)); + } + r.on('readable', flow); + r.on('end', () => { + results.push('EOF'); + }); + flow(); + + process.on('exit', () => { + assert.deepStrictEqual(results, [ 'xxxxx', 'xxxxx', 'EOF' ]); + console.log('ok'); + }); +} + +function test2() { + const r = new Readable({ encoding: 'base64' }); + let reads = 5; + r._read = function(n) { + if (!reads--) + return r.push(null); // EOF + return r.push(Buffer.from('x')); + }; + + const results = []; + function flow() { + let chunk; + while (null !== (chunk = r.read())) + results.push(String(chunk)); + } + r.on('readable', flow); + r.on('end', () => { + results.push('EOF'); + }); + flow(); + + process.on('exit', () => { + assert.deepStrictEqual(results, [ 'eHh4', 'eHg=', 'EOF' ]); + console.log('ok'); + }); +} diff --git a/tests/node_compat/test/parallel/test-stream2-readable-from-list.js b/tests/node_compat/test/parallel/test-stream2-readable-from-list.js new file mode 100644 index 000000000..90f93d040 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream2-readable-from-list.js @@ -0,0 +1,108 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// Flags: --expose-internals +'use strict'; +require('../common'); +const assert = require('assert'); +const fromList = require('stream').Readable._fromList; +const BufferList = require('internal/streams/buffer_list'); +const util = require('util'); + +function bufferListFromArray(arr) { + const bl = new BufferList(); + for (let i = 0; i < arr.length; ++i) + bl.push(arr[i]); + return bl; +} + +{ + // Verify behavior with buffers + let list = [ Buffer.from('foog'), + Buffer.from('bark'), + Buffer.from('bazy'), + Buffer.from('kuel') ]; + list = bufferListFromArray(list); + + assert.strictEqual( + util.inspect([ list ], { compact: false }), + `[ + BufferList { + head: [Object], + tail: [Object], + length: 4 + } +]`); + + // Read more than the first element. + let ret = fromList(6, { buffer: list, length: 16 }); + assert.strictEqual(ret.toString(), 'foogba'); + + // Read exactly the first element. + ret = fromList(2, { buffer: list, length: 10 }); + assert.strictEqual(ret.toString(), 'rk'); + + // Read less than the first element. + ret = fromList(2, { buffer: list, length: 8 }); + assert.strictEqual(ret.toString(), 'ba'); + + // Read more than we have. + ret = fromList(100, { buffer: list, length: 6 }); + assert.strictEqual(ret.toString(), 'zykuel'); + + // all consumed. + assert.deepStrictEqual(list, new BufferList()); +} + +{ + // Verify behavior with strings + let list = [ 'foog', + 'bark', + 'bazy', + 'kuel' ]; + list = bufferListFromArray(list); + + // Read more than the first element. + let ret = fromList(6, { buffer: list, length: 16, decoder: true }); + assert.strictEqual(ret, 'foogba'); + + // Read exactly the first element. + ret = fromList(2, { buffer: list, length: 10, decoder: true }); + assert.strictEqual(ret, 'rk'); + + // Read less than the first element. + ret = fromList(2, { buffer: list, length: 8, decoder: true }); + assert.strictEqual(ret, 'ba'); + + // Read more than we have. + ret = fromList(100, { buffer: list, length: 6, decoder: true }); + assert.strictEqual(ret, 'zykuel'); + + // all consumed. + assert.deepStrictEqual(list, new BufferList()); +} diff --git a/tests/node_compat/test/parallel/test-stream2-readable-legacy-drain.js b/tests/node_compat/test/parallel/test-stream2-readable-legacy-drain.js new file mode 100644 index 000000000..bf65fda0a --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream2-readable-legacy-drain.js @@ -0,0 +1,62 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const Stream = require('stream'); +const Readable = Stream.Readable; + +const r = new Readable(); +const N = 256; +let reads = 0; +r._read = function(n) { + return r.push(++reads === N ? null : Buffer.allocUnsafe(1)); +}; + +r.on('end', common.mustCall()); + +const w = new Stream(); +w.writable = true; +let buffered = 0; +w.write = function(c) { + buffered += c.length; + process.nextTick(drain); + return false; +}; + +function drain() { + assert(buffered <= 3); + buffered = 0; + w.emit('drain'); +} + +w.end = common.mustCall(); + +r.pipe(w); diff --git a/tests/node_compat/test/parallel/test-stream2-readable-non-empty-end.js b/tests/node_compat/test/parallel/test-stream2-readable-non-empty-end.js new file mode 100644 index 000000000..c1e3a2f46 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream2-readable-non-empty-end.js @@ -0,0 +1,79 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const { Readable } = require('stream'); + +let len = 0; +const chunks = new Array(10); +for (let i = 1; i <= 10; i++) { + chunks[i - 1] = Buffer.allocUnsafe(i); + len += i; +} + +const test = new Readable(); +let n = 0; +test._read = function(size) { + const chunk = chunks[n++]; + setTimeout(function() { + test.push(chunk === undefined ? null : chunk); + }, 1); +}; + +test.on('end', thrower); +function thrower() { + throw new Error('this should not happen!'); +} + +let bytesread = 0; +test.on('readable', function() { + const b = len - bytesread - 1; + const res = test.read(b); + if (res) { + bytesread += res.length; + console.error(`br=${bytesread} len=${len}`); + setTimeout(next, 1); + } + test.read(0); +}); +test.read(0); + +function next() { + // Now let's make 'end' happen + test.removeListener('end', thrower); + test.on('end', common.mustCall()); + + // One to get the last byte + let r = test.read(); + assert(r); + assert.strictEqual(r.length, 1); + r = test.read(); + assert.strictEqual(r, null); +} diff --git a/tests/node_compat/test/parallel/test-stream2-readable-wrap-destroy.js b/tests/node_compat/test/parallel/test-stream2-readable-wrap-destroy.js new file mode 100644 index 000000000..8971536e7 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream2-readable-wrap-destroy.js @@ -0,0 +1,34 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); + +const { Readable } = require('stream'); +const EE = require('events').EventEmitter; + +const oldStream = new EE(); +oldStream.pause = () => {}; +oldStream.resume = () => {}; + +{ + new Readable({ + autoDestroy: false, + destroy: common.mustCall() + }) + .wrap(oldStream); + oldStream.emit('destroy'); +} + +{ + new Readable({ + autoDestroy: false, + destroy: common.mustCall() + }) + .wrap(oldStream); + oldStream.emit('close'); +} diff --git a/tests/node_compat/test/parallel/test-stream2-readable-wrap-empty.js b/tests/node_compat/test/parallel/test-stream2-readable-wrap-empty.js new file mode 100644 index 000000000..5716d0bf9 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream2-readable-wrap-empty.js @@ -0,0 +1,45 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); + +const { Readable } = require('stream'); +const EE = require('events').EventEmitter; + +const oldStream = new EE(); +oldStream.pause = () => {}; +oldStream.resume = () => {}; + +const newStream = new Readable().wrap(oldStream); + +newStream + .on('readable', () => {}) + .on('end', common.mustCall()); + +oldStream.emit('end'); diff --git a/tests/node_compat/test/parallel/test-stream2-readable-wrap-error.js b/tests/node_compat/test/parallel/test-stream2-readable-wrap-error.js new file mode 100644 index 000000000..77cb757c4 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream2-readable-wrap-error.js @@ -0,0 +1,44 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const { Readable } = require('stream'); +const EE = require('events').EventEmitter; + +class LegacyStream extends EE { + pause() {} + resume() {} +} + +{ + const err = new Error(); + const oldStream = new LegacyStream(); + const r = new Readable({ autoDestroy: true }) + .wrap(oldStream) + .on('error', common.mustCall(() => { + assert.strictEqual(r._readableState.errorEmitted, true); + assert.strictEqual(r._readableState.errored, err); + assert.strictEqual(r.destroyed, true); + })); + oldStream.emit('error', err); +} + +{ + const err = new Error(); + const oldStream = new LegacyStream(); + const r = new Readable({ autoDestroy: false }) + .wrap(oldStream) + .on('error', common.mustCall(() => { + assert.strictEqual(r._readableState.errorEmitted, true); + assert.strictEqual(r._readableState.errored, err); + assert.strictEqual(r.destroyed, false); + })); + oldStream.emit('error', err); +} diff --git a/tests/node_compat/test/parallel/test-stream2-readable-wrap.js b/tests/node_compat/test/parallel/test-stream2-readable-wrap.js new file mode 100644 index 000000000..2bf8e99b0 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream2-readable-wrap.js @@ -0,0 +1,107 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const { Readable, Writable } = require('stream'); +const EE = require('events').EventEmitter; + +function runTest(highWaterMark, objectMode, produce) { + + const old = new EE(); + const r = new Readable({ highWaterMark, objectMode }); + assert.strictEqual(r, r.wrap(old)); + + r.on('end', common.mustCall()); + + old.pause = function() { + old.emit('pause'); + flowing = false; + }; + + old.resume = function() { + old.emit('resume'); + flow(); + }; + + // Make sure pause is only emitted once. + let pausing = false; + r.on('pause', () => { + assert.strictEqual(pausing, false); + pausing = true; + process.nextTick(() => { + pausing = false; + }); + }); + + let flowing; + let chunks = 10; + let oldEnded = false; + const expected = []; + function flow() { + flowing = true; + while (flowing && chunks-- > 0) { + const item = produce(); + expected.push(item); + old.emit('data', item); + } + if (chunks <= 0) { + oldEnded = true; + old.emit('end'); + } + } + + const w = new Writable({ highWaterMark: highWaterMark * 2, + objectMode }); + const written = []; + w._write = function(chunk, encoding, cb) { + written.push(chunk); + setTimeout(cb, 1); + }; + + w.on('finish', common.mustCall(function() { + performAsserts(); + })); + + r.pipe(w); + + flow(); + + function performAsserts() { + assert(oldEnded); + assert.deepStrictEqual(written, expected); + } +} + +runTest(100, false, function() { return Buffer.allocUnsafe(100); }); +runTest(10, false, function() { return Buffer.from('xxxxxxxxxx'); }); +runTest(1, true, function() { return { foo: 'bar' }; }); + +const objectChunks = [ 5, 'a', false, 0, '', 'xyz', { x: 4 }, 7, [], 555 ]; +runTest(1, true, function() { return objectChunks.shift(); }); diff --git a/tests/node_compat/test/parallel/test-stream2-set-encoding.js b/tests/node_compat/test/parallel/test-stream2-set-encoding.js new file mode 100644 index 000000000..ed7023b29 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream2-set-encoding.js @@ -0,0 +1,330 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const { Readable: R } = require('stream'); + +class TestReader extends R { + constructor(n, opts) { + super(opts); + this.pos = 0; + this.len = n || 100; + } + + _read(n) { + setTimeout(() => { + if (this.pos >= this.len) { + // Double push(null) to test eos handling + this.push(null); + return this.push(null); + } + + n = Math.min(n, this.len - this.pos); + if (n <= 0) { + // Double push(null) to test eos handling + this.push(null); + return this.push(null); + } + + this.pos += n; + const ret = Buffer.alloc(n, 'a'); + + return this.push(ret); + }, 1); + } +} + +{ + // Verify utf8 encoding + const tr = new TestReader(100); + tr.setEncoding('utf8'); + const out = []; + const expect = + [ 'aaaaaaaaaa', + 'aaaaaaaaaa', + 'aaaaaaaaaa', + 'aaaaaaaaaa', + 'aaaaaaaaaa', + 'aaaaaaaaaa', + 'aaaaaaaaaa', + 'aaaaaaaaaa', + 'aaaaaaaaaa', + 'aaaaaaaaaa' ]; + + tr.on('readable', function flow() { + let chunk; + while (null !== (chunk = tr.read(10))) + out.push(chunk); + }); + + tr.on('end', common.mustCall(function() { + assert.deepStrictEqual(out, expect); + })); +} + + +{ + // Verify hex encoding + const tr = new TestReader(100); + tr.setEncoding('hex'); + const out = []; + const expect = + [ '6161616161', + '6161616161', + '6161616161', + '6161616161', + '6161616161', + '6161616161', + '6161616161', + '6161616161', + '6161616161', + '6161616161', + '6161616161', + '6161616161', + '6161616161', + '6161616161', + '6161616161', + '6161616161', + '6161616161', + '6161616161', + '6161616161', + '6161616161' ]; + + tr.on('readable', function flow() { + let chunk; + while (null !== (chunk = tr.read(10))) + out.push(chunk); + }); + + tr.on('end', common.mustCall(function() { + assert.deepStrictEqual(out, expect); + })); +} + +{ + // Verify hex encoding with read(13) + const tr = new TestReader(100); + tr.setEncoding('hex'); + const out = []; + const expect = + [ '6161616161616', + '1616161616161', + '6161616161616', + '1616161616161', + '6161616161616', + '1616161616161', + '6161616161616', + '1616161616161', + '6161616161616', + '1616161616161', + '6161616161616', + '1616161616161', + '6161616161616', + '1616161616161', + '6161616161616', + '16161' ]; + + tr.on('readable', function flow() { + let chunk; + while (null !== (chunk = tr.read(13))) + out.push(chunk); + }); + + tr.on('end', common.mustCall(function() { + assert.deepStrictEqual(out, expect); + })); +} + +{ + // Verify base64 encoding + const tr = new TestReader(100); + tr.setEncoding('base64'); + const out = []; + const expect = + [ 'YWFhYWFhYW', + 'FhYWFhYWFh', + 'YWFhYWFhYW', + 'FhYWFhYWFh', + 'YWFhYWFhYW', + 'FhYWFhYWFh', + 'YWFhYWFhYW', + 'FhYWFhYWFh', + 'YWFhYWFhYW', + 'FhYWFhYWFh', + 'YWFhYWFhYW', + 'FhYWFhYWFh', + 'YWFhYWFhYW', + 'FhYQ==' ]; + + tr.on('readable', function flow() { + let chunk; + while (null !== (chunk = tr.read(10))) + out.push(chunk); + }); + + tr.on('end', common.mustCall(function() { + assert.deepStrictEqual(out, expect); + })); +} + +{ + // Verify utf8 encoding + const tr = new TestReader(100, { encoding: 'utf8' }); + const out = []; + const expect = + [ 'aaaaaaaaaa', + 'aaaaaaaaaa', + 'aaaaaaaaaa', + 'aaaaaaaaaa', + 'aaaaaaaaaa', + 'aaaaaaaaaa', + 'aaaaaaaaaa', + 'aaaaaaaaaa', + 'aaaaaaaaaa', + 'aaaaaaaaaa' ]; + + tr.on('readable', function flow() { + let chunk; + while (null !== (chunk = tr.read(10))) + out.push(chunk); + }); + + tr.on('end', common.mustCall(function() { + assert.deepStrictEqual(out, expect); + })); +} + + +{ + // Verify hex encoding + const tr = new TestReader(100, { encoding: 'hex' }); + const out = []; + const expect = + [ '6161616161', + '6161616161', + '6161616161', + '6161616161', + '6161616161', + '6161616161', + '6161616161', + '6161616161', + '6161616161', + '6161616161', + '6161616161', + '6161616161', + '6161616161', + '6161616161', + '6161616161', + '6161616161', + '6161616161', + '6161616161', + '6161616161', + '6161616161' ]; + + tr.on('readable', function flow() { + let chunk; + while (null !== (chunk = tr.read(10))) + out.push(chunk); + }); + + tr.on('end', common.mustCall(function() { + assert.deepStrictEqual(out, expect); + })); +} + +{ + // Verify hex encoding with read(13) + const tr = new TestReader(100, { encoding: 'hex' }); + const out = []; + const expect = + [ '6161616161616', + '1616161616161', + '6161616161616', + '1616161616161', + '6161616161616', + '1616161616161', + '6161616161616', + '1616161616161', + '6161616161616', + '1616161616161', + '6161616161616', + '1616161616161', + '6161616161616', + '1616161616161', + '6161616161616', + '16161' ]; + + tr.on('readable', function flow() { + let chunk; + while (null !== (chunk = tr.read(13))) + out.push(chunk); + }); + + tr.on('end', common.mustCall(function() { + assert.deepStrictEqual(out, expect); + })); +} + +{ + // Verify base64 encoding + const tr = new TestReader(100, { encoding: 'base64' }); + const out = []; + const expect = + [ 'YWFhYWFhYW', + 'FhYWFhYWFh', + 'YWFhYWFhYW', + 'FhYWFhYWFh', + 'YWFhYWFhYW', + 'FhYWFhYWFh', + 'YWFhYWFhYW', + 'FhYWFhYWFh', + 'YWFhYWFhYW', + 'FhYWFhYWFh', + 'YWFhYWFhYW', + 'FhYWFhYWFh', + 'YWFhYWFhYW', + 'FhYQ==' ]; + + tr.on('readable', function flow() { + let chunk; + while (null !== (chunk = tr.read(10))) + out.push(chunk); + }); + + tr.on('end', common.mustCall(function() { + assert.deepStrictEqual(out, expect); + })); +} + +{ + // Verify chaining behavior + const tr = new TestReader(100); + assert.deepStrictEqual(tr.setEncoding('utf8'), tr); +} diff --git a/tests/node_compat/test/parallel/test-stream2-transform.js b/tests/node_compat/test/parallel/test-stream2-transform.js new file mode 100644 index 000000000..2bd376b1f --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream2-transform.js @@ -0,0 +1,501 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const { PassThrough, Transform } = require('stream'); + +{ + // Verify writable side consumption + const tx = new Transform({ + highWaterMark: 10 + }); + + let transformed = 0; + tx._transform = function(chunk, encoding, cb) { + transformed += chunk.length; + tx.push(chunk); + cb(); + }; + + for (let i = 1; i <= 10; i++) { + tx.write(Buffer.allocUnsafe(i)); + } + tx.end(); + + assert.strictEqual(tx.readableLength, 10); + assert.strictEqual(transformed, 10); + assert.deepStrictEqual(tx.writableBuffer.map(function(c) { + return c.chunk.length; + }), [5, 6, 7, 8, 9, 10]); +} + +{ + // Verify passthrough behavior + const pt = new PassThrough(); + + pt.write(Buffer.from('foog')); + pt.write(Buffer.from('bark')); + pt.write(Buffer.from('bazy')); + pt.write(Buffer.from('kuel')); + pt.end(); + + assert.strictEqual(pt.read(5).toString(), 'foogb'); + assert.strictEqual(pt.read(5).toString(), 'arkba'); + assert.strictEqual(pt.read(5).toString(), 'zykue'); + assert.strictEqual(pt.read(5).toString(), 'l'); +} + +{ + // Verify object passthrough behavior + const pt = new PassThrough({ objectMode: true }); + + pt.write(1); + pt.write(true); + pt.write(false); + pt.write(0); + pt.write('foo'); + pt.write(''); + pt.write({ a: 'b' }); + pt.end(); + + assert.strictEqual(pt.read(), 1); + assert.strictEqual(pt.read(), true); + assert.strictEqual(pt.read(), false); + assert.strictEqual(pt.read(), 0); + assert.strictEqual(pt.read(), 'foo'); + assert.strictEqual(pt.read(), ''); + assert.deepStrictEqual(pt.read(), { a: 'b' }); +} + +{ + // Verify passthrough constructor behavior + const pt = PassThrough(); + + assert(pt instanceof PassThrough); +} + +{ + // Verify transform constructor behavior + const pt = Transform(); + + assert(pt instanceof Transform); +} + +{ + // Perform a simple transform + const pt = new Transform(); + pt._transform = function(c, e, cb) { + const ret = Buffer.alloc(c.length, 'x'); + pt.push(ret); + cb(); + }; + + pt.write(Buffer.from('foog')); + pt.write(Buffer.from('bark')); + pt.write(Buffer.from('bazy')); + pt.write(Buffer.from('kuel')); + pt.end(); + + assert.strictEqual(pt.read(5).toString(), 'xxxxx'); + assert.strictEqual(pt.read(5).toString(), 'xxxxx'); + assert.strictEqual(pt.read(5).toString(), 'xxxxx'); + assert.strictEqual(pt.read(5).toString(), 'x'); +} + +{ + // Verify simple object transform + const pt = new Transform({ objectMode: true }); + pt._transform = function(c, e, cb) { + pt.push(JSON.stringify(c)); + cb(); + }; + + pt.write(1); + pt.write(true); + pt.write(false); + pt.write(0); + pt.write('foo'); + pt.write(''); + pt.write({ a: 'b' }); + pt.end(); + + assert.strictEqual(pt.read(), '1'); + assert.strictEqual(pt.read(), 'true'); + assert.strictEqual(pt.read(), 'false'); + assert.strictEqual(pt.read(), '0'); + assert.strictEqual(pt.read(), '"foo"'); + assert.strictEqual(pt.read(), '""'); + assert.strictEqual(pt.read(), '{"a":"b"}'); +} + +{ + // Verify async passthrough + const pt = new Transform(); + pt._transform = function(chunk, encoding, cb) { + setTimeout(function() { + pt.push(chunk); + cb(); + }, 10); + }; + + pt.write(Buffer.from('foog')); + pt.write(Buffer.from('bark')); + pt.write(Buffer.from('bazy')); + pt.write(Buffer.from('kuel')); + pt.end(); + + pt.on('finish', common.mustCall(function() { + assert.strictEqual(pt.read(5).toString(), 'foogb'); + assert.strictEqual(pt.read(5).toString(), 'arkba'); + assert.strictEqual(pt.read(5).toString(), 'zykue'); + assert.strictEqual(pt.read(5).toString(), 'l'); + })); +} + +{ + // Verify asymmetric transform (expand) + const pt = new Transform(); + + // Emit each chunk 2 times. + pt._transform = function(chunk, encoding, cb) { + setTimeout(function() { + pt.push(chunk); + setTimeout(function() { + pt.push(chunk); + cb(); + }, 10); + }, 10); + }; + + pt.write(Buffer.from('foog')); + pt.write(Buffer.from('bark')); + pt.write(Buffer.from('bazy')); + pt.write(Buffer.from('kuel')); + pt.end(); + + pt.on('finish', common.mustCall(function() { + assert.strictEqual(pt.read(5).toString(), 'foogf'); + assert.strictEqual(pt.read(5).toString(), 'oogba'); + assert.strictEqual(pt.read(5).toString(), 'rkbar'); + assert.strictEqual(pt.read(5).toString(), 'kbazy'); + assert.strictEqual(pt.read(5).toString(), 'bazyk'); + assert.strictEqual(pt.read(5).toString(), 'uelku'); + assert.strictEqual(pt.read(5).toString(), 'el'); + })); +} + +{ + // Verify asymmetric transform (compress) + const pt = new Transform(); + + // Each output is the first char of 3 consecutive chunks, + // or whatever's left. + pt.state = ''; + + pt._transform = function(chunk, encoding, cb) { + if (!chunk) + chunk = ''; + const s = chunk.toString(); + setTimeout(() => { + this.state += s.charAt(0); + if (this.state.length === 3) { + pt.push(Buffer.from(this.state)); + this.state = ''; + } + cb(); + }, 10); + }; + + pt._flush = function(cb) { + // Just output whatever we have. + pt.push(Buffer.from(this.state)); + this.state = ''; + cb(); + }; + + pt.write(Buffer.from('aaaa')); + pt.write(Buffer.from('bbbb')); + pt.write(Buffer.from('cccc')); + pt.write(Buffer.from('dddd')); + pt.write(Buffer.from('eeee')); + pt.write(Buffer.from('aaaa')); + pt.write(Buffer.from('bbbb')); + pt.write(Buffer.from('cccc')); + pt.write(Buffer.from('dddd')); + pt.write(Buffer.from('eeee')); + pt.write(Buffer.from('aaaa')); + pt.write(Buffer.from('bbbb')); + pt.write(Buffer.from('cccc')); + pt.write(Buffer.from('dddd')); + pt.end(); + + // 'abcdeabcdeabcd' + pt.on('finish', common.mustCall(function() { + assert.strictEqual(pt.read(5).toString(), 'abcde'); + assert.strictEqual(pt.read(5).toString(), 'abcde'); + assert.strictEqual(pt.read(5).toString(), 'abcd'); + })); +} + +// This tests for a stall when data is written to a full stream +// that has empty transforms. +{ + // Verify complex transform behavior + let count = 0; + let saved = null; + const pt = new Transform({ highWaterMark: 3 }); + pt._transform = function(c, e, cb) { + if (count++ === 1) + saved = c; + else { + if (saved) { + pt.push(saved); + saved = null; + } + pt.push(c); + } + + cb(); + }; + + pt.once('readable', function() { + process.nextTick(function() { + pt.write(Buffer.from('d')); + pt.write(Buffer.from('ef'), common.mustCall(function() { + pt.end(); + })); + assert.strictEqual(pt.read().toString(), 'abcdef'); + assert.strictEqual(pt.read(), null); + }); + }); + + pt.write(Buffer.from('abc')); +} + + +{ + // Verify passthrough event emission + const pt = new PassThrough(); + let emits = 0; + pt.on('readable', function() { + emits++; + }); + + pt.write(Buffer.from('foog')); + pt.write(Buffer.from('bark')); + + assert.strictEqual(emits, 0); + assert.strictEqual(pt.read(5).toString(), 'foogb'); + assert.strictEqual(String(pt.read(5)), 'null'); + assert.strictEqual(emits, 0); + + pt.write(Buffer.from('bazy')); + pt.write(Buffer.from('kuel')); + + assert.strictEqual(emits, 0); + assert.strictEqual(pt.read(5).toString(), 'arkba'); + assert.strictEqual(pt.read(5).toString(), 'zykue'); + assert.strictEqual(pt.read(5), null); + + pt.end(); + + assert.strictEqual(emits, 1); + assert.strictEqual(pt.read(5).toString(), 'l'); + assert.strictEqual(pt.read(5), null); + assert.strictEqual(emits, 1); +} + +{ + // Verify passthrough event emission reordering + const pt = new PassThrough(); + let emits = 0; + pt.on('readable', function() { + emits++; + }); + + pt.write(Buffer.from('foog')); + pt.write(Buffer.from('bark')); + + assert.strictEqual(emits, 0); + assert.strictEqual(pt.read(5).toString(), 'foogb'); + assert.strictEqual(pt.read(5), null); + + pt.once('readable', common.mustCall(function() { + assert.strictEqual(pt.read(5).toString(), 'arkba'); + assert.strictEqual(pt.read(5), null); + + pt.once('readable', common.mustCall(function() { + assert.strictEqual(pt.read(5).toString(), 'zykue'); + assert.strictEqual(pt.read(5), null); + pt.once('readable', common.mustCall(function() { + assert.strictEqual(pt.read(5).toString(), 'l'); + assert.strictEqual(pt.read(5), null); + assert.strictEqual(emits, 3); + })); + pt.end(); + })); + pt.write(Buffer.from('kuel')); + })); + + pt.write(Buffer.from('bazy')); +} + +{ + // Verify passthrough facade + const pt = new PassThrough(); + const datas = []; + pt.on('data', function(chunk) { + datas.push(chunk.toString()); + }); + + pt.on('end', common.mustCall(function() { + assert.deepStrictEqual(datas, ['foog', 'bark', 'bazy', 'kuel']); + })); + + pt.write(Buffer.from('foog')); + setTimeout(function() { + pt.write(Buffer.from('bark')); + setTimeout(function() { + pt.write(Buffer.from('bazy')); + setTimeout(function() { + pt.write(Buffer.from('kuel')); + setTimeout(function() { + pt.end(); + }, 10); + }, 10); + }, 10); + }, 10); +} + +{ + // Verify object transform (JSON parse) + const jp = new Transform({ objectMode: true }); + jp._transform = function(data, encoding, cb) { + try { + jp.push(JSON.parse(data)); + cb(); + } catch (er) { + cb(er); + } + }; + + // Anything except null/undefined is fine. + // those are "magic" in the stream API, because they signal EOF. + const objects = [ + { foo: 'bar' }, + 100, + 'string', + { nested: { things: [ { foo: 'bar' }, 100, 'string' ] } }, + ]; + + let ended = false; + jp.on('end', function() { + ended = true; + }); + + objects.forEach(function(obj) { + jp.write(JSON.stringify(obj)); + const res = jp.read(); + assert.deepStrictEqual(res, obj); + }); + + jp.end(); + // Read one more time to get the 'end' event + jp.read(); + + process.nextTick(common.mustCall(function() { + assert.strictEqual(ended, true); + })); +} + +{ + // Verify object transform (JSON stringify) + const js = new Transform({ objectMode: true }); + js._transform = function(data, encoding, cb) { + try { + js.push(JSON.stringify(data)); + cb(); + } catch (er) { + cb(er); + } + }; + + // Anything except null/undefined is fine. + // those are "magic" in the stream API, because they signal EOF. + const objects = [ + { foo: 'bar' }, + 100, + 'string', + { nested: { things: [ { foo: 'bar' }, 100, 'string' ] } }, + ]; + + let ended = false; + js.on('end', function() { + ended = true; + }); + + objects.forEach(function(obj) { + js.write(obj); + const res = js.read(); + assert.strictEqual(res, JSON.stringify(obj)); + }); + + js.end(); + // Read one more time to get the 'end' event + js.read(); + + process.nextTick(common.mustCall(function() { + assert.strictEqual(ended, true); + })); +} + +{ + const s = new Transform({ + objectMode: true, + construct(callback) { + this.push('header from constructor'); + callback(); + }, + transform: (row, encoding, callback) => { + callback(null, row); + }, + }); + + const expected = [ + 'header from constructor', + 'firstLine', + 'secondLine', + ]; + s.on('data', common.mustCall((data) => { + assert.strictEqual(data.toString(), expected.shift()); + }, 3)); + s.write('firstLine'); + process.nextTick(() => s.write('secondLine')); +} diff --git a/tests/node_compat/test/parallel/test-stream2-unpipe-drain.js b/tests/node_compat/test/parallel/test-stream2-unpipe-drain.js new file mode 100644 index 000000000..9c1a6844d --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream2-unpipe-drain.js @@ -0,0 +1,79 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); + +const stream = require('stream'); + +class TestWriter extends stream.Writable { + _write(buffer, encoding, callback) { + console.log('write called'); + // Super slow write stream (callback never called) + } +} + +const dest = new TestWriter(); + +class TestReader extends stream.Readable { + constructor() { + super(); + this.reads = 0; + } + + _read(size) { + this.reads += 1; + this.push(Buffer.alloc(size)); + } +} + +const src1 = new TestReader(); +const src2 = new TestReader(); + +src1.pipe(dest); + +src1.once('readable', () => { + process.nextTick(() => { + + src2.pipe(dest); + + src2.once('readable', () => { + process.nextTick(() => { + + src1.unpipe(dest); + }); + }); + }); +}); + + +process.on('exit', () => { + assert.strictEqual(src1.reads, 2); + assert.strictEqual(src2.reads, 2); +}); diff --git a/tests/node_compat/test/parallel/test-stream2-unpipe-leak.js b/tests/node_compat/test/parallel/test-stream2-unpipe-leak.js new file mode 100644 index 000000000..8958bc06b --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream2-unpipe-leak.js @@ -0,0 +1,80 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const stream = require('stream'); + +const chunk = Buffer.from('hallo'); + +class TestWriter extends stream.Writable { + _write(buffer, encoding, callback) { + callback(null); + } +} + +const dest = new TestWriter(); + +// Set this high so that we'd trigger a nextTick warning +// and/or RangeError if we do maybeReadMore wrong. +class TestReader extends stream.Readable { + constructor() { + super({ + highWaterMark: 0x10000 + }); + } + + _read(size) { + this.push(chunk); + } +} + +const src = new TestReader(); + +for (let i = 0; i < 10; i++) { + src.pipe(dest); + src.unpipe(dest); +} + +assert.strictEqual(src.listeners('end').length, 0); +assert.strictEqual(src.listeners('readable').length, 0); + +assert.strictEqual(dest.listeners('unpipe').length, 0); +assert.strictEqual(dest.listeners('drain').length, 0); +assert.strictEqual(dest.listeners('error').length, 0); +assert.strictEqual(dest.listeners('close').length, 0); +assert.strictEqual(dest.listeners('finish').length, 0); + +console.error(src._readableState); +process.on('exit', function() { + src.readableBuffer.length = 0; + console.error(src._readableState); + assert(src.readableLength >= src.readableHighWaterMark); + console.log('ok'); +}); diff --git a/tests/node_compat/test/parallel/test-stream2-writable.js b/tests/node_compat/test/parallel/test-stream2-writable.js new file mode 100644 index 000000000..8b7197b9b --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream2-writable.js @@ -0,0 +1,466 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; + +const common = require('../common'); +const { Writable: W, Duplex: D } = require('stream'); +const assert = require('assert'); + +class TestWriter extends W { + constructor(opts) { + super(opts); + this.buffer = []; + this.written = 0; + } + + _write(chunk, encoding, cb) { + // Simulate a small unpredictable latency + setTimeout(() => { + this.buffer.push(chunk.toString()); + this.written += chunk.length; + cb(); + }, Math.floor(Math.random() * 10)); + } +} + +const chunks = new Array(50); +for (let i = 0; i < chunks.length; i++) { + chunks[i] = 'x'.repeat(i); +} + +{ + // Verify fast writing + const tw = new TestWriter({ + highWaterMark: 100 + }); + + tw.on('finish', common.mustCall(function() { + // Got chunks in the right order + assert.deepStrictEqual(tw.buffer, chunks); + })); + + chunks.forEach(function(chunk) { + // Ignore backpressure. Just buffer it all up. + tw.write(chunk); + }); + tw.end(); +} + +{ + // Verify slow writing + const tw = new TestWriter({ + highWaterMark: 100 + }); + + tw.on('finish', common.mustCall(function() { + // Got chunks in the right order + assert.deepStrictEqual(tw.buffer, chunks); + })); + + let i = 0; + (function W() { + tw.write(chunks[i++]); + if (i < chunks.length) + setTimeout(W, 10); + else + tw.end(); + })(); +} + +{ + // Verify write backpressure + const tw = new TestWriter({ + highWaterMark: 50 + }); + + let drains = 0; + + tw.on('finish', common.mustCall(function() { + // Got chunks in the right order + assert.deepStrictEqual(tw.buffer, chunks); + assert.strictEqual(drains, 17); + })); + + tw.on('drain', function() { + drains++; + }); + + let i = 0; + (function W() { + let ret; + do { + ret = tw.write(chunks[i++]); + } while (ret !== false && i < chunks.length); + + if (i < chunks.length) { + assert(tw.writableLength >= 50); + tw.once('drain', W); + } else { + tw.end(); + } + })(); +} + +{ + // Verify write buffersize + const tw = new TestWriter({ + highWaterMark: 100 + }); + + const encodings = + [ 'hex', + 'utf8', + 'utf-8', + 'ascii', + 'latin1', + 'binary', + 'base64', + 'ucs2', + 'ucs-2', + 'utf16le', + 'utf-16le', + undefined ]; + + tw.on('finish', function() { + // Got the expected chunks + assert.deepStrictEqual(tw.buffer, chunks); + }); + + chunks.forEach(function(chunk, i) { + const enc = encodings[i % encodings.length]; + chunk = Buffer.from(chunk); + tw.write(chunk.toString(enc), enc); + }); +} + +{ + // Verify write with no buffersize + const tw = new TestWriter({ + highWaterMark: 100, + decodeStrings: false + }); + + tw._write = function(chunk, encoding, cb) { + assert.strictEqual(typeof chunk, 'string'); + chunk = Buffer.from(chunk, encoding); + return TestWriter.prototype._write.call(this, chunk, encoding, cb); + }; + + const encodings = + [ 'hex', + 'utf8', + 'utf-8', + 'ascii', + 'latin1', + 'binary', + 'base64', + 'ucs2', + 'ucs-2', + 'utf16le', + 'utf-16le', + undefined ]; + + tw.on('finish', function() { + // Got the expected chunks + assert.deepStrictEqual(tw.buffer, chunks); + }); + + chunks.forEach(function(chunk, i) { + const enc = encodings[i % encodings.length]; + chunk = Buffer.from(chunk); + tw.write(chunk.toString(enc), enc); + }); +} + +{ + // Verify write callbacks + const callbacks = chunks.map(function(chunk, i) { + return [i, function() { + callbacks._called[i] = chunk; + }]; + }).reduce(function(set, x) { + set[`callback-${x[0]}`] = x[1]; + return set; + }, {}); + callbacks._called = []; + + const tw = new TestWriter({ + highWaterMark: 100 + }); + + tw.on('finish', common.mustCall(function() { + process.nextTick(common.mustCall(function() { + // Got chunks in the right order + assert.deepStrictEqual(tw.buffer, chunks); + // Called all callbacks + assert.deepStrictEqual(callbacks._called, chunks); + })); + })); + + chunks.forEach(function(chunk, i) { + tw.write(chunk, callbacks[`callback-${i}`]); + }); + tw.end(); +} + +{ + // Verify end() callback + const tw = new TestWriter(); + tw.end(common.mustCall()); +} + +const helloWorldBuffer = Buffer.from('hello world'); + +{ + // Verify end() callback with chunk + const tw = new TestWriter(); + tw.end(helloWorldBuffer, common.mustCall()); +} + +{ + // Verify end() callback with chunk and encoding + const tw = new TestWriter(); + tw.end('hello world', 'ascii', common.mustCall()); +} + +{ + // Verify end() callback after write() call + const tw = new TestWriter(); + tw.write(helloWorldBuffer); + tw.end(common.mustCall()); +} + +{ + // Verify end() callback after write() callback + const tw = new TestWriter(); + let writeCalledback = false; + tw.write(helloWorldBuffer, function() { + writeCalledback = true; + }); + tw.end(common.mustCall(function() { + assert.strictEqual(writeCalledback, true); + })); +} + +{ + // Verify encoding is ignored for buffers + const tw = new W(); + const hex = '018b5e9a8f6236ffe30e31baf80d2cf6eb'; + tw._write = common.mustCall(function(chunk) { + assert.strictEqual(chunk.toString('hex'), hex); + }); + const buf = Buffer.from(hex, 'hex'); + tw.write(buf, 'latin1'); +} + +{ + // Verify writables cannot be piped + const w = new W({ autoDestroy: false }); + w._write = common.mustNotCall(); + let gotError = false; + w.on('error', function() { + gotError = true; + }); + w.pipe(process.stdout); + assert.strictEqual(gotError, true); +} + +{ + // Verify that duplex streams cannot be piped + const d = new D(); + d._read = common.mustCall(); + d._write = common.mustNotCall(); + let gotError = false; + d.on('error', function() { + gotError = true; + }); + d.pipe(process.stdout); + assert.strictEqual(gotError, false); +} + +{ + // Verify that end(chunk) twice is an error + const w = new W(); + w._write = common.mustCall((msg) => { + assert.strictEqual(msg.toString(), 'this is the end'); + }); + let gotError = false; + w.on('error', function(er) { + gotError = true; + assert.strictEqual(er.message, 'write after end'); + }); + w.end('this is the end'); + w.end('and so is this'); + process.nextTick(common.mustCall(function() { + assert.strictEqual(gotError, true); + })); +} + +{ + // Verify stream doesn't end while writing + const w = new W(); + let wrote = false; + w._write = function(chunk, e, cb) { + assert.strictEqual(this.writing, undefined); + wrote = true; + this.writing = true; + setTimeout(() => { + this.writing = false; + cb(); + }, 1); + }; + w.on('finish', common.mustCall(function() { + assert.strictEqual(wrote, true); + assert.strictEqual(this.writing, false); + })); + w.write(Buffer.alloc(0)); + w.end(); +} + +{ + // Verify finish does not come before write() callback + const w = new W(); + let writeCb = false; + w._write = function(chunk, e, cb) { + setTimeout(function() { + writeCb = true; + cb(); + }, 10); + }; + w.on('finish', common.mustCall(function() { + assert.strictEqual(writeCb, true); + })); + w.write(Buffer.alloc(0)); + w.end(); +} + +{ + // Verify finish does not come before synchronous _write() callback + const w = new W(); + let writeCb = false; + w._write = function(chunk, e, cb) { + cb(); + }; + w.on('finish', common.mustCall(function() { + assert.strictEqual(writeCb, true); + })); + w.write(Buffer.alloc(0), function() { + writeCb = true; + }); + w.end(); +} + +{ + // Verify finish is emitted if the last chunk is empty + const w = new W(); + w._write = function(chunk, e, cb) { + process.nextTick(cb); + }; + w.on('finish', common.mustCall()); + w.write(Buffer.allocUnsafe(1)); + w.end(Buffer.alloc(0)); +} + +{ + // Verify that finish is emitted after shutdown + const w = new W(); + let shutdown = false; + + w._final = common.mustCall(function(cb) { + assert.strictEqual(this, w); + setTimeout(function() { + shutdown = true; + cb(); + }, 100); + }); + w._write = function(chunk, e, cb) { + process.nextTick(cb); + }; + w.on('finish', common.mustCall(function() { + assert.strictEqual(shutdown, true); + })); + w.write(Buffer.allocUnsafe(1)); + w.end(Buffer.allocUnsafe(0)); +} + +{ + // Verify that error is only emitted once when failing in _finish. + const w = new W(); + + w._final = common.mustCall(function(cb) { + cb(new Error('test')); + }); + w.on('error', common.mustCall((err) => { + assert.strictEqual(w._writableState.errorEmitted, true); + assert.strictEqual(err.message, 'test'); + w.on('error', common.mustNotCall()); + w.destroy(new Error()); + })); + w.end(); +} + +{ + // Verify that error is only emitted once when failing in write. + const w = new W(); + w.on('error', common.mustNotCall()); + assert.throws(() => { + w.write(null); + }, { + code: 'ERR_STREAM_NULL_VALUES' + }); +} + +{ + // Verify that error is only emitted once when failing in write after end. + const w = new W(); + w.on('error', common.mustCall((err) => { + assert.strictEqual(w._writableState.errorEmitted, true); + assert.strictEqual(err.code, 'ERR_STREAM_WRITE_AFTER_END'); + })); + w.end(); + w.write('hello'); + w.destroy(new Error()); +} + +{ + // Verify that finish is not emitted after error + const w = new W(); + + w._final = common.mustCall(function(cb) { + cb(new Error()); + }); + w._write = function(chunk, e, cb) { + process.nextTick(cb); + }; + w.on('error', common.mustCall()); + w.on('prefinish', common.mustNotCall()); + w.on('finish', common.mustNotCall()); + w.write(Buffer.allocUnsafe(1)); + w.end(Buffer.allocUnsafe(0)); +} diff --git a/tests/node_compat/test/parallel/test-stream3-cork-end.js b/tests/node_compat/test/parallel/test-stream3-cork-end.js new file mode 100644 index 000000000..52f881121 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream3-cork-end.js @@ -0,0 +1,98 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const assert = require('assert'); +const stream = require('stream'); +const Writable = stream.Writable; + +// Test the buffering behavior of Writable streams. +// +// The call to cork() triggers storing chunks which are flushed +// on calling end() and the stream subsequently ended. +// +// node version target: 0.12 + +const expectedChunks = ['please', 'buffer', 'me', 'kindly']; +const inputChunks = expectedChunks.slice(0); +let seenChunks = []; +let seenEnd = false; + +const w = new Writable(); +// Let's arrange to store the chunks. +w._write = function(chunk, encoding, cb) { + // Stream end event is not seen before the last write. + assert.ok(!seenEnd); + // Default encoding given none was specified. + assert.strictEqual(encoding, 'buffer'); + + seenChunks.push(chunk); + cb(); +}; +// Let's record the stream end event. +w.on('finish', () => { + seenEnd = true; +}); + +function writeChunks(remainingChunks, callback) { + const writeChunk = remainingChunks.shift(); + let writeState; + + if (writeChunk) { + setImmediate(() => { + writeState = w.write(writeChunk); + // We were not told to stop writing. + assert.ok(writeState); + + writeChunks(remainingChunks, callback); + }); + } else { + callback(); + } +} + +// Do an initial write. +w.write('stuff'); +// The write was immediate. +assert.strictEqual(seenChunks.length, 1); +// Reset the seen chunks. +seenChunks = []; + +// Trigger stream buffering. +w.cork(); + +// Write the bufferedChunks. +writeChunks(inputChunks, () => { + // Should not have seen anything yet. + assert.strictEqual(seenChunks.length, 0); + + // Trigger flush and ending the stream. + w.end(); + + // Stream should not ended in current tick. + assert.ok(!seenEnd); + + // Buffered bytes should be seen in current tick. + assert.strictEqual(seenChunks.length, 4); + + // Did the chunks match. + for (let i = 0, l = expectedChunks.length; i < l; i++) { + const seen = seenChunks[i]; + // There was a chunk. + assert.ok(seen); + + const expected = Buffer.from(expectedChunks[i]); + // It was what we expected. + assert.ok(seen.equals(expected)); + } + + setImmediate(() => { + // Stream should have ended in next tick. + assert.ok(seenEnd); + }); +}); diff --git a/tests/node_compat/test/parallel/test-stream3-cork-uncork.js b/tests/node_compat/test/parallel/test-stream3-cork-uncork.js new file mode 100644 index 000000000..1fb993003 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream3-cork-uncork.js @@ -0,0 +1,93 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const assert = require('assert'); +const stream = require('stream'); +const Writable = stream.Writable; + +// Test the buffering behavior of Writable streams. +// +// The call to cork() triggers storing chunks which are flushed +// on calling uncork() in the same tick. +// +// node version target: 0.12 + +const expectedChunks = ['please', 'buffer', 'me', 'kindly']; +const inputChunks = expectedChunks.slice(0); +let seenChunks = []; +let seenEnd = false; + +const w = new Writable(); +// Let's arrange to store the chunks. +w._write = function(chunk, encoding, cb) { + // Default encoding given none was specified. + assert.strictEqual(encoding, 'buffer'); + + seenChunks.push(chunk); + cb(); +}; +// Let's record the stream end event. +w.on('finish', () => { + seenEnd = true; +}); + +function writeChunks(remainingChunks, callback) { + const writeChunk = remainingChunks.shift(); + let writeState; + + if (writeChunk) { + setImmediate(() => { + writeState = w.write(writeChunk); + // We were not told to stop writing. + assert.ok(writeState); + + writeChunks(remainingChunks, callback); + }); + } else { + callback(); + } +} + +// Do an initial write. +w.write('stuff'); +// The write was immediate. +assert.strictEqual(seenChunks.length, 1); +// Reset the chunks seen so far. +seenChunks = []; + +// Trigger stream buffering. +w.cork(); + +// Write the bufferedChunks. +writeChunks(inputChunks, () => { + // Should not have seen anything yet. + assert.strictEqual(seenChunks.length, 0); + + // Trigger writing out the buffer. + w.uncork(); + + // Buffered bytes should be seen in current tick. + assert.strictEqual(seenChunks.length, 4); + + // Did the chunks match. + for (let i = 0, l = expectedChunks.length; i < l; i++) { + const seen = seenChunks[i]; + // There was a chunk. + assert.ok(seen); + + const expected = Buffer.from(expectedChunks[i]); + // It was what we expected. + assert.ok(seen.equals(expected)); + } + + setImmediate(() => { + // The stream should not have been ended. + assert.ok(!seenEnd); + }); +}); diff --git a/tests/node_compat/test/parallel/test-stream3-pause-then-read.js b/tests/node_compat/test/parallel/test-stream3-pause-then-read.js new file mode 100644 index 000000000..f840672ce --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream3-pause-then-read.js @@ -0,0 +1,177 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); + +const stream = require('stream'); +const Readable = stream.Readable; +const Writable = stream.Writable; + +const totalChunks = 100; +const chunkSize = 99; +const expectTotalData = totalChunks * chunkSize; +let expectEndingData = expectTotalData; + +const r = new Readable({ highWaterMark: 1000 }); +let chunks = totalChunks; +r._read = function(n) { + console.log('_read called', chunks); + if (!(chunks % 2)) + setImmediate(push); + else if (!(chunks % 3)) + process.nextTick(push); + else + push(); +}; + +let totalPushed = 0; +function push() { + const chunk = chunks-- > 0 ? Buffer.alloc(chunkSize, 'x') : null; + if (chunk) { + totalPushed += chunk.length; + } + console.log('chunks', chunks); + r.push(chunk); +} + +read100(); + +// First we read 100 bytes. +function read100() { + readn(100, onData); +} + +function readn(n, then) { + console.error(`read ${n}`); + expectEndingData -= n; + (function read() { + const c = r.read(n); + console.error('c', c); + if (!c) + r.once('readable', read); + else { + assert.strictEqual(c.length, n); + assert(!r.readableFlowing); + then(); + } + })(); +} + +// Then we listen to some data events. +function onData() { + expectEndingData -= 100; + console.error('onData'); + let seen = 0; + r.on('data', function od(c) { + seen += c.length; + if (seen >= 100) { + // Seen enough + r.removeListener('data', od); + r.pause(); + if (seen > 100) { + // Oh no, seen too much! + // Put the extra back. + const diff = seen - 100; + r.unshift(c.slice(c.length - diff)); + console.error('seen too much', seen, diff); + } + + // Nothing should be lost in-between. + setImmediate(pipeLittle); + } + }); +} + +// Just pipe 200 bytes, then unshift the extra and unpipe. +function pipeLittle() { + expectEndingData -= 200; + console.error('pipe a little'); + const w = new Writable(); + let written = 0; + w.on('finish', () => { + assert.strictEqual(written, 200); + setImmediate(read1234); + }); + w._write = function(chunk, encoding, cb) { + written += chunk.length; + if (written >= 200) { + r.unpipe(w); + w.end(); + cb(); + if (written > 200) { + const diff = written - 200; + written -= diff; + r.unshift(chunk.slice(chunk.length - diff)); + } + } else { + setImmediate(cb); + } + }; + r.pipe(w); +} + +// Now read 1234 more bytes. +function read1234() { + readn(1234, resumePause); +} + +function resumePause() { + console.error('resumePause'); + // Don't read anything, just resume and re-pause a whole bunch. + r.resume(); + r.pause(); + r.resume(); + r.pause(); + r.resume(); + r.pause(); + r.resume(); + r.pause(); + r.resume(); + r.pause(); + setImmediate(pipe); +} + + +function pipe() { + console.error('pipe the rest'); + const w = new Writable(); + let written = 0; + w._write = function(chunk, encoding, cb) { + written += chunk.length; + cb(); + }; + w.on('finish', () => { + console.error('written', written, totalPushed); + assert.strictEqual(written, expectEndingData); + assert.strictEqual(totalPushed, expectTotalData); + console.log('ok'); + }); + r.pipe(w); +} diff --git a/tests/node_compat/test/parallel/test-streams-highwatermark.js b/tests/node_compat/test/parallel/test-streams-highwatermark.js new file mode 100644 index 000000000..9245f7db0 --- /dev/null +++ b/tests/node_compat/test/parallel/test-streams-highwatermark.js @@ -0,0 +1,94 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); + +const assert = require('assert'); +const stream = require('stream'); +const { inspect } = require('util'); + +{ + // This test ensures that the stream implementation correctly handles values + // for highWaterMark which exceed the range of signed 32 bit integers and + // rejects invalid values. + + // This number exceeds the range of 32 bit integer arithmetic but should still + // be handled correctly. + const ovfl = Number.MAX_SAFE_INTEGER; + + const readable = stream.Readable({ highWaterMark: ovfl }); + assert.strictEqual(readable._readableState.highWaterMark, ovfl); + + const writable = stream.Writable({ highWaterMark: ovfl }); + assert.strictEqual(writable._writableState.highWaterMark, ovfl); + + for (const invalidHwm of [true, false, '5', {}, -5, NaN]) { + for (const type of [stream.Readable, stream.Writable]) { + assert.throws(() => { + type({ highWaterMark: invalidHwm }); + }, { + name: 'TypeError', + code: 'ERR_INVALID_ARG_VALUE', + message: "The property 'options.highWaterMark' is invalid. " + + `Received ${inspect(invalidHwm)}` + }); + } + } +} + +{ + // This test ensures that the push method's implementation + // correctly handles the edge case where the highWaterMark and + // the state.length are both zero + + const readable = stream.Readable({ highWaterMark: 0 }); + + for (let i = 0; i < 3; i++) { + const needMoreData = readable.push(); + assert.strictEqual(needMoreData, true); + } +} + +{ + // This test ensures that the read(n) method's implementation + // correctly handles the edge case where the highWaterMark, state.length + // and n are all zero + + const readable = stream.Readable({ highWaterMark: 0 }); + + readable._read = common.mustCall(); + readable.read(0); +} + +{ + // Parse size as decimal integer + ['1', '1.0', 1].forEach((size) => { + const readable = new stream.Readable({ + read: common.mustCall(), + highWaterMark: 0, + }); + readable.read(size); + + assert.strictEqual(readable._readableState.highWaterMark, Number(size)); + }); +} + +{ + // Test highwatermark limit + const hwm = 0x40000000 + 1; + const readable = stream.Readable({ + read() {}, + }); + + assert.throws(() => readable.read(hwm), common.expectsError({ + code: 'ERR_OUT_OF_RANGE', + message: 'The value of "size" is out of range.' + + ' It must be <= 1GiB. Received ' + + hwm, + })); +} diff --git a/tests/node_compat/test/parallel/test-timers-api-refs.js b/tests/node_compat/test/parallel/test-timers-api-refs.js new file mode 100644 index 000000000..62ce55fad --- /dev/null +++ b/tests/node_compat/test/parallel/test-timers-api-refs.js @@ -0,0 +1,28 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const timers = require('timers'); + +// Delete global APIs to make sure they're not relied on by the internal timers +// code +delete global.setTimeout; +delete global.clearTimeout; +delete global.setInterval; +delete global.clearInterval; +delete global.setImmediate; +delete global.clearImmediate; + +const timeoutCallback = () => { timers.clearTimeout(timeout); }; +const timeout = timers.setTimeout(common.mustCall(timeoutCallback), 1); + +const intervalCallback = () => { timers.clearInterval(interval); }; +const interval = timers.setInterval(common.mustCall(intervalCallback), 1); + +const immediateCallback = () => { timers.clearImmediate(immediate); }; +const immediate = timers.setImmediate(immediateCallback); diff --git a/tests/node_compat/test/parallel/test-timers-args.js b/tests/node_compat/test/parallel/test-timers-args.js new file mode 100644 index 000000000..b771bf591 --- /dev/null +++ b/tests/node_compat/test/parallel/test-timers-args.js @@ -0,0 +1,38 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const assert = require('assert'); + +function range(n) { + return 'x'.repeat(n + 1).split('').map(function(_, i) { return i; }); +} + +function timeout(nargs) { + const args = range(nargs); + setTimeout.apply(null, [callback, 1].concat(args)); + + function callback() { + assert.deepStrictEqual([].slice.call(arguments), args); + if (nargs < 128) timeout(nargs + 1); + } +} + +function interval(nargs) { + const args = range(nargs); + const timer = setTimeout.apply(null, [callback, 1].concat(args)); + + function callback() { + clearInterval(timer); + assert.deepStrictEqual([].slice.call(arguments), args); + if (nargs < 128) interval(nargs + 1); + } +} + +timeout(0); +interval(0); diff --git a/tests/node_compat/test/parallel/test-timers-clear-null-does-not-throw-error.js b/tests/node_compat/test/parallel/test-timers-clear-null-does-not-throw-error.js new file mode 100644 index 000000000..7b7b59b27 --- /dev/null +++ b/tests/node_compat/test/parallel/test-timers-clear-null-does-not-throw-error.js @@ -0,0 +1,18 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); + +// This test makes sure clearing timers with +// 'null' or no input does not throw error +clearInterval(null); +clearInterval(); +clearTimeout(null); +clearTimeout(); +clearImmediate(null); +clearImmediate(); diff --git a/tests/node_compat/test/parallel/test-timers-clear-object-does-not-throw-error.js b/tests/node_compat/test/parallel/test-timers-clear-object-does-not-throw-error.js new file mode 100644 index 000000000..524389c6b --- /dev/null +++ b/tests/node_compat/test/parallel/test-timers-clear-object-does-not-throw-error.js @@ -0,0 +1,15 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); + +// This test makes sure clearing timers with +// objects doesn't throw +clearImmediate({}); +clearTimeout({}); +clearInterval({}); diff --git a/tests/node_compat/test/parallel/test-timers-clear-timeout-interval-equivalent.js b/tests/node_compat/test/parallel/test-timers-clear-timeout-interval-equivalent.js new file mode 100644 index 000000000..b6af3f943 --- /dev/null +++ b/tests/node_compat/test/parallel/test-timers-clear-timeout-interval-equivalent.js @@ -0,0 +1,25 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); + +// This test makes sure that timers created with setTimeout can be disarmed by +// clearInterval and that timers created with setInterval can be disarmed by +// clearTimeout. +// +// This behavior is documented in the HTML Living Standard: +// +// * Refs: https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-setinterval + +// Disarm interval with clearTimeout. +const interval = setInterval(common.mustNotCall(), 1); +clearTimeout(interval); + +// Disarm timeout with clearInterval. +const timeout = setTimeout(common.mustNotCall(), 1); +clearInterval(timeout); diff --git a/tests/node_compat/test/parallel/test-timers-clearImmediate.js b/tests/node_compat/test/parallel/test-timers-clearImmediate.js new file mode 100644 index 000000000..129e301f2 --- /dev/null +++ b/tests/node_compat/test/parallel/test-timers-clearImmediate.js @@ -0,0 +1,20 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); + +const N = 3; + +function next() { + const fn = common.mustCall(() => clearImmediate(immediate)); + const immediate = setImmediate(fn); +} + +for (let i = 0; i < N; i++) { + next(); +} diff --git a/tests/node_compat/test/parallel/test-timers-interval-throw.js b/tests/node_compat/test/parallel/test-timers-interval-throw.js new file mode 100644 index 000000000..d408fc866 --- /dev/null +++ b/tests/node_compat/test/parallel/test-timers-interval-throw.js @@ -0,0 +1,24 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); + +// To match browser behaviour, interval should continue +// being rescheduled even if it throws. + +let count = 2; +const interval = setInterval(() => { throw new Error('IntervalError'); }, 1); + +process.on('uncaughtException', common.mustCall((err) => { + assert.strictEqual(err.message, 'IntervalError'); + if (--count === 0) { + clearInterval(interval); + } +}, 2)); diff --git a/tests/node_compat/test/parallel/test-timers-non-integer-delay.js b/tests/node_compat/test/parallel/test-timers-non-integer-delay.js new file mode 100644 index 000000000..1d3ca55c2 --- /dev/null +++ b/tests/node_compat/test/parallel/test-timers-non-integer-delay.js @@ -0,0 +1,88 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +// This test makes sure that non-integer timer delays do not make the process +// hang. See https://github.com/joyent/node/issues/8065 and +// https://github.com/joyent/node/issues/8068 which have been fixed by +// https://github.com/joyent/node/pull/8073. +// +// If the process hangs, this test will make the tests suite timeout, +// otherwise it will exit very quickly (after 50 timers with a short delay +// fire). +// +// We have to set at least several timers with a non-integer delay to +// reproduce the issue. Sometimes, a timer with a non-integer delay will +// expire correctly. 50 timers has always been more than enough to reproduce +// it 100%. + +const TIMEOUT_DELAY = 1.1; +let N = 50; + +const interval = setInterval(common.mustCall(() => { + if (--N === 0) { + clearInterval(interval); + } +}, N), TIMEOUT_DELAY); + +// Test non-integer delay ordering +{ + const ordering = []; + + setTimeout(common.mustCall(() => { + ordering.push(1); + }), 1); + + setTimeout(common.mustCall(() => { + ordering.push(2); + }), 1.8); + + setTimeout(common.mustCall(() => { + ordering.push(3); + }), 1.1); + + setTimeout(common.mustCall(() => { + ordering.push(4); + }), 1); + + setTimeout(common.mustCall(() => { + const expected = [1, 2, 3, 4]; + + assert.deepStrictEqual( + ordering, + expected, + `Non-integer delay ordering should be ${expected}, but got ${ordering}` + ); + + // 2 should always be last of these delays due to ordering guarantees by + // the implementation. + }), 2); +} diff --git a/tests/node_compat/test/parallel/test-timers-refresh.js b/tests/node_compat/test/parallel/test-timers-refresh.js new file mode 100644 index 000000000..942cf5604 --- /dev/null +++ b/tests/node_compat/test/parallel/test-timers-refresh.js @@ -0,0 +1,109 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Flags: --expose-internals + +'use strict'; + +const common = require('../common'); + +const { strictEqual, throws } = require('assert'); +const { setUnrefTimeout } = require('internal/timers'); + +// Schedule the unrefed cases first so that the later case keeps the event loop +// active. + +// Every case in this test relies on implicit sorting within either Node's or +// libuv's timers storage data structures. + +// unref()'d timer +{ + let called = false; + const timer = setTimeout(common.mustCall(() => { + called = true; + }), 1); + timer.unref(); + + // This relies on implicit timers handle sorting within libuv. + + setTimeout(common.mustCall(() => { + strictEqual(called, false, 'unref()\'d timer returned before check'); + }), 1); + + strictEqual(timer.refresh(), timer); +} + +// Should throw with non-functions +{ + [null, true, false, 0, 1, NaN, '', 'foo', {}, Symbol()].forEach((cb) => { + throws( + () => setUnrefTimeout(cb), + { + code: 'ERR_INVALID_ARG_TYPE', + } + ); + }); +} + +// unref pooled timer +{ + let called = false; + const timer = setUnrefTimeout(common.mustCall(() => { + called = true; + }), 1); + + setUnrefTimeout(common.mustCall(() => { + strictEqual(called, false, 'unref pooled timer returned before check'); + }), 1); + + strictEqual(timer.refresh(), timer); +} + +// regular timer +{ + let called = false; + const timer = setTimeout(common.mustCall(() => { + called = true; + }), 1); + + setTimeout(common.mustCall(() => { + strictEqual(called, false, 'pooled timer returned before check'); + }), 1); + + strictEqual(timer.refresh(), timer); +} + +// regular timer +{ + let called = false; + const timer = setTimeout(common.mustCall(() => { + if (!called) { + called = true; + process.nextTick(common.mustCall(() => { + timer.refresh(); + strictEqual(timer.hasRef(), true); + })); + } + }, 2), 1); +} + +// interval +{ + let called = 0; + const timer = setInterval(common.mustCall(() => { + called += 1; + if (called === 2) { + clearInterval(timer); + } + }, 2), 1); + + setTimeout(common.mustCall(() => { + strictEqual(called, 0, 'pooled timer returned before check'); + }), 1); + + strictEqual(timer.refresh(), timer); +} diff --git a/tests/node_compat/test/parallel/test-timers-same-timeout-wrong-list-deleted.js b/tests/node_compat/test/parallel/test-timers-same-timeout-wrong-list-deleted.js new file mode 100644 index 000000000..fa6348d75 --- /dev/null +++ b/tests/node_compat/test/parallel/test-timers-same-timeout-wrong-list-deleted.js @@ -0,0 +1,41 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +// This is a regression test for https://github.com/nodejs/node/issues/7722. +// +// When nested timers have the same timeout, calling clearTimeout on the +// older timer after it has fired causes the list the newer timer is in +// to be deleted. Since the newer timer was not cleared, it still blocks +// the event loop completing for the duration of its timeout, however, since +// no reference exists to it in its list, it cannot be canceled and its +// callback is not called when the timeout elapses. + +const common = require('../common'); + +const TIMEOUT = common.platformTimeout(100); + +const handle1 = setTimeout(common.mustCall(function() { + // Cause the old TIMEOUT list to be deleted + clearTimeout(handle1); + + // Cause a new list with the same key (TIMEOUT) to be created for this timer + const handle2 = setTimeout(common.mustNotCall(), TIMEOUT); + + setTimeout(common.mustCall(function() { + // Attempt to cancel the second timer. Fix for this bug will keep the + // newer timer from being dereferenced by keeping its list from being + // erroneously deleted. If we are able to cancel the timer successfully, + // the bug is fixed. + clearTimeout(handle2); + }), 1); + + // When this callback completes, `listOnTimeout` should now look at the + // correct list and refrain from removing the new TIMEOUT list which + // contains the reference to the newer timer. +}), TIMEOUT); diff --git a/tests/node_compat/test/parallel/test-timers-timeout-with-non-integer.js b/tests/node_compat/test/parallel/test-timers-timeout-with-non-integer.js new file mode 100644 index 000000000..d93ef57fe --- /dev/null +++ b/tests/node_compat/test/parallel/test-timers-timeout-with-non-integer.js @@ -0,0 +1,22 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); + +/** + * This test is for https://github.com/nodejs/node/issues/24203 + */ +let count = 50; +const time = 1.00000000000001; +const exec = common.mustCall(() => { + if (--count === 0) { + return; + } + setTimeout(exec, time); +}, count); +exec(); diff --git a/tests/node_compat/test/parallel/test-timers-uncaught-exception.js b/tests/node_compat/test/parallel/test-timers-uncaught-exception.js new file mode 100644 index 000000000..e76c11afc --- /dev/null +++ b/tests/node_compat/test/parallel/test-timers-uncaught-exception.js @@ -0,0 +1,46 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const errorMsg = 'BAM!'; + +// The first timer throws... +setTimeout(common.mustCall(function() { + throw new Error(errorMsg); +}), 1); + +// ...but the second one should still run +setTimeout(common.mustCall(), 1); + +function uncaughtException(err) { + assert.strictEqual(err.message, errorMsg); +} + +process.on('uncaughtException', common.mustCall(uncaughtException)); diff --git a/tests/node_compat/test/parallel/test-timers-unref-throw-then-ref.js b/tests/node_compat/test/parallel/test-timers-unref-throw-then-ref.js new file mode 100644 index 000000000..03a0861e2 --- /dev/null +++ b/tests/node_compat/test/parallel/test-timers-unref-throw-then-ref.js @@ -0,0 +1,26 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +process.once('uncaughtException', common.mustCall((err) => { + common.expectsError({ + message: 'Timeout Error' + })(err); +})); + +let called = false; +const t = setTimeout(() => { + assert(!called); + called = true; + t.ref(); + throw new Error('Timeout Error'); +}, 1).unref(); + +setTimeout(common.mustCall(), 1); diff --git a/tests/node_compat/test/parallel/test-timers-user-call.js b/tests/node_compat/test/parallel/test-timers-user-call.js new file mode 100644 index 000000000..969051f80 --- /dev/null +++ b/tests/node_compat/test/parallel/test-timers-user-call.js @@ -0,0 +1,47 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Make sure `setTimeout()` and friends don't throw if the user-supplied +// function has .call() and .apply() monkey-patched to undesirable values. + +// Refs: https://github.com/nodejs/node/issues/12956 + +'use strict'; + +const common = require('../common'); + +{ + const fn = common.mustCall(10); + fn.call = 'not a function'; + fn.apply = 'also not a function'; + setTimeout(fn, 1); + setTimeout(fn, 1, 'oneArg'); + setTimeout(fn, 1, 'two', 'args'); + setTimeout(fn, 1, 'three', '(3)', 'args'); + setTimeout(fn, 1, 'more', 'than', 'three', 'args'); + + setImmediate(fn, 1); + setImmediate(fn, 1, 'oneArg'); + setImmediate(fn, 1, 'two', 'args'); + setImmediate(fn, 1, 'three', '(3)', 'args'); + setImmediate(fn, 1, 'more', 'than', 'three', 'args'); +} + +{ + const testInterval = (...args) => { + const fn = common.mustCall(() => { clearInterval(interval); }); + fn.call = 'not a function'; + fn.apply = 'also not a function'; + const interval = setInterval(fn, 1, ...args); + }; + + testInterval(); + testInterval('oneArg'); + testInterval('two', 'args'); + testInterval('three', '(3)', 'args'); + testInterval('more', 'than', 'three', 'args'); +} diff --git a/tests/node_compat/test/parallel/test-timers-zero-timeout.js b/tests/node_compat/test/parallel/test-timers-zero-timeout.js new file mode 100644 index 000000000..ef32f7381 --- /dev/null +++ b/tests/node_compat/test/parallel/test-timers-zero-timeout.js @@ -0,0 +1,56 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +// https://github.com/joyent/node/issues/2079 - zero timeout drops extra args +{ + setTimeout(common.mustCall(f), 0, 'foo', 'bar', 'baz'); + setTimeout(() => {}, 0); + + function f(a, b, c) { + assert.strictEqual(a, 'foo'); + assert.strictEqual(b, 'bar'); + assert.strictEqual(c, 'baz'); + } +} + +{ + let ncalled = 3; + + const f = common.mustCall((a, b, c) => { + assert.strictEqual(a, 'foo'); + assert.strictEqual(b, 'bar'); + assert.strictEqual(c, 'baz'); + if (--ncalled === 0) clearTimeout(iv); + }, ncalled); + + const iv = setInterval(f, 0, 'foo', 'bar', 'baz'); +} diff --git a/tests/node_compat/test/parallel/test-tty-stdin-end.js b/tests/node_compat/test/parallel/test-tty-stdin-end.js new file mode 100644 index 000000000..ee38cbd2c --- /dev/null +++ b/tests/node_compat/test/parallel/test-tty-stdin-end.js @@ -0,0 +1,14 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); + +// This test ensures that Node.js doesn't crash on `process.stdin.emit("end")`. +// https://github.com/nodejs/node/issues/1068 + +process.stdin.emit('end'); diff --git a/tests/node_compat/test/parallel/test-ttywrap-invalid-fd.js b/tests/node_compat/test/parallel/test-ttywrap-invalid-fd.js new file mode 100644 index 000000000..95b9bffe6 --- /dev/null +++ b/tests/node_compat/test/parallel/test-ttywrap-invalid-fd.js @@ -0,0 +1,74 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Flags: --expose-internals +'use strict'; + +// const common = require('../common'); +const tty = require('tty'); +// const { internalBinding } = require('internal/test/binding'); +// const { +// UV_EBADF, +// UV_EINVAL +// } = internalBinding('uv'); +const assert = require('assert'); + +assert.throws( + () => new tty.WriteStream(-1), + { + code: 'ERR_INVALID_FD', + name: 'RangeError', + message: '"fd" must be a positive integer: -1' + } +); + +// { +// const info = { +// code: common.isWindows ? 'EBADF' : 'EINVAL', +// message: common.isWindows ? 'bad file descriptor' : 'invalid argument', +// errno: common.isWindows ? UV_EBADF : UV_EINVAL, +// syscall: 'uv_tty_init' +// }; + +// const suffix = common.isWindows ? +// 'EBADF (bad file descriptor)' : 'EINVAL (invalid argument)'; +// const message = `TTY initialization failed: uv_tty_init returned ${suffix}`; + +// assert.throws( +// () => { +// common.runWithInvalidFD((fd) => { +// new tty.WriteStream(fd); +// }); +// }, { +// code: 'ERR_TTY_INIT_FAILED', +// name: 'SystemError', +// message, +// info +// } +// ); + +// assert.throws( +// () => { +// common.runWithInvalidFD((fd) => { +// new tty.ReadStream(fd); +// }); +// }, { +// code: 'ERR_TTY_INIT_FAILED', +// name: 'SystemError', +// message, +// info +// }); +// } + +assert.throws( + () => new tty.ReadStream(-1), + { + code: 'ERR_INVALID_FD', + name: 'RangeError', + message: '"fd" must be a positive integer: -1' + } +); diff --git a/tests/node_compat/test/parallel/test-url-domain-ascii-unicode.js b/tests/node_compat/test/parallel/test-url-domain-ascii-unicode.js new file mode 100644 index 000000000..9aeb23a54 --- /dev/null +++ b/tests/node_compat/test/parallel/test-url-domain-ascii-unicode.js @@ -0,0 +1,38 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +if (!common.hasIntl) + common.skip('missing Intl'); + +const strictEqual = require('assert').strictEqual; +const url = require('url'); + +const domainToASCII = url.domainToASCII; +const domainToUnicode = url.domainToUnicode; + +const domainWithASCII = [ + ['ıíd', 'xn--d-iga7r'], + ['يٴ', 'xn--mhb8f'], + ['www.ϧƽəʐ.com', 'www.xn--cja62apfr6c.com'], + ['новини.com', 'xn--b1amarcd.com'], + ['名がドメイン.com', 'xn--v8jxj3d1dzdz08w.com'], + ['افغانستا.icom.museum', 'xn--mgbaal8b0b9b2b.icom.museum'], + ['الجزائر.icom.fake', 'xn--lgbbat1ad8j.icom.fake'], + ['भारत.org', 'xn--h2brj9c.org'], +]; + +domainWithASCII.forEach((pair) => { + const domain = pair[0]; + const ascii = pair[1]; + const domainConvertedToASCII = domainToASCII(domain); + strictEqual(domainConvertedToASCII, ascii); + const asciiConvertedToUnicode = domainToUnicode(ascii); + strictEqual(asciiConvertedToUnicode, domain); +}); diff --git a/tests/node_compat/test/parallel/test-url-fileurltopath.js b/tests/node_compat/test/parallel/test-url-fileurltopath.js new file mode 100644 index 000000000..72ba73166 --- /dev/null +++ b/tests/node_compat/test/parallel/test-url-fileurltopath.js @@ -0,0 +1,161 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const { isWindows } = require('../common'); +const assert = require('assert'); +const url = require('url'); + +function testInvalidArgs(...args) { + for (const arg of args) { + assert.throws(() => url.fileURLToPath(arg), { + code: 'ERR_INVALID_ARG_TYPE' + }); + } +} + +// Input must be string or URL +testInvalidArgs(null, undefined, 1, {}, true); + +// Input must be a file URL +assert.throws(() => url.fileURLToPath('https://a/b/c'), { + code: 'ERR_INVALID_URL_SCHEME' +}); + +{ + const withHost = new URL('file://host/a'); + + if (isWindows) { + assert.strictEqual(url.fileURLToPath(withHost), '\\\\host\\a'); + } else { + assert.throws(() => url.fileURLToPath(withHost), { + code: 'ERR_INVALID_FILE_URL_HOST' + }); + } +} + +{ + if (isWindows) { + assert.throws(() => url.fileURLToPath('file:///C:/a%2F/'), { + code: 'ERR_INVALID_FILE_URL_PATH' + }); + assert.throws(() => url.fileURLToPath('file:///C:/a%5C/'), { + code: 'ERR_INVALID_FILE_URL_PATH' + }); + assert.throws(() => url.fileURLToPath('file:///?:/'), { + code: 'ERR_INVALID_FILE_URL_PATH' + }); + } else { + assert.throws(() => url.fileURLToPath('file:///a%2F/'), { + code: 'ERR_INVALID_FILE_URL_PATH' + }); + } +} + +{ + let testCases; + if (isWindows) { + testCases = [ + // Lowercase ascii alpha + { path: 'C:\\foo', fileURL: 'file:///C:/foo' }, + // Uppercase ascii alpha + { path: 'C:\\FOO', fileURL: 'file:///C:/FOO' }, + // dir + { path: 'C:\\dir\\foo', fileURL: 'file:///C:/dir/foo' }, + // trailing separator + { path: 'C:\\dir\\', fileURL: 'file:///C:/dir/' }, + // dot + { path: 'C:\\foo.mjs', fileURL: 'file:///C:/foo.mjs' }, + // space + { path: 'C:\\foo bar', fileURL: 'file:///C:/foo%20bar' }, + // question mark + { path: 'C:\\foo?bar', fileURL: 'file:///C:/foo%3Fbar' }, + // number sign + { path: 'C:\\foo#bar', fileURL: 'file:///C:/foo%23bar' }, + // ampersand + { path: 'C:\\foo&bar', fileURL: 'file:///C:/foo&bar' }, + // equals + { path: 'C:\\foo=bar', fileURL: 'file:///C:/foo=bar' }, + // colon + { path: 'C:\\foo:bar', fileURL: 'file:///C:/foo:bar' }, + // semicolon + { path: 'C:\\foo;bar', fileURL: 'file:///C:/foo;bar' }, + // percent + { path: 'C:\\foo%bar', fileURL: 'file:///C:/foo%25bar' }, + // backslash + { path: 'C:\\foo\\bar', fileURL: 'file:///C:/foo/bar' }, + // backspace + { path: 'C:\\foo\bbar', fileURL: 'file:///C:/foo%08bar' }, + // tab + { path: 'C:\\foo\tbar', fileURL: 'file:///C:/foo%09bar' }, + // newline + { path: 'C:\\foo\nbar', fileURL: 'file:///C:/foo%0Abar' }, + // carriage return + { path: 'C:\\foo\rbar', fileURL: 'file:///C:/foo%0Dbar' }, + // latin1 + { path: 'C:\\fóóbàr', fileURL: 'file:///C:/f%C3%B3%C3%B3b%C3%A0r' }, + // Euro sign (BMP code point) + { path: 'C:\\€', fileURL: 'file:///C:/%E2%82%AC' }, + // Rocket emoji (non-BMP code point) + { path: 'C:\\🚀', fileURL: 'file:///C:/%F0%9F%9A%80' }, + // UNC path (see https://docs.microsoft.com/en-us/archive/blogs/ie/file-uris-in-windows) + { path: '\\\\nas\\My Docs\\File.doc', fileURL: 'file://nas/My%20Docs/File.doc' }, + ]; + } else { + testCases = [ + // Lowercase ascii alpha + { path: '/foo', fileURL: 'file:///foo' }, + // Uppercase ascii alpha + { path: '/FOO', fileURL: 'file:///FOO' }, + // dir + { path: '/dir/foo', fileURL: 'file:///dir/foo' }, + // trailing separator + { path: '/dir/', fileURL: 'file:///dir/' }, + // dot + { path: '/foo.mjs', fileURL: 'file:///foo.mjs' }, + // space + { path: '/foo bar', fileURL: 'file:///foo%20bar' }, + // question mark + { path: '/foo?bar', fileURL: 'file:///foo%3Fbar' }, + // number sign + { path: '/foo#bar', fileURL: 'file:///foo%23bar' }, + // ampersand + { path: '/foo&bar', fileURL: 'file:///foo&bar' }, + // equals + { path: '/foo=bar', fileURL: 'file:///foo=bar' }, + // colon + { path: '/foo:bar', fileURL: 'file:///foo:bar' }, + // semicolon + { path: '/foo;bar', fileURL: 'file:///foo;bar' }, + // percent + { path: '/foo%bar', fileURL: 'file:///foo%25bar' }, + // backslash + { path: '/foo\\bar', fileURL: 'file:///foo%5Cbar' }, + // backspace + { path: '/foo\bbar', fileURL: 'file:///foo%08bar' }, + // tab + { path: '/foo\tbar', fileURL: 'file:///foo%09bar' }, + // newline + { path: '/foo\nbar', fileURL: 'file:///foo%0Abar' }, + // carriage return + { path: '/foo\rbar', fileURL: 'file:///foo%0Dbar' }, + // latin1 + { path: '/fóóbàr', fileURL: 'file:///f%C3%B3%C3%B3b%C3%A0r' }, + // Euro sign (BMP code point) + { path: '/€', fileURL: 'file:///%E2%82%AC' }, + // Rocket emoji (non-BMP code point) + { path: '/🚀', fileURL: 'file:///%F0%9F%9A%80' }, + ]; + } + + for (const { path, fileURL } of testCases) { + const fromString = url.fileURLToPath(fileURL); + assert.strictEqual(fromString, path); + const fromURL = url.fileURLToPath(new URL(fileURL)); + assert.strictEqual(fromURL, path); + } +} diff --git a/tests/node_compat/test/parallel/test-url-format-invalid-input.js b/tests/node_compat/test/parallel/test-url-format-invalid-input.js new file mode 100644 index 000000000..d411b8d32 --- /dev/null +++ b/tests/node_compat/test/parallel/test-url-format-invalid-input.js @@ -0,0 +1,34 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const url = require('url'); + +const throwsObjsAndReportTypes = [ + undefined, + null, + true, + false, + 0, + function() {}, + Symbol('foo'), +]; + +for (const urlObject of throwsObjsAndReportTypes) { + assert.throws(() => { + url.format(urlObject); + }, { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "urlObject" argument must be one of type object or string.' + + common.invalidArgTypeHelper(urlObject) + }); +} +assert.strictEqual(url.format(''), ''); +assert.strictEqual(url.format({}), ''); diff --git a/tests/node_compat/test/parallel/test-url-format-whatwg.js b/tests/node_compat/test/parallel/test-url-format-whatwg.js new file mode 100644 index 000000000..1e9b36dcb --- /dev/null +++ b/tests/node_compat/test/parallel/test-url-format-whatwg.js @@ -0,0 +1,149 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +if (!common.hasIntl) + common.skip('missing Intl'); + +const assert = require('assert'); +const url = require('url'); + +const myURL = new URL('http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b#c'); + +assert.strictEqual( + url.format(myURL), + 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b#c' +); + +assert.strictEqual( + url.format(myURL, {}), + 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b#c' +); + +{ + [true, 1, 'test', Infinity].forEach((value) => { + assert.throws( + () => url.format(myURL, value), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "options" argument must be of type object.' + + common.invalidArgTypeHelper(value) + } + ); + }); +} + +// Any falsy value other than undefined will be treated as false. +// Any truthy value will be treated as true. + +assert.strictEqual( + url.format(myURL, { auth: false }), + 'http://xn--lck1c3crb1723bpq4a.com/a?a=b#c' +); + +assert.strictEqual( + url.format(myURL, { auth: '' }), + 'http://xn--lck1c3crb1723bpq4a.com/a?a=b#c' +); + +assert.strictEqual( + url.format(myURL, { auth: 0 }), + 'http://xn--lck1c3crb1723bpq4a.com/a?a=b#c' +); + +assert.strictEqual( + url.format(myURL, { auth: 1 }), + 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b#c' +); + +assert.strictEqual( + url.format(myURL, { auth: {} }), + 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b#c' +); + +assert.strictEqual( + url.format(myURL, { fragment: false }), + 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b' +); + +assert.strictEqual( + url.format(myURL, { fragment: '' }), + 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b' +); + +assert.strictEqual( + url.format(myURL, { fragment: 0 }), + 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b' +); + +assert.strictEqual( + url.format(myURL, { fragment: 1 }), + 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b#c' +); + +assert.strictEqual( + url.format(myURL, { fragment: {} }), + 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b#c' +); + +assert.strictEqual( + url.format(myURL, { search: false }), + 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a#c' +); + +assert.strictEqual( + url.format(myURL, { search: '' }), + 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a#c' +); + +assert.strictEqual( + url.format(myURL, { search: 0 }), + 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a#c' +); + +assert.strictEqual( + url.format(myURL, { search: 1 }), + 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b#c' +); + +assert.strictEqual( + url.format(myURL, { search: {} }), + 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b#c' +); + +assert.strictEqual( + url.format(myURL, { unicode: true }), + 'http://user:pass@理容ナカムラ.com/a?a=b#c' +); + +assert.strictEqual( + url.format(myURL, { unicode: 1 }), + 'http://user:pass@理容ナカムラ.com/a?a=b#c' +); + +assert.strictEqual( + url.format(myURL, { unicode: {} }), + 'http://user:pass@理容ナカムラ.com/a?a=b#c' +); + +assert.strictEqual( + url.format(myURL, { unicode: false }), + 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b#c' +); + +assert.strictEqual( + url.format(myURL, { unicode: 0 }), + 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b#c' +); + +assert.strictEqual( + url.format(new URL('http://user:pass@xn--0zwm56d.com:8080/path'), { unicode: true }), + 'http://user:pass@测试.com:8080/path' +); diff --git a/tests/node_compat/test/parallel/test-url-format.js b/tests/node_compat/test/parallel/test-url-format.js new file mode 100644 index 000000000..1208509c7 --- /dev/null +++ b/tests/node_compat/test/parallel/test-url-format.js @@ -0,0 +1,284 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const url = require('url'); + +if (!common.hasIntl) + common.skip('missing Intl'); + +// Formatting tests to verify that it'll format slightly wonky content to a +// valid URL. +const formatTests = { + 'http://example.com?': { + href: 'http://example.com/?', + protocol: 'http:', + slashes: true, + host: 'example.com', + hostname: 'example.com', + search: '?', + query: {}, + pathname: '/' + }, + 'http://example.com?foo=bar#frag': { + href: 'http://example.com/?foo=bar#frag', + protocol: 'http:', + host: 'example.com', + hostname: 'example.com', + hash: '#frag', + search: '?foo=bar', + query: 'foo=bar', + pathname: '/' + }, + 'http://example.com?foo=@bar#frag': { + href: 'http://example.com/?foo=@bar#frag', + protocol: 'http:', + host: 'example.com', + hostname: 'example.com', + hash: '#frag', + search: '?foo=@bar', + query: 'foo=@bar', + pathname: '/' + }, + 'http://example.com?foo=/bar/#frag': { + href: 'http://example.com/?foo=/bar/#frag', + protocol: 'http:', + host: 'example.com', + hostname: 'example.com', + hash: '#frag', + search: '?foo=/bar/', + query: 'foo=/bar/', + pathname: '/' + }, + 'http://example.com?foo=?bar/#frag': { + href: 'http://example.com/?foo=?bar/#frag', + protocol: 'http:', + host: 'example.com', + hostname: 'example.com', + hash: '#frag', + search: '?foo=?bar/', + query: 'foo=?bar/', + pathname: '/' + }, + 'http://example.com#frag=?bar/#frag': { + href: 'http://example.com/#frag=?bar/#frag', + protocol: 'http:', + host: 'example.com', + hostname: 'example.com', + hash: '#frag=?bar/#frag', + pathname: '/' + }, + 'http://google.com" onload="alert(42)/': { + href: 'http://google.com/%22%20onload=%22alert(42)/', + protocol: 'http:', + host: 'google.com', + pathname: '/%22%20onload=%22alert(42)/' + }, + 'http://a.com/a/b/c?s#h': { + href: 'http://a.com/a/b/c?s#h', + protocol: 'http', + host: 'a.com', + pathname: 'a/b/c', + hash: 'h', + search: 's' + }, + 'xmpp:isaacschlueter@jabber.org': { + href: 'xmpp:isaacschlueter@jabber.org', + protocol: 'xmpp:', + host: 'jabber.org', + auth: 'isaacschlueter', + hostname: 'jabber.org' + }, + 'http://atpass:foo%40bar@127.0.0.1/': { + href: 'http://atpass:foo%40bar@127.0.0.1/', + auth: 'atpass:foo@bar', + hostname: '127.0.0.1', + protocol: 'http:', + pathname: '/' + }, + 'http://atslash%2F%40:%2F%40@foo/': { + href: 'http://atslash%2F%40:%2F%40@foo/', + auth: 'atslash/@:/@', + hostname: 'foo', + protocol: 'http:', + pathname: '/' + }, + 'svn+ssh://foo/bar': { + href: 'svn+ssh://foo/bar', + hostname: 'foo', + protocol: 'svn+ssh:', + pathname: '/bar', + slashes: true + }, + 'dash-test://foo/bar': { + href: 'dash-test://foo/bar', + hostname: 'foo', + protocol: 'dash-test:', + pathname: '/bar', + slashes: true + }, + 'dash-test:foo/bar': { + href: 'dash-test:foo/bar', + hostname: 'foo', + protocol: 'dash-test:', + pathname: '/bar' + }, + 'dot.test://foo/bar': { + href: 'dot.test://foo/bar', + hostname: 'foo', + protocol: 'dot.test:', + pathname: '/bar', + slashes: true + }, + 'dot.test:foo/bar': { + href: 'dot.test:foo/bar', + hostname: 'foo', + protocol: 'dot.test:', + pathname: '/bar' + }, + // IPv6 support + 'coap:u:p@[::1]:61616/.well-known/r?n=Temperature': { + href: 'coap:u:p@[::1]:61616/.well-known/r?n=Temperature', + protocol: 'coap:', + auth: 'u:p', + hostname: '::1', + port: '61616', + pathname: '/.well-known/r', + search: 'n=Temperature' + }, + 'coap:[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:61616/s/stopButton': { + href: 'coap:[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:61616/s/stopButton', + protocol: 'coap', + host: '[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:61616', + pathname: '/s/stopButton' + }, + 'http://[::]/': { + href: 'http://[::]/', + protocol: 'http:', + hostname: '[::]', + pathname: '/' + }, + + // Encode context-specific delimiters in path and query, but do not touch + // other non-delimiter chars like `%`. + // + + // `#`,`?` in path + '/path/to/%%23%3F+=&.txt?foo=theA1#bar': { + href: '/path/to/%%23%3F+=&.txt?foo=theA1#bar', + pathname: '/path/to/%#?+=&.txt', + query: { + foo: 'theA1' + }, + hash: '#bar' + }, + + // `#`,`?` in path + `#` in query + '/path/to/%%23%3F+=&.txt?foo=the%231#bar': { + href: '/path/to/%%23%3F+=&.txt?foo=the%231#bar', + pathname: '/path/to/%#?+=&.txt', + query: { + foo: 'the#1' + }, + hash: '#bar' + }, + + // `#` in path end + `#` in query + '/path/to/%%23?foo=the%231#bar': { + href: '/path/to/%%23?foo=the%231#bar', + pathname: '/path/to/%#', + query: { + foo: 'the#1' + }, + hash: '#bar' + }, + + // `?` and `#` in path and search + 'http://ex.com/foo%3F100%m%23r?abc=the%231?&foo=bar#frag': { + href: 'http://ex.com/foo%3F100%m%23r?abc=the%231?&foo=bar#frag', + protocol: 'http:', + hostname: 'ex.com', + hash: '#frag', + search: '?abc=the#1?&foo=bar', + pathname: '/foo?100%m#r', + }, + + // `?` and `#` in search only + 'http://ex.com/fooA100%mBr?abc=the%231?&foo=bar#frag': { + href: 'http://ex.com/fooA100%mBr?abc=the%231?&foo=bar#frag', + protocol: 'http:', + hostname: 'ex.com', + hash: '#frag', + search: '?abc=the#1?&foo=bar', + pathname: '/fooA100%mBr', + }, + + // Multiple `#` in search + 'http://example.com/?foo=bar%231%232%233&abc=%234%23%235#frag': { + href: 'http://example.com/?foo=bar%231%232%233&abc=%234%23%235#frag', + protocol: 'http:', + slashes: true, + host: 'example.com', + hostname: 'example.com', + hash: '#frag', + search: '?foo=bar#1#2#3&abc=#4##5', + query: {}, + pathname: '/' + }, + + // More than 255 characters in hostname which exceeds the limit + [`http://${'a'.repeat(255)}.com/node`]: { + href: 'http:///node', + protocol: 'http:', + slashes: true, + host: '', + hostname: '', + pathname: '/node', + path: '/node' + }, + + // Greater than or equal to 63 characters after `.` in hostname + [`http://www.${'z'.repeat(63)}example.com/node`]: { + href: `http://www.${'z'.repeat(63)}example.com/node`, + protocol: 'http:', + slashes: true, + host: `www.${'z'.repeat(63)}example.com`, + hostname: `www.${'z'.repeat(63)}example.com`, + pathname: '/node', + path: '/node' + }, + + // https://github.com/nodejs/node/issues/3361 + 'file:///home/user': { + href: 'file:///home/user', + protocol: 'file', + pathname: '/home/user', + path: '/home/user' + }, + + // surrogate in auth + 'http://%F0%9F%98%80@www.example.com/': { + href: 'http://%F0%9F%98%80@www.example.com/', + protocol: 'http:', + auth: '\uD83D\uDE00', + hostname: 'www.example.com', + pathname: '/' + } +}; +for (const u in formatTests) { + const expect = formatTests[u].href; + delete formatTests[u].href; + const actual = url.format(u); + const actualObj = url.format(formatTests[u]); + assert.strictEqual(actual, expect, + `wonky format(${u}) == ${expect}\nactual:${actual}`); + assert.strictEqual(actualObj, expect, + `wonky format(${JSON.stringify(formatTests[u])}) == ${ + expect}\nactual: ${actualObj}`); +} diff --git a/tests/node_compat/test/parallel/test-url-parse-invalid-input.js b/tests/node_compat/test/parallel/test-url-parse-invalid-input.js new file mode 100644 index 000000000..345e8d338 --- /dev/null +++ b/tests/node_compat/test/parallel/test-url-parse-invalid-input.js @@ -0,0 +1,83 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const url = require('url'); + +// https://github.com/joyent/node/issues/568 +[ + [undefined, 'undefined'], + [null, 'object'], + [true, 'boolean'], + [false, 'boolean'], + [0.0, 'number'], + [0, 'number'], + [[], 'object'], + [{}, 'object'], + [() => {}, 'function'], + [Symbol('foo'), 'symbol'], +].forEach(([val, type]) => { + assert.throws(() => { + url.parse(val); + }, { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "url" argument must be of type string.' + + common.invalidArgTypeHelper(val) + }); +}); + +assert.throws(() => { url.parse('http://%E0%A4%A@fail'); }, + (e) => { + // The error should be a URIError. + if (!(e instanceof URIError)) + return false; + + // The error should be from the JS engine and not from Node.js. + // JS engine errors do not have the `code` property. + return e.code === undefined; + }); + +assert.throws(() => { url.parse('http://[127.0.0.1\x00c8763]:8000/'); }, + { code: 'ERR_INVALID_URL', input: 'http://[127.0.0.1\x00c8763]:8000/' } +); + +if (common.hasIntl) { + // An array of Unicode code points whose Unicode NFKD contains a "bad + // character". + const badIDNA = (() => { + const BAD_CHARS = '#%/:?@[\\]^|'; + const out = []; + for (let i = 0x80; i < 0x110000; i++) { + const cp = String.fromCodePoint(i); + for (const badChar of BAD_CHARS) { + if (cp.normalize('NFKD').includes(badChar)) { + out.push(cp); + } + } + } + return out; + })(); + + // The generation logic above should at a minimum produce these two + // characters. + assert(badIDNA.includes('℀')); + assert(badIDNA.includes('@')); + + for (const badCodePoint of badIDNA) { + const badURL = `http://fail${badCodePoint}fail.com/`; + assert.throws(() => { url.parse(badURL); }, + (e) => e.code === 'ERR_INVALID_URL', + `parsing ${badURL}`); + } + + assert.throws(() => { url.parse('http://\u00AD/bad.com/'); }, + (e) => e.code === 'ERR_INVALID_URL', + 'parsing http://\u00AD/bad.com/'); +} diff --git a/tests/node_compat/test/parallel/test-url-parse-query.js b/tests/node_compat/test/parallel/test-url-parse-query.js new file mode 100644 index 000000000..f6ccb1f46 --- /dev/null +++ b/tests/node_compat/test/parallel/test-url-parse-query.js @@ -0,0 +1,97 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const assert = require('assert'); +const url = require('url'); + +function createWithNoPrototype(properties = []) { + const noProto = Object.create(null); + properties.forEach((property) => { + noProto[property.key] = property.value; + }); + return noProto; +} + +function check(actual, expected) { + assert.notStrictEqual(Object.getPrototypeOf(actual), Object.prototype); + assert.deepStrictEqual(Object.keys(actual).sort(), + Object.keys(expected).sort()); + Object.keys(expected).forEach(function(key) { + assert.deepStrictEqual(actual[key], expected[key]); + }); +} + +const parseTestsWithQueryString = { + '/foo/bar?baz=quux#frag': { + href: '/foo/bar?baz=quux#frag', + hash: '#frag', + search: '?baz=quux', + query: createWithNoPrototype([{ key: 'baz', value: 'quux' }]), + pathname: '/foo/bar', + path: '/foo/bar?baz=quux' + }, + 'http://example.com': { + href: 'http://example.com/', + protocol: 'http:', + slashes: true, + host: 'example.com', + hostname: 'example.com', + query: createWithNoPrototype(), + search: null, + pathname: '/', + path: '/' + }, + '/example': { + protocol: null, + slashes: null, + auth: undefined, + host: null, + port: null, + hostname: null, + hash: null, + search: null, + query: createWithNoPrototype(), + pathname: '/example', + path: '/example', + href: '/example' + }, + '/example?query=value': { + protocol: null, + slashes: null, + auth: undefined, + host: null, + port: null, + hostname: null, + hash: null, + search: '?query=value', + query: createWithNoPrototype([{ key: 'query', value: 'value' }]), + pathname: '/example', + path: '/example?query=value', + href: '/example?query=value' + } +}; +for (const u in parseTestsWithQueryString) { + const actual = url.parse(u, true); + const expected = Object.assign(new url.Url(), parseTestsWithQueryString[u]); + for (const i in actual) { + if (actual[i] === null && expected[i] === undefined) { + expected[i] = null; + } + } + + const properties = Object.keys(actual).sort(); + assert.deepStrictEqual(properties, Object.keys(expected).sort()); + properties.forEach((property) => { + if (property === 'query') { + check(actual[property], expected[property]); + } else { + assert.deepStrictEqual(actual[property], expected[property]); + } + }); +} diff --git a/tests/node_compat/test/parallel/test-url-pathtofileurl.js b/tests/node_compat/test/parallel/test-url-pathtofileurl.js new file mode 100644 index 000000000..bafd870aa --- /dev/null +++ b/tests/node_compat/test/parallel/test-url-pathtofileurl.js @@ -0,0 +1,153 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const { isWindows } = require('../common'); +const assert = require('assert'); +const url = require('url'); + +{ + const fileURL = url.pathToFileURL('test/').href; + assert.ok(fileURL.startsWith('file:///')); + assert.ok(fileURL.endsWith('/')); +} + +{ + const fileURL = url.pathToFileURL('test\\').href; + assert.ok(fileURL.startsWith('file:///')); + if (isWindows) + assert.ok(fileURL.endsWith('/')); + else + assert.ok(fileURL.endsWith('%5C')); +} + +{ + const fileURL = url.pathToFileURL('test/%').href; + assert.ok(fileURL.includes('%25')); +} + +{ + if (isWindows) { + // UNC path: \\server\share\resource + + // Missing server: + assert.throws(() => url.pathToFileURL('\\\\\\no-server'), { + code: 'ERR_INVALID_ARG_VALUE' + }); + + // Missing share or resource: + assert.throws(() => url.pathToFileURL('\\\\host'), { + code: 'ERR_INVALID_ARG_VALUE' + }); + } else { + // UNC paths on posix are considered a single path that has backslashes: + const fileURL = url.pathToFileURL('\\\\nas\\share\\path.txt').href; + assert.match(fileURL, /file:\/\/.+%5C%5Cnas%5Cshare%5Cpath\.txt$/); + } +} + +{ + let testCases; + if (isWindows) { + testCases = [ + // Lowercase ascii alpha + { path: 'C:\\foo', expected: 'file:///C:/foo' }, + // Uppercase ascii alpha + { path: 'C:\\FOO', expected: 'file:///C:/FOO' }, + // dir + { path: 'C:\\dir\\foo', expected: 'file:///C:/dir/foo' }, + // trailing separator + { path: 'C:\\dir\\', expected: 'file:///C:/dir/' }, + // dot + { path: 'C:\\foo.mjs', expected: 'file:///C:/foo.mjs' }, + // space + { path: 'C:\\foo bar', expected: 'file:///C:/foo%20bar' }, + // question mark + { path: 'C:\\foo?bar', expected: 'file:///C:/foo%3Fbar' }, + // number sign + { path: 'C:\\foo#bar', expected: 'file:///C:/foo%23bar' }, + // ampersand + { path: 'C:\\foo&bar', expected: 'file:///C:/foo&bar' }, + // equals + { path: 'C:\\foo=bar', expected: 'file:///C:/foo=bar' }, + // colon + { path: 'C:\\foo:bar', expected: 'file:///C:/foo:bar' }, + // semicolon + { path: 'C:\\foo;bar', expected: 'file:///C:/foo;bar' }, + // percent + { path: 'C:\\foo%bar', expected: 'file:///C:/foo%25bar' }, + // backslash + { path: 'C:\\foo\\bar', expected: 'file:///C:/foo/bar' }, + // backspace + { path: 'C:\\foo\bbar', expected: 'file:///C:/foo%08bar' }, + // tab + { path: 'C:\\foo\tbar', expected: 'file:///C:/foo%09bar' }, + // newline + { path: 'C:\\foo\nbar', expected: 'file:///C:/foo%0Abar' }, + // carriage return + { path: 'C:\\foo\rbar', expected: 'file:///C:/foo%0Dbar' }, + // latin1 + { path: 'C:\\fóóbàr', expected: 'file:///C:/f%C3%B3%C3%B3b%C3%A0r' }, + // Euro sign (BMP code point) + { path: 'C:\\€', expected: 'file:///C:/%E2%82%AC' }, + // Rocket emoji (non-BMP code point) + { path: 'C:\\🚀', expected: 'file:///C:/%F0%9F%9A%80' }, + // UNC path (see https://docs.microsoft.com/en-us/archive/blogs/ie/file-uris-in-windows) + { path: '\\\\nas\\My Docs\\File.doc', expected: 'file://nas/My%20Docs/File.doc' }, + ]; + } else { + testCases = [ + // Lowercase ascii alpha + { path: '/foo', expected: 'file:///foo' }, + // Uppercase ascii alpha + { path: '/FOO', expected: 'file:///FOO' }, + // dir + { path: '/dir/foo', expected: 'file:///dir/foo' }, + // trailing separator + { path: '/dir/', expected: 'file:///dir/' }, + // dot + { path: '/foo.mjs', expected: 'file:///foo.mjs' }, + // space + { path: '/foo bar', expected: 'file:///foo%20bar' }, + // question mark + { path: '/foo?bar', expected: 'file:///foo%3Fbar' }, + // number sign + { path: '/foo#bar', expected: 'file:///foo%23bar' }, + // ampersand + { path: '/foo&bar', expected: 'file:///foo&bar' }, + // equals + { path: '/foo=bar', expected: 'file:///foo=bar' }, + // colon + { path: '/foo:bar', expected: 'file:///foo:bar' }, + // semicolon + { path: '/foo;bar', expected: 'file:///foo;bar' }, + // percent + { path: '/foo%bar', expected: 'file:///foo%25bar' }, + // backslash + { path: '/foo\\bar', expected: 'file:///foo%5Cbar' }, + // backspace + { path: '/foo\bbar', expected: 'file:///foo%08bar' }, + // tab + { path: '/foo\tbar', expected: 'file:///foo%09bar' }, + // newline + { path: '/foo\nbar', expected: 'file:///foo%0Abar' }, + // carriage return + { path: '/foo\rbar', expected: 'file:///foo%0Dbar' }, + // latin1 + { path: '/fóóbàr', expected: 'file:///f%C3%B3%C3%B3b%C3%A0r' }, + // Euro sign (BMP code point) + { path: '/€', expected: 'file:///%E2%82%AC' }, + // Rocket emoji (non-BMP code point) + { path: '/🚀', expected: 'file:///%F0%9F%9A%80' }, + ]; + } + + for (const { path, expected } of testCases) { + const actual = url.pathToFileURL(path).href; + assert.strictEqual(actual, expected); + } +} diff --git a/tests/node_compat/test/parallel/test-url-relative.js b/tests/node_compat/test/parallel/test-url-relative.js new file mode 100644 index 000000000..2bcddd96f --- /dev/null +++ b/tests/node_compat/test/parallel/test-url-relative.js @@ -0,0 +1,441 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const assert = require('assert'); +const inspect = require('util').inspect; +const url = require('url'); + +// When source is false +assert.strictEqual(url.resolveObject('', 'foo'), 'foo'); + +// [from, path, expected] +const relativeTests = [ + ['/foo/bar/baz', 'quux', '/foo/bar/quux'], + ['/foo/bar/baz', 'quux/asdf', '/foo/bar/quux/asdf'], + ['/foo/bar/baz', 'quux/baz', '/foo/bar/quux/baz'], + ['/foo/bar/baz', '../quux/baz', '/foo/quux/baz'], + ['/foo/bar/baz', '/bar', '/bar'], + ['/foo/bar/baz/', 'quux', '/foo/bar/baz/quux'], + ['/foo/bar/baz/', 'quux/baz', '/foo/bar/baz/quux/baz'], + ['/foo/bar/baz', '../../../../../../../../quux/baz', '/quux/baz'], + ['/foo/bar/baz', '../../../../../../../quux/baz', '/quux/baz'], + ['/foo', '.', '/'], + ['/foo', '..', '/'], + ['/foo/', '.', '/foo/'], + ['/foo/', '..', '/'], + ['/foo/bar', '.', '/foo/'], + ['/foo/bar', '..', '/'], + ['/foo/bar/', '.', '/foo/bar/'], + ['/foo/bar/', '..', '/foo/'], + ['foo/bar', '../../../baz', '../../baz'], + ['foo/bar/', '../../../baz', '../baz'], + ['http://example.com/b//c//d;p?q#blarg', 'https:#hash2', 'https:///#hash2'], + ['http://example.com/b//c//d;p?q#blarg', + 'https:/p/a/t/h?s#hash2', + 'https://p/a/t/h?s#hash2'], + ['http://example.com/b//c//d;p?q#blarg', + 'https://u:p@h.com/p/a/t/h?s#hash2', + 'https://u:p@h.com/p/a/t/h?s#hash2'], + ['http://example.com/b//c//d;p?q#blarg', + 'https:/a/b/c/d', + 'https://a/b/c/d'], + ['http://example.com/b//c//d;p?q#blarg', + 'http:#hash2', + 'http://example.com/b//c//d;p?q#hash2'], + ['http://example.com/b//c//d;p?q#blarg', + 'http:/p/a/t/h?s#hash2', + 'http://example.com/p/a/t/h?s#hash2'], + ['http://example.com/b//c//d;p?q#blarg', + 'http://u:p@h.com/p/a/t/h?s#hash2', + 'http://u:p@h.com/p/a/t/h?s#hash2'], + ['http://example.com/b//c//d;p?q#blarg', + 'http:/a/b/c/d', + 'http://example.com/a/b/c/d'], + ['/foo/bar/baz', '/../etc/passwd', '/etc/passwd'], + ['http://localhost', 'file:///Users/foo', 'file:///Users/foo'], + ['http://localhost', 'file://foo/Users', 'file://foo/Users'], + ['https://registry.npmjs.org', '@foo/bar', 'https://registry.npmjs.org/@foo/bar'], +]; +relativeTests.forEach(function(relativeTest) { + const a = url.resolve(relativeTest[0], relativeTest[1]); + const e = relativeTest[2]; + assert.strictEqual(a, e, + `resolve(${relativeTest[0]}, ${relativeTest[1]})` + + ` == ${e}\n actual=${a}`); +}); + +// +// Tests below taken from Chiron +// http://code.google.com/p/chironjs/source/browse/trunk/src/test/http/url.js +// +// Copyright (c) 2002-2008 Kris Kowal +// used with permission under MIT License +// +// Changes marked with @isaacs + +const bases = [ + 'http://a/b/c/d;p?q', + 'http://a/b/c/d;p?q=1/2', + 'http://a/b/c/d;p=1/2?q', + 'fred:///s//a/b/c', + 'http:///s//a/b/c', +]; + +// [to, from, result] +const relativeTests2 = [ + // http://lists.w3.org/Archives/Public/uri/2004Feb/0114.html + ['../c', 'foo:a/b', 'foo:c'], + ['foo:.', 'foo:a', 'foo:'], + ['/foo/../../../bar', 'zz:abc', 'zz:/bar'], + ['/foo/../bar', 'zz:abc', 'zz:/bar'], + // @isaacs Disagree. Not how web browsers resolve this. + ['foo/../../../bar', 'zz:abc', 'zz:bar'], + // ['foo/../../../bar', 'zz:abc', 'zz:../../bar'], // @isaacs Added + ['foo/../bar', 'zz:abc', 'zz:bar'], + ['zz:.', 'zz:abc', 'zz:'], + ['/.', bases[0], 'http://a/'], + ['/.foo', bases[0], 'http://a/.foo'], + ['.foo', bases[0], 'http://a/b/c/.foo'], + + // http://gbiv.com/protocols/uri/test/rel_examples1.html + // examples from RFC 2396 + ['g:h', bases[0], 'g:h'], + ['g', bases[0], 'http://a/b/c/g'], + ['./g', bases[0], 'http://a/b/c/g'], + ['g/', bases[0], 'http://a/b/c/g/'], + ['/g', bases[0], 'http://a/g'], + ['//g', bases[0], 'http://g/'], + // Changed with RFC 2396bis + // ('?y', bases[0], 'http://a/b/c/d;p?y'], + ['?y', bases[0], 'http://a/b/c/d;p?y'], + ['g?y', bases[0], 'http://a/b/c/g?y'], + // Changed with RFC 2396bis + // ('#s', bases[0], CURRENT_DOC_URI + '#s'], + ['#s', bases[0], 'http://a/b/c/d;p?q#s'], + ['g#s', bases[0], 'http://a/b/c/g#s'], + ['g?y#s', bases[0], 'http://a/b/c/g?y#s'], + [';x', bases[0], 'http://a/b/c/;x'], + ['g;x', bases[0], 'http://a/b/c/g;x'], + ['g;x?y#s', bases[0], 'http://a/b/c/g;x?y#s'], + // Changed with RFC 2396bis + // ('', bases[0], CURRENT_DOC_URI], + ['', bases[0], 'http://a/b/c/d;p?q'], + ['.', bases[0], 'http://a/b/c/'], + ['./', bases[0], 'http://a/b/c/'], + ['..', bases[0], 'http://a/b/'], + ['../', bases[0], 'http://a/b/'], + ['../g', bases[0], 'http://a/b/g'], + ['../..', bases[0], 'http://a/'], + ['../../', bases[0], 'http://a/'], + ['../../g', bases[0], 'http://a/g'], + ['../../../g', bases[0], ('http://a/../g', 'http://a/g')], + ['../../../../g', bases[0], ('http://a/../../g', 'http://a/g')], + // Changed with RFC 2396bis + // ('/./g', bases[0], 'http://a/./g'], + ['/./g', bases[0], 'http://a/g'], + // Changed with RFC 2396bis + // ('/../g', bases[0], 'http://a/../g'], + ['/../g', bases[0], 'http://a/g'], + ['g.', bases[0], 'http://a/b/c/g.'], + ['.g', bases[0], 'http://a/b/c/.g'], + ['g..', bases[0], 'http://a/b/c/g..'], + ['..g', bases[0], 'http://a/b/c/..g'], + ['./../g', bases[0], 'http://a/b/g'], + ['./g/.', bases[0], 'http://a/b/c/g/'], + ['g/./h', bases[0], 'http://a/b/c/g/h'], + ['g/../h', bases[0], 'http://a/b/c/h'], + ['g;x=1/./y', bases[0], 'http://a/b/c/g;x=1/y'], + ['g;x=1/../y', bases[0], 'http://a/b/c/y'], + ['g?y/./x', bases[0], 'http://a/b/c/g?y/./x'], + ['g?y/../x', bases[0], 'http://a/b/c/g?y/../x'], + ['g#s/./x', bases[0], 'http://a/b/c/g#s/./x'], + ['g#s/../x', bases[0], 'http://a/b/c/g#s/../x'], + ['http:g', bases[0], ('http:g', 'http://a/b/c/g')], + ['http:', bases[0], ('http:', bases[0])], + // Not sure where this one originated + ['/a/b/c/./../../g', bases[0], 'http://a/a/g'], + + // http://gbiv.com/protocols/uri/test/rel_examples2.html + // slashes in base URI's query args + ['g', bases[1], 'http://a/b/c/g'], + ['./g', bases[1], 'http://a/b/c/g'], + ['g/', bases[1], 'http://a/b/c/g/'], + ['/g', bases[1], 'http://a/g'], + ['//g', bases[1], 'http://g/'], + // Changed in RFC 2396bis + // ('?y', bases[1], 'http://a/b/c/?y'], + ['?y', bases[1], 'http://a/b/c/d;p?y'], + ['g?y', bases[1], 'http://a/b/c/g?y'], + ['g?y/./x', bases[1], 'http://a/b/c/g?y/./x'], + ['g?y/../x', bases[1], 'http://a/b/c/g?y/../x'], + ['g#s', bases[1], 'http://a/b/c/g#s'], + ['g#s/./x', bases[1], 'http://a/b/c/g#s/./x'], + ['g#s/../x', bases[1], 'http://a/b/c/g#s/../x'], + ['./', bases[1], 'http://a/b/c/'], + ['../', bases[1], 'http://a/b/'], + ['../g', bases[1], 'http://a/b/g'], + ['../../', bases[1], 'http://a/'], + ['../../g', bases[1], 'http://a/g'], + + // http://gbiv.com/protocols/uri/test/rel_examples3.html + // slashes in path params + // all of these changed in RFC 2396bis + ['g', bases[2], 'http://a/b/c/d;p=1/g'], + ['./g', bases[2], 'http://a/b/c/d;p=1/g'], + ['g/', bases[2], 'http://a/b/c/d;p=1/g/'], + ['g?y', bases[2], 'http://a/b/c/d;p=1/g?y'], + [';x', bases[2], 'http://a/b/c/d;p=1/;x'], + ['g;x', bases[2], 'http://a/b/c/d;p=1/g;x'], + ['g;x=1/./y', bases[2], 'http://a/b/c/d;p=1/g;x=1/y'], + ['g;x=1/../y', bases[2], 'http://a/b/c/d;p=1/y'], + ['./', bases[2], 'http://a/b/c/d;p=1/'], + ['../', bases[2], 'http://a/b/c/'], + ['../g', bases[2], 'http://a/b/c/g'], + ['../../', bases[2], 'http://a/b/'], + ['../../g', bases[2], 'http://a/b/g'], + + // http://gbiv.com/protocols/uri/test/rel_examples4.html + // double and triple slash, unknown scheme + ['g:h', bases[3], 'g:h'], + ['g', bases[3], 'fred:///s//a/b/g'], + ['./g', bases[3], 'fred:///s//a/b/g'], + ['g/', bases[3], 'fred:///s//a/b/g/'], + ['/g', bases[3], 'fred:///g'], // May change to fred:///s//a/g + ['//g', bases[3], 'fred://g'], // May change to fred:///s//g + ['//g/x', bases[3], 'fred://g/x'], // May change to fred:///s//g/x + ['///g', bases[3], 'fred:///g'], + ['./', bases[3], 'fred:///s//a/b/'], + ['../', bases[3], 'fred:///s//a/'], + ['../g', bases[3], 'fred:///s//a/g'], + + ['../../', bases[3], 'fred:///s//'], + ['../../g', bases[3], 'fred:///s//g'], + ['../../../g', bases[3], 'fred:///s/g'], + // May change to fred:///s//a/../../../g + ['../../../../g', bases[3], 'fred:///g'], + + // http://gbiv.com/protocols/uri/test/rel_examples5.html + // double and triple slash, well-known scheme + ['g:h', bases[4], 'g:h'], + ['g', bases[4], 'http:///s//a/b/g'], + ['./g', bases[4], 'http:///s//a/b/g'], + ['g/', bases[4], 'http:///s//a/b/g/'], + ['/g', bases[4], 'http:///g'], // May change to http:///s//a/g + ['//g', bases[4], 'http://g/'], // May change to http:///s//g + ['//g/x', bases[4], 'http://g/x'], // May change to http:///s//g/x + ['///g', bases[4], 'http:///g'], + ['./', bases[4], 'http:///s//a/b/'], + ['../', bases[4], 'http:///s//a/'], + ['../g', bases[4], 'http:///s//a/g'], + ['../../', bases[4], 'http:///s//'], + ['../../g', bases[4], 'http:///s//g'], + // May change to http:///s//a/../../g + ['../../../g', bases[4], 'http:///s/g'], + // May change to http:///s//a/../../../g + ['../../../../g', bases[4], 'http:///g'], + + // From Dan Connelly's tests in http://www.w3.org/2000/10/swap/uripath.py + ['bar:abc', 'foo:xyz', 'bar:abc'], + ['../abc', 'http://example/x/y/z', 'http://example/x/abc'], + ['http://example/x/abc', 'http://example2/x/y/z', 'http://example/x/abc'], + ['../r', 'http://ex/x/y/z', 'http://ex/x/r'], + ['q/r', 'http://ex/x/y', 'http://ex/x/q/r'], + ['q/r#s', 'http://ex/x/y', 'http://ex/x/q/r#s'], + ['q/r#s/t', 'http://ex/x/y', 'http://ex/x/q/r#s/t'], + ['ftp://ex/x/q/r', 'http://ex/x/y', 'ftp://ex/x/q/r'], + ['', 'http://ex/x/y', 'http://ex/x/y'], + ['', 'http://ex/x/y/', 'http://ex/x/y/'], + ['', 'http://ex/x/y/pdq', 'http://ex/x/y/pdq'], + ['z/', 'http://ex/x/y/', 'http://ex/x/y/z/'], + ['#Animal', + 'file:/swap/test/animal.rdf', + 'file:/swap/test/animal.rdf#Animal'], + ['../abc', 'file:/e/x/y/z', 'file:/e/x/abc'], + ['/example/x/abc', 'file:/example2/x/y/z', 'file:/example/x/abc'], + ['../r', 'file:/ex/x/y/z', 'file:/ex/x/r'], + ['/r', 'file:/ex/x/y/z', 'file:/r'], + ['q/r', 'file:/ex/x/y', 'file:/ex/x/q/r'], + ['q/r#s', 'file:/ex/x/y', 'file:/ex/x/q/r#s'], + ['q/r#', 'file:/ex/x/y', 'file:/ex/x/q/r#'], + ['q/r#s/t', 'file:/ex/x/y', 'file:/ex/x/q/r#s/t'], + ['ftp://ex/x/q/r', 'file:/ex/x/y', 'ftp://ex/x/q/r'], + ['', 'file:/ex/x/y', 'file:/ex/x/y'], + ['', 'file:/ex/x/y/', 'file:/ex/x/y/'], + ['', 'file:/ex/x/y/pdq', 'file:/ex/x/y/pdq'], + ['z/', 'file:/ex/x/y/', 'file:/ex/x/y/z/'], + ['file://meetings.example.com/cal#m1', + 'file:/devel/WWW/2000/10/swap/test/reluri-1.n3', + 'file://meetings.example.com/cal#m1'], + ['file://meetings.example.com/cal#m1', + 'file:/home/connolly/w3ccvs/WWW/2000/10/swap/test/reluri-1.n3', + 'file://meetings.example.com/cal#m1'], + ['./#blort', 'file:/some/dir/foo', 'file:/some/dir/#blort'], + ['./#', 'file:/some/dir/foo', 'file:/some/dir/#'], + // Ryan Lee + ['./', 'http://example/x/abc.efg', 'http://example/x/'], + + + // Graham Klyne's tests + // http://www.ninebynine.org/Software/HaskellUtils/Network/UriTest.xls + // 01-31 are from Connelly's cases + + // 32-49 + ['./q:r', 'http://ex/x/y', 'http://ex/x/q:r'], + ['./p=q:r', 'http://ex/x/y', 'http://ex/x/p=q:r'], + ['?pp/rr', 'http://ex/x/y?pp/qq', 'http://ex/x/y?pp/rr'], + ['y/z', 'http://ex/x/y?pp/qq', 'http://ex/x/y/z'], + ['local/qual@domain.org#frag', + 'mailto:local', + 'mailto:local/qual@domain.org#frag'], + ['more/qual2@domain2.org#frag', + 'mailto:local/qual1@domain1.org', + 'mailto:local/more/qual2@domain2.org#frag'], + ['y?q', 'http://ex/x/y?q', 'http://ex/x/y?q'], + ['/x/y?q', 'http://ex?p', 'http://ex/x/y?q'], + ['c/d', 'foo:a/b', 'foo:a/c/d'], + ['/c/d', 'foo:a/b', 'foo:/c/d'], + ['', 'foo:a/b?c#d', 'foo:a/b?c'], + ['b/c', 'foo:a', 'foo:b/c'], + ['../b/c', 'foo:/a/y/z', 'foo:/a/b/c'], + ['./b/c', 'foo:a', 'foo:b/c'], + ['/./b/c', 'foo:a', 'foo:/b/c'], + ['../../d', 'foo://a//b/c', 'foo://a/d'], + ['.', 'foo:a', 'foo:'], + ['..', 'foo:a', 'foo:'], + + // 50-57[cf. TimBL comments -- + // http://lists.w3.org/Archives/Public/uri/2003Feb/0028.html, + // http://lists.w3.org/Archives/Public/uri/2003Jan/0008.html) + ['abc', 'http://example/x/y%2Fz', 'http://example/x/abc'], + ['../../x%2Fabc', 'http://example/a/x/y/z', 'http://example/a/x%2Fabc'], + ['../x%2Fabc', 'http://example/a/x/y%2Fz', 'http://example/a/x%2Fabc'], + ['abc', 'http://example/x%2Fy/z', 'http://example/x%2Fy/abc'], + ['q%3Ar', 'http://ex/x/y', 'http://ex/x/q%3Ar'], + ['/x%2Fabc', 'http://example/x/y%2Fz', 'http://example/x%2Fabc'], + ['/x%2Fabc', 'http://example/x/y/z', 'http://example/x%2Fabc'], + ['/x%2Fabc', 'http://example/x/y%2Fz', 'http://example/x%2Fabc'], + + // 70-77 + ['local2@domain2', 'mailto:local1@domain1?query1', 'mailto:local2@domain2'], + ['local2@domain2?query2', + 'mailto:local1@domain1', + 'mailto:local2@domain2?query2'], + ['local2@domain2?query2', + 'mailto:local1@domain1?query1', + 'mailto:local2@domain2?query2'], + ['?query2', 'mailto:local@domain?query1', 'mailto:local@domain?query2'], + ['local@domain?query2', 'mailto:?query1', 'mailto:local@domain?query2'], + ['?query2', 'mailto:local@domain?query1', 'mailto:local@domain?query2'], + ['http://example/a/b?c/../d', 'foo:bar', 'http://example/a/b?c/../d'], + ['http://example/a/b#c/../d', 'foo:bar', 'http://example/a/b#c/../d'], + + // 82-88 + // @isaacs Disagree. Not how browsers do it. + // ['http:this', 'http://example.org/base/uri', 'http:this'], + // @isaacs Added + ['http:this', 'http://example.org/base/uri', 'http://example.org/base/this'], + ['http:this', 'http:base', 'http:this'], + ['.//g', 'f:/a', 'f://g'], + ['b/c//d/e', 'f://example.org/base/a', 'f://example.org/base/b/c//d/e'], + ['m2@example.ord/c2@example.org', + 'mid:m@example.ord/c@example.org', + 'mid:m@example.ord/m2@example.ord/c2@example.org'], + ['mini1.xml', + 'file:///C:/DEV/Haskell/lib/HXmlToolbox-3.01/examples/', + 'file:///C:/DEV/Haskell/lib/HXmlToolbox-3.01/examples/mini1.xml'], + ['../b/c', 'foo:a/y/z', 'foo:a/b/c'], + + // changeing auth + ['http://diff:auth@www.example.com', + 'http://asdf:qwer@www.example.com', + 'http://diff:auth@www.example.com/'], + + // changing port + ['https://example.com:81/', + 'https://example.com:82/', + 'https://example.com:81/'], + + // https://github.com/nodejs/node/issues/1435 + ['https://another.host.com/', + 'https://user:password@example.org/', + 'https://another.host.com/'], + ['//another.host.com/', + 'https://user:password@example.org/', + 'https://another.host.com/'], + ['http://another.host.com/', + 'https://user:password@example.org/', + 'http://another.host.com/'], + ['mailto:another.host.com', + 'mailto:user@example.org', + 'mailto:another.host.com'], + ['https://example.com/foo', + 'https://user:password@example.com', + 'https://user:password@example.com/foo'], + + // No path at all + ['#hash1', '#hash2', '#hash1'], +]; +relativeTests2.forEach(function(relativeTest) { + const a = url.resolve(relativeTest[1], relativeTest[0]); + const e = url.format(relativeTest[2]); + assert.strictEqual(a, e, + `resolve(${relativeTest[0]}, ${relativeTest[1]})` + + ` == ${e}\n actual=${a}`); +}); + +// If format and parse are inverse operations then +// resolveObject(parse(x), y) == parse(resolve(x, y)) + +// format: [from, path, expected] +relativeTests.forEach(function(relativeTest) { + let actual = url.resolveObject(url.parse(relativeTest[0]), relativeTest[1]); + let expected = url.parse(relativeTest[2]); + + + assert.deepStrictEqual(actual, expected); + + expected = relativeTest[2]; + actual = url.format(actual); + + assert.strictEqual(actual, expected, + `format(${actual}) == ${expected}\n` + + `actual: ${actual}`); +}); + +// format: [to, from, result] +// the test: ['.//g', 'f:/a', 'f://g'] is a fundamental problem +// url.parse('f:/a') does not have a host +// url.resolve('f:/a', './/g') does not have a host because you have moved +// down to the g directory. i.e. f: //g, however when this url is parsed +// f:// will indicate that the host is g which is not the case. +// it is unclear to me how to keep this information from being lost +// it may be that a pathname of ////g should collapse to /g but this seems +// to be a lot of work for an edge case. Right now I remove the test +if (relativeTests2[181][0] === './/g' && + relativeTests2[181][1] === 'f:/a' && + relativeTests2[181][2] === 'f://g') { + relativeTests2.splice(181, 1); +} +relativeTests2.forEach(function(relativeTest) { + let actual = url.resolveObject(url.parse(relativeTest[1]), relativeTest[0]); + let expected = url.parse(relativeTest[2]); + + assert.deepStrictEqual( + actual, + expected, + `expected ${inspect(expected)} but got ${inspect(actual)}` + ); + + expected = url.format(relativeTest[2]); + actual = url.format(actual); + + assert.strictEqual(actual, expected, + `format(${relativeTest[1]}) == ${expected}\n` + + `actual: ${actual}`); +}); diff --git a/tests/node_compat/test/parallel/test-url-urltooptions.js b/tests/node_compat/test/parallel/test-url-urltooptions.js new file mode 100644 index 000000000..05813f0ae --- /dev/null +++ b/tests/node_compat/test/parallel/test-url-urltooptions.js @@ -0,0 +1,45 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.11.1 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +'use strict'; +require('../common'); +const assert = require('assert'); +const { urlToHttpOptions } = require('url'); + +// Test urlToHttpOptions +const urlObj = new URL('http://user:pass@foo.bar.com:21/aaa/zzz?l=24#test'); +const opts = urlToHttpOptions(urlObj); +assert.strictEqual(opts instanceof URL, false); +assert.strictEqual(opts.protocol, 'http:'); +assert.strictEqual(opts.auth, 'user:pass'); +assert.strictEqual(opts.hostname, 'foo.bar.com'); +assert.strictEqual(opts.port, 21); +assert.strictEqual(opts.path, '/aaa/zzz?l=24'); +assert.strictEqual(opts.pathname, '/aaa/zzz'); +assert.strictEqual(opts.search, '?l=24'); +assert.strictEqual(opts.hash, '#test'); + +const { hostname } = urlToHttpOptions(new URL('http://[::1]:21')); +assert.strictEqual(hostname, '::1'); + +// If a WHATWG URL object is copied, it is possible that the resulting copy +// contains the Symbols that Node uses for brand checking, but not the data +// properties, which are getters. Verify that urlToHttpOptions() can handle +// such a case. +const copiedUrlObj = { ...urlObj }; +const copiedOpts = urlToHttpOptions(copiedUrlObj); +assert.strictEqual(copiedOpts instanceof URL, false); +assert.strictEqual(copiedOpts.protocol, undefined); +assert.strictEqual(copiedOpts.auth, undefined); +assert.strictEqual(copiedOpts.hostname, undefined); +// TODO(wafuwafu13): Fix `AssertionError: Values have the same structure but are not reference-equal` +// assert.strictEqual(copiedOpts.port, NaN); +assert.strictEqual(copiedOpts.path, ''); +assert.strictEqual(copiedOpts.pathname, undefined); +assert.strictEqual(copiedOpts.search, undefined); +assert.strictEqual(copiedOpts.hash, undefined); +assert.strictEqual(copiedOpts.href, undefined); diff --git a/tests/node_compat/test/parallel/test-util-deprecate-invalid-code.js b/tests/node_compat/test/parallel/test-util-deprecate-invalid-code.js new file mode 100644 index 000000000..19093a3ae --- /dev/null +++ b/tests/node_compat/test/parallel/test-util-deprecate-invalid-code.js @@ -0,0 +1,21 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const util = require('util'); + +[1, true, false, null, {}].forEach((notString) => { + assert.throws(() => util.deprecate(() => {}, 'message', notString), { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "code" argument must be of type string.' + + common.invalidArgTypeHelper(notString) + }); +}); diff --git a/tests/node_compat/test/parallel/test-util-deprecate.js b/tests/node_compat/test/parallel/test-util-deprecate.js new file mode 100644 index 000000000..2394caa22 --- /dev/null +++ b/tests/node_compat/test/parallel/test-util-deprecate.js @@ -0,0 +1,64 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); + +// Tests basic functionality of util.deprecate(). + +const assert = require('assert'); +const util = require('util'); + +const expectedWarnings = new Map(); + +// Emits deprecation only once if same function is called. +{ + const msg = 'fhqwhgads'; + const fn = util.deprecate(() => {}, msg); + expectedWarnings.set(msg, { code: undefined, count: 1 }); + fn(); + fn(); +} + +// Emits deprecation twice for different functions. +{ + const msg = 'sterrance'; + const fn1 = util.deprecate(() => {}, msg); + const fn2 = util.deprecate(() => {}, msg); + expectedWarnings.set(msg, { code: undefined, count: 2 }); + fn1(); + fn2(); +} + +// Emits deprecation only once if optional code is the same, even for different +// functions. +{ + const msg = 'cannonmouth'; + const code = 'deprecatesque'; + const fn1 = util.deprecate(() => {}, msg, code); + const fn2 = util.deprecate(() => {}, msg, code); + expectedWarnings.set(msg, { code, count: 1 }); + fn1(); + fn2(); + fn1(); + fn2(); +} + +process.on('warning', (warning) => { + assert.strictEqual(warning.name, 'DeprecationWarning'); + assert.ok(expectedWarnings.has(warning.message)); + const expected = expectedWarnings.get(warning.message); + assert.strictEqual(warning.code, expected.code); + expected.count = expected.count - 1; + if (expected.count === 0) + expectedWarnings.delete(warning.message); +}); + +process.on('exit', () => { + assert.deepStrictEqual(expectedWarnings, new Map()); +}); diff --git a/tests/node_compat/test/parallel/test-util-format.js b/tests/node_compat/test/parallel/test-util-format.js new file mode 100644 index 000000000..9d474c481 --- /dev/null +++ b/tests/node_compat/test/parallel/test-util-format.js @@ -0,0 +1,504 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const util = require('util'); +const symbol = Symbol('foo'); + +assert.strictEqual(util.format(), ''); +assert.strictEqual(util.format(''), ''); +assert.strictEqual(util.format([]), '[]'); +assert.strictEqual(util.format([0]), '[ 0 ]'); +assert.strictEqual(util.format({}), '{}'); +assert.strictEqual(util.format({ foo: 42 }), '{ foo: 42 }'); +assert.strictEqual(util.format(null), 'null'); +assert.strictEqual(util.format(true), 'true'); +assert.strictEqual(util.format(false), 'false'); +assert.strictEqual(util.format('test'), 'test'); + +// CHECKME this is for console.log() compatibility - but is it *right*? +assert.strictEqual(util.format('foo', 'bar', 'baz'), 'foo bar baz'); + +// ES6 Symbol handling +assert.strictEqual(util.format(symbol), 'Symbol(foo)'); +assert.strictEqual(util.format('foo', symbol), 'foo Symbol(foo)'); +assert.strictEqual(util.format('%s', symbol), 'Symbol(foo)'); +assert.strictEqual(util.format('%j', symbol), 'undefined'); + +// Number format specifier +assert.strictEqual(util.format('%d'), '%d'); +assert.strictEqual(util.format('%d', 42.0), '42'); +assert.strictEqual(util.format('%d', 42), '42'); +assert.strictEqual(util.format('%d', '42'), '42'); +assert.strictEqual(util.format('%d', '42.0'), '42'); +assert.strictEqual(util.format('%d', 1.5), '1.5'); +assert.strictEqual(util.format('%d', -0.5), '-0.5'); +assert.strictEqual(util.format('%d', -0.0), '-0'); +assert.strictEqual(util.format('%d', ''), '0'); +assert.strictEqual(util.format('%d', ' -0.000'), '-0'); +assert.strictEqual(util.format('%d', Symbol()), 'NaN'); +assert.strictEqual(util.format('%d', Infinity), 'Infinity'); +assert.strictEqual(util.format('%d', -Infinity), '-Infinity'); +assert.strictEqual(util.format('%d %d', 42, 43), '42 43'); +assert.strictEqual(util.format('%d %d', 42), '42 %d'); +assert.strictEqual( + util.format('%d', 1180591620717411303424), + '1.1805916207174113e+21' +); +assert.strictEqual( + util.format('%d', 1180591620717411303424n), + '1180591620717411303424n' +); +assert.strictEqual( + util.format('%d %d', 1180591620717411303424n, 12345678901234567890123n), + '1180591620717411303424n 12345678901234567890123n' +); + +// Integer format specifier +assert.strictEqual(util.format('%i'), '%i'); +assert.strictEqual(util.format('%i', 42.0), '42'); +assert.strictEqual(util.format('%i', 42), '42'); +assert.strictEqual(util.format('%i', '42'), '42'); +assert.strictEqual(util.format('%i', '42.0'), '42'); +assert.strictEqual(util.format('%i', 1.5), '1'); +assert.strictEqual(util.format('%i', -0.5), '-0'); +assert.strictEqual(util.format('%i', ''), 'NaN'); +assert.strictEqual(util.format('%i', Infinity), 'NaN'); +assert.strictEqual(util.format('%i', -Infinity), 'NaN'); +assert.strictEqual(util.format('%i', Symbol()), 'NaN'); +assert.strictEqual(util.format('%i %i', 42, 43), '42 43'); +assert.strictEqual(util.format('%i %i', 42), '42 %i'); +assert.strictEqual( + util.format('%i', 1180591620717411303424), + '1' +); +assert.strictEqual( + util.format('%i', 1180591620717411303424n), + '1180591620717411303424n' +); +assert.strictEqual( + util.format('%i %i', 1180591620717411303424n, 12345678901234567890123n), + '1180591620717411303424n 12345678901234567890123n' +); + +assert.strictEqual( + util.format('%d %i', 1180591620717411303424n, 12345678901234567890123n), + '1180591620717411303424n 12345678901234567890123n' +); + +assert.strictEqual( + util.format('%i %d', 1180591620717411303424n, 12345678901234567890123n), + '1180591620717411303424n 12345678901234567890123n' +); + +// Float format specifier +assert.strictEqual(util.format('%f'), '%f'); +assert.strictEqual(util.format('%f', 42.0), '42'); +assert.strictEqual(util.format('%f', 42), '42'); +assert.strictEqual(util.format('%f', '42'), '42'); +assert.strictEqual(util.format('%f', '-0.0'), '-0'); +assert.strictEqual(util.format('%f', '42.0'), '42'); +assert.strictEqual(util.format('%f', 1.5), '1.5'); +assert.strictEqual(util.format('%f', -0.5), '-0.5'); +assert.strictEqual(util.format('%f', Math.PI), '3.141592653589793'); +assert.strictEqual(util.format('%f', ''), 'NaN'); +assert.strictEqual(util.format('%f', Symbol('foo')), 'NaN'); +assert.strictEqual(util.format('%f', 5n), '5'); +assert.strictEqual(util.format('%f', Infinity), 'Infinity'); +assert.strictEqual(util.format('%f', -Infinity), '-Infinity'); +assert.strictEqual(util.format('%f %f', 42, 43), '42 43'); +assert.strictEqual(util.format('%f %f', 42), '42 %f'); + +// String format specifier +assert.strictEqual(util.format('%s'), '%s'); +assert.strictEqual(util.format('%s', undefined), 'undefined'); +assert.strictEqual(util.format('%s', null), 'null'); +assert.strictEqual(util.format('%s', 'foo'), 'foo'); +assert.strictEqual(util.format('%s', 42), '42'); +assert.strictEqual(util.format('%s', '42'), '42'); +assert.strictEqual(util.format('%s', -0), '-0'); +assert.strictEqual(util.format('%s', '-0.0'), '-0.0'); +assert.strictEqual(util.format('%s %s', 42, 43), '42 43'); +assert.strictEqual(util.format('%s %s', 42), '42 %s'); +assert.strictEqual(util.format('%s', 42n), '42n'); +assert.strictEqual(util.format('%s', Symbol('foo')), 'Symbol(foo)'); +assert.strictEqual(util.format('%s', true), 'true'); +assert.strictEqual(util.format('%s', { a: [1, 2, 3] }), '{ a: [Array] }'); +assert.strictEqual(util.format('%s', { toString() { return 'Foo'; } }), 'Foo'); +assert.strictEqual(util.format('%s', { toString: 5 }), '{ toString: 5 }'); +assert.strictEqual(util.format('%s', () => 5), '() => 5'); +assert.strictEqual(util.format('%s', Infinity), 'Infinity'); +assert.strictEqual(util.format('%s', -Infinity), '-Infinity'); + +// TODO(wafuwafu13): Fix +// // String format specifier including `toString` properties on the prototype. +// { +// class Foo { toString() { return 'Bar'; } } +// assert.strictEqual(util.format('%s', new Foo()), 'Bar'); +// assert.strictEqual( +// util.format('%s', Object.setPrototypeOf(new Foo(), null)), +// '[Foo: null prototype] {}' +// ); +// global.Foo = Foo; +// assert.strictEqual(util.format('%s', new Foo()), 'Bar'); +// delete global.Foo; +// class Bar { abc = true; } +// assert.strictEqual(util.format('%s', new Bar()), 'Bar { abc: true }'); +// class Foobar extends Array { aaa = true; } +// assert.strictEqual( +// util.format('%s', new Foobar(5)), +// 'Foobar(5) [ <5 empty items>, aaa: true ]' +// ); + +// // Subclassing: +// class B extends Foo {} + +// function C() {} +// C.prototype.toString = function() { +// return 'Custom'; +// }; + +// function D() { +// C.call(this); +// } +// D.prototype = Object.create(C.prototype); + +// assert.strictEqual( +// util.format('%s', new B()), +// 'Bar' +// ); +// assert.strictEqual( +// util.format('%s', new C()), +// 'Custom' +// ); +// assert.strictEqual( +// util.format('%s', new D()), +// 'Custom' +// ); + +// D.prototype.constructor = D; +// assert.strictEqual( +// util.format('%s', new D()), +// 'Custom' +// ); + +// D.prototype.constructor = null; +// assert.strictEqual( +// util.format('%s', new D()), +// 'Custom' +// ); + +// D.prototype.constructor = { name: 'Foobar' }; +// assert.strictEqual( +// util.format('%s', new D()), +// 'Custom' +// ); + +// Object.defineProperty(D.prototype, 'constructor', { +// get() { +// throw new Error(); +// }, +// configurable: true +// }); +// assert.strictEqual( +// util.format('%s', new D()), +// 'Custom' +// ); + +// assert.strictEqual( +// util.format('%s', Object.create(null)), +// '[Object: null prototype] {}' +// ); +// } + +// JSON format specifier +assert.strictEqual(util.format('%j'), '%j'); +assert.strictEqual(util.format('%j', 42), '42'); +assert.strictEqual(util.format('%j', '42'), '"42"'); +assert.strictEqual(util.format('%j %j', 42, 43), '42 43'); +assert.strictEqual(util.format('%j %j', 42), '42 %j'); + +// Object format specifier +const obj = { + foo: 'bar', + foobar: 1, + func: function() {} +}; +const nestedObj = { + foo: 'bar', + foobar: { + foo: 'bar', + func: function() {} + } +}; +const nestedObj2 = { + foo: 'bar', + foobar: 1, + func: [{ a: function() {} }] +}; +assert.strictEqual(util.format('%o'), '%o'); +assert.strictEqual(util.format('%o', 42), '42'); +assert.strictEqual(util.format('%o', 'foo'), '\'foo\''); +assert.strictEqual( + util.format('%o', obj), + '{\n' + + ' foo: \'bar\',\n' + + ' foobar: 1,\n' + + ' func: [Function: func] {\n' + + ' [length]: 0,\n' + + ' [name]: \'func\',\n' + + ' [prototype]: { [constructor]: [Circular *1] }\n' + + ' }\n' + + '}'); +assert.strictEqual( + util.format('%o', nestedObj2), + '{\n' + + ' foo: \'bar\',\n' + + ' foobar: 1,\n' + + ' func: [\n' + + ' {\n' + + ' a: [Function: a] {\n' + + ' [length]: 0,\n' + + ' [name]: \'a\',\n' + + ' [prototype]: { [constructor]: [Circular *1] }\n' + + ' }\n' + + ' },\n' + + ' [length]: 1\n' + + ' ]\n' + + '}'); +assert.strictEqual( + util.format('%o', nestedObj), + '{\n' + + ' foo: \'bar\',\n' + + ' foobar: {\n' + + ' foo: \'bar\',\n' + + ' func: [Function: func] {\n' + + ' [length]: 0,\n' + + ' [name]: \'func\',\n' + + ' [prototype]: { [constructor]: [Circular *1] }\n' + + ' }\n' + + ' }\n' + + '}'); +assert.strictEqual( + util.format('%o %o', obj, obj), + '{\n' + + ' foo: \'bar\',\n' + + ' foobar: 1,\n' + + ' func: [Function: func] {\n' + + ' [length]: 0,\n' + + ' [name]: \'func\',\n' + + ' [prototype]: { [constructor]: [Circular *1] }\n' + + ' }\n' + + '} {\n' + + ' foo: \'bar\',\n' + + ' foobar: 1,\n' + + ' func: [Function: func] {\n' + + ' [length]: 0,\n' + + ' [name]: \'func\',\n' + + ' [prototype]: { [constructor]: [Circular *1] }\n' + + ' }\n' + + '}'); +assert.strictEqual( + util.format('%o %o', obj), + '{\n' + + ' foo: \'bar\',\n' + + ' foobar: 1,\n' + + ' func: [Function: func] {\n' + + ' [length]: 0,\n' + + ' [name]: \'func\',\n' + + ' [prototype]: { [constructor]: [Circular *1] }\n' + + ' }\n' + + '} %o'); + +assert.strictEqual(util.format('%O'), '%O'); +assert.strictEqual(util.format('%O', 42), '42'); +assert.strictEqual(util.format('%O', 'foo'), '\'foo\''); +assert.strictEqual( + util.format('%O', obj), + '{ foo: \'bar\', foobar: 1, func: [Function: func] }'); +assert.strictEqual( + util.format('%O', nestedObj), + '{ foo: \'bar\', foobar: { foo: \'bar\', func: [Function: func] } }'); +assert.strictEqual( + util.format('%O %O', obj, obj), + '{ foo: \'bar\', foobar: 1, func: [Function: func] } ' + + '{ foo: \'bar\', foobar: 1, func: [Function: func] }'); +assert.strictEqual( + util.format('%O %O', obj), + '{ foo: \'bar\', foobar: 1, func: [Function: func] } %O'); + +// Various format specifiers +assert.strictEqual(util.format('%%s%s', 'foo'), '%sfoo'); +assert.strictEqual(util.format('%s:%s'), '%s:%s'); +assert.strictEqual(util.format('%s:%s', undefined), 'undefined:%s'); +assert.strictEqual(util.format('%s:%s', 'foo'), 'foo:%s'); +assert.strictEqual(util.format('%s:%i', 'foo'), 'foo:%i'); +assert.strictEqual(util.format('%s:%f', 'foo'), 'foo:%f'); +assert.strictEqual(util.format('%s:%s', 'foo', 'bar'), 'foo:bar'); +assert.strictEqual(util.format('%s:%s', 'foo', 'bar', 'baz'), 'foo:bar baz'); +assert.strictEqual(util.format('%%%s%%', 'hi'), '%hi%'); +assert.strictEqual(util.format('%%%s%%%%', 'hi'), '%hi%%'); +assert.strictEqual(util.format('%sbc%%def', 'a'), 'abc%def'); +assert.strictEqual(util.format('%d:%d', 12, 30), '12:30'); +assert.strictEqual(util.format('%d:%d', 12), '12:%d'); +assert.strictEqual(util.format('%d:%d'), '%d:%d'); +assert.strictEqual(util.format('%i:%i', 12, 30), '12:30'); +assert.strictEqual(util.format('%i:%i', 12), '12:%i'); +assert.strictEqual(util.format('%i:%i'), '%i:%i'); +assert.strictEqual(util.format('%f:%f', 12, 30), '12:30'); +assert.strictEqual(util.format('%f:%f', 12), '12:%f'); +assert.strictEqual(util.format('%f:%f'), '%f:%f'); +assert.strictEqual(util.format('o: %j, a: %j', {}, []), 'o: {}, a: []'); +assert.strictEqual(util.format('o: %j, a: %j', {}), 'o: {}, a: %j'); +assert.strictEqual(util.format('o: %j, a: %j'), 'o: %j, a: %j'); +assert.strictEqual(util.format('o: %o, a: %O', {}, []), 'o: {}, a: []'); +assert.strictEqual(util.format('o: %o, a: %o', {}), 'o: {}, a: %o'); +assert.strictEqual(util.format('o: %O, a: %O'), 'o: %O, a: %O'); + + +// Invalid format specifiers +assert.strictEqual(util.format('a% b', 'x'), 'a% b x'); +assert.strictEqual(util.format('percent: %d%, fraction: %d', 10, 0.1), + 'percent: 10%, fraction: 0.1'); +assert.strictEqual(util.format('abc%', 1), 'abc% 1'); + +// Additional arguments after format specifiers +assert.strictEqual(util.format('%i', 1, 'number'), '1 number'); +assert.strictEqual(util.format('%i', 1, () => {}), '1 [Function (anonymous)]'); + +// %c from https://console.spec.whatwg.org/ +assert.strictEqual(util.format('%c'), '%c'); +assert.strictEqual(util.format('%cab'), '%cab'); +assert.strictEqual(util.format('%cab', 'color: blue'), 'ab'); +assert.strictEqual(util.format('%cab', 'color: blue', 'c'), 'ab c'); + +{ + const o = {}; + o.o = o; + assert.strictEqual(util.format('%j', o), '[Circular]'); +} + +{ + const o = { + toJSON() { + throw new Error('Not a circular object but still not serializable'); + } + }; + assert.throws(() => util.format('%j', o), + /^Error: Not a circular object but still not serializable$/); +} + +// Errors +const err = new Error('foo'); +assert.strictEqual(util.format(err), err.stack); +class CustomError extends Error { + constructor(msg) { + super(); + Object.defineProperty(this, 'message', + { value: msg, enumerable: false }); + Object.defineProperty(this, 'name', + { value: 'CustomError', enumerable: false }); + Error.captureStackTrace(this, CustomError); + } +} +const customError = new CustomError('bar'); +assert.strictEqual(util.format(customError), customError.stack); +// Doesn't capture stack trace +function BadCustomError(msg) { + Error.call(this); + Object.defineProperty(this, 'message', + { value: msg, enumerable: false }); + Object.defineProperty(this, 'name', + { value: 'BadCustomError', enumerable: false }); +} +Object.setPrototypeOf(BadCustomError.prototype, Error.prototype); +Object.setPrototypeOf(BadCustomError, Error); +assert.strictEqual(util.format(new BadCustomError('foo')), + '[BadCustomError: foo]'); + +// The format of arguments should not depend on type of the first argument +assert.strictEqual(util.format('1', '1'), '1 1'); +assert.strictEqual(util.format(1, '1'), '1 1'); +assert.strictEqual(util.format('1', 1), '1 1'); +assert.strictEqual(util.format(1, -0), '1 -0'); +assert.strictEqual(util.format('1', () => {}), '1 [Function (anonymous)]'); +assert.strictEqual(util.format(1, () => {}), '1 [Function (anonymous)]'); +assert.strictEqual(util.format('1', "'"), "1 '"); +assert.strictEqual(util.format(1, "'"), "1 '"); +assert.strictEqual(util.format('1', 'number'), '1 number'); +assert.strictEqual(util.format(1, 'number'), '1 number'); +assert.strictEqual(util.format(5n), '5n'); +assert.strictEqual(util.format(5n, 5n), '5n 5n'); + +// Check `formatWithOptions`. +assert.strictEqual( + util.formatWithOptions( + { colors: true }, + true, undefined, Symbol(), 1, 5n, null, 'foobar' + ), + '\u001b[33mtrue\u001b[39m ' + + '\u001b[90mundefined\u001b[39m ' + + '\u001b[32mSymbol()\u001b[39m ' + + '\u001b[33m1\u001b[39m ' + + '\u001b[33m5n\u001b[39m ' + + '\u001b[1mnull\u001b[22m ' + + 'foobar' +); + +// TODO(wafuwafu13): Fix +// assert.strictEqual( +// util.format(new SharedArrayBuffer(4)), +// 'SharedArrayBuffer { [Uint8Contents]: <00 00 00 00>, byteLength: 4 }' +// ); + +assert.strictEqual( + util.formatWithOptions( + { colors: true, compact: 3 }, + '%s', [ 1, { a: true }] + ), + '[ 1, [Object] ]' +); + +[ + undefined, + null, + false, + 5n, + 5, + 'test', + Symbol(), +].forEach((invalidOptions) => { + assert.throws(() => { + util.formatWithOptions(invalidOptions, { a: true }); + }, { + code: 'ERR_INVALID_ARG_TYPE', + message: /"inspectOptions".+object/ + }); +}); diff --git a/tests/node_compat/test/parallel/test-util-inherits.js b/tests/node_compat/test/parallel/test-util-inherits.js new file mode 100644 index 000000000..ac1ab596b --- /dev/null +++ b/tests/node_compat/test/parallel/test-util-inherits.js @@ -0,0 +1,117 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); +const { inherits } = require('util'); + +// Super constructor +function A() { + this._a = 'a'; +} +A.prototype.a = function() { return this._a; }; + +// One level of inheritance +function B(value) { + A.call(this); + this._b = value; +} +inherits(B, A); +B.prototype.b = function() { return this._b; }; + +assert.deepStrictEqual( + Object.getOwnPropertyDescriptor(B, 'super_'), + { + value: A, + enumerable: false, + configurable: true, + writable: true + } +); + +const b = new B('b'); +assert.strictEqual(b.a(), 'a'); +assert.strictEqual(b.b(), 'b'); +assert.strictEqual(b.constructor, B); + +// Two levels of inheritance +function C() { + B.call(this, 'b'); + this._c = 'c'; +} +inherits(C, B); +C.prototype.c = function() { return this._c; }; +C.prototype.getValue = function() { return this.a() + this.b() + this.c(); }; + +assert.strictEqual(C.super_, B); + +const c = new C(); +assert.strictEqual(c.getValue(), 'abc'); +assert.strictEqual(c.constructor, C); + +// Inherits can be called after setting prototype properties +function D() { + C.call(this); + this._d = 'd'; +} + +D.prototype.d = function() { return this._d; }; +inherits(D, C); + +assert.strictEqual(D.super_, C); + +const d = new D(); +assert.strictEqual(d.c(), 'c'); +assert.strictEqual(d.d(), 'd'); +assert.strictEqual(d.constructor, D); + +// ES6 classes can inherit from a constructor function +class E { + constructor() { + D.call(this); + this._e = 'e'; + } + e() { return this._e; } +} +inherits(E, D); + +assert.strictEqual(E.super_, D); + +const e = new E(); +assert.strictEqual(e.getValue(), 'abc'); +assert.strictEqual(e.d(), 'd'); +assert.strictEqual(e.e(), 'e'); +assert.strictEqual(e.constructor, E); + +// Should throw with invalid arguments +assert.throws(() => { + inherits(A, {}); +}, { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "superCtor.prototype" property must be of type object. ' + + 'Received undefined' +}); + +assert.throws(() => { + inherits(A, null); +}, { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "superCtor" argument must be of type function. ' + + 'Received null' +}); + +assert.throws(() => { + inherits(null, A); +}, { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "ctor" argument must be of type function. Received null' +}); diff --git a/tests/node_compat/test/parallel/test-util-inspect-long-running.js b/tests/node_compat/test/parallel/test-util-inspect-long-running.js new file mode 100644 index 000000000..67dc03ba4 --- /dev/null +++ b/tests/node_compat/test/parallel/test-util-inspect-long-running.js @@ -0,0 +1,27 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); + +// Test that huge objects don't crash due to exceeding the maximum heap size. + +const util = require('util'); + +// Create a difficult to stringify object. Without the artificial limitation +// this would crash or throw an maximum string size error. +let last = {}; +const obj = last; + +for (let i = 0; i < 1000; i++) { + last.next = { circular: obj, last, obj: { a: 1, b: 2, c: true } }; + last = last.next; + obj[i] = last; +} + +util.inspect(obj, { depth: Infinity }); diff --git a/tests/node_compat/test/parallel/test-util-inspect-namespace.js b/tests/node_compat/test/parallel/test-util-inspect-namespace.js new file mode 100644 index 000000000..786f05671 --- /dev/null +++ b/tests/node_compat/test/parallel/test-util-inspect-namespace.js @@ -0,0 +1,28 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Flags: --experimental-vm-modules +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +// TODO(wafuwafu13): Implement 'vm' +// const { SourceTextModule } = require('vm'); +const { inspect } = require('util'); + +// (async () => { +// const m = new SourceTextModule('export const a = 1; export var b = 2'); +// await m.link(() => 0); +// assert.strictEqual( +// inspect(m.namespace), +// '[Module: null prototype] { a: , b: undefined }'); +// await m.evaluate(); +// assert.strictEqual( +// inspect(m.namespace), +// '[Module: null prototype] { a: 1, b: 2 }' +// ); +// })().then(common.mustCall()); diff --git a/tests/node_compat/test/parallel/test-util-inspect-proxy.js b/tests/node_compat/test/parallel/test-util-inspect-proxy.js new file mode 100644 index 000000000..ef78ab07a --- /dev/null +++ b/tests/node_compat/test/parallel/test-util-inspect-proxy.js @@ -0,0 +1,172 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Flags: --expose-internals +'use strict'; + +require('../common'); +const assert = require('assert'); +const util = require('util'); +// TODO(wafuwafu13): Implement 'internal/test/binding' +// const { internalBinding } = require('internal/test/binding'); +// const processUtil = internalBinding('util'); +const opts = { showProxy: true }; + +// let proxyObj; +// let called = false; +// const target = { +// [util.inspect.custom](depth, { showProxy }) { +// if (showProxy === false) { +// called = true; +// if (proxyObj !== this) { +// throw new Error('Failed'); +// } +// } +// return [1, 2, 3]; +// } +// }; + +// // TODO(wafuwafu13): Fix Uncaught Error +// const handler = { +// getPrototypeOf() { throw new Error('getPrototypeOf'); }, +// setPrototypeOf() { throw new Error('setPrototypeOf'); }, +// isExtensible() { throw new Error('isExtensible'); }, +// preventExtensions() { throw new Error('preventExtensions'); }, +// getOwnPropertyDescriptor() { throw new Error('getOwnPropertyDescriptor'); }, +// defineProperty() { throw new Error('defineProperty'); }, +// has() { throw new Error('has'); }, +// get() { throw new Error('get'); }, +// set() { throw new Error('set'); }, +// deleteProperty() { throw new Error('deleteProperty'); }, +// ownKeys() { throw new Error('ownKeys'); }, +// apply() { throw new Error('apply'); }, +// construct() { throw new Error('construct'); } +// }; +// proxyObj = new Proxy(target, handler); + +// // Inspecting the proxy should not actually walk it's properties +// util.inspect(proxyObj, opts); + +// // Make sure inspecting object does not trigger any proxy traps. +// util.format('%s', proxyObj); + +// TODO(wafuwafu13): Implement processUtil +// // getProxyDetails is an internal method, not intended for public use. +// // This is here to test that the internals are working correctly. +// let details = processUtil.getProxyDetails(proxyObj, true); +// assert.strictEqual(target, details[0]); +// assert.strictEqual(handler, details[1]); + +// details = processUtil.getProxyDetails(proxyObj); +// assert.strictEqual(target, details[0]); +// assert.strictEqual(handler, details[1]); + +// details = processUtil.getProxyDetails(proxyObj, false); +// assert.strictEqual(target, details); + +// assert.strictEqual( +// util.inspect(proxyObj, opts), +// 'Proxy [\n' + +// ' [ 1, 2, 3 ],\n' + +// ' {\n' + +// ' getPrototypeOf: [Function: getPrototypeOf],\n' + +// ' setPrototypeOf: [Function: setPrototypeOf],\n' + +// ' isExtensible: [Function: isExtensible],\n' + +// ' preventExtensions: [Function: preventExtensions],\n' + +// ' getOwnPropertyDescriptor: [Function: getOwnPropertyDescriptor],\n' + +// ' defineProperty: [Function: defineProperty],\n' + +// ' has: [Function: has],\n' + +// ' get: [Function: get],\n' + +// ' set: [Function: set],\n' + +// ' deleteProperty: [Function: deleteProperty],\n' + +// ' ownKeys: [Function: ownKeys],\n' + +// ' apply: [Function: apply],\n' + +// ' construct: [Function: construct]\n' + +// ' }\n' + +// ']' +// ); + +// TODO(wafuwafu13): Implement processUtil +// // Using getProxyDetails with non-proxy returns undefined +// assert.strictEqual(processUtil.getProxyDetails({}), undefined); + +// // Inspecting a proxy without the showProxy option set to true should not +// // trigger any proxy handlers. +// assert.strictEqual(util.inspect(proxyObj), '[ 1, 2, 3 ]'); +// assert(called); + +// Yo dawg, I heard you liked Proxy so I put a Proxy +// inside your Proxy that proxies your Proxy's Proxy. +const proxy1 = new Proxy({}, {}); +const proxy2 = new Proxy(proxy1, {}); +const proxy3 = new Proxy(proxy2, proxy1); +const proxy4 = new Proxy(proxy1, proxy2); +const proxy5 = new Proxy(proxy3, proxy4); +const proxy6 = new Proxy(proxy5, proxy5); +const expected0 = '{}'; +const expected1 = 'Proxy [ {}, {} ]'; +const expected2 = 'Proxy [ Proxy [ {}, {} ], {} ]'; +const expected3 = 'Proxy [ Proxy [ Proxy [ {}, {} ], {} ], Proxy [ {}, {} ] ]'; +const expected4 = 'Proxy [ Proxy [ {}, {} ], Proxy [ Proxy [ {}, {} ], {} ] ]'; +const expected5 = 'Proxy [\n ' + + 'Proxy [ Proxy [ Proxy [Array], {} ], Proxy [ {}, {} ] ],\n' + + ' Proxy [ Proxy [ {}, {} ], Proxy [ Proxy [Array], {} ] ]' + + '\n]'; +const expected6 = 'Proxy [\n' + + ' Proxy [\n' + + ' Proxy [ Proxy [Array], Proxy [Array] ],\n' + + ' Proxy [ Proxy [Array], Proxy [Array] ]\n' + + ' ],\n' + + ' Proxy [\n' + + ' Proxy [ Proxy [Array], Proxy [Array] ],\n' + + ' Proxy [ Proxy [Array], Proxy [Array] ]\n' + + ' ]\n' + + ']'; +// assert.strictEqual( +// util.inspect(proxy1, { showProxy: 1, depth: null }), +// expected1); +// assert.strictEqual(util.inspect(proxy2, opts), expected2); +// assert.strictEqual(util.inspect(proxy3, opts), expected3); +// assert.strictEqual(util.inspect(proxy4, opts), expected4); +// assert.strictEqual(util.inspect(proxy5, opts), expected5); +// assert.strictEqual(util.inspect(proxy6, opts), expected6); +// assert.strictEqual(util.inspect(proxy1), expected0); +// assert.strictEqual(util.inspect(proxy2), expected0); +// assert.strictEqual(util.inspect(proxy3), expected0); +// assert.strictEqual(util.inspect(proxy4), expected0); +// assert.strictEqual(util.inspect(proxy5), expected0); +// assert.strictEqual(util.inspect(proxy6), expected0); + +// // Just for fun, let's create a Proxy using Arrays. +// const proxy7 = new Proxy([], []); +// const expected7 = 'Proxy [ [], [] ]'; +// assert.strictEqual(util.inspect(proxy7, opts), expected7); +// assert.strictEqual(util.inspect(proxy7), '[]'); + +// // Now we're just getting silly, right? +// const proxy8 = new Proxy(Date, []); +// const proxy9 = new Proxy(Date, String); +// const expected8 = 'Proxy [ [Function: Date], [] ]'; +// const expected9 = 'Proxy [ [Function: Date], [Function: String] ]'; +// assert.strictEqual(util.inspect(proxy8, opts), expected8); +// assert.strictEqual(util.inspect(proxy9, opts), expected9); +// assert.strictEqual(util.inspect(proxy8), '[Function: Date]'); +// assert.strictEqual(util.inspect(proxy9), '[Function: Date]'); + +// const proxy10 = new Proxy(() => {}, {}); +// const proxy11 = new Proxy(() => {}, { +// get() { +// return proxy11; +// }, +// apply() { +// return proxy11; +// } +// }); +// const expected10 = '[Function (anonymous)]'; +// const expected11 = '[Function (anonymous)]'; +// assert.strictEqual(util.inspect(proxy10), expected10); +// assert.strictEqual(util.inspect(proxy11), expected11); diff --git a/tests/node_compat/test/parallel/test-util-inspect.js b/tests/node_compat/test/parallel/test-util-inspect.js new file mode 100644 index 000000000..17fafed2e --- /dev/null +++ b/tests/node_compat/test/parallel/test-util-inspect.js @@ -0,0 +1,3201 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Flags: --expose-internals +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. +'use strict'; +const common = require('../common'); +const assert = require('assert'); +// TODO(wafuwafu13): Implement 'internal/test/binding' +// const { internalBinding } = require('internal/test/binding'); +// const JSStream = internalBinding('js_stream').JSStream; +const util = require('util'); +const vm = require('vm'); +// TODO(wafuwafu13): Implement 'v8' +// const v8 = require('v8'); +// TODO(wafuwafu13): Implement 'internal/test/binding' +// const { previewEntries } = internalBinding('util'); +const { inspect } = util; +// TODO(wafuwafu13): Implement MessageChannel +// const { MessageChannel } = require('worker_threads'); + +assert.strictEqual(util.inspect(1), '1'); +assert.strictEqual(util.inspect(false), 'false'); +assert.strictEqual(util.inspect(''), "''"); +assert.strictEqual(util.inspect('hello'), "'hello'"); +assert.strictEqual(util.inspect(function abc() {}), '[Function: abc]'); +assert.strictEqual(util.inspect(() => {}), '[Function (anonymous)]'); +assert.strictEqual( + util.inspect(async function() {}), + '[AsyncFunction (anonymous)]' +); +assert.strictEqual(util.inspect(async () => {}), '[AsyncFunction (anonymous)]'); + +// Special function inspection. +{ + const fn = (() => function*() {})(); + assert.strictEqual( + util.inspect(fn), + '[GeneratorFunction (anonymous)]' + ); + // TODO(wafuwafu13): Fix + // assert.strictEqual( + // util.inspect(async function* abc() {}), + // '[AsyncGeneratorFunction: abc]' + // ); + Object.setPrototypeOf(fn, Object.getPrototypeOf(async () => {})); + // TODO(wafuwafu13): Fix + // assert.strictEqual( + // util.inspect(fn), + // '[GeneratorFunction (anonymous)] AsyncFunction' + // ); + Object.defineProperty(fn, 'name', { value: 5, configurable: true }); + // TODO(wafuwafu13): Fix + // assert.strictEqual( + // util.inspect(fn), + // '[GeneratorFunction: 5] AsyncFunction' + // ); + Object.defineProperty(fn, Symbol.toStringTag, { + value: 'Foobar', + configurable: true + }); + // TODO(wafuwafu13): Fix + // assert.strictEqual( + // util.inspect({ ['5']: fn }), + // "{ '5': [GeneratorFunction: 5] AsyncFunction [Foobar] }" + // ); + Object.defineProperty(fn, 'name', { value: '5', configurable: true }); + Object.setPrototypeOf(fn, null); + // TODO(wafuwafu13): Fix + // assert.strictEqual( + // util.inspect(fn), + // '[GeneratorFunction (null prototype): 5] [Foobar]' + // ); + // assert.strictEqual( + // util.inspect({ ['5']: fn }), + // "{ '5': [GeneratorFunction (null prototype): 5] [Foobar] }" + // ); +} + +assert.strictEqual(util.inspect(undefined), 'undefined'); +assert.strictEqual(util.inspect(null), 'null'); +assert.strictEqual(util.inspect(/foo(bar\n)?/gi), '/foo(bar\\n)?/gi'); +assert.strictEqual( + util.inspect(new Date('Sun, 14 Feb 2010 11:48:40 GMT')), + new Date('2010-02-14T12:48:40+01:00').toISOString() +); +assert.strictEqual(util.inspect(new Date('')), (new Date('')).toString()); +assert.strictEqual(util.inspect('\n\x01'), "'\\n\\x01'"); +// TODO(@crowlKats) +//assert.strictEqual( +// util.inspect(`${Array(75).fill(1)}'\n\x1d\n\x03\x85\x7f\x7e\x9f\xa0`), +// // eslint-disable-next-line no-irregular-whitespace +// `"${Array(75).fill(1)}'\\n" +\n '\\x1D\\n' +\n '\\x03\\x85\\x7F~\\x9F '` +//); +assert.strictEqual(util.inspect([]), '[]'); +assert.strictEqual(util.inspect(Object.create([])), 'Array {}'); +assert.strictEqual(util.inspect([1, 2]), '[ 1, 2 ]'); +assert.strictEqual(util.inspect([1, [2, 3]]), '[ 1, [ 2, 3 ] ]'); +assert.strictEqual(util.inspect({}), '{}'); +assert.strictEqual(util.inspect({ a: 1 }), '{ a: 1 }'); +assert.strictEqual(util.inspect({ a: function() {} }), '{ a: [Function: a] }'); +assert.strictEqual(util.inspect({ a: () => {} }), '{ a: [Function: a] }'); +// eslint-disable-next-line func-name-matching +assert.strictEqual(util.inspect({ a: async function abc() {} }), + '{ a: [AsyncFunction: abc] }'); +assert.strictEqual(util.inspect({ a: async () => {} }), + '{ a: [AsyncFunction: a] }'); +assert.strictEqual(util.inspect({ a: function*() {} }), + '{ a: [GeneratorFunction: a] }'); +assert.strictEqual(util.inspect({ a: 1, b: 2 }), '{ a: 1, b: 2 }'); +assert.strictEqual(util.inspect({ 'a': {} }), '{ a: {} }'); +assert.strictEqual(util.inspect({ 'a': { 'b': 2 } }), '{ a: { b: 2 } }'); +assert.strictEqual(util.inspect({ 'a': { 'b': { 'c': { 'd': 2 } } } }), + '{ a: { b: { c: [Object] } } }'); +assert.strictEqual( + util.inspect({ 'a': { 'b': { 'c': { 'd': 2 } } } }, false, null), + '{\n a: { b: { c: { d: 2 } } }\n}'); +// TODO(wafuwafu13): Fix +// assert.strictEqual(util.inspect([1, 2, 3], true), '[ 1, 2, 3, [length]: 3 ]'); +assert.strictEqual(util.inspect({ 'a': { 'b': { 'c': 2 } } }, false, 0), + '{ a: [Object] }'); +assert.strictEqual(util.inspect({ 'a': { 'b': { 'c': 2 } } }, false, 1), + '{ a: { b: [Object] } }'); +assert.strictEqual(util.inspect({ 'a': { 'b': ['c'] } }, false, 1), + '{ a: { b: [Array] } }'); +// TODO(wafuwafu13): Fix +// assert.strictEqual(util.inspect(new Uint8Array(0)), 'Uint8Array(0) []'); +// assert(inspect(new Uint8Array(0), { showHidden: true }).includes('[buffer]')); +assert.strictEqual( + util.inspect( + Object.create( + {}, + { visible: { value: 1, enumerable: true }, hidden: { value: 2 } } + ) + ), + '{ visible: 1 }' +); +// TODO(wafuwafu13): Fix +// assert.strictEqual( +// util.inspect( +// Object.assign(new String('hello'), { [Symbol('foo')]: 123 }), +// { showHidden: true } +// ), +// "[String: 'hello'] { [length]: 5, [Symbol(foo)]: 123 }" +// ); + +// TODO(wafuwafu13): Implement JSStream +// assert.match(util.inspect((new JSStream())._externalStream), +// /^\[External: [0-9a-f]+\]$/); + +{ + const regexp = /regexp/; + regexp.aprop = 42; + assert.strictEqual(util.inspect({ a: regexp }, false, 0), '{ a: /regexp/ }'); +} + +assert.match( + util.inspect({ a: { a: { a: { a: {} } } } }, undefined, undefined, true), + /Object/ +); +assert.doesNotMatch( + util.inspect({ a: { a: { a: { a: {} } } } }, undefined, null, true), + /Object/ +); + +// TODO(wafuwafu13): Fix +// { +// const showHidden = true; +// const ab = new Uint8Array([1, 2, 3, 4]).buffer; +// const dv = new DataView(ab, 1, 2); +// assert.strictEqual( +// util.inspect(ab, showHidden), +// 'ArrayBuffer { [Uint8Contents]: <01 02 03 04>, byteLength: 4 }' +// ); +// assert.strictEqual(util.inspect(new DataView(ab, 1, 2), showHidden), +// 'DataView {\n' + +// ' byteLength: 2,\n' + +// ' byteOffset: 1,\n' + +// ' buffer: ArrayBuffer {' + +// ' [Uint8Contents]: <01 02 03 04>, byteLength: 4 }\n}'); +// assert.strictEqual( +// util.inspect(ab, showHidden), +// 'ArrayBuffer { [Uint8Contents]: <01 02 03 04>, byteLength: 4 }' +// ); +// assert.strictEqual(util.inspect(dv, showHidden), +// 'DataView {\n' + +// ' byteLength: 2,\n' + +// ' byteOffset: 1,\n' + +// ' buffer: ArrayBuffer { [Uint8Contents]: ' + +// '<01 02 03 04>, byteLength: 4 }\n}'); +// ab.x = 42; +// dv.y = 1337; +// assert.strictEqual(util.inspect(ab, showHidden), +// 'ArrayBuffer { [Uint8Contents]: <01 02 03 04>, ' + +// 'byteLength: 4, x: 42 }'); +// assert.strictEqual(util.inspect(dv, showHidden), +// 'DataView {\n' + +// ' byteLength: 2,\n' + +// ' byteOffset: 1,\n' + +// ' buffer: ArrayBuffer { [Uint8Contents]: <01 02 03 04>,' + +// ' byteLength: 4, x: 42 },\n' + +// ' y: 1337\n}'); +// } + +// TODO(wafuwafu13): Implement `MessageChannel` +// { +// const ab = new ArrayBuffer(42); +// assert.strictEqual(ab.byteLength, 42); +// new MessageChannel().port1.postMessage(ab, [ ab ]); +// assert.strictEqual(ab.byteLength, 0); +// assert.strictEqual(util.inspect(ab), +// 'ArrayBuffer { (detached), byteLength: 0 }'); +// } + +// TODO(wafuwafu13): Fix +// // Truncate output for ArrayBuffers using plural or singular bytes +// { +// const ab = new ArrayBuffer(3); +// assert.strictEqual(util.inspect(ab, { showHidden: true, maxArrayLength: 2 }), +// 'ArrayBuffer { [Uint8Contents]' + +// ': <00 00 ... 1 more byte>, byteLength: 3 }'); +// assert.strictEqual(util.inspect(ab, { showHidden: true, maxArrayLength: 1 }), +// 'ArrayBuffer { [Uint8Contents]' + +// ': <00 ... 2 more bytes>, byteLength: 3 }'); +// } + +// TODO(wafuwafu13): Implement 'vm' +// // Now do the same checks but from a different context. +// { +// const showHidden = false; +// const ab = vm.runInNewContext('new ArrayBuffer(4)'); +// const dv = vm.runInNewContext('new DataView(ab, 1, 2)', { ab }); +// assert.strictEqual( +// util.inspect(ab, showHidden), +// 'ArrayBuffer { [Uint8Contents]: <00 00 00 00>, byteLength: 4 }' +// ); +// assert.strictEqual(util.inspect(new DataView(ab, 1, 2), showHidden), +// 'DataView {\n' + +// ' byteLength: 2,\n' + +// ' byteOffset: 1,\n' + +// ' buffer: ArrayBuffer { [Uint8Contents]: <00 00 00 00>,' + +// ' byteLength: 4 }\n}'); +// assert.strictEqual( +// util.inspect(ab, showHidden), +// 'ArrayBuffer { [Uint8Contents]: <00 00 00 00>, byteLength: 4 }' +// ); +// assert.strictEqual(util.inspect(dv, showHidden), +// 'DataView {\n' + +// ' byteLength: 2,\n' + +// ' byteOffset: 1,\n' + +// ' buffer: ArrayBuffer { [Uint8Contents]: <00 00 00 00>,' + +// ' byteLength: 4 }\n}'); +// ab.x = 42; +// dv.y = 1337; +// assert.strictEqual(util.inspect(ab, showHidden), +// 'ArrayBuffer { [Uint8Contents]: <00 00 00 00>, ' + +// 'byteLength: 4, x: 42 }'); +// assert.strictEqual(util.inspect(dv, showHidden), +// 'DataView {\n' + +// ' byteLength: 2,\n' + +// ' byteOffset: 1,\n' + +// ' buffer: ArrayBuffer { [Uint8Contents]: <00 00 00 00>,' + +// ' byteLength: 4, x: 42 },\n' + +// ' y: 1337\n}'); +// } + +// TODO(wafuwafu13): Fix +// [ Float32Array, +// Float64Array, +// Int16Array, +// Int32Array, +// Int8Array, +// Uint16Array, +// Uint32Array, +// Uint8Array, +// Uint8ClampedArray ].forEach((constructor) => { +// const length = 2; +// const byteLength = length * constructor.BYTES_PER_ELEMENT; +// const array = new constructor(new ArrayBuffer(byteLength), 0, length); +// array[0] = 65; +// array[1] = 97; +// assert.strictEqual( +// util.inspect(array, { showHidden: true }), +// `${constructor.name}(${length}) [\n` + +// ' 65,\n' + +// ' 97,\n' + +// ` [BYTES_PER_ELEMENT]: ${constructor.BYTES_PER_ELEMENT},\n` + +// ` [length]: ${length},\n` + +// ` [byteLength]: ${byteLength},\n` + +// ' [byteOffset]: 0,\n' + +// ` [buffer]: ArrayBuffer { byteLength: ${byteLength} }\n]`); +// assert.strictEqual( +// util.inspect(array, false), +// `${constructor.name}(${length}) [ 65, 97 ]` +// ); +// }); + +// TODO(wafuwafu13): Implement 'vm' +// // Now check that declaring a TypedArray in a different context works the same. +// [ Float32Array, +// Float64Array, +// Int16Array, +// Int32Array, +// Int8Array, +// Uint16Array, +// Uint32Array, +// Uint8Array, +// Uint8ClampedArray ].forEach((constructor) => { +// const length = 2; +// const byteLength = length * constructor.BYTES_PER_ELEMENT; +// const array = vm.runInNewContext( +// 'new constructor(new ArrayBuffer(byteLength), 0, length)', +// { constructor, byteLength, length } +// ); +// array[0] = 65; +// array[1] = 97; +// assert.strictEqual( +// util.inspect(array, true), +// `${constructor.name}(${length}) [\n` + +// ' 65,\n' + +// ' 97,\n' + +// ` [BYTES_PER_ELEMENT]: ${constructor.BYTES_PER_ELEMENT},\n` + +// ` [length]: ${length},\n` + +// ` [byteLength]: ${byteLength},\n` + +// ' [byteOffset]: 0,\n' + +// ` [buffer]: ArrayBuffer { byteLength: ${byteLength} }\n]`); +// assert.strictEqual( +// util.inspect(array, false), +// `${constructor.name}(${length}) [ 65, 97 ]` +// ); +// }); + +// TODO(wafuwafu13): Fix +// { +// const brokenLength = new Float32Array(2); +// Object.defineProperty(brokenLength, 'length', { value: -1 }); +// assert.strictEqual(inspect(brokenLength), 'Float32Array(2) [ 0n, 0n ]'); +// } + +assert.strictEqual( + util.inspect(Object.create({}, { + visible: { value: 1, enumerable: true }, + hidden: { value: 2 } + }), { showHidden: true }), + '{ visible: 1, [hidden]: 2 }' +); +// Objects without prototype. +assert.strictEqual( + util.inspect(Object.create(null, { + name: { value: 'Tim', enumerable: true }, + hidden: { value: 'secret' } + }), { showHidden: true }), + "[Object: null prototype] { name: 'Tim', [hidden]: 'secret' }" +); + +assert.strictEqual( + util.inspect(Object.create(null, { + name: { value: 'Tim', enumerable: true }, + hidden: { value: 'secret' } + })), + "[Object: null prototype] { name: 'Tim' }" +); + +// Dynamic properties. +{ + assert.strictEqual( + util.inspect({ get readonly() { return 1; } }), + '{ readonly: [Getter] }'); + + assert.strictEqual( + util.inspect({ get readwrite() { return 1; }, set readwrite(val) {} }), + '{ readwrite: [Getter/Setter] }'); + + assert.strictEqual( + // eslint-disable-next-line accessor-pairs + util.inspect({ set writeonly(val) {} }), + '{ writeonly: [Setter] }'); + + const value = {}; + value.a = value; + assert.strictEqual(util.inspect(value), ' { a: [Circular *1] }'); + const getterFn = { + get one() { + return null; + } + }; + assert.strictEqual( + util.inspect(getterFn, { getters: true }), + '{ one: [Getter: null] }' + ); +} + +// TODO(wafuwafu13): Fix +// // Array with dynamic properties. +// { +// const value = [1, 2, 3]; +// Object.defineProperty( +// value, +// 'growingLength', +// { +// enumerable: true, +// get: function() { this.push(true); return this.length; } +// } +// ); +// Object.defineProperty( +// value, +// '-1', +// { +// enumerable: true, +// value: -1 +// } +// ); +// assert.strictEqual(util.inspect(value), +// "[ 1, 2, 3, growingLength: [Getter], '-1': -1 ]"); +// } + +// Array with inherited number properties. +{ + class CustomArray extends Array {} + CustomArray.prototype[5] = 'foo'; + CustomArray.prototype[49] = 'bar'; + CustomArray.prototype.foo = true; + const arr = new CustomArray(50); + arr[49] = 'I win'; + assert.strictEqual( + util.inspect(arr), + "CustomArray(50) [ <49 empty items>, 'I win' ]" + ); + // TODO(wafuwafu13): Fix + // assert.strictEqual( + // util.inspect(arr, { showHidden: true }), + // 'CustomArray(50) [\n' + + // ' <49 empty items>,\n' + + // " 'I win',\n" + + // ' [length]: 50,\n' + + // " '5': 'foo',\n" + + // ' foo: true\n' + + // ']' + // ); +} + +// TODO(wafuwafu13): Fix +// // Array with extra properties. +// { +// const arr = [1, 2, 3, , ]; +// arr.foo = 'bar'; +// assert.strictEqual(util.inspect(arr), +// "[ 1, 2, 3, <1 empty item>, foo: 'bar' ]"); + +// const arr2 = []; +// assert.strictEqual(util.inspect([], { showHidden: true }), '[ [length]: 0 ]'); +// arr2['00'] = 1; +// assert.strictEqual(util.inspect(arr2), "[ '00': 1 ]"); +// assert.strictEqual(util.inspect(arr2, { showHidden: true }), +// "[ [length]: 0, '00': 1 ]"); +// arr2[1] = 0; +// assert.strictEqual(util.inspect(arr2), "[ <1 empty item>, 0, '00': 1 ]"); +// assert.strictEqual(util.inspect(arr2, { showHidden: true }), +// "[ <1 empty item>, 0, [length]: 2, '00': 1 ]"); +// delete arr2[1]; +// assert.strictEqual(util.inspect(arr2), "[ <2 empty items>, '00': 1 ]"); +// assert.strictEqual(util.inspect(arr2, { showHidden: true }), +// "[ <2 empty items>, [length]: 2, '00': 1 ]"); +// arr2['01'] = 2; +// assert.strictEqual(util.inspect(arr2), +// "[ <2 empty items>, '00': 1, '01': 2 ]"); +// assert.strictEqual(util.inspect(arr2, { showHidden: true }), +// "[ <2 empty items>, [length]: 2, '00': 1, '01': 2 ]"); +// delete arr2['00']; +// arr2[0] = 0; +// assert.strictEqual(util.inspect(arr2), +// "[ 0, <1 empty item>, '01': 2 ]"); +// assert.strictEqual(util.inspect(arr2, { showHidden: true }), +// "[ 0, <1 empty item>, [length]: 2, '01': 2 ]"); +// delete arr2['01']; +// arr2[2 ** 32 - 2] = 'max'; +// arr2[2 ** 32 - 1] = 'too far'; +// assert.strictEqual( +// util.inspect(arr2), +// "[ 0, <4294967293 empty items>, 'max', '4294967295': 'too far' ]" +// ); + +// const arr3 = []; +// arr3[-1] = -1; +// assert.strictEqual(util.inspect(arr3), "[ '-1': -1 ]"); +// } + +// TODO(wafuwafu13): Fix +// // Indices out of bounds. +// { +// const arr = []; +// arr[2 ** 32] = true; // Not a valid array index. +// assert.strictEqual(util.inspect(arr), "[ '4294967296': true ]"); +// arr[0] = true; +// arr[10] = true; +// assert.strictEqual(util.inspect(arr), +// "[ true, <9 empty items>, true, '4294967296': true ]"); +// arr[2 ** 32 - 2] = true; +// arr[2 ** 32 - 1] = true; +// arr[2 ** 32 + 1] = true; +// delete arr[0]; +// delete arr[10]; +// assert.strictEqual(util.inspect(arr), +// ['[', +// '<4294967294 empty items>,', +// 'true,', +// "'4294967296': true,", +// "'4294967295': true,", +// "'4294967297': true\n]", +// ].join('\n ')); +// } + +// Function with properties. +{ + const value = () => {}; + value.aprop = 42; + assert.strictEqual(util.inspect(value), '[Function: value] { aprop: 42 }'); +} + +// Anonymous function with properties. +{ + const value = (() => function() {})(); + value.aprop = 42; + assert.strictEqual( + util.inspect(value), + '[Function (anonymous)] { aprop: 42 }' + ); +} + +// Regular expressions with properties. +{ + const value = /123/ig; + value.aprop = 42; + assert.strictEqual(util.inspect(value), '/123/gi { aprop: 42 }'); +} + +// Dates with properties. +{ + const value = new Date('Sun, 14 Feb 2010 11:48:40 GMT'); + value.aprop = 42; + assert.strictEqual(util.inspect(value), + '2010-02-14T11:48:40.000Z { aprop: 42 }'); +} + +// Test the internal isDate implementation. +{ + const Date2 = vm.runInNewContext('Date'); + const d = new Date2(); + const orig = util.inspect(d); + Date2.prototype.foo = 'bar'; + const after = util.inspect(d); + assert.strictEqual(orig, after); +} + +// Test positive/negative zero. +assert.strictEqual(util.inspect(0), '0'); +assert.strictEqual(util.inspect(-0), '-0'); +// Edge case from check. +assert.strictEqual(util.inspect(-5e-324), '-5e-324'); + +// Test for sparse array. +{ + const a = ['foo', 'bar', 'baz']; + assert.strictEqual(util.inspect(a), "[ 'foo', 'bar', 'baz' ]"); + delete a[1]; + assert.strictEqual(util.inspect(a), "[ 'foo', <1 empty item>, 'baz' ]"); + // TODO(wafuwafu13): Fix + // assert.strictEqual( + // util.inspect(a, true), + // "[ 'foo', <1 empty item>, 'baz', [length]: 3 ]" + // ); + assert.strictEqual(util.inspect(new Array(5)), '[ <5 empty items> ]'); + a[3] = 'bar'; + a[100] = 'qux'; + assert.strictEqual( + util.inspect(a, { breakLength: Infinity }), + "[ 'foo', <1 empty item>, 'baz', 'bar', <96 empty items>, 'qux' ]" + ); + delete a[3]; + assert.strictEqual( + util.inspect(a, { maxArrayLength: 4 }), + "[ 'foo', <1 empty item>, 'baz', <97 empty items>, ... 1 more item ]" + ); + // test 4 special case + assert.strictEqual(util.inspect(a, { + maxArrayLength: 2 + }), "[ 'foo', <1 empty item>, ... 99 more items ]"); +} + +// TODO(wafuwafu13): Implement `previewEntries` +// Test for Array constructor in different context. +// { +// const map = new Map(); +// map.set(1, 2); +// // Passing only a single argument to indicate a set iterator. +// const valsSetIterator = previewEntries(map.entries()); +// // Passing through true to indicate a map iterator. +// const valsMapIterEntries = previewEntries(map.entries(), true); +// const valsMapIterKeys = previewEntries(map.keys(), true); + +// assert.strictEqual(util.inspect(valsSetIterator), '[ 1, 2 ]'); +// assert.strictEqual(util.inspect(valsMapIterEntries), '[ [ 1, 2 ], true ]'); +// assert.strictEqual(util.inspect(valsMapIterKeys), '[ [ 1 ], false ]'); +// } + +// TODO(wafuwafu13): Implement 'vm' +// // Test for other constructors in different context. +// { +// let obj = vm.runInNewContext('(function(){return {}})()', {}); +// assert.strictEqual(util.inspect(obj), '{}'); +// obj = vm.runInNewContext('const m=new Map();m.set(1,2);m', {}); +// assert.strictEqual(util.inspect(obj), 'Map(1) { 1 => 2 }'); +// obj = vm.runInNewContext('const s=new Set();s.add(1);s.add(2);s', {}); +// assert.strictEqual(util.inspect(obj), 'Set(2) { 1, 2 }'); +// obj = vm.runInNewContext('fn=function(){};new Promise(fn,fn)', {}); +// assert.strictEqual(util.inspect(obj), 'Promise { }'); +// } + +// Test for property descriptors. +{ + const getter = Object.create(null, { + a: { + get: function() { return 'aaa'; } + } + }); + const setter = Object.create(null, { + b: { // eslint-disable-line accessor-pairs + set: function() {} + } + }); + const getterAndSetter = Object.create(null, { + c: { + get: function() { return 'ccc'; }, + set: function() {} + } + }); + assert.strictEqual( + util.inspect(getter, true), + '[Object: null prototype] { [a]: [Getter] }' + ); + assert.strictEqual( + util.inspect(setter, true), + '[Object: null prototype] { [b]: [Setter] }' + ); + assert.strictEqual( + util.inspect(getterAndSetter, true), + '[Object: null prototype] { [c]: [Getter/Setter] }' + ); +} + +// Exceptions should print the error message, not '{}'. +{ + [ + new Error(), + new Error('FAIL'), + new TypeError('FAIL'), + new SyntaxError('FAIL'), + ].forEach((err) => { + assert.strictEqual(util.inspect(err), err.stack); + }); + assert.throws( + () => undef(), // eslint-disable-line no-undef + (e) => { + assert.strictEqual(util.inspect(e), e.stack); + return true; + } + ); + + const ex = util.inspect(new Error('FAIL'), true); + assert(ex.includes('Error: FAIL')); + assert(ex.includes('[stack]')); + assert(ex.includes('[message]')); +} + +{ + const tmp = Error.stackTraceLimit; + Error.stackTraceLimit = 0; + const err = new Error('foo'); + const err2 = new Error('foo\nbar'); + assert.strictEqual(util.inspect(err, { compact: true }), '[Error: foo]'); + assert(err.stack); + delete err.stack; + assert(!err.stack); + assert.strictEqual(util.inspect(err, { compact: true }), '[Error: foo]'); + assert.strictEqual( + util.inspect(err2, { compact: true }), + '[Error: foo\nbar]' + ); + + err.bar = true; + err2.bar = true; + + assert.strictEqual( + util.inspect(err, { compact: true }), + '{ [Error: foo] bar: true }' + ); + assert.strictEqual( + util.inspect(err2, { compact: true }), + '{ [Error: foo\nbar]\n bar: true }' + ); + assert.strictEqual( + util.inspect(err, { compact: true, breakLength: 5 }), + '{ [Error: foo]\n bar: true }' + ); + assert.strictEqual( + util.inspect(err, { compact: true, breakLength: 1 }), + '{ [Error: foo]\n bar:\n true }' + ); + assert.strictEqual( + util.inspect(err2, { compact: true, breakLength: 5 }), + '{ [Error: foo\nbar]\n bar: true }' + ); + assert.strictEqual( + util.inspect(err, { compact: false }), + '[Error: foo] {\n bar: true\n}' + ); + assert.strictEqual( + util.inspect(err2, { compact: false }), + '[Error: foo\nbar] {\n bar: true\n}' + ); + + Error.stackTraceLimit = tmp; +} + +// TODO(wafuwafu13): Fix +// // Prevent enumerable error properties from being printed. +// { +// let err = new Error(); +// err.message = 'foobar'; +// let out = util.inspect(err).split('\n'); +// assert.strictEqual(out[0], 'Error: foobar'); +// assert(out[out.length - 1].startsWith(' at ')); +// // Reset the error, the stack is otherwise not recreated. +// err = new Error(); +// err.message = 'foobar'; +// err.name = 'Unique'; +// Object.defineProperty(err, 'stack', { value: err.stack, enumerable: true }); +// out = util.inspect(err).split('\n'); +// assert.strictEqual(out[0], 'Unique: foobar'); +// assert(out[out.length - 1].startsWith(' at ')); +// err.name = 'Baz'; +// out = util.inspect(err).split('\n'); +// assert.strictEqual(out[0], 'Unique: foobar'); +// assert.strictEqual(out[out.length - 2], " name: 'Baz'"); +// assert.strictEqual(out[out.length - 1], '}'); +// } + +// // Doesn't capture stack trace. +{ + function BadCustomError(msg) { + Error.call(this); + Object.defineProperty(this, 'message', + { value: msg, enumerable: false }); + Object.defineProperty(this, 'name', + { value: 'BadCustomError', enumerable: false }); + } + Object.setPrototypeOf(BadCustomError.prototype, Error.prototype); + Object.setPrototypeOf(BadCustomError, Error); + assert.strictEqual( + util.inspect(new BadCustomError('foo')), + '[BadCustomError: foo]' + ); +} + +// TODO(wafuwafu13): Fix +// // Tampered error stack or name property (different type than string). +// // Note: Symbols are not supported by `Error#toString()` which is called by +// // accessing the `stack` property. +// [ +// [404, '404: foo', '[404]'], +// [0, '0: foo', '[RangeError: foo]'], +// [0n, '0: foo', '[RangeError: foo]'], +// [null, 'null: foo', '[RangeError: foo]'], +// [undefined, 'RangeError: foo', '[RangeError: foo]'], +// [false, 'false: foo', '[RangeError: foo]'], +// ['', 'foo', '[RangeError: foo]'], +// [[1, 2, 3], '1,2,3: foo', '[1,2,3]'], +// ].forEach(([value, outputStart, stack]) => { +// let err = new RangeError('foo'); +// err.name = value; +// assert( +// util.inspect(err).startsWith(outputStart), +// util.format( +// 'The name set to %o did not result in the expected output "%s"', +// value, +// outputStart +// ) +// ); + +// err = new RangeError('foo'); +// err.stack = value; +// assert.strictEqual(util.inspect(err), stack); +// }); + +// https://github.com/nodejs/node-v0.x-archive/issues/1941 +// TODO(@crowlKats) +//assert.strictEqual(util.inspect(Object.create(Date.prototype)), 'Date {}'); + +// https://github.com/nodejs/node-v0.x-archive/issues/1944 +{ + const d = new Date(); + d.toUTCString = null; + util.inspect(d); +} + +// TODO(wafuwafu13): Fix +// // Should not throw. +// { +// const d = new Date(); +// d.toISOString = null; +// util.inspect(d); +// } + +// TODO(wafuwafu13): Fix +// // Should not throw. +// { +// const r = /regexp/; +// r.toString = null; +// util.inspect(r); +// } + +// TODO(wafuwafu13): Fix +// // See https://github.com/nodejs/node-v0.x-archive/issues/2225 +// { +// const x = { [util.inspect.custom]: util.inspect }; +// assert(util.inspect(x).includes( +// '[Symbol(nodejs.util.inspect.custom)]: [Function: inspect] {\n')); +// } + +// TODO(wafuwafu13): Fix +// // `util.inspect` should display the escaped value of a key. +// { +// const w = { +// '\\': 1, +// '\\\\': 2, +// '\\\\\\': 3, +// '\\\\\\\\': 4, +// '\n': 5, +// '\r': 6 +// }; + +// const y = ['a', 'b', 'c']; +// y['\\\\'] = 'd'; +// y['\n'] = 'e'; +// y['\r'] = 'f'; + +// assert.strictEqual( +// util.inspect(w), +// "{ '\\\\': 1, '\\\\\\\\': 2, '\\\\\\\\\\\\': 3, " + +// "'\\\\\\\\\\\\\\\\': 4, '\\n': 5, '\\r': 6 }" +// ); +// assert.strictEqual( +// util.inspect(y), +// "[ 'a', 'b', 'c', '\\\\\\\\': 'd', " + +// "'\\n': 'e', '\\r': 'f' ]" +// ); +// } + +// Test util.inspect.styles and util.inspect.colors. +{ + function testColorStyle(style, input, implicit) { + const colorName = util.inspect.styles[style]; + let color = ['', '']; + if (util.inspect.colors[colorName]) + color = util.inspect.colors[colorName]; + + const withoutColor = util.inspect(input, false, 0, false); + const withColor = util.inspect(input, false, 0, true); + const expect = `\u001b[${color[0]}m${withoutColor}\u001b[${color[1]}m`; + assert.strictEqual( + withColor, + expect, + `util.inspect color for style ${style}`); + } + + testColorStyle('special', function() {}); + testColorStyle('number', 123.456); + testColorStyle('boolean', true); + testColorStyle('undefined', undefined); + testColorStyle('null', null); + testColorStyle('string', 'test string'); + testColorStyle('date', new Date()); + testColorStyle('regexp', /regexp/); +} + +// An object with "hasOwnProperty" overwritten should not throw. +util.inspect({ hasOwnProperty: null }); + +// New API, accepts an "options" object. +{ + const subject = { foo: 'bar', hello: 31, a: { b: { c: { d: 0 } } } }; + Object.defineProperty(subject, 'hidden', { enumerable: false, value: null }); + + assert.strictEqual( + util.inspect(subject, { showHidden: false }).includes('hidden'), + false + ); + assert.strictEqual( + util.inspect(subject, { showHidden: true }).includes('hidden'), + true + ); + assert.strictEqual( + util.inspect(subject, { colors: false }).includes('\u001b[32m'), + false + ); + assert.strictEqual( + util.inspect(subject, { colors: true }).includes('\u001b[32m'), + true + ); + assert.strictEqual( + util.inspect(subject, { depth: 2 }).includes('c: [Object]'), + true + ); + assert.strictEqual( + util.inspect(subject, { depth: 0 }).includes('a: [Object]'), + true + ); + assert.strictEqual( + util.inspect(subject, { depth: null }).includes('{ d: 0 }'), + true + ); + assert.strictEqual( + util.inspect(subject, { depth: undefined }).includes('{ d: 0 }'), + true + ); +} + +{ + // "customInspect" option can enable/disable calling [util.inspect.custom](). + const subject = { [util.inspect.custom]: () => 123 }; + + assert.strictEqual( + util.inspect(subject, { customInspect: true }).includes('123'), + true + ); + assert.strictEqual( + util.inspect(subject, { customInspect: true }).includes('inspect'), + false + ); + assert.strictEqual( + util.inspect(subject, { customInspect: false }).includes('123'), + false + ); + // TODO(wafuwafu13): Fix + // assert.strictEqual( + // util.inspect(subject, { customInspect: false }).includes('inspect'), + // true + // ); + + // A custom [util.inspect.custom]() should be able to return other Objects. + subject[util.inspect.custom] = () => ({ foo: 'bar' }); + + assert.strictEqual(util.inspect(subject), "{ foo: 'bar' }"); + + subject[util.inspect.custom] = common.mustCall((depth, opts) => { + const clone = { ...opts }; + // This might change at some point but for now we keep the stylize function. + // The function should either be documented or an alternative should be + // implemented. + assert.strictEqual(typeof opts.stylize, 'function'); + assert.strictEqual(opts.seen, undefined); + assert.strictEqual(opts.budget, undefined); + assert.strictEqual(opts.indentationLvl, undefined); + assert.strictEqual(opts.showHidden, false); + // TODO(@crowlKats) + //assert.deepStrictEqual( + // new Set(Object.keys(util.inspect.defaultOptions).concat(['stylize'])), + // new Set(Object.keys(opts)) + //); + opts.showHidden = true; + return { [util.inspect.custom]: common.mustCall((depth, opts2) => { + assert.deepStrictEqual(clone, opts2); + }) }; + }); + + util.inspect(subject); + + // util.inspect.custom is a shared symbol which can be accessed as + // Symbol.for("nodejs.util.inspect.custom"). + const inspect = Symbol.for('nodejs.util.inspect.custom'); + + subject[inspect] = () => ({ baz: 'quux' }); + + assert.strictEqual(util.inspect(subject), '{ baz: \'quux\' }'); + + subject[inspect] = (depth, opts) => { + assert.strictEqual(opts.customInspectOptions, true); + assert.strictEqual(opts.seen, null); + return {}; + }; + + util.inspect(subject, { customInspectOptions: true, seen: null }); +} + +{ + const subject = { [util.inspect.custom]: common.mustCall((depth, opts) => { + assert.strictEqual(depth, null); + assert.strictEqual(opts.compact, true); + }) }; + util.inspect(subject, { depth: null, compact: true }); +} + +// TODO(wafuwafu13): Fix +// { +// // Returning `this` from a custom inspection function works. +// const subject = { a: 123, [util.inspect.custom]() { return this; } }; +// const UIC = 'nodejs.util.inspect.custom'; +// assert.strictEqual( +// util.inspect(subject), +// `{\n a: 123,\n [Symbol(${UIC})]: [Function: [${UIC}]]\n}` +// ); +// } + +// Verify that it's possible to use the stylize function to manipulate input. +assert.strictEqual( + util.inspect([1, 2, 3], { stylize() { return 'x'; } }), + '[ x, x, x ]' +); + +// Using `util.inspect` with "colors" option should produce as many lines as +// without it. +{ + function testLines(input) { + const countLines = (str) => (str.match(/\n/g) || []).length; + const withoutColor = util.inspect(input); + const withColor = util.inspect(input, { colors: true }); + assert.strictEqual(countLines(withoutColor), countLines(withColor)); + } + + const bigArray = new Array(100).fill().map((value, index) => index); + + testLines([1, 2, 3, 4, 5, 6, 7]); + testLines(bigArray); + testLines({ foo: 'bar', baz: 35, b: { a: 35 } }); + testLines({ a: { a: 3, b: 1, c: 1, d: 1, e: 1, f: 1, g: 1, h: 1 }, b: 1 }); + testLines({ + foo: 'bar', + baz: 35, + b: { a: 35 }, + veryLongKey: 'very long value', + evenLongerKey: ['with even longer value in array'] + }); +} + +// Test boxed primitives output the correct values. +assert.strictEqual(util.inspect(new String('test')), "[String: 'test']"); +assert.strictEqual( + util.inspect(new String('test'), { colors: true }), + "\u001b[32m[String: 'test']\u001b[39m" +); +assert.strictEqual( + util.inspect(Object(Symbol('test'))), + '[Symbol: Symbol(test)]' +); +assert.strictEqual(util.inspect(new Boolean(false)), '[Boolean: false]'); +// TODO(wafuwafu13): Fix +// assert.strictEqual( +// util.inspect(Object.setPrototypeOf(new Boolean(true), null)), +// '[Boolean (null prototype): true]' +// ); +// assert.strictEqual(util.inspect(new Number(0)), '[Number: 0]'); +// assert.strictEqual( +// util.inspect( +// Object.defineProperty( +// Object.setPrototypeOf(new Number(-0), Array.prototype), +// Symbol.toStringTag, +// { value: 'Foobar' } +// ) +// ), +// '[Number (Array): -0] [Foobar]' +// ); +assert.strictEqual(util.inspect(new Number(-1.1)), '[Number: -1.1]'); +assert.strictEqual(util.inspect(new Number(13.37)), '[Number: 13.37]'); + +// Test boxed primitives with own properties. +{ + const str = new String('baz'); + str.foo = 'bar'; + assert.strictEqual(util.inspect(str), "[String: 'baz'] { foo: 'bar' }"); + + const bool = new Boolean(true); + bool.foo = 'bar'; + assert.strictEqual(util.inspect(bool), "[Boolean: true] { foo: 'bar' }"); + + const num = new Number(13.37); + num.foo = 'bar'; + assert.strictEqual(util.inspect(num), "[Number: 13.37] { foo: 'bar' }"); + + const sym = Object(Symbol('foo')); + sym.foo = 'bar'; + assert.strictEqual(util.inspect(sym), "[Symbol: Symbol(foo)] { foo: 'bar' }"); + + const big = Object(BigInt(55)); + big.foo = 'bar'; + assert.strictEqual(util.inspect(big), "[BigInt: 55n] { foo: 'bar' }"); +} + +// Test es6 Symbol. +if (typeof Symbol !== 'undefined') { + assert.strictEqual(util.inspect(Symbol()), 'Symbol()'); + //assert.strictEqual(util.inspect(Symbol(123)), 'Symbol(123)'); + //assert.strictEqual(util.inspect(Symbol('hi')), 'Symbol(hi)'); + assert.strictEqual(util.inspect([Symbol()]), '[ Symbol() ]'); + assert.strictEqual(util.inspect({ foo: Symbol() }), '{ foo: Symbol() }'); + + const options = { showHidden: true }; + let subject = {}; + + subject[Symbol('sym\nbol')] = 42; + + // TODO(wafuwafu13): Fix + // assert.strictEqual(util.inspect(subject), '{ [Symbol(sym\\nbol)]: 42 }'); + // assert.strictEqual( + // util.inspect(subject, options), + // '{ [Symbol(sym\\nbol)]: 42 }' + // ); + + // Object.defineProperty( + // subject, + // Symbol(), + // { enumerable: false, value: 'non-enum' }); + // assert.strictEqual(util.inspect(subject), '{ [Symbol(sym\\nbol)]: 42 }'); + // assert.strictEqual( + // util.inspect(subject, options), + // "{ [Symbol(sym\\nbol)]: 42, [Symbol()]: 'non-enum' }" + // ); + + // subject = [1, 2, 3]; + // subject[Symbol('symbol')] = 42; + + // assert.strictEqual(util.inspect(subject), + // '[ 1, 2, 3, [Symbol(symbol)]: 42 ]'); +} + +// Test Set. +{ + assert.strictEqual(util.inspect(new Set()), 'Set(0) {}'); + // TODO(wafuwafu13): Fix + // assert.strictEqual(util.inspect(new Set([1, 2, 3])), 'Set(3) { 1, 2, 3 }'); + // const set = new Set(['foo']); + // set.bar = 42; + // assert.strictEqual( + // util.inspect(set, { showHidden: true }), + // "Set(1) { 'foo', bar: 42 }" + // ); +} + +// TODO(wafuwafu13): Fix +// // Test circular Set. +// { +// const set = new Set(); +// set.add(set); +// assert.strictEqual(util.inspect(set), ' Set(1) { [Circular *1] }'); +// } + +// Test Map. +{ + assert.strictEqual(util.inspect(new Map()), 'Map(0) {}'); + assert.strictEqual(util.inspect(new Map([[1, 'a'], [2, 'b'], [3, 'c']])), + "Map(3) { 1 => 'a', 2 => 'b', 3 => 'c' }"); + const map = new Map([['foo', null]]); + map.bar = 42; + assert.strictEqual(util.inspect(map, true), + "Map(1) { 'foo' => null, bar: 42 }"); +} + +// Test circular Map. +{ + const map = new Map(); + map.set(map, 'map'); + assert.strictEqual( + inspect(map), + " Map(1) { [Circular *1] => 'map' }" + ); + map.set(map, map); + assert.strictEqual( + inspect(map), + ' Map(1) { [Circular *1] => [Circular *1] }' + ); + map.delete(map); + map.set('map', map); + assert.strictEqual( + inspect(map), + " Map(1) { 'map' => [Circular *1] }" + ); +} + +// Test multiple circular references. +{ + const obj = {}; + obj.a = [obj]; + obj.b = {}; + obj.b.inner = obj.b; + obj.b.obj = obj; + + assert.strictEqual( + inspect(obj), + ' {\n' + + ' a: [ [Circular *1] ],\n' + + ' b: { inner: [Circular *2], obj: [Circular *1] }\n' + + '}' + ); +} + +// TODO(wafuwafu13): Fix +// // Test Promise. +// { +// const resolved = Promise.resolve(3); +// assert.strictEqual(util.inspect(resolved), 'Promise { 3 }'); + +// const rejected = Promise.reject(3); +// assert.strictEqual(util.inspect(rejected), 'Promise { 3 }'); +// // Squelch UnhandledPromiseRejection. +// rejected.catch(() => {}); + +// const pending = new Promise(() => {}); +// assert.strictEqual(util.inspect(pending), 'Promise { }'); + +// const promiseWithProperty = Promise.resolve('foo'); +// promiseWithProperty.bar = 42; +// assert.strictEqual(util.inspect(promiseWithProperty), +// "Promise { 'foo', bar: 42 }"); +// } + +// Make sure it doesn't choke on polyfills. Unlike Set/Map, there is no standard +// interface to synchronously inspect a Promise, so our techniques only work on +// a bonafide native Promise. +{ + const oldPromise = Promise; + global.Promise = function() { this.bar = 42; }; + assert.strictEqual(util.inspect(new Promise()), '{ bar: 42 }'); + global.Promise = oldPromise; +} + +// TODO(wafuwafu13): Fix +// // Test Map iterators. +// { +// const map = new Map([['foo', 'bar']]); +// assert.strictEqual(util.inspect(map.keys()), '[Map Iterator] { \'foo\' }'); +// const mapValues = map.values(); +// Object.defineProperty(mapValues, Symbol.toStringTag, { value: 'Foo' }); +// assert.strictEqual( +// util.inspect(mapValues), +// '[Foo] [Map Iterator] { \'bar\' }' +// ); +// map.set('A', 'B!'); +// assert.strictEqual(util.inspect(map.entries(), { maxArrayLength: 1 }), +// "[Map Entries] { [ 'foo', 'bar' ], ... 1 more item }"); +// // Make sure the iterator doesn't get consumed. +// const keys = map.keys(); +// assert.strictEqual(util.inspect(keys), "[Map Iterator] { 'foo', 'A' }"); +// assert.strictEqual(util.inspect(keys), "[Map Iterator] { 'foo', 'A' }"); +// keys.extra = true; +// assert.strictEqual( +// util.inspect(keys, { maxArrayLength: 0 }), +// '[Map Iterator] { ... 2 more items, extra: true }'); +// } + +// TODO(wafuwafu13): Fix +// // Test Set iterators. +// { +// const aSet = new Set([1]); +// assert.strictEqual(util.inspect(aSet.entries(), { compact: false }), +// '[Set Entries] {\n [\n 1,\n 1\n ]\n}'); +// aSet.add(3); +// assert.strictEqual(util.inspect(aSet.keys()), '[Set Iterator] { 1, 3 }'); +// assert.strictEqual(util.inspect(aSet.values()), '[Set Iterator] { 1, 3 }'); +// const setEntries = aSet.entries(); +// Object.defineProperty(setEntries, Symbol.toStringTag, { value: 'Foo' }); +// assert.strictEqual(util.inspect(setEntries), +// '[Foo] [Set Entries] { [ 1, 1 ], [ 3, 3 ] }'); +// // Make sure the iterator doesn't get consumed. +// const keys = aSet.keys(); +// Object.defineProperty(keys, Symbol.toStringTag, { value: null }); +// assert.strictEqual(util.inspect(keys), '[Set Iterator] { 1, 3 }'); +// assert.strictEqual(util.inspect(keys), '[Set Iterator] { 1, 3 }'); +// keys.extra = true; +// assert.strictEqual( +// util.inspect(keys, { maxArrayLength: 1 }), +// '[Set Iterator] { 1, ... 1 more item, extra: true }'); +// } + +// Minimal inspection should still return as much information as possible about +// the constructor and Symbol.toStringTag. +{ + class Foo { + get [Symbol.toStringTag]() { + return 'ABC'; + } + } + const a = new Foo(); + assert.strictEqual(inspect(a, { depth: -1 }), 'Foo [ABC] {}'); + a.foo = true; + assert.strictEqual(inspect(a, { depth: -1 }), '[Foo [ABC]]'); + Object.defineProperty(a, Symbol.toStringTag, { + value: 'Foo', + configurable: true, + writable: true + }); + assert.strictEqual(inspect(a, { depth: -1 }), '[Foo]'); + delete a[Symbol.toStringTag]; + Object.setPrototypeOf(a, null); + // TODO(wafuwafu13): Fix + // assert.strictEqual(inspect(a, { depth: -1 }), '[Foo: null prototype]'); + // delete a.foo; + // assert.strictEqual(inspect(a, { depth: -1 }), '[Foo: null prototype] {}'); + // Object.defineProperty(a, Symbol.toStringTag, { + // value: 'ABC', + // configurable: true + // }); + // assert.strictEqual( + // inspect(a, { depth: -1 }), + // '[Foo: null prototype] [ABC] {}' + // ); + // Object.defineProperty(a, Symbol.toStringTag, { + // value: 'Foo', + // configurable: true + // }); + // assert.strictEqual( + // inspect(a, { depth: -1 }), + // '[Object: null prototype] [Foo] {}' + // ); +} + +// Test alignment of items in container. +// Assumes that the first numeric character is the start of an item. +{ + function checkAlignment(container, start, lineX, end) { + const lines = util.inspect(container).split('\n'); + lines.forEach((line, i) => { + if (i === 0) { + assert.strictEqual(line, start); + } else if (i === lines.length - 1) { + assert.strictEqual(line, end); + } else { + let expected = lineX.replace('X', i - 1); + if (i !== lines.length - 2) + expected += ','; + assert.strictEqual(line, expected); + } + }); + } + + const bigArray = []; + for (let i = 0; i < 100; i++) { + bigArray.push(i); + } + + const obj = {}; + bigArray.forEach((prop) => { + obj[prop] = null; + }); + + checkAlignment(obj, '{', " 'X': null", '}'); + // TODO(wafuwafu13): Fix + // checkAlignment(new Set(bigArray), 'Set(100) {', ' X', '}'); + checkAlignment( + new Map(bigArray.map((number) => [number, null])), + 'Map(100) {', ' X => null', '}' + ); +} + + +// Test display of constructors. +{ + class ObjectSubclass {} + class ArraySubclass extends Array {} + class SetSubclass extends Set {} + class MapSubclass extends Map {} + class PromiseSubclass extends Promise {} + + const x = new ObjectSubclass(); + x.foo = 42; + assert.strictEqual(util.inspect(x), + 'ObjectSubclass { foo: 42 }'); + assert.strictEqual(util.inspect(new ArraySubclass(1, 2, 3)), + 'ArraySubclass(3) [ 1, 2, 3 ]'); + // TODO(wafuwafu13): Fix + // assert.strictEqual(util.inspect(new SetSubclass([1, 2, 3])), + // 'SetSubclass(3) [Set] { 1, 2, 3 }'); + assert.strictEqual(util.inspect(new MapSubclass([['foo', 42]])), + "MapSubclass(1) [Map] { 'foo' => 42 }"); + // TODO(wafuwafu13): Fix + // assert.strictEqual(util.inspect(new PromiseSubclass(() => {})), + // 'PromiseSubclass [Promise] { }'); + assert.strictEqual( + util.inspect({ a: { b: new ArraySubclass([1, [2], 3]) } }, { depth: 1 }), + '{ a: { b: [ArraySubclass] } }' + ); + // TODO(wafuwafu13): Fix + // assert.strictEqual( + // util.inspect(Object.setPrototypeOf(x, null)), + // '[ObjectSubclass: null prototype] { foo: 42 }' + // ); +} + +// Empty and circular before depth. +{ + const arr = [[[[]]]]; + assert.strictEqual(util.inspect(arr), '[ [ [ [] ] ] ]'); + arr[0][0][0][0] = []; + assert.strictEqual(util.inspect(arr), '[ [ [ [Array] ] ] ]'); + arr[0][0][0] = {}; + assert.strictEqual(util.inspect(arr), '[ [ [ {} ] ] ]'); + arr[0][0][0] = { a: 2 }; + assert.strictEqual(util.inspect(arr), '[ [ [ [Object] ] ] ]'); + arr[0][0][0] = arr; + assert.strictEqual(util.inspect(arr), ' [ [ [ [Circular *1] ] ] ]'); + arr[0][0][0] = arr[0][0]; + assert.strictEqual(util.inspect(arr), '[ [ [ [Circular *1] ] ] ]'); +} + +// Corner cases. +{ + const x = { constructor: 42 }; + assert.strictEqual(util.inspect(x), '{ constructor: 42 }'); +} + +{ + const x = {}; + Object.defineProperty(x, 'constructor', { + get: function() { + throw new Error('should not access constructor'); + }, + enumerable: true + }); + assert.strictEqual(util.inspect(x), '{ constructor: [Getter] }'); +} + +{ + const x = new function() {}; // eslint-disable-line new-parens + assert.strictEqual(util.inspect(x), '{}'); +} + +{ + const x = Object.create(null); + assert.strictEqual(util.inspect(x), '[Object: null prototype] {}'); +} + +// TODO(wafuwafu13): Fix +// { +// const x = []; +// x[''] = 1; +// assert.strictEqual(util.inspect(x), "[ '': 1 ]"); +// } + +// TODO(wafuwafu13): Fix +// // The following maxArrayLength tests were introduced after v6.0.0 was released. +// // Do not backport to v5/v4 unless all of +// // https://github.com/nodejs/node/pull/6334 is backported. +// { +// const x = new Array(101).fill(); +// assert(util.inspect(x).endsWith('1 more item\n]')); +// assert(!util.inspect(x, { maxArrayLength: 101 }).endsWith('1 more item\n]')); +// assert.strictEqual( +// util.inspect(x, { maxArrayLength: -1 }), +// '[ ... 101 more items ]' +// ); +// assert.strictEqual(util.inspect(x, { maxArrayLength: 0 }), +// '[ ... 101 more items ]'); +// } + +{ + const x = Array(101); + assert.strictEqual(util.inspect(x, { maxArrayLength: 0 }), + '[ ... 101 more items ]'); + assert(!util.inspect(x, { maxArrayLength: null }).endsWith('1 more item\n]')); + assert(!util.inspect( + x, { maxArrayLength: Infinity } + ).endsWith('1 more item ]')); +} + +{ + const x = new Uint8Array(101); + // TODO(wafuwafu13): Fix + // assert(util.inspect(x).endsWith('1 more item\n]')); + assert(!util.inspect(x, { maxArrayLength: 101 }).includes('1 more item')); + // TODO(wafuwafu13): Fix + // assert.strictEqual(util.inspect(x, { maxArrayLength: 0 }), + // 'Uint8Array(101) [ ... 101 more items ]'); + assert(!util.inspect(x, { maxArrayLength: null }).includes('1 more item')); + // TODO(wafuwafu13): Fix + // assert(util.inspect(x, { maxArrayLength: Infinity }).endsWith(' 0, 0\n]')); +} + +{ + const obj = { foo: 'abc', bar: 'xyz' }; + const oneLine = util.inspect(obj, { breakLength: Infinity }); + // Subtract four for the object's two curly braces and two spaces of padding. + // Add one more to satisfy the strictly greater than condition in the code. + const breakpoint = oneLine.length - 5; + const twoLines = util.inspect(obj, { breakLength: breakpoint }); + + assert.strictEqual(oneLine, "{ foo: 'abc', bar: 'xyz' }"); + assert.strictEqual( + util.inspect(obj, { breakLength: breakpoint + 1 }), + twoLines + ); + assert.strictEqual(twoLines, "{\n foo: 'abc',\n bar: 'xyz'\n}"); +} + +// util.inspect.defaultOptions tests. +{ + const arr = new Array(101).fill(); + const obj = { a: { a: { a: { a: 1 } } } }; + + const oldOptions = { ...util.inspect.defaultOptions }; + + // Set single option through property assignment. + util.inspect.defaultOptions.maxArrayLength = null; + assert.doesNotMatch(util.inspect(arr), /1 more item/); + util.inspect.defaultOptions.maxArrayLength = oldOptions.maxArrayLength; + // TODO(wafuwafu13): Fix + // assert.match(util.inspect(arr), /1 more item/); + util.inspect.defaultOptions.depth = null; + assert.doesNotMatch(util.inspect(obj), /Object/); + util.inspect.defaultOptions.depth = oldOptions.depth; + assert.match(util.inspect(obj), /Object/); + assert.strictEqual( + JSON.stringify(util.inspect.defaultOptions), + JSON.stringify(oldOptions) + ); + + // Set multiple options through object assignment. + util.inspect.defaultOptions = { maxArrayLength: null, depth: 2 }; + assert.doesNotMatch(util.inspect(arr), /1 more item/); + assert.match(util.inspect(obj), /Object/); + util.inspect.defaultOptions = oldOptions; + // assert.match(util.inspect(arr), /1 more item/); + assert.match(util.inspect(obj), /Object/); + assert.strictEqual( + JSON.stringify(util.inspect.defaultOptions), + JSON.stringify(oldOptions) + ); + + assert.throws(() => { + util.inspect.defaultOptions = null; + }, { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "options" argument must be of type object. ' + + 'Received null' + } + ); + + assert.throws(() => { + util.inspect.defaultOptions = 'bad'; + }, { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "options" argument must be of type object. ' + + "Received type string ('bad')" + } + ); +} + +util.inspect(process); + +// TODO(wafuwafu13): Fix +// // Setting custom inspect property to a non-function should do nothing. +// { +// const obj = { [util.inspect.custom]: 'fhqwhgads' }; +// assert.strictEqual( +// util.inspect(obj), +// "{ [Symbol(nodejs.util.inspect.custom)]: 'fhqwhgads' }" +// ); +// } + +{ + // @@toStringTag + const obj = { [Symbol.toStringTag]: 'a' }; + // TODO(wafuwafu13): Fix + // assert.strictEqual( + // util.inspect(obj), + // "{ [Symbol(Symbol.toStringTag)]: 'a' }" + // ); + Object.defineProperty(obj, Symbol.toStringTag, { + value: 'a', + enumerable: false + }); + assert.strictEqual(util.inspect(obj), 'Object [a] {}'); + // TODO(wafuwafu13): Fix + // assert.strictEqual( + // util.inspect(obj, { showHidden: true }), + // "{ [Symbol(Symbol.toStringTag)]: 'a' }" + // ); + + class Foo { + constructor() { + this.foo = 'bar'; + } + + get [Symbol.toStringTag]() { + return this.foo; + } + } + + // TODO(wafuwafu13): Fix + // assert.strictEqual(util.inspect( + // Object.create(null, { [Symbol.toStringTag]: { value: 'foo' } })), + // '[Object: null prototype] [foo] {}'); + + assert.strictEqual(util.inspect(new Foo()), "Foo [bar] { foo: 'bar' }"); + + assert.strictEqual( + util.inspect(new (class extends Foo {})()), + "Foo [bar] { foo: 'bar' }"); + + assert.strictEqual( + util.inspect(Object.create(Object.create(Foo.prototype), { + foo: { value: 'bar', enumerable: true } + })), + "Foo [bar] { foo: 'bar' }"); + + class ThrowingClass { + get [Symbol.toStringTag]() { + throw new Error('toStringTag error'); + } + } + + assert.throws(() => util.inspect(new ThrowingClass()), /toStringTag error/); + + class NotStringClass { + get [Symbol.toStringTag]() { + return null; + } + } + + assert.strictEqual(util.inspect(new NotStringClass()), + 'NotStringClass {}'); +} + +{ + const o = { + a: [1, 2, [[ + 'Lorem ipsum dolor\nsit amet,\tconsectetur adipiscing elit, sed do ' + + 'eiusmod tempor incididunt ut labore et dolore magna aliqua.', + 'test', + 'foo']], 4], + b: new Map([['za', 1], ['zb', 'test']]) + }; + + let out = util.inspect(o, { compact: true, depth: 5, breakLength: 80 }); + let expect = [ + '{ a:', + ' [ 1,', + ' 2,', + " [ [ 'Lorem ipsum dolor\\nsit amet,\\tconsectetur adipiscing elit, " + + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.',", + " 'test',", + " 'foo' ] ],", + ' 4 ],', + " b: Map(2) { 'za' => 1, 'zb' => 'test' } }", + ].join('\n'); + assert.strictEqual(out, expect); + + out = util.inspect(o, { compact: false, depth: 5, breakLength: 60 }); + expect = [ + '{', + ' a: [', + ' 1,', + ' 2,', + ' [', + ' [', + " 'Lorem ipsum dolor\\n' +", + " 'sit amet,\\tconsectetur adipiscing elit, sed do eiusmod " + + "tempor incididunt ut labore et dolore magna aliqua.',", + " 'test',", + " 'foo'", + ' ]', + ' ],', + ' 4', + ' ],', + ' b: Map(2) {', + " 'za' => 1,", + " 'zb' => 'test'", + ' }', + '}', + ].join('\n'); + assert.strictEqual(out, expect); + + out = util.inspect(o.a[2][0][0], { compact: false, breakLength: 30 }); + expect = [ + "'Lorem ipsum dolor\\n' +", + " 'sit amet,\\tconsectetur adipiscing elit, sed do eiusmod tempor " + + "incididunt ut labore et dolore magna aliqua.'", + ].join('\n'); + assert.strictEqual(out, expect); + + out = util.inspect( + '12345678901234567890123456789012345678901234567890', + { compact: false, breakLength: 3 }); + expect = "'12345678901234567890123456789012345678901234567890'"; + assert.strictEqual(out, expect); + + out = util.inspect( + '12 45 78 01 34 67 90 23 56 89 123456789012345678901234567890', + { compact: false, breakLength: 3 }); + expect = [ + "'12 45 78 01 34 67 90 23 56 89 123456789012345678901234567890'", + ].join('\n'); + assert.strictEqual(out, expect); + + // TODO(wafuwafu13): Fix + o.a = () => {}; + o.b = new Number(3); + out = util.inspect(o, { compact: false, breakLength: 3 }); + expect = [ + '{', + ' a: [Function (anonymous)],', + ' b: [Number: 3]', + '}', + ].join('\n'); + assert.strictEqual(out, expect); + + out = util.inspect(o, { compact: false, breakLength: 3, showHidden: true }); + expect = [ + '{', + ' a: [Function (anonymous)] {', + ' [length]: 0,', + " [name]: ''", + ' },', + ' b: [Number: 3]', + '}', + ].join('\n'); + assert.strictEqual(out, expect); + + o[util.inspect.custom] = () => 42; + out = util.inspect(o, { compact: false, breakLength: 3 }); + expect = '42'; + assert.strictEqual(out, expect); + + o[util.inspect.custom] = () => '12 45 78 01 34 67 90 23'; + out = util.inspect(o, { compact: false, breakLength: 3 }); + expect = '12 45 78 01 34 67 90 23'; + assert.strictEqual(out, expect); + + o[util.inspect.custom] = () => ({ a: '12 45 78 01 34 67 90 23' }); + out = util.inspect(o, { compact: false, breakLength: 3 }); + expect = "{\n a: '12 45 78 01 34 67 90 23'\n}"; + assert.strictEqual(out, expect); +} + +// TODO(wafuwafu13): Fix +// // Check compact indentation. +// { +// const typed = new Uint8Array(); +// typed.buffer.foo = true; +// const set = new Set([[1, 2]]); +// const promise = Promise.resolve([[1, set]]); +// const map = new Map([[promise, typed]]); +// map.set(set.values(), map.values()); + +// let out = util.inspect(map, { compact: false, showHidden: true, depth: 9 }); +// let expected = [ +// 'Map(2) {', +// ' Promise {', +// ' [', +// ' [', +// ' 1,', +// ' Set(1) {', +// ' [', +// ' 1,', +// ' 2,', +// ' [length]: 2', +// ' ]', +// ' },', +// ' [length]: 2', +// ' ],', +// ' [length]: 1', +// ' ]', +// ' } => Uint8Array(0) [', +// ' [BYTES_PER_ELEMENT]: 1,', +// ' [length]: 0,', +// ' [byteLength]: 0,', +// ' [byteOffset]: 0,', +// ' [buffer]: ArrayBuffer {', +// ' byteLength: 0,', +// ' foo: true', +// ' }', +// ' ],', +// ' [Set Iterator] {', +// ' [', +// ' 1,', +// ' 2,', +// ' [length]: 2', +// ' ],', +// " [Symbol(Symbol.toStringTag)]: 'Set Iterator'", +// ' } => [Map Iterator] {', +// ' Uint8Array(0) [', +// ' [BYTES_PER_ELEMENT]: 1,', +// ' [length]: 0,', +// ' [byteLength]: 0,', +// ' [byteOffset]: 0,', +// ' [buffer]: ArrayBuffer {', +// ' byteLength: 0,', +// ' foo: true', +// ' }', +// ' ],', +// ' [Circular *1],', +// " [Symbol(Symbol.toStringTag)]: 'Map Iterator'", +// ' }', +// '}', +// ].join('\n'); + +// assert.strict.equal(out, expected); + +// out = util.inspect(map, { compact: 2, showHidden: true, depth: 9 }); + +// expected = [ +// 'Map(2) {', +// ' Promise {', +// ' [', +// ' [', +// ' 1,', +// ' Set(1) { [ 1, 2, [length]: 2 ] },', +// ' [length]: 2', +// ' ],', +// ' [length]: 1', +// ' ]', +// ' } => Uint8Array(0) [', +// ' [BYTES_PER_ELEMENT]: 1,', +// ' [length]: 0,', +// ' [byteLength]: 0,', +// ' [byteOffset]: 0,', +// ' [buffer]: ArrayBuffer { byteLength: 0, foo: true }', +// ' ],', +// ' [Set Iterator] {', +// ' [ 1, 2, [length]: 2 ],', +// " [Symbol(Symbol.toStringTag)]: 'Set Iterator'", +// ' } => [Map Iterator] {', +// ' Uint8Array(0) [', +// ' [BYTES_PER_ELEMENT]: 1,', +// ' [length]: 0,', +// ' [byteLength]: 0,', +// ' [byteOffset]: 0,', +// ' [buffer]: ArrayBuffer { byteLength: 0, foo: true }', +// ' ],', +// ' [Circular *1],', +// " [Symbol(Symbol.toStringTag)]: 'Map Iterator'", +// ' }', +// '}', +// ].join('\n'); + +// assert.strict.equal(out, expected); + +// out = util.inspect(map, { +// showHidden: true, depth: 9, breakLength: 4, compact: true +// }); +// expected = [ +// 'Map(2) {', +// ' Promise {', +// ' [ [ 1,', +// ' Set(1) {', +// ' [ 1,', +// ' 2,', +// ' [length]: 2 ] },', +// ' [length]: 2 ],', +// ' [length]: 1 ] } => Uint8Array(0) [', +// ' [BYTES_PER_ELEMENT]: 1,', +// ' [length]: 0,', +// ' [byteLength]: 0,', +// ' [byteOffset]: 0,', +// ' [buffer]: ArrayBuffer {', +// ' byteLength: 0,', +// ' foo: true } ],', +// ' [Set Iterator] {', +// ' [ 1,', +// ' 2,', +// ' [length]: 2 ],', +// ' [Symbol(Symbol.toStringTag)]:', +// " 'Set Iterator' } => [Map Iterator] {", +// ' Uint8Array(0) [', +// ' [BYTES_PER_ELEMENT]: 1,', +// ' [length]: 0,', +// ' [byteLength]: 0,', +// ' [byteOffset]: 0,', +// ' [buffer]: ArrayBuffer {', +// ' byteLength: 0,', +// ' foo: true } ],', +// ' [Circular *1],', +// ' [Symbol(Symbol.toStringTag)]:', +// " 'Map Iterator' } }", +// ].join('\n'); + +// assert.strict.equal(out, expected); +// } + +// TODO(wafuwafu13): Fix +// { // Test WeakMap && WeakSet +// const obj = {}; +// const arr = []; +// const weakMap = new WeakMap([[obj, arr], [arr, obj]]); +// let out = util.inspect(weakMap, { showHidden: true }); +// let expect = 'WeakMap { [ [length]: 0 ] => {}, {} => [ [length]: 0 ] }'; +// assert.strictEqual(out, expect); + +// out = util.inspect(weakMap); +// expect = 'WeakMap { }'; +// assert.strictEqual(out, expect); + +// out = util.inspect(weakMap, { maxArrayLength: 0, showHidden: true }); +// expect = 'WeakMap { ... 2 more items }'; +// assert.strictEqual(out, expect); + +// weakMap.extra = true; +// out = util.inspect(weakMap, { maxArrayLength: 1, showHidden: true }); +// // It is not possible to determine the output reliable. +// expect = 'WeakMap { [ [length]: 0 ] => {}, ... 1 more item, extra: true }'; +// let expectAlt = 'WeakMap { {} => [ [length]: 0 ], ... 1 more item, ' + +// 'extra: true }'; +// assert(out === expect || out === expectAlt, +// `Found: "${out}"\nrather than: "${expect}"\nor: "${expectAlt}"`); + +// // Test WeakSet +// arr.push(1); +// const weakSet = new WeakSet([obj, arr]); +// out = util.inspect(weakSet, { showHidden: true }); +// expect = 'WeakSet { [ 1, [length]: 1 ], {} }'; +// assert.strictEqual(out, expect); + +// out = util.inspect(weakSet); +// expect = 'WeakSet { }'; +// assert.strictEqual(out, expect); + +// out = util.inspect(weakSet, { maxArrayLength: -2, showHidden: true }); +// expect = 'WeakSet { ... 2 more items }'; +// assert.strictEqual(out, expect); + +// weakSet.extra = true; +// out = util.inspect(weakSet, { maxArrayLength: 1, showHidden: true }); +// // It is not possible to determine the output reliable. +// expect = 'WeakSet { {}, ... 1 more item, extra: true }'; +// expectAlt = 'WeakSet { [ 1, [length]: 1 ], ... 1 more item, extra: true }'; +// assert(out === expect || out === expectAlt, +// `Found: "${out}"\nrather than: "${expect}"\nor: "${expectAlt}"`); +// // Keep references to the WeakMap entries, otherwise they could be GCed too +// // early. +// assert(obj && arr); +// } + +{ // Test argument objects. + const args = (function() { return arguments; })('a'); + assert.strictEqual(util.inspect(args), "[Arguments] { '0': 'a' }"); +} + +{ + // Test that a long linked list can be inspected without throwing an error. + const list = {}; + let head = list; + // A linked list of length 100k should be inspectable in some way, even though + // the real cutoff value is much lower than 100k. + for (let i = 0; i < 100000; i++) + head = head.next = {}; + assert.strictEqual( + util.inspect(list), + '{ next: { next: { next: [Object] } } }' + ); + const longList = util.inspect(list, { depth: Infinity }); + const match = longList.match(/next/g); + assert(match.length > 500 && match.length < 10000); + // TODO(wafuwafu13): Fix + // assert(longList.includes('[Object: Inspection interrupted ' + + // 'prematurely. Maximum call stack size exceeded.]')); +} + +// Do not escape single quotes if no double quote or backtick is present. +assert.strictEqual(util.inspect("'"), '"\'"'); +assert.strictEqual(util.inspect('"\''), '`"\'`'); +// eslint-disable-next-line no-template-curly-in-string +// TODO(@crowlKats) +//assert.strictEqual(util.inspect('"\'${a}'), "'\"\\'${a}'"); + +// TODO(wafuwafu13): Fix +// // Errors should visualize as much information as possible. +// // If the name is not included in the stack, visualize it as well. +// [ +// [class Foo extends TypeError {}, 'test'], +// [class Foo extends TypeError {}, undefined], +// [class BarError extends Error {}, 'test'], +// [class BazError extends Error { +// get name() { +// return 'BazError'; +// } +// }, undefined], +// ].forEach(([Class, message], i) => { +// console.log('Test %i', i); +// const foo = new Class(message); +// const name = foo.name; +// const extra = Class.name.includes('Error') ? '' : ` [${foo.name}]`; +// assert( +// util.inspect(foo).startsWith( +// `${Class.name}${extra}${message ? `: ${message}` : '\n'}`), +// util.inspect(foo) +// ); +// Object.defineProperty(foo, Symbol.toStringTag, { +// value: 'WOW', +// writable: true, +// configurable: true +// }); +// const stack = foo.stack; +// foo.stack = 'This is a stack'; +// assert.strictEqual( +// util.inspect(foo), +// '[This is a stack]' +// ); +// foo.stack = stack; +// assert( +// util.inspect(foo).startsWith( +// `${Class.name} [WOW]${extra}${message ? `: ${message}` : '\n'}`), +// util.inspect(foo) +// ); +// Object.setPrototypeOf(foo, null); +// assert( +// util.inspect(foo).startsWith( +// `[${name}: null prototype] [WOW]${message ? `: ${message}` : '\n'}` +// ), +// util.inspect(foo) +// ); +// foo.bar = true; +// delete foo[Symbol.toStringTag]; +// assert( +// util.inspect(foo).startsWith( +// `[${name}: null prototype]${message ? `: ${message}` : '\n'}`), +// util.inspect(foo) +// ); +// foo.stack = 'This is a stack'; +// assert.strictEqual( +// util.inspect(foo), +// '[[Error: null prototype]: This is a stack] { bar: true }' +// ); +// foo.stack = stack.split('\n')[0]; +// assert.strictEqual( +// util.inspect(foo), +// `[[${name}: null prototype]${message ? `: ${message}` : ''}] { bar: true }` +// ); +// }); + +// TODO(wafuwafu13): Fix +// // Verify that classes are properly inspected. +// [ +// /* eslint-disable spaced-comment, no-multi-spaces, brace-style */ +// // The whitespace is intentional. +// [class { }, '[class (anonymous)]'], +// [class extends Error { log() {} }, '[class (anonymous) extends Error]'], +// [class A { constructor(a) { this.a = a; } log() { return this.a; } }, +// '[class A]'], +// [class +// // Random { // comments /* */ are part of the toString() result +// /* eslint-disable-next-line space-before-blocks */ +// äß/**/extends/*{*/TypeError{}, '[class äß extends TypeError]'], +// /* The whitespace and new line is intended! */ +// // Foobar !!! +// [class X extends /****/ Error +// // More comments +// {}, '[class X extends Error]'], +// /* eslint-enable spaced-comment, no-multi-spaces, brace-style */ +// ].forEach(([clazz, string]) => { +// const inspected = util.inspect(clazz); +// assert.strictEqual(inspected, string); +// Object.defineProperty(clazz, Symbol.toStringTag, { +// value: 'Woohoo' +// }); +// const parts = inspected.slice(0, -1).split(' '); +// const [, name, ...rest] = parts; +// rest.unshift('[Woohoo]'); +// if (rest.length) { +// rest[rest.length - 1] += ']'; +// } +// assert.strictEqual( +// util.inspect(clazz), +// ['[class', name, ...rest].join(' ') +// ); +// if (rest.length) { +// rest[rest.length - 1] = rest[rest.length - 1].slice(0, -1); +// rest.length = 1; +// } +// Object.setPrototypeOf(clazz, Map.prototype); +// assert.strictEqual( +// util.inspect(clazz), +// ['[class', name, '[Map]', ...rest].join(' ') + ']' +// ); +// Object.setPrototypeOf(clazz, null); +// assert.strictEqual( +// util.inspect(clazz), +// ['[class', name, ...rest, 'extends [null prototype]]'].join(' ') +// ); +// Object.defineProperty(clazz, 'name', { value: 'Foo' }); +// const res = ['[class', 'Foo', ...rest, 'extends [null prototype]]'].join(' '); +// assert.strictEqual(util.inspect(clazz), res); +// clazz.foo = true; +// assert.strictEqual(util.inspect(clazz), `${res} { foo: true }`); +// }); + +// "class" properties should not be detected as "class". +{ + // eslint-disable-next-line space-before-function-paren + let obj = { class () {} }; + assert.strictEqual( + util.inspect(obj), + '{ class: [Function: class] }' + ); + obj = { class: () => {} }; + assert.strictEqual( + util.inspect(obj), + '{ class: [Function: class] }' + ); + obj = { ['class Foo {}']() {} }; + assert.strictEqual( + util.inspect(obj), + "{ 'class Foo {}': [Function: class Foo {}] }" + ); + function Foo() {} + Object.defineProperty(Foo, 'toString', { value: () => 'class Foo {}' }); + assert.strictEqual( + util.inspect(Foo), + '[Function: Foo]' + ); + function fn() {} + Object.defineProperty(fn, 'name', { value: 'class Foo {}' }); + assert.strictEqual( + util.inspect(fn), + '[Function: class Foo {}]' + ); +} + +// TODO(wafuwafu13): Fix +// // Verify that throwing in valueOf and toString still produces nice results. +// [ +// [new String(55), "[String: '55']"], +// [new Boolean(true), '[Boolean: true]'], +// [new Number(55), '[Number: 55]'], +// [Object(BigInt(55)), '[BigInt: 55n]'], +// [Object(Symbol('foo')), '[Symbol: Symbol(foo)]'], +// [function() {}, '[Function (anonymous)]'], +// [() => {}, '[Function (anonymous)]'], +// [[1, 2], '[ 1, 2 ]'], +// [[, , 5, , , , ], '[ <2 empty items>, 5, <3 empty items> ]'], +// [{ a: 5 }, '{ a: 5 }'], +// [new Set([1, 2]), 'Set(2) { 1, 2 }'], +// [new Map([[1, 2]]), 'Map(1) { 1 => 2 }'], +// [new Set([1, 2]).entries(), '[Set Entries] { [ 1, 1 ], [ 2, 2 ] }'], +// [new Map([[1, 2]]).keys(), '[Map Iterator] { 1 }'], +// [new Date(2000), '1970-01-01T00:00:02.000Z'], +// [new Uint8Array(2), 'Uint8Array(2) [ 0, 0 ]'], +// [new Promise((resolve) => setTimeout(resolve, 10)), 'Promise { }'], +// [new WeakSet(), 'WeakSet { }'], +// [new WeakMap(), 'WeakMap { }'], +// [/foobar/g, '/foobar/g'], +// ].forEach(([value, expected]) => { +// Object.defineProperty(value, 'valueOf', { +// get() { +// throw new Error('valueOf'); +// } +// }); +// Object.defineProperty(value, 'toString', { +// get() { +// throw new Error('toString'); +// } +// }); +// assert.strictEqual(util.inspect(value), expected); +// value.foo = 'bar'; +// assert.notStrictEqual(util.inspect(value), expected); +// delete value.foo; +// value[Symbol('foo')] = 'yeah'; +// assert.notStrictEqual(util.inspect(value), expected); +// }); + +// TODO(wafuwafu13): Fix +// // Verify that having no prototype still produces nice results. +// [ +// [[1, 3, 4], '[Array(3): null prototype] [ 1, 3, 4 ]'], +// [new Set([1, 2]), '[Set(2): null prototype] { 1, 2 }'], +// [new Map([[1, 2]]), '[Map(1): null prototype] { 1 => 2 }'], +// [new Promise((resolve) => setTimeout(resolve, 10)), +// '[Promise: null prototype] { }'], +// [new WeakSet(), '[WeakSet: null prototype] { }'], +// [new WeakMap(), '[WeakMap: null prototype] { }'], +// [new Uint8Array(2), '[Uint8Array(2): null prototype] [ 0, 0 ]'], +// [new Uint16Array(2), '[Uint16Array(2): null prototype] [ 0, 0 ]'], +// [new Uint32Array(2), '[Uint32Array(2): null prototype] [ 0, 0 ]'], +// [new Int8Array(2), '[Int8Array(2): null prototype] [ 0, 0 ]'], +// [new Int16Array(2), '[Int16Array(2): null prototype] [ 0, 0 ]'], +// [new Int32Array(2), '[Int32Array(2): null prototype] [ 0, 0 ]'], +// [new Float32Array(2), '[Float32Array(2): null prototype] [ 0, 0 ]'], +// [new Float64Array(2), '[Float64Array(2): null prototype] [ 0, 0 ]'], +// [new BigInt64Array(2), '[BigInt64Array(2): null prototype] [ 0n, 0n ]'], +// [new BigUint64Array(2), '[BigUint64Array(2): null prototype] [ 0n, 0n ]'], +// [new ArrayBuffer(16), '[ArrayBuffer: null prototype] {\n' + +// ' [Uint8Contents]: <00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00>,\n' + +// ' byteLength: undefined\n}'], +// [new DataView(new ArrayBuffer(16)), +// '[DataView: null prototype] {\n byteLength: undefined,\n ' + +// 'byteOffset: undefined,\n buffer: undefined\n}'], +// [new SharedArrayBuffer(2), '[SharedArrayBuffer: null prototype] ' + +// '{\n [Uint8Contents]: <00 00>,\n byteLength: undefined\n}'], +// [/foobar/, '[RegExp: null prototype] /foobar/'], +// [new Date('Sun, 14 Feb 2010 11:48:40 GMT'), +// '[Date: null prototype] 2010-02-14T11:48:40.000Z'], +// ].forEach(([value, expected]) => { +// assert.strictEqual( +// util.inspect(Object.setPrototypeOf(value, null)), +// expected +// ); +// value.foo = 'bar'; +// assert.notStrictEqual(util.inspect(value), expected); +// delete value.foo; +// value[Symbol('foo')] = 'yeah'; +// assert.notStrictEqual(util.inspect(value), expected); +// }); + +// TODO(wafuwafu13): Fix +// // Verify that subclasses with and without prototype produce nice results. +// [ +// [RegExp, ['foobar', 'g'], '/foobar/g'], +// [WeakSet, [[{}]], '{ }'], +// [WeakMap, [[[{}, {}]]], '{ }'], +// [BigInt64Array, +// [10], +// '[\n 0n, 0n, 0n, 0n, 0n,\n 0n, 0n, 0n, 0n, 0n\n]'], +// [Date, ['Sun, 14 Feb 2010 11:48:40 GMT'], '2010-02-14T11:48:40.000Z'], +// [Date, ['invalid_date'], 'Invalid Date'], +// ].forEach(([base, input, rawExpected]) => { +// class Foo extends base {} +// const value = new Foo(...input); +// const symbol = value[Symbol.toStringTag]; +// const size = base.name.includes('Array') ? `(${input[0]})` : ''; +// const expected = `Foo${size} ${symbol ? `[${symbol}] ` : ''}${rawExpected}`; +// const expectedWithoutProto = +// `[${base.name}${size}: null prototype] ${rawExpected}`; +// assert.strictEqual(util.inspect(value), expected); +// value.foo = 'bar'; +// assert.notStrictEqual(util.inspect(value), expected); +// delete value.foo; +// assert.strictEqual( +// util.inspect(Object.setPrototypeOf(value, null)), +// expectedWithoutProto +// ); +// value.foo = 'bar'; +// let res = util.inspect(value); +// assert.notStrictEqual(res, expectedWithoutProto); +// assert.match(res, /foo: 'bar'/); +// delete value.foo; +// value[Symbol('foo')] = 'yeah'; +// res = util.inspect(value); +// assert.notStrictEqual(res, expectedWithoutProto); +// assert.match(res, /\[Symbol\(foo\)]: 'yeah'/); +// }); + +assert.strictEqual(inspect(1n), '1n'); +assert.strictEqual(inspect(Object(-1n)), '[BigInt: -1n]'); +assert.strictEqual(inspect(Object(13n)), '[BigInt: 13n]'); +// TODO(wafuwafu13): Fix +// assert.strictEqual(inspect(new BigInt64Array([0n])), 'BigInt64Array(1) [ 0n ]'); +// assert.strictEqual( +// inspect(new BigUint64Array([0n])), 'BigUint64Array(1) [ 0n ]'); + +// Verify non-enumerable keys get escaped. +{ + const obj = {}; + Object.defineProperty(obj, 'Non\nenumerable\tkey', { value: true }); + assert.strictEqual( + util.inspect(obj, { showHidden: true }), + '{ [Non\\nenumerable\\tkey]: true }' + ); +} + +// Check for special colors. +{ + const special = inspect.colors[inspect.styles.special]; + const string = inspect.colors[inspect.styles.string]; + + assert.strictEqual( + inspect(new WeakSet(), { colors: true }), + `WeakSet { \u001b[${special[0]}m\u001b[${special[1]}m }` + ); + assert.strictEqual( + inspect(new WeakMap(), { colors: true }), + `WeakMap { \u001b[${special[0]}m\u001b[${special[1]}m }` + ); + // TODO(wafuwafu13): Fix + // assert.strictEqual( + // inspect(new Promise(() => {}), { colors: true }), + // `Promise { \u001b[${special[0]}m\u001b[${special[1]}m }` + // ); + + // const rejection = Promise.reject('Oh no!'); + // assert.strictEqual( + // inspect(rejection, { colors: true }), + // `Promise { \u001b[${special[0]}m\u001b[${special[1]}m ` + + // `\u001b[${string[0]}m'Oh no!'\u001b[${string[1]}m }` + // ); + // rejection.catch(() => {}); + + // Verify that aliases do not show up as key while checking `inspect.colors`. + const colors = Object.keys(inspect.colors); + const aliases = Object.getOwnPropertyNames(inspect.colors) + .filter((c) => !colors.includes(c)); + assert(!colors.includes('grey')); + assert(colors.includes('gray')); + // Verify that all aliases are correctly mapped. + for (const alias of aliases) { + assert(Array.isArray(inspect.colors[alias])); + } + // Check consistent naming. + [ + 'black', + 'red', + 'green', + 'yellow', + 'blue', + 'magenta', + 'cyan', + 'white', + ].forEach((color, i) => { + assert.deepStrictEqual(inspect.colors[color], [30 + i, 39]); + assert.deepStrictEqual(inspect.colors[`${color}Bright`], [90 + i, 39]); + const bgColor = `bg${color[0].toUpperCase()}${color.slice(1)}`; + assert.deepStrictEqual(inspect.colors[bgColor], [40 + i, 49]); + assert.deepStrictEqual(inspect.colors[`${bgColor}Bright`], [100 + i, 49]); + }); + + // Unknown colors are handled gracefully: + const stringStyle = inspect.styles.string; + inspect.styles.string = 'UNKNOWN'; + assert.strictEqual(inspect('foobar', { colors: true }), "'foobar'"); + inspect.styles.string = stringStyle; +} + +assert.strictEqual( + inspect([1, 3, 2], { sorted: true }), + inspect([1, 3, 2]) +); +assert.strictEqual( + inspect({ c: 3, a: 1, b: 2 }, { sorted: true }), + '{ a: 1, b: 2, c: 3 }' +); +assert.strictEqual( + inspect( + { a200: 4, a100: 1, a102: 3, a101: 2 }, + { sorted(a, b) { return b.localeCompare(a); } } + ), + '{ a200: 4, a102: 3, a101: 2, a100: 1 }' +); + +// TODO(wafuwafu13): Fix +// // Non-indices array properties are sorted as well. +// { +// const arr = [3, 2, 1]; +// arr.b = 2; +// arr.c = 3; +// arr.a = 1; +// arr[Symbol('b')] = true; +// arr[Symbol('a')] = false; +// assert.strictEqual( +// inspect(arr, { sorted: true }), +// '[ 3, 2, 1, [Symbol(a)]: false, [Symbol(b)]: true, a: 1, b: 2, c: 3 ]' +// ); +// } + +// TODO(wafuwafu13): Fix +// // Manipulate the prototype in weird ways. +// { +// let obj = { a: true }; +// let value = (function() { return function() {}; })(); +// Object.setPrototypeOf(value, null); +// Object.setPrototypeOf(obj, value); +// assert.strictEqual( +// util.inspect(obj), +// 'Object <[Function (null prototype) (anonymous)]> { a: true }' +// ); +// assert.strictEqual( +// util.inspect(obj, { colors: true }), +// 'Object <\u001b[36m[Function (null prototype) (anonymous)]\u001b[39m> ' + +// '{ a: \u001b[33mtrue\u001b[39m }' +// ); + +// obj = { a: true }; +// value = []; +// Object.setPrototypeOf(value, null); +// Object.setPrototypeOf(obj, value); +// assert.strictEqual( +// util.inspect(obj), +// 'Object <[Array(0): null prototype] []> { a: true }' +// ); + +// function StorageObject() {} +// StorageObject.prototype = Object.create(null); +// assert.strictEqual( +// util.inspect(new StorageObject()), +// 'StorageObject <[Object: null prototype] {}> {}' +// ); + +// obj = [1, 2, 3]; +// Object.setPrototypeOf(obj, Number.prototype); +// assert.strictEqual(inspect(obj), "Number { '0': 1, '1': 2, '2': 3 }"); + +// Object.setPrototypeOf(obj, Object.create(null)); +// assert.strictEqual( +// inspect(obj), +// "Array <[Object: null prototype] {}> { '0': 1, '1': 2, '2': 3 }" +// ); + +// StorageObject.prototype = Object.create(null); +// Object.setPrototypeOf(StorageObject.prototype, Object.create(null)); +// Object.setPrototypeOf( +// Object.getPrototypeOf(StorageObject.prototype), +// Object.create(null) +// ); +// assert.strictEqual( +// util.inspect(new StorageObject()), +// 'StorageObject >> {}' +// ); +// assert.strictEqual( +// util.inspect(new StorageObject(), { depth: 1 }), +// 'StorageObject >> {}' +// ); +// } + +// TODO(wafuwafu13): Fix +// // Check that the fallback always works. +// { +// const obj = new Set([1, 2]); +// const iterator = obj[Symbol.iterator]; +// Object.setPrototypeOf(obj, null); +// Object.defineProperty(obj, Symbol.iterator, { +// value: iterator, +// configurable: true +// }); +// assert.strictEqual(util.inspect(obj), '[Set(2): null prototype] { 1, 2 }'); +// Object.defineProperty(obj, Symbol.iterator, { +// value: true, +// configurable: true +// }); +// Object.defineProperty(obj, 'size', { +// value: NaN, +// configurable: true, +// enumerable: true +// }); +// assert.strictEqual( +// util.inspect(obj), +// '[Set(2): null prototype] { 1, 2, size: NaN }' +// ); +// } + +// TODO(wafuwafu13): Fix +// Check the getter option. +{ + let foo = 1; + const get = { get foo() { return foo; } }; + const getset = { + get foo() { return foo; }, + set foo(val) { foo = val; }, + get inc() { return ++foo; } + }; + const thrower = { get foo() { throw new Error('Oops'); } }; + assert.strictEqual( + inspect(get, { getters: true, colors: true }), + '{ foo: \u001b[36m[Getter:\u001b[39m ' + + '\u001b[33m1\u001b[39m\u001b[36m]\u001b[39m }'); + assert.strictEqual( + inspect(thrower, { getters: true }), + '{ foo: [Getter: ] }'); + assert.strictEqual( + inspect(getset, { getters: true }), + '{ foo: [Getter/Setter: 1], inc: [Getter: 2] }'); + assert.strictEqual( + inspect(getset, { getters: 'get' }), + '{ foo: [Getter/Setter], inc: [Getter: 3] }'); + assert.strictEqual( + inspect(getset, { getters: 'set' }), + '{ foo: [Getter/Setter: 3], inc: [Getter] }'); + getset.foo = new Set([[{ a: true }, 2, {}], 'foobar', { x: 1 }]); + // assert.strictEqual( + // inspect(getset, { getters: true }), + // '{\n foo: [Getter/Setter] Set(3) { [ [Object], 2, {} ], ' + + // "'foobar', { x: 1 } },\n inc: [Getter: NaN]\n}"); +} + +// Check compact number mode. +{ + let obj = { + a: { + b: { + x: 5, + c: { + x: '10000000000000000 00000000000000000 '.repeat(1e1), + d: 2, + e: 3 + } + } + }, + b: [ + 1, + 2, + [ 1, 2, { a: 1, b: 2, c: 3 } ], + ], + c: ['foo', 4, 444444], + d: Array.from({ length: 101 }).map((e, i) => { + return i % 2 === 0 ? i * i : i; + }), + e: Array(6).fill('foobar'), + f: Array(9).fill('foobar'), + g: Array(21).fill('foobar baz'), + h: [100].concat(Array.from({ length: 9 }).map((e, n) => (n))), + long: Array(9).fill('This text is too long for grouping!') + }; + + let out = util.inspect(obj, { compact: 3, depth: 10, breakLength: 60 }); + let expected = [ + '{', + ' a: {', + ' b: {', + ' x: 5,', + ' c: {', + " x: '10000000000000000 00000000000000000 10000000000000000 " + + '00000000000000000 10000000000000000 00000000000000000 ' + + '10000000000000000 00000000000000000 10000000000000000 ' + + '00000000000000000 10000000000000000 00000000000000000 ' + + '10000000000000000 00000000000000000 10000000000000000 ' + + '00000000000000000 10000000000000000 00000000000000000 ' + + "10000000000000000 00000000000000000 ',", + ' d: 2,', + ' e: 3', + ' }', + ' }', + ' },', + ' b: [ 1, 2, [ 1, 2, { a: 1, b: 2, c: 3 } ] ],', + " c: [ 'foo', 4, 444444 ],", + ' d: [', + ' 0, 1, 4, 3, 16, 5, 36, 7, 64,', + ' 9, 100, 11, 144, 13, 196, 15, 256, 17,', + ' 324, 19, 400, 21, 484, 23, 576, 25, 676,', + ' 27, 784, 29, 900, 31, 1024, 33, 1156, 35,', + ' 1296, 37, 1444, 39, 1600, 41, 1764, 43, 1936,', + ' 45, 2116, 47, 2304, 49, 2500, 51, 2704, 53,', + ' 2916, 55, 3136, 57, 3364, 59, 3600, 61, 3844,', + ' 63, 4096, 65, 4356, 67, 4624, 69, 4900, 71,', + ' 5184, 73, 5476, 75, 5776, 77, 6084, 79, 6400,', + ' 81, 6724, 83, 7056, 85, 7396, 87, 7744, 89,', + ' 8100, 91, 8464, 93, 8836, 95, 9216, 97, 9604,', + ' 99,', + ' ... 1 more item', + ' ],', + ' e: [', + " 'foobar',", + " 'foobar',", + " 'foobar',", + " 'foobar',", + " 'foobar',", + " 'foobar'", + ' ],', + ' f: [', + " 'foobar', 'foobar',", + " 'foobar', 'foobar',", + " 'foobar', 'foobar',", + " 'foobar', 'foobar',", + " 'foobar'", + ' ],', + ' g: [', + " 'foobar baz', 'foobar baz',", + " 'foobar baz', 'foobar baz',", + " 'foobar baz', 'foobar baz',", + " 'foobar baz', 'foobar baz',", + " 'foobar baz', 'foobar baz',", + " 'foobar baz', 'foobar baz',", + " 'foobar baz', 'foobar baz',", + " 'foobar baz', 'foobar baz',", + " 'foobar baz', 'foobar baz',", + " 'foobar baz', 'foobar baz',", + " 'foobar baz'", + ' ],', + ' h: [', + ' 100, 0, 1, 2, 3,', + ' 4, 5, 6, 7, 8', + ' ],', + ' long: [', + " 'This text is too long for grouping!',", + " 'This text is too long for grouping!',", + " 'This text is too long for grouping!',", + " 'This text is too long for grouping!',", + " 'This text is too long for grouping!',", + " 'This text is too long for grouping!',", + " 'This text is too long for grouping!',", + " 'This text is too long for grouping!',", + " 'This text is too long for grouping!'", + ' ]', + '}', + ].join('\n'); + + // TODO(wafuwafu13): Fix + // assert.strictEqual(out, expected); + + obj = [ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 123456789, + ]; + + out = util.inspect(obj, { compact: 3 }); + + expected = [ + '[', + ' 1, 1, 1, 1,', + ' 1, 1, 1, 1,', + ' 1, 1, 1, 1,', + ' 1, 1, 1, 1,', + ' 1, 1, 1, 1,', + ' 1, 1, 1, 1,', + ' 1, 1, 123456789', + ']', + ].join('\n'); + + // TODO(wafuwafu13): Fix + // assert.strictEqual(out, expected); + + // Unicode support. あ has a length of one and a width of two. + obj = [ + '123', '123', '123', '123', 'あああ', + '123', '123', '123', '123', 'あああ', + ]; + + out = util.inspect(obj, { compact: 3 }); + + expected = [ + '[', + " '123', '123',", + " '123', '123',", + " 'あああ', '123',", + " '123', '123',", + " '123', 'あああ'", + ']', + ].join('\n'); + + // TODO(wafuwafu13): Fix + // assert.strictEqual(out, expected); + + // Verify that array grouping and line consolidation does not happen together. + obj = { + a: { + b: { + x: 5, + c: { + d: 2, + e: 3 + } + } + }, + b: Array.from({ length: 9 }).map((e, n) => { + return n % 2 === 0 ? 'foobar' : 'baz'; + }) + }; + + out = util.inspect(obj, { compact: 1, breakLength: Infinity, colors: true }); + + expected = [ + '{', + ' a: {', + ' b: { x: \u001b[33m5\u001b[39m, c: \u001b[36m[Object]\u001b[39m }', + ' },', + ' b: [', + " \u001b[32m'foobar'\u001b[39m, \u001b[32m'baz'\u001b[39m,", + " \u001b[32m'foobar'\u001b[39m, \u001b[32m'baz'\u001b[39m,", + " \u001b[32m'foobar'\u001b[39m, \u001b[32m'baz'\u001b[39m,", + " \u001b[32m'foobar'\u001b[39m, \u001b[32m'baz'\u001b[39m,", + " \u001b[32m'foobar'\u001b[39m", + ' ]', + '}', + ].join('\n'); + + // TODO(wafuwafu13): Fix + // assert.strictEqual(out, expected); + + obj = Array.from({ length: 60 }).map((e, i) => i); + out = util.inspect(obj, { compact: 1, breakLength: Infinity, colors: true }); + + expected = [ + '[', + /* eslint-disable max-len */ + ' \u001b[33m0\u001b[39m, \u001b[33m1\u001b[39m, \u001b[33m2\u001b[39m, \u001b[33m3\u001b[39m,', + ' \u001b[33m4\u001b[39m, \u001b[33m5\u001b[39m, \u001b[33m6\u001b[39m, \u001b[33m7\u001b[39m,', + ' \u001b[33m8\u001b[39m, \u001b[33m9\u001b[39m, \u001b[33m10\u001b[39m, \u001b[33m11\u001b[39m,', + ' \u001b[33m12\u001b[39m, \u001b[33m13\u001b[39m, \u001b[33m14\u001b[39m, \u001b[33m15\u001b[39m,', + ' \u001b[33m16\u001b[39m, \u001b[33m17\u001b[39m, \u001b[33m18\u001b[39m, \u001b[33m19\u001b[39m,', + ' \u001b[33m20\u001b[39m, \u001b[33m21\u001b[39m, \u001b[33m22\u001b[39m, \u001b[33m23\u001b[39m,', + ' \u001b[33m24\u001b[39m, \u001b[33m25\u001b[39m, \u001b[33m26\u001b[39m, \u001b[33m27\u001b[39m,', + ' \u001b[33m28\u001b[39m, \u001b[33m29\u001b[39m, \u001b[33m30\u001b[39m, \u001b[33m31\u001b[39m,', + ' \u001b[33m32\u001b[39m, \u001b[33m33\u001b[39m, \u001b[33m34\u001b[39m, \u001b[33m35\u001b[39m,', + ' \u001b[33m36\u001b[39m, \u001b[33m37\u001b[39m, \u001b[33m38\u001b[39m, \u001b[33m39\u001b[39m,', + ' \u001b[33m40\u001b[39m, \u001b[33m41\u001b[39m, \u001b[33m42\u001b[39m, \u001b[33m43\u001b[39m,', + ' \u001b[33m44\u001b[39m, \u001b[33m45\u001b[39m, \u001b[33m46\u001b[39m, \u001b[33m47\u001b[39m,', + ' \u001b[33m48\u001b[39m, \u001b[33m49\u001b[39m, \u001b[33m50\u001b[39m, \u001b[33m51\u001b[39m,', + ' \u001b[33m52\u001b[39m, \u001b[33m53\u001b[39m, \u001b[33m54\u001b[39m, \u001b[33m55\u001b[39m,', + ' \u001b[33m56\u001b[39m, \u001b[33m57\u001b[39m, \u001b[33m58\u001b[39m, \u001b[33m59\u001b[39m', + /* eslint-enable max-len */ + ']', + ].join('\n'); + + // TODO(wafuwafu13): Fix + // assert.strictEqual(out, expected); + + out = util.inspect([1, 2, 3, 4], { compact: 1, colors: true }); + expected = '[ \u001b[33m1\u001b[39m, \u001b[33m2\u001b[39m, ' + + '\u001b[33m3\u001b[39m, \u001b[33m4\u001b[39m ]'; + + assert.strictEqual(out, expected); + + obj = [ + 'Object', 'Function', 'Array', + 'Number', 'parseFloat', 'parseInt', + 'Infinity', 'NaN', 'undefined', + 'Boolean', 'String', 'Symbol', + 'Date', 'Promise', 'RegExp', + 'Error', 'EvalError', 'RangeError', + 'ReferenceError', 'SyntaxError', 'TypeError', + 'URIError', 'JSON', 'Math', + 'console', 'Intl', 'ArrayBuffer', + 'Uint8Array', 'Int8Array', 'Uint16Array', + 'Int16Array', 'Uint32Array', 'Int32Array', + 'Float32Array', 'Float64Array', 'Uint8ClampedArray', + 'BigUint64Array', 'BigInt64Array', 'DataView', + 'Map', 'BigInt', 'Set', + 'WeakMap', 'WeakSet', 'Proxy', + 'Reflect', 'decodeURI', 'decodeURIComponent', + 'encodeURI', 'encodeURIComponent', 'escape', + 'unescape', 'eval', 'isFinite', + 'isNaN', 'SharedArrayBuffer', 'Atomics', + 'globalThis', 'WebAssembly', 'global', + 'process', 'Buffer', 'URL', + 'URLSearchParams', 'TextEncoder', 'TextDecoder', + 'clearInterval', 'clearTimeout', 'setInterval', + 'setTimeout', 'queueMicrotask', 'clearImmediate', + 'setImmediate', 'module', 'require', + 'assert', 'async_hooks', 'buffer', + 'child_process', 'cluster', 'crypto', + 'dgram', 'dns', 'domain', + 'events', 'fs', 'http', + 'http2', 'https', 'inspector', + 'net', 'os', 'path', + 'perf_hooks', 'punycode', 'querystring', + 'readline', 'repl', 'stream', + 'string_decoder', 'tls', 'trace_events', + 'tty', 'url', 'v8', + 'vm', 'worker_threads', 'zlib', + '_', '_error', 'util', + ]; + + out = util.inspect( + obj, + { compact: 3, breakLength: 80, maxArrayLength: 250 } + ); + expected = [ + '[', + " 'Object', 'Function', 'Array',", + " 'Number', 'parseFloat', 'parseInt',", + " 'Infinity', 'NaN', 'undefined',", + " 'Boolean', 'String', 'Symbol',", + " 'Date', 'Promise', 'RegExp',", + " 'Error', 'EvalError', 'RangeError',", + " 'ReferenceError', 'SyntaxError', 'TypeError',", + " 'URIError', 'JSON', 'Math',", + " 'console', 'Intl', 'ArrayBuffer',", + " 'Uint8Array', 'Int8Array', 'Uint16Array',", + " 'Int16Array', 'Uint32Array', 'Int32Array',", + " 'Float32Array', 'Float64Array', 'Uint8ClampedArray',", + " 'BigUint64Array', 'BigInt64Array', 'DataView',", + " 'Map', 'BigInt', 'Set',", + " 'WeakMap', 'WeakSet', 'Proxy',", + " 'Reflect', 'decodeURI', 'decodeURIComponent',", + " 'encodeURI', 'encodeURIComponent', 'escape',", + " 'unescape', 'eval', 'isFinite',", + " 'isNaN', 'SharedArrayBuffer', 'Atomics',", + " 'globalThis', 'WebAssembly', 'global',", + " 'process', 'Buffer', 'URL',", + " 'URLSearchParams', 'TextEncoder', 'TextDecoder',", + " 'clearInterval', 'clearTimeout', 'setInterval',", + " 'setTimeout', 'queueMicrotask', 'clearImmediate',", + " 'setImmediate', 'module', 'require',", + " 'assert', 'async_hooks', 'buffer',", + " 'child_process', 'cluster', 'crypto',", + " 'dgram', 'dns', 'domain',", + " 'events', 'fs', 'http',", + " 'http2', 'https', 'inspector',", + " 'net', 'os', 'path',", + " 'perf_hooks', 'punycode', 'querystring',", + " 'readline', 'repl', 'stream',", + " 'string_decoder', 'tls', 'trace_events',", + " 'tty', 'url', 'v8',", + " 'vm', 'worker_threads', 'zlib',", + " '_', '_error', 'util'", + ']', + ].join('\n'); + + // TODO(wafuwafu13): Fix + // assert.strictEqual(out, expected); +} + +// TODO(wafuwafu13): Fix +// { +// // Use a fake stack to verify the expected colored outcome. +// const stack = [ +// 'TypedError: Wonderful message!', +// ' at A. (/test/node_modules/foo/node_modules/bar/baz.js:2:7)', +// ' at Module._compile (node:internal/modules/cjs/loader:827:30)', +// ' at Fancy (node:vm:697:32)', +// // This file is not an actual Node.js core file. +// ' at tryModuleLoad (node:internal/modules/cjs/foo:629:12)', +// ' at Function.Module._load (node:internal/modules/cjs/loader:621:3)', +// // This file is not an actual Node.js core file. +// ' at Module.require [as weird/name] (node:internal/aaaaa/loader:735:19)', +// ' at require (node:internal/modules/cjs/helpers:14:16)', +// ' at /test/test-util-inspect.js:2239:9', +// ' at getActual (node:assert:592:5)', +// ]; +// const isNodeCoreFile = [ +// false, false, true, true, false, true, false, true, false, true, +// ]; +// const err = new TypeError('Wonderful message!'); +// err.stack = stack.join('\n'); +// util.inspect(err, { colors: true }).split('\n').forEach((line, i) => { +// let actual = stack[i].replace(/node_modules\/([a-z]+)/g, (a, m) => { +// return `node_modules/\u001b[4m${m}\u001b[24m`; +// }); +// if (isNodeCoreFile[i]) { +// actual = `\u001b[90m${actual}\u001b[39m`; +// } +// assert.strictEqual(actual, line); +// }); +// } + +// { +// // Cross platform checks. +// const err = new Error('foo'); +// util.inspect(err, { colors: true }).split('\n').forEach((line, i) => { +// assert(i < 2 || line.startsWith('\u001b[90m')); +// }); +// } + +// TODO(wafuwafu13): Implement "trace_events" +// { +// // Tracing class respects inspect depth. +// try { +// const trace = require('trace_events').createTracing({ categories: ['fo'] }); +// const actualDepth0 = util.inspect({ trace }, { depth: 0 }); +// assert.strictEqual(actualDepth0, '{ trace: [Tracing] }'); +// const actualDepth1 = util.inspect({ trace }, { depth: 1 }); +// assert.strictEqual( +// actualDepth1, +// "{ trace: Tracing { enabled: false, categories: 'fo' } }" +// ); +// } catch (err) { +// if (err.code !== 'ERR_TRACE_EVENTS_UNAVAILABLE') +// throw err; +// } +// } + +// Inspect prototype properties. +{ + class Foo extends Map { + prop = false; + prop2 = true; + get abc() { + return true; + } + get def() { + return false; + } + set def(v) {} + get xyz() { + return 'Should be ignored'; + } + func(a) {} + [util.inspect.custom]() { + return this; + } + } + + class Bar extends Foo { + abc = true; + prop = true; + get xyz() { + return 'YES!'; + } + [util.inspect.custom]() { + return this; + } + } + + const bar = new Bar(); + + assert.strictEqual( + inspect(bar), + 'Bar(0) [Map] { prop: true, prop2: true, abc: true }' + ); + // TODO(wafuwafu13): Fix + // assert.strictEqual( + // inspect(bar, { showHidden: true, getters: true, colors: false }), + // 'Bar(0) [Map] {\n' + + // ' prop: true,\n' + + // ' prop2: true,\n' + + // ' abc: true,\n' + + // " [xyz]: [Getter: 'YES!'],\n" + + // ' [def]: [Getter/Setter: false]\n' + + // '}' + // ); + // assert.strictEqual( + // inspect(bar, { showHidden: true, getters: false, colors: true }), + // 'Bar(0) [Map] {\n' + + // ' prop: \x1B[33mtrue\x1B[39m,\n' + + // ' prop2: \x1B[33mtrue\x1B[39m,\n' + + // ' abc: \x1B[33mtrue\x1B[39m,\n' + + // ' \x1B[2m[xyz]: \x1B[36m[Getter]\x1B[39m\x1B[22m,\n' + + // ' \x1B[2m[def]: \x1B[36m[Getter/Setter]\x1B[39m\x1B[22m\n' + + // '}' + // ); + + // const obj = Object.create({ abc: true, def: 5, toString() {} }); + // assert.strictEqual( + // inspect(obj, { showHidden: true, colors: true }), + // '{ \x1B[2mabc: \x1B[33mtrue\x1B[39m\x1B[22m, ' + + // '\x1B[2mdef: \x1B[33m5\x1B[39m\x1B[22m }' + // ); + + // assert.strictEqual( + // inspect(Object.getPrototypeOf(bar), { showHidden: true, getters: true }), + // ' Foo [Map] {\n' + + // ' [constructor]: [class Bar extends Foo] {\n' + + // ' [length]: 0,\n' + + // " [name]: 'Bar',\n" + + // ' [prototype]: [Circular *1],\n' + + // ' [Symbol(Symbol.species)]: [Getter: ]\n" + + // ' },\n' + + // " [xyz]: [Getter: 'YES!'],\n" + + // ' [Symbol(nodejs.util.inspect.custom)]: ' + + // '[Function: [nodejs.util.inspect.custom]] {\n' + + // ' [length]: 0,\n' + + // " [name]: '[nodejs.util.inspect.custom]'\n" + + // ' },\n' + + // ' [abc]: [Getter: true],\n' + + // ' [def]: [Getter/Setter: false]\n' + + // ' }' + // ); + + // assert.strictEqual( + // inspect(Object.getPrototypeOf(bar)), + // 'Foo [Map] {}' + // ); + + // assert.strictEqual( + // inspect(Object.getPrototypeOf(new Foo())), + // 'Map {}' + // ); +} + +// Check that prototypes with a null prototype are inspectable. +// Regression test for https://github.com/nodejs/node/issues/35730 +{ + function Func() {} + Func.prototype = null; + const object = {}; + object.constructor = Func; + + assert.strictEqual(util.inspect(object), '{ constructor: [Function: Func] }'); +} + +// Test changing util.inspect.colors colors and aliases. +{ + const colors = util.inspect.colors; + + const originalValue = colors.gray; + + // "grey" is reference-equal alias of "gray". + assert.strictEqual(colors.grey, colors.gray); + + // Assigninging one should assign the other. This tests that the alias setter + // function keeps things reference-equal. + colors.gray = [0, 0]; + assert.deepStrictEqual(colors.gray, [0, 0]); + assert.strictEqual(colors.grey, colors.gray); + + colors.grey = [1, 1]; + assert.deepStrictEqual(colors.grey, [1, 1]); + assert.strictEqual(colors.grey, colors.gray); + + // Restore original value to avoid side effects in other tests. + colors.gray = originalValue; + assert.deepStrictEqual(colors.gray, originalValue); + assert.strictEqual(colors.grey, colors.gray); +} + +// TODO(wafuwafu13): Implement 'vm' +// // https://github.com/nodejs/node/issues/31889 +// { +// v8.setFlagsFromString('--allow-natives-syntax'); +// const undetectable = vm.runInThisContext('%GetUndetectable()'); +// v8.setFlagsFromString('--no-allow-natives-syntax'); +// assert.strictEqual(inspect(undetectable), '{}'); +// } + +// Truncate output for Primitives with 1 character left +{ + assert.strictEqual(util.inspect('bl', { maxStringLength: 1 }), + "'b'... 1 more character"); +} + +{ + const x = 'a'.repeat(1e6); + assert(util.inspect(x).endsWith('... 990000 more characters')); + assert.strictEqual( + util.inspect(x, { maxStringLength: 4 }), + "'aaaa'... 999996 more characters" + ); + assert.match(util.inspect(x, { maxStringLength: null }), /a'$/); +} + +// TODO(wafuwafu13): Implement 'vm' +// { +// // Verify that util.inspect() invokes custom inspect functions on objects +// // from other vm.Contexts but does not pass data from its own Context to that +// // function. +// const target = vm.runInNewContext(` +// ({ +// [Symbol.for('nodejs.util.inspect.custom')](depth, ctx) { +// this.depth = depth; +// this.ctx = ctx; +// try { +// this.stylized = ctx.stylize('🐈'); +// } catch (e) { +// this.stylizeException = e; +// } +// return this.stylized; +// } +// }) +// `, Object.create(null)); +// assert.strictEqual(target.ctx, undefined); + +// { +// // Subtest 1: Just try to inspect the object with default options. +// assert.strictEqual(util.inspect(target), '🐈'); +// assert.strictEqual(typeof target.ctx, 'object'); +// const objectGraph = fullObjectGraph(target); +// assert(!objectGraph.has(Object)); +// assert(!objectGraph.has(Function)); +// } + +// { +// // Subtest 2: Use a stylize function that returns a non-primitive. +// const output = util.inspect(target, { +// stylize: common.mustCall((str) => { +// return {}; +// }) +// }); +// assert.strictEqual(output, '[object Object]'); +// assert.strictEqual(typeof target.ctx, 'object'); +// const objectGraph = fullObjectGraph(target); +// assert(!objectGraph.has(Object)); +// assert(!objectGraph.has(Function)); +// } + +// { +// // Subtest 3: Use a stylize function that throws an exception. +// const output = util.inspect(target, { +// stylize: common.mustCall((str) => { +// throw new Error('oops'); +// }) +// }); +// assert.strictEqual(output, '🐈'); +// assert.strictEqual(typeof target.ctx, 'object'); +// const objectGraph = fullObjectGraph(target); +// assert(!objectGraph.has(Object)); +// assert(!objectGraph.has(Function)); +// } + +// function fullObjectGraph(value) { +// const graph = new Set([value]); + +// for (const entry of graph) { +// if ((typeof entry !== 'object' && typeof entry !== 'function') || +// entry === null) { +// continue; +// } + +// graph.add(Object.getPrototypeOf(entry)); +// const descriptors = Object.values( +// Object.getOwnPropertyDescriptors(entry)); +// for (const descriptor of descriptors) { +// graph.add(descriptor.value); +// graph.add(descriptor.set); +// graph.add(descriptor.get); +// } +// } + +// return graph; +// } + +// // Consistency check. +// assert(fullObjectGraph(global).has(Function.prototype)); +// } + +{ + // Confirm that own constructor value displays correctly. + + function Fhqwhgads() {} + + const sterrance = new Fhqwhgads(); + sterrance.constructor = Fhqwhgads; + + assert.strictEqual( + util.inspect(sterrance, { showHidden: true }), + 'Fhqwhgads {\n' + + ' constructor: [Function: Fhqwhgads] {\n' + + ' [length]: 0,\n' + + " [name]: 'Fhqwhgads',\n" + + ' [prototype]: { [constructor]: [Circular *1] }\n' + + ' }\n' + + '}' + ); +} + +// TODO(wafuwafu13): Fix TypeError: main.hasOwnProperty is not a function +// { +// // Confirm null prototype of generator prototype displays as expected. + +// function getProtoOfProto() { +// return Object.getPrototypeOf(Object.getPrototypeOf(function* () {})); +// } + +// function* generator() {} + +// const generatorPrototype = Object.getPrototypeOf(generator); +// const originalProtoOfProto = Object.getPrototypeOf(generatorPrototype); +// assert.strictEqual(getProtoOfProto(), originalProtoOfProto); +// Object.setPrototypeOf(generatorPrototype, null); +// assert.notStrictEqual(getProtoOfProto, originalProtoOfProto); + +// // This is the actual test. The other assertions in this block are about +// // making sure the test is set up correctly and isn't polluting other tests. +// assert.strictEqual( +// util.inspect(generator, { showHidden: true }), +// '[GeneratorFunction: generator] {\n' + +// ' [length]: 0,\n' + +// " [name]: 'generator',\n" + +// " [prototype]: Object [Generator] { [Symbol(Symbol.toStringTag)]: 'Generator' },\n" + // eslint-disable-line max-len +// " [Symbol(Symbol.toStringTag)]: 'GeneratorFunction'\n" + +// '}' +// ); + +// // Reset so we don't pollute other tests +// Object.setPrototypeOf(generatorPrototype, originalProtoOfProto); +// assert.strictEqual(getProtoOfProto(), originalProtoOfProto); +// } + +{ + // Test for when breakLength results in a single column. + const obj = Array(9).fill('fhqwhgadshgnsdhjsdbkhsdabkfabkveybvf'); + assert.strictEqual( + util.inspect(obj, { breakLength: 256 }), + '[\n' + + " 'fhqwhgadshgnsdhjsdbkhsdabkfabkveybvf',\n" + + " 'fhqwhgadshgnsdhjsdbkhsdabkfabkveybvf',\n" + + " 'fhqwhgadshgnsdhjsdbkhsdabkfabkveybvf',\n" + + " 'fhqwhgadshgnsdhjsdbkhsdabkfabkveybvf',\n" + + " 'fhqwhgadshgnsdhjsdbkhsdabkfabkveybvf',\n" + + " 'fhqwhgadshgnsdhjsdbkhsdabkfabkveybvf',\n" + + " 'fhqwhgadshgnsdhjsdbkhsdabkfabkveybvf',\n" + + " 'fhqwhgadshgnsdhjsdbkhsdabkfabkveybvf',\n" + + " 'fhqwhgadshgnsdhjsdbkhsdabkfabkveybvf'\n" + + ']' + ); +} + +{ + assert.strictEqual( + util.inspect({ ['__proto__']: { a: 1 } }), + "{ ['__proto__']: { a: 1 } }" + ); +} diff --git a/tests/node_compat/test/parallel/test-util-isDeepStrictEqual.js b/tests/node_compat/test/parallel/test-util-isDeepStrictEqual.js new file mode 100644 index 000000000..25caac1f7 --- /dev/null +++ b/tests/node_compat/test/parallel/test-util-isDeepStrictEqual.js @@ -0,0 +1,608 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +"use strict"; + +// Confirm functionality of `util.isDeepStrictEqual()`. + +require("../common"); + +const assert = require("assert"); +const util = require("util"); + +class MyDate extends Date { + constructor(...args) { + super(...args); + this[0] = "1"; + } +} + +class MyRegExp extends RegExp { + constructor(...args) { + super(...args); + this[0] = "1"; + } +} + +{ + const arr = new Uint8Array([120, 121, 122, 10]); + const buf = Buffer.from(arr); + // They have different [[Prototype]] + assert.strictEqual(util.isDeepStrictEqual(arr, buf), false); + + const buf2 = Buffer.from(arr); + buf2.prop = 1; + + assert.strictEqual(util.isDeepStrictEqual(buf2, buf), false); + + const arr2 = new Uint8Array([120, 121, 122, 10]); + arr2.prop = 5; + assert.strictEqual(util.isDeepStrictEqual(arr, arr2), false); +} + +{ + const date = new Date("2016"); + + const date2 = new MyDate("2016"); + + // deepStrictEqual checks own properties + assert.strictEqual(util.isDeepStrictEqual(date, date2), false); + assert.strictEqual(util.isDeepStrictEqual(date2, date), false); +} + +{ + const re1 = new RegExp("test"); + const re2 = new MyRegExp("test"); + + // deepStrictEqual checks all properties + assert.strictEqual(util.isDeepStrictEqual(re1, re2), false); +} + +{ + // For these cases, deepStrictEqual should throw. + const similar = new Set([ + { 0: "1" }, // Object + { 0: 1 }, // Object + new String("1"), // Object + ["1"], // Array + [1], // Array + new MyDate("2016"), // Date with this[0] = '1' + new MyRegExp("test"), // RegExp with this[0] = '1' + new Int8Array([1]), // Int8Array + new Uint8Array([1]), // Uint8Array + new Int16Array([1]), // Int16Array + new Uint16Array([1]), // Uint16Array + new Int32Array([1]), // Int32Array + new Uint32Array([1]), // Uint32Array + Buffer.from([1]), // Buffer + ]); + + for (const a of similar) { + for (const b of similar) { + if (a !== b) { + assert.strictEqual(util.isDeepStrictEqual(a, b), false); + } + } + } +} + +function utilIsDeepStrict(a, b) { + assert.strictEqual(util.isDeepStrictEqual(a, b), true); + assert.strictEqual(util.isDeepStrictEqual(b, a), true); +} +function notUtilIsDeepStrict(a, b) { + assert.strictEqual(util.isDeepStrictEqual(a, b), false); + assert.strictEqual(util.isDeepStrictEqual(b, a), false); +} + +// es6 Maps and Sets +utilIsDeepStrict(new Set(), new Set()); +utilIsDeepStrict(new Map(), new Map()); + +utilIsDeepStrict(new Set([1, 2, 3]), new Set([1, 2, 3])); +notUtilIsDeepStrict(new Set([1, 2, 3]), new Set([1, 2, 3, 4])); +notUtilIsDeepStrict(new Set([1, 2, 3, 4]), new Set([1, 2, 3])); +utilIsDeepStrict(new Set(["1", "2", "3"]), new Set(["1", "2", "3"])); +utilIsDeepStrict( + new Set([ + [1, 2], + [3, 4], + ]), + new Set([ + [3, 4], + [1, 2], + ]) +); + +{ + const a = [1, 2]; + const b = [3, 4]; + const c = [1, 2]; + const d = [3, 4]; + + utilIsDeepStrict( + { a: a, b: b, s: new Set([a, b]) }, + { a: c, b: d, s: new Set([d, c]) } + ); +} + +utilIsDeepStrict( + new Map([ + [1, 1], + [2, 2], + ]), + new Map([ + [1, 1], + [2, 2], + ]) +); +utilIsDeepStrict( + new Map([ + [1, 1], + [2, 2], + ]), + new Map([ + [2, 2], + [1, 1], + ]) +); +notUtilIsDeepStrict( + new Map([ + [1, 1], + [2, 2], + ]), + new Map([ + [1, 2], + [2, 1], + ]) +); +notUtilIsDeepStrict( + new Map([ + [[1], 1], + [{}, 2], + ]), + new Map([ + [[1], 2], + [{}, 1], + ]) +); + +notUtilIsDeepStrict(new Set([1]), [1]); +notUtilIsDeepStrict(new Set(), []); +notUtilIsDeepStrict(new Set(), {}); + +notUtilIsDeepStrict(new Map([["a", 1]]), { a: 1 }); +notUtilIsDeepStrict(new Map(), []); +notUtilIsDeepStrict(new Map(), {}); + +notUtilIsDeepStrict(new Set(["1"]), new Set([1])); + +notUtilIsDeepStrict(new Map([["1", "a"]]), new Map([[1, "a"]])); +notUtilIsDeepStrict(new Map([["a", "1"]]), new Map([["a", 1]])); +notUtilIsDeepStrict(new Map([["a", "1"]]), new Map([["a", 2]])); + +utilIsDeepStrict(new Set([{}]), new Set([{}])); + +// Ref: https://github.com/nodejs/node/issues/13347 +notUtilIsDeepStrict( + new Set([{ a: 1 }, { a: 1 }]), + new Set([{ a: 1 }, { a: 2 }]) +); +notUtilIsDeepStrict( + new Set([{ a: 1 }, { a: 1 }, { a: 2 }]), + new Set([{ a: 1 }, { a: 2 }, { a: 2 }]) +); +notUtilIsDeepStrict( + new Map([ + [{ x: 1 }, 5], + [{ x: 1 }, 5], + ]), + new Map([ + [{ x: 1 }, 5], + [{ x: 2 }, 5], + ]) +); + +notUtilIsDeepStrict(new Set([3, "3"]), new Set([3, 4])); +notUtilIsDeepStrict( + new Map([ + [3, 0], + ["3", 0], + ]), + new Map([ + [3, 0], + [4, 0], + ]) +); + +notUtilIsDeepStrict( + new Set([{ a: 1 }, { a: 1 }, { a: 2 }]), + new Set([{ a: 1 }, { a: 2 }, { a: 2 }]) +); + +// Mixed primitive and object keys +utilIsDeepStrict( + new Map([ + [1, "a"], + [{}, "a"], + ]), + new Map([ + [1, "a"], + [{}, "a"], + ]) +); +utilIsDeepStrict(new Set([1, "a", [{}, "a"]]), new Set([1, "a", [{}, "a"]])); + +// This is an awful case, where a map contains multiple equivalent keys: +notUtilIsDeepStrict( + new Map([ + [1, "a"], + ["1", "b"], + ]), + new Map([ + ["1", "a"], + [true, "b"], + ]) +); +notUtilIsDeepStrict(new Set(["a"]), new Set(["b"])); +utilIsDeepStrict( + new Map([ + [{}, "a"], + [{}, "b"], + ]), + new Map([ + [{}, "b"], + [{}, "a"], + ]) +); +notUtilIsDeepStrict( + new Map([ + [true, "a"], + ["1", "b"], + [1, "a"], + ]), + new Map([ + ["1", "a"], + [1, "b"], + [true, "a"], + ]) +); +notUtilIsDeepStrict( + new Map([ + [true, "a"], + ["1", "b"], + [1, "c"], + ]), + new Map([ + ["1", "a"], + [1, "b"], + [true, "a"], + ]) +); + +// Similar object keys +notUtilIsDeepStrict(new Set([{}, {}]), new Set([{}, 1])); +notUtilIsDeepStrict( + new Set([ + [{}, 1], + [{}, 1], + ]), + new Set([ + [{}, 1], + [1, 1], + ]) +); +notUtilIsDeepStrict( + new Map([ + [{}, 1], + [{}, 1], + ]), + new Map([ + [{}, 1], + [1, 1], + ]) +); +notUtilIsDeepStrict( + new Map([ + [{}, 1], + [true, 1], + ]), + new Map([ + [{}, 1], + [1, 1], + ]) +); + +// Similar primitive key / values +notUtilIsDeepStrict(new Set([1, true, false]), new Set(["1", 0, "0"])); +notUtilIsDeepStrict( + new Map([ + [1, 5], + [true, 5], + [false, 5], + ]), + new Map([ + ["1", 5], + [0, 5], + ["0", 5], + ]) +); + +// Undefined value in Map +utilIsDeepStrict(new Map([[1, undefined]]), new Map([[1, undefined]])); +notUtilIsDeepStrict(new Map([[1, null]]), new Map([["1", undefined]])); +notUtilIsDeepStrict(new Map([[1, undefined]]), new Map([[2, undefined]])); + +// null as key +utilIsDeepStrict(new Map([[null, 3]]), new Map([[null, 3]])); +notUtilIsDeepStrict(new Map([[null, undefined]]), new Map([[undefined, null]])); +notUtilIsDeepStrict(new Set([null]), new Set([undefined])); + +// GH-6416. Make sure circular refs don't throw. +{ + const b = {}; + b.b = b; + const c = {}; + c.b = c; + + utilIsDeepStrict(b, c); + + const d = {}; + d.a = 1; + d.b = d; + const e = {}; + e.a = 1; + e.b = {}; + + notUtilIsDeepStrict(d, e); +} + +// GH-14441. Circular structures should be consistent +{ + const a = {}; + const b = {}; + a.a = a; + b.a = {}; + b.a.a = a; + utilIsDeepStrict(a, b); +} + +{ + const a = new Set(); + const b = new Set(); + const c = new Set(); + a.add(a); + b.add(b); + c.add(a); + utilIsDeepStrict(b, c); +} + +// GH-7178. Ensure reflexivity of deepEqual with `arguments` objects. +{ + const args = (function () { + return arguments; + })(); + notUtilIsDeepStrict([], args); +} + +// More checking that arguments objects are handled correctly +{ + // eslint-disable-next-line func-style + const returnArguments = function () { + return arguments; + }; + + const someArgs = returnArguments("a"); + const sameArgs = returnArguments("a"); + const diffArgs = returnArguments("b"); + + notUtilIsDeepStrict(someArgs, ["a"]); + notUtilIsDeepStrict(someArgs, { 0: "a" }); + notUtilIsDeepStrict(someArgs, diffArgs); + utilIsDeepStrict(someArgs, sameArgs); +} + +{ + const values = [ + 123, + Infinity, + 0, + null, + undefined, + false, + true, + {}, + [], + () => {}, + ]; + utilIsDeepStrict(new Set(values), new Set(values)); + utilIsDeepStrict(new Set(values), new Set(values.reverse())); + + const mapValues = values.map((v) => [v, { a: 5 }]); + utilIsDeepStrict(new Map(mapValues), new Map(mapValues)); + utilIsDeepStrict(new Map(mapValues), new Map(mapValues.reverse())); +} + +{ + const s1 = new Set(); + const s2 = new Set(); + s1.add(1); + s1.add(2); + s2.add(2); + s2.add(1); + utilIsDeepStrict(s1, s2); +} + +{ + const m1 = new Map(); + const m2 = new Map(); + const obj = { a: 5, b: 6 }; + m1.set(1, obj); + m1.set(2, "hi"); + m1.set(3, [1, 2, 3]); + + m2.set(2, "hi"); // different order + m2.set(1, obj); + m2.set(3, [1, 2, 3]); // Deep equal, but not reference equal. + + utilIsDeepStrict(m1, m2); +} + +{ + const m1 = new Map(); + const m2 = new Map(); + + // m1 contains itself. + m1.set(1, m1); + m2.set(1, new Map()); + + notUtilIsDeepStrict(m1, m2); +} + +{ + const map1 = new Map([[1, 1]]); + const map2 = new Map([[1, "1"]]); + assert.strictEqual(util.isDeepStrictEqual(map1, map2), false); +} + +{ + // Two equivalent sets / maps with different key/values applied shouldn't be + // the same. This is a terrible idea to do in practice, but deepEqual should + // still check for it. + const s1 = new Set(); + const s2 = new Set(); + s1.x = 5; + notUtilIsDeepStrict(s1, s2); + + const m1 = new Map(); + const m2 = new Map(); + m1.x = 5; + notUtilIsDeepStrict(m1, m2); +} + +{ + // Circular references. + const s1 = new Set(); + s1.add(s1); + const s2 = new Set(); + s2.add(s2); + utilIsDeepStrict(s1, s2); + + const m1 = new Map(); + m1.set(2, m1); + const m2 = new Map(); + m2.set(2, m2); + utilIsDeepStrict(m1, m2); + + const m3 = new Map(); + m3.set(m3, 2); + const m4 = new Map(); + m4.set(m4, 2); + utilIsDeepStrict(m3, m4); +} + +// Handle sparse arrays +utilIsDeepStrict([1, , , 3], [1, , , 3]); +notUtilIsDeepStrict([1, , , 3], [1, , , 3, , ,]); + +// Handle different error messages +{ + const err1 = new Error("foo1"); + const err2 = new Error("foo2"); + const err3 = new TypeError("foo1"); + notUtilIsDeepStrict(err1, err2, assert.AssertionError); + notUtilIsDeepStrict(err1, err3, assert.AssertionError); + notUtilIsDeepStrict(err1, {}, assert.AssertionError); +} + +// Handle NaN +assert.strictEqual(util.isDeepStrictEqual(NaN, NaN), true); +assert.strictEqual(util.isDeepStrictEqual({ a: NaN }, { a: NaN }), true); +assert.strictEqual( + util.isDeepStrictEqual([1, 2, NaN, 4], [1, 2, NaN, 4]), + true +); + +// Handle boxed primitives +{ + const boxedString = new String("test"); + const boxedSymbol = Object(Symbol()); + notUtilIsDeepStrict(new Boolean(true), Object(false)); + notUtilIsDeepStrict(Object(true), new Number(1)); + notUtilIsDeepStrict(new Number(2), new Number(1)); + notUtilIsDeepStrict(boxedSymbol, Object(Symbol())); + notUtilIsDeepStrict(boxedSymbol, {}); + utilIsDeepStrict(boxedSymbol, boxedSymbol); + utilIsDeepStrict(Object(true), Object(true)); + utilIsDeepStrict(Object(2), Object(2)); + utilIsDeepStrict(boxedString, Object("test")); + boxedString.slow = true; + notUtilIsDeepStrict(boxedString, Object("test")); + boxedSymbol.slow = true; + notUtilIsDeepStrict(boxedSymbol, {}); + utilIsDeepStrict(Object(BigInt(1)), Object(BigInt(1))); + notUtilIsDeepStrict(Object(BigInt(1)), Object(BigInt(2))); + + const booleanish = new Boolean(true); + Object.defineProperty(booleanish, Symbol.toStringTag, { value: "String" }); + Object.setPrototypeOf(booleanish, String.prototype); + notUtilIsDeepStrict(booleanish, new String("true")); + + const numberish = new Number(42); + Object.defineProperty(numberish, Symbol.toStringTag, { value: "String" }); + Object.setPrototypeOf(numberish, String.prototype); + notUtilIsDeepStrict(numberish, new String("42")); + + const stringish = new String("0"); + Object.defineProperty(stringish, Symbol.toStringTag, { value: "Number" }); + Object.setPrototypeOf(stringish, Number.prototype); + notUtilIsDeepStrict(stringish, new Number(0)); + + const bigintish = new Object(BigInt(42)); + Object.defineProperty(bigintish, Symbol.toStringTag, { value: "String" }); + Object.setPrototypeOf(bigintish, String.prototype); + notUtilIsDeepStrict(bigintish, new String("42")); + + const symbolish = new Object(Symbol("fhqwhgads")); + Object.defineProperty(symbolish, Symbol.toStringTag, { value: "String" }); + Object.setPrototypeOf(symbolish, String.prototype); + notUtilIsDeepStrict(symbolish, new String("fhqwhgads")); +} + +// Minus zero +notUtilIsDeepStrict(0, -0); +utilIsDeepStrict(-0, -0); + +// Handle symbols (enumerable only) +{ + const symbol1 = Symbol(); + const obj1 = { [symbol1]: 1 }; + const obj2 = { [symbol1]: 1 }; + const obj3 = { [Symbol()]: 1 }; + const obj4 = {}; + // Add a non enumerable symbol as well. It is going to be ignored! + Object.defineProperty(obj2, Symbol(), { value: 1 }); + Object.defineProperty(obj4, symbol1, { value: 1 }); + notUtilIsDeepStrict(obj1, obj3); + utilIsDeepStrict(obj1, obj2); + notUtilIsDeepStrict(obj1, obj4); + // TypedArrays have a fast path. Test for this as well. + const a = new Uint8Array(4); + const b = new Uint8Array(4); + a[symbol1] = true; + b[symbol1] = false; + notUtilIsDeepStrict(a, b); + b[symbol1] = true; + utilIsDeepStrict(a, b); + // The same as TypedArrays is valid for boxed primitives + const boxedStringA = new String("test"); + const boxedStringB = new String("test"); + boxedStringA[symbol1] = true; + notUtilIsDeepStrict(boxedStringA, boxedStringB); + boxedStringA[symbol1] = true; + utilIsDeepStrict(a, b); +} diff --git a/tests/node_compat/test/parallel/test-util-promisify.js b/tests/node_compat/test/parallel/test-util-promisify.js new file mode 100644 index 000000000..8046f6fb8 --- /dev/null +++ b/tests/node_compat/test/parallel/test-util-promisify.js @@ -0,0 +1,218 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +'use strict'; +// Flags: --expose-internals +const common = require('../common'); +const assert = require('assert'); +const fs = require('fs'); +const vm = require('vm'); +const { promisify } = require('util'); +const { customPromisifyArgs } = require('internal/util'); + +const stat = promisify(fs.stat); + +// TODO(wafuwafu13): Fix +// { +// const promise = stat(__filename); +// assert(promise instanceof Promise); +// promise.then(common.mustCall((value) => { +// assert.deepStrictEqual(value, fs.statSync(__filename)); +// })); +// } + +{ + const promise = stat('/dontexist'); + promise.catch(common.mustCall((error) => { + assert(error.message.includes('ENOENT: no such file or directory, stat')); + })); +} + +{ + function fn() {} + + function promisifedFn() {} + fn[promisify.custom] = promisifedFn; + assert.strictEqual(promisify(fn), promisifedFn); + assert.strictEqual(promisify(promisify(fn)), promisifedFn); +} + +{ + function fn() {} + + function promisifiedFn() {} + + // util.promisify.custom is a shared symbol which can be accessed + // as `Symbol.for("nodejs.util.promisify.custom")`. + const kCustomPromisifiedSymbol = Symbol.for('nodejs.util.promisify.custom'); + fn[kCustomPromisifiedSymbol] = promisifiedFn; + + assert.strictEqual(kCustomPromisifiedSymbol, promisify.custom); + assert.strictEqual(promisify(fn), promisifiedFn); + assert.strictEqual(promisify(promisify(fn)), promisifiedFn); +} + +{ + function fn() {} + fn[promisify.custom] = 42; + assert.throws( + () => promisify(fn), + { code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' } + ); +} + +// TODO(wafuwafu13): Fix +// { +// const firstValue = 5; +// const secondValue = 17; + +// function fn(callback) { +// callback(null, firstValue, secondValue); +// } + +// fn[customPromisifyArgs] = ['first', 'second']; + +// promisify(fn)().then(common.mustCall((obj) => { +// assert.deepStrictEqual(obj, { first: firstValue, second: secondValue }); +// })); +// } + +{ + const fn = vm.runInNewContext('(function() {})'); + assert.notStrictEqual(Object.getPrototypeOf(promisify(fn)), + Function.prototype); +} + +{ + function fn(callback) { + callback(null, 'foo', 'bar'); + } + promisify(fn)().then(common.mustCall((value) => { + assert.deepStrictEqual(value, 'foo'); + })); +} + +{ + function fn(callback) { + callback(null); + } + promisify(fn)().then(common.mustCall((value) => { + assert.strictEqual(value, undefined); + })); +} + +{ + function fn(callback) { + callback(); + } + promisify(fn)().then(common.mustCall((value) => { + assert.strictEqual(value, undefined); + })); +} + +{ + function fn(err, val, callback) { + callback(err, val); + } + promisify(fn)(null, 42).then(common.mustCall((value) => { + assert.strictEqual(value, 42); + })); +} + +{ + function fn(err, val, callback) { + callback(err, val); + } + promisify(fn)(new Error('oops'), null).catch(common.mustCall((err) => { + assert.strictEqual(err.message, 'oops'); + })); +} + +{ + function fn(err, val, callback) { + callback(err, val); + } + + (async () => { + const value = await promisify(fn)(null, 42); + assert.strictEqual(value, 42); + })().then(common.mustCall()); +} + +{ + const o = {}; + const fn = promisify(function(cb) { + + cb(null, this === o); + }); + + o.fn = fn; + + o.fn().then(common.mustCall((val) => assert(val))); +} + +{ + const err = new Error('Should not have called the callback with the error.'); + const stack = err.stack; + + const fn = promisify(function(cb) { + cb(null); + cb(err); + }); + + (async () => { + await fn(); + await Promise.resolve(); + return assert.strictEqual(stack, err.stack); + })().then(common.mustCall()); +} + +{ + function c() { } + const a = promisify(function() { }); + const b = promisify(a); + assert.notStrictEqual(c, a); + assert.strictEqual(a, b); +} + +{ + let errToThrow; + const thrower = promisify(function(a, b, c, cb) { + errToThrow = new Error(); + throw errToThrow; + }); + thrower(1, 2, 3) + .then(assert.fail) + .then(assert.fail, (e) => assert.strictEqual(e, errToThrow)); +} + +{ + const err = new Error(); + + const a = promisify((cb) => cb(err))(); + const b = promisify(() => { throw err; })(); + + Promise.all([ + a.then(assert.fail, function(e) { + assert.strictEqual(err, e); + }), + b.then(assert.fail, function(e) { + assert.strictEqual(err, e); + }), + ]); +} + +[undefined, null, true, 0, 'str', {}, [], Symbol()].forEach((input) => { + assert.throws( + () => promisify(input), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "original" argument must be of type function.' + + common.invalidArgTypeHelper(input) + }); +}); diff --git a/tests/node_compat/test/parallel/test-util-types-exists.js b/tests/node_compat/test/parallel/test-util-types-exists.js new file mode 100644 index 000000000..0c04a38b0 --- /dev/null +++ b/tests/node_compat/test/parallel/test-util-types-exists.js @@ -0,0 +1,13 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); + +assert.strictEqual(require('util/types'), require('util').types); diff --git a/tests/node_compat/test/parallel/test-util-types.js b/tests/node_compat/test/parallel/test-util-types.js new file mode 100644 index 000000000..d401a282c --- /dev/null +++ b/tests/node_compat/test/parallel/test-util-types.js @@ -0,0 +1,304 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Flags: --experimental-vm-modules --expose-internals +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const { types, inspect } = require('util'); +const vm = require('vm'); +// TODO(wafuwafu13): Implement "internalBinding" +// const { internalBinding } = require('internal/test/binding'); +// const { JSStream } = internalBinding('js_stream'); + +// TODO(wafuwafu13): Implement "JSStream" +// const external = (new JSStream())._externalStream; + +for (const [ value, _method ] of [ + // TODO(wafuwafu13): Implement "JSStream" + // [ external, 'isExternal' ], + [ new Date() ], + [ (function() { return arguments; })(), 'isArgumentsObject' ], + [ new Boolean(), 'isBooleanObject' ], + [ new Number(), 'isNumberObject' ], + [ new String(), 'isStringObject' ], + [ Object(Symbol()), 'isSymbolObject' ], + [ Object(BigInt(0)), 'isBigIntObject' ], + [ new Error(), 'isNativeError' ], + [ new RegExp() ], + [ async function() {}, 'isAsyncFunction' ], + [ function*() {}, 'isGeneratorFunction' ], + [ (function*() {})(), 'isGeneratorObject' ], + [ Promise.resolve() ], + [ new Map() ], + [ new Set() ], + [ (new Map())[Symbol.iterator](), 'isMapIterator' ], + [ (new Set())[Symbol.iterator](), 'isSetIterator' ], + [ new WeakMap() ], + [ new WeakSet() ], + [ new ArrayBuffer() ], + [ new Uint8Array() ], + [ new Uint8ClampedArray() ], + [ new Uint16Array() ], + [ new Uint32Array() ], + [ new Int8Array() ], + [ new Int16Array() ], + [ new Int32Array() ], + [ new Float32Array() ], + [ new Float64Array() ], + [ new BigInt64Array() ], + [ new BigUint64Array() ], + // [ Object.defineProperty(new Uint8Array(), + // Symbol.toStringTag, + // { value: 'foo' }) ], + [ new DataView(new ArrayBuffer()) ], + [ new SharedArrayBuffer() ], + [ new Proxy({}, {}), 'isProxy' ], +]) { + const method = _method || `is${value.constructor.name}`; + assert(method in types, `Missing ${method} for ${inspect(value)}`); + assert(types[method](value), `Want ${inspect(value)} to match ${method}`); + + for (const key of Object.keys(types)) { + if ((types.isArrayBufferView(value) || + types.isAnyArrayBuffer(value)) && key.includes('Array') || + key === 'isBoxedPrimitive') { + continue; + } + + assert.strictEqual(types[key](value), + key === method, + `${inspect(value)}: ${key}, ` + + `${method}, ${types[key](value)}`); + } +} + +// Check boxed primitives. +[ + new Boolean(), + new Number(), + new String(), + Object(Symbol()), + Object(BigInt(0)), +].forEach((entry) => assert(types.isBoxedPrimitive(entry))); + +{ + assert(!types.isUint8Array({ [Symbol.toStringTag]: 'Uint8Array' })); + assert(types.isUint8Array(vm.runInNewContext('new Uint8Array'))); + + assert(!types.isUint8ClampedArray({ + [Symbol.toStringTag]: 'Uint8ClampedArray' + })); + assert(types.isUint8ClampedArray( + vm.runInNewContext('new Uint8ClampedArray') + )); + + assert(!types.isUint16Array({ [Symbol.toStringTag]: 'Uint16Array' })); + assert(types.isUint16Array(vm.runInNewContext('new Uint16Array'))); + + assert(!types.isUint32Array({ [Symbol.toStringTag]: 'Uint32Array' })); + assert(types.isUint32Array(vm.runInNewContext('new Uint32Array'))); + + assert(!types.isInt8Array({ [Symbol.toStringTag]: 'Int8Array' })); + assert(types.isInt8Array(vm.runInNewContext('new Int8Array'))); + + assert(!types.isInt16Array({ [Symbol.toStringTag]: 'Int16Array' })); + assert(types.isInt16Array(vm.runInNewContext('new Int16Array'))); + + assert(!types.isInt32Array({ [Symbol.toStringTag]: 'Int32Array' })); + assert(types.isInt32Array(vm.runInNewContext('new Int32Array'))); + + assert(!types.isFloat32Array({ [Symbol.toStringTag]: 'Float32Array' })); + assert(types.isFloat32Array(vm.runInNewContext('new Float32Array'))); + + assert(!types.isFloat64Array({ [Symbol.toStringTag]: 'Float64Array' })); + assert(types.isFloat64Array(vm.runInNewContext('new Float64Array'))); + + assert(!types.isBigInt64Array({ [Symbol.toStringTag]: 'BigInt64Array' })); + assert(types.isBigInt64Array(vm.runInNewContext('new BigInt64Array'))); + + assert(!types.isBigUint64Array({ [Symbol.toStringTag]: 'BigUint64Array' })); + assert(types.isBigUint64Array(vm.runInNewContext('new BigUint64Array'))); +} + +{ + const primitive = true; + const arrayBuffer = new ArrayBuffer(); + const buffer = Buffer.from(arrayBuffer); + const dataView = new DataView(arrayBuffer); + const uint8Array = new Uint8Array(arrayBuffer); + const uint8ClampedArray = new Uint8ClampedArray(arrayBuffer); + const uint16Array = new Uint16Array(arrayBuffer); + const uint32Array = new Uint32Array(arrayBuffer); + const int8Array = new Int8Array(arrayBuffer); + const int16Array = new Int16Array(arrayBuffer); + const int32Array = new Int32Array(arrayBuffer); + const float32Array = new Float32Array(arrayBuffer); + const float64Array = new Float64Array(arrayBuffer); + const bigInt64Array = new BigInt64Array(arrayBuffer); + const bigUint64Array = new BigUint64Array(arrayBuffer); + + const fakeBuffer = Object.create(Buffer.prototype); + const fakeDataView = Object.create(DataView.prototype); + const fakeUint8Array = Object.create(Uint8Array.prototype); + const fakeUint8ClampedArray = Object.create(Uint8ClampedArray.prototype); + const fakeUint16Array = Object.create(Uint16Array.prototype); + const fakeUint32Array = Object.create(Uint32Array.prototype); + const fakeInt8Array = Object.create(Int8Array.prototype); + const fakeInt16Array = Object.create(Int16Array.prototype); + const fakeInt32Array = Object.create(Int32Array.prototype); + const fakeFloat32Array = Object.create(Float32Array.prototype); + const fakeFloat64Array = Object.create(Float64Array.prototype); + const fakeBigInt64Array = Object.create(BigInt64Array.prototype); + const fakeBigUint64Array = Object.create(BigUint64Array.prototype); + + const stealthyDataView = + Object.setPrototypeOf(new DataView(arrayBuffer), Uint8Array.prototype); + const stealthyUint8Array = + Object.setPrototypeOf(new Uint8Array(arrayBuffer), ArrayBuffer.prototype); + const stealthyUint8ClampedArray = + Object.setPrototypeOf( + new Uint8ClampedArray(arrayBuffer), ArrayBuffer.prototype + ); + const stealthyUint16Array = + Object.setPrototypeOf(new Uint16Array(arrayBuffer), Uint16Array.prototype); + const stealthyUint32Array = + Object.setPrototypeOf(new Uint32Array(arrayBuffer), Uint32Array.prototype); + const stealthyInt8Array = + Object.setPrototypeOf(new Int8Array(arrayBuffer), Int8Array.prototype); + const stealthyInt16Array = + Object.setPrototypeOf(new Int16Array(arrayBuffer), Int16Array.prototype); + const stealthyInt32Array = + Object.setPrototypeOf(new Int32Array(arrayBuffer), Int32Array.prototype); + const stealthyFloat32Array = + Object.setPrototypeOf( + new Float32Array(arrayBuffer), Float32Array.prototype + ); + const stealthyFloat64Array = + Object.setPrototypeOf( + new Float64Array(arrayBuffer), Float64Array.prototype + ); + const stealthyBigInt64Array = + Object.setPrototypeOf( + new BigInt64Array(arrayBuffer), BigInt64Array.prototype + ); + const stealthyBigUint64Array = + Object.setPrototypeOf( + new BigUint64Array(arrayBuffer), BigUint64Array.prototype + ); + + const all = [ + primitive, arrayBuffer, buffer, fakeBuffer, + dataView, fakeDataView, stealthyDataView, + uint8Array, fakeUint8Array, stealthyUint8Array, + uint8ClampedArray, fakeUint8ClampedArray, stealthyUint8ClampedArray, + uint16Array, fakeUint16Array, stealthyUint16Array, + uint32Array, fakeUint32Array, stealthyUint32Array, + int8Array, fakeInt8Array, stealthyInt8Array, + int16Array, fakeInt16Array, stealthyInt16Array, + int32Array, fakeInt32Array, stealthyInt32Array, + float32Array, fakeFloat32Array, stealthyFloat32Array, + float64Array, fakeFloat64Array, stealthyFloat64Array, + bigInt64Array, fakeBigInt64Array, stealthyBigInt64Array, + bigUint64Array, fakeBigUint64Array, stealthyBigUint64Array, + ]; + + const expected = { + isArrayBufferView: [ + buffer, + dataView, stealthyDataView, + uint8Array, stealthyUint8Array, + uint8ClampedArray, stealthyUint8ClampedArray, + uint16Array, stealthyUint16Array, + uint32Array, stealthyUint32Array, + int8Array, stealthyInt8Array, + int16Array, stealthyInt16Array, + int32Array, stealthyInt32Array, + float32Array, stealthyFloat32Array, + float64Array, stealthyFloat64Array, + bigInt64Array, stealthyBigInt64Array, + bigUint64Array, stealthyBigUint64Array, + ], + isTypedArray: [ + buffer, + uint8Array, stealthyUint8Array, + uint8ClampedArray, stealthyUint8ClampedArray, + uint16Array, stealthyUint16Array, + uint32Array, stealthyUint32Array, + int8Array, stealthyInt8Array, + int16Array, stealthyInt16Array, + int32Array, stealthyInt32Array, + float32Array, stealthyFloat32Array, + float64Array, stealthyFloat64Array, + bigInt64Array, stealthyBigInt64Array, + bigUint64Array, stealthyBigUint64Array, + ], + isUint8Array: [ + buffer, uint8Array, stealthyUint8Array, + ], + isUint8ClampedArray: [ + uint8ClampedArray, stealthyUint8ClampedArray, + ], + isUint16Array: [ + uint16Array, stealthyUint16Array, + ], + isUint32Array: [ + uint32Array, stealthyUint32Array, + ], + isInt8Array: [ + int8Array, stealthyInt8Array, + ], + isInt16Array: [ + int16Array, stealthyInt16Array, + ], + isInt32Array: [ + int32Array, stealthyInt32Array, + ], + isFloat32Array: [ + float32Array, stealthyFloat32Array, + ], + isFloat64Array: [ + float64Array, stealthyFloat64Array, + ], + isBigInt64Array: [ + bigInt64Array, stealthyBigInt64Array, + ], + isBigUint64Array: [ + bigUint64Array, stealthyBigUint64Array, + ] + }; + + for (const testedFunc of Object.keys(expected)) { + const func = types[testedFunc]; + const yup = []; + for (const value of all) { + if (func(value)) { + yup.push(value); + } + } + console.log('Testing', testedFunc); + assert.deepStrictEqual(yup, expected[testedFunc]); + } +} + +// TODO(wafuwafu13): Implement "vm" +// (async () => { +// const m = new vm.SourceTextModule(''); +// await m.link(() => 0); +// await m.evaluate(); +// assert.ok(types.isModuleNamespaceObject(m.namespace)); +// })().then(common.mustCall()); + +{ + // eslint-disable-next-line node-core/crypto-check + if (common.hasCrypto) { + const crypto = require('crypto'); + assert.ok(!types.isKeyObject(crypto.createHash('sha1'))); + } + assert.ok(!types.isCryptoKey()); + assert.ok(!types.isKeyObject()); +} diff --git a/tests/node_compat/test/parallel/test-util.js b/tests/node_compat/test/parallel/test-util.js new file mode 100644 index 000000000..eaffc7f6d --- /dev/null +++ b/tests/node_compat/test/parallel/test-util.js @@ -0,0 +1,202 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +// Flags: --expose-internals +const common = require('../common'); +const assert = require('assert'); +const util = require('util'); +const errors = require('internal/errors'); +// TODO(wafuwafu13): Enable this when "vm" is ready. +// const context = require('vm').runInNewContext; + +// isArray +assert.strictEqual(util.isArray([]), true); +assert.strictEqual(util.isArray(Array()), true); +assert.strictEqual(util.isArray(new Array()), true); +assert.strictEqual(util.isArray(new Array(5)), true); +assert.strictEqual(util.isArray(new Array('with', 'some', 'entries')), true); +// TODO(wafuwafu13): Enable this when "vm" is ready. +// assert.strictEqual(util.isArray(context('Array')()), true); +assert.strictEqual(util.isArray({}), false); +assert.strictEqual(util.isArray({ push: function() {} }), false); +assert.strictEqual(util.isArray(/regexp/), false); +assert.strictEqual(util.isArray(new Error()), false); +assert.strictEqual(util.isArray(Object.create(Array.prototype)), false); + +// isRegExp +assert.strictEqual(util.isRegExp(/regexp/), true); +assert.strictEqual(util.isRegExp(RegExp(), 'foo'), true); +assert.strictEqual(util.isRegExp(new RegExp()), true); +// TODO(wafuwafu13): Enable this when "vm" is ready. +// assert.strictEqual(util.isRegExp(context('RegExp')()), true); +assert.strictEqual(util.isRegExp({}), false); +assert.strictEqual(util.isRegExp([]), false); +assert.strictEqual(util.isRegExp(new Date()), false); +// TODO(wafuwafu13): Enable this. +assert.strictEqual(util.isRegExp(Object.create(RegExp.prototype)), false); + +// isDate +assert.strictEqual(util.isDate(new Date()), true); +assert.strictEqual(util.isDate(new Date(0), 'foo'), true); +// TODO(wafuwafu13): Enable this when "vm" is ready. +// assert.strictEqual(util.isDate(new (context('Date'))()), true); +assert.strictEqual(util.isDate(Date()), false); +assert.strictEqual(util.isDate({}), false); +assert.strictEqual(util.isDate([]), false); +assert.strictEqual(util.isDate(new Error()), false); +assert.strictEqual(util.isDate(Object.create(Date.prototype)), false); + +// isError +assert.strictEqual(util.isError(new Error()), true); +assert.strictEqual(util.isError(new TypeError()), true); +assert.strictEqual(util.isError(new SyntaxError()), true); +// TODO(wafuwafu13): Enable this when "vm" is ready. +// assert.strictEqual(util.isError(new (context('Error'))()), true); +// assert.strictEqual(util.isError(new (context('TypeError'))()), true); +// assert.strictEqual(util.isError(new (context('SyntaxError'))()), true); +assert.strictEqual(util.isError({}), false); +assert.strictEqual(util.isError({ name: 'Error', message: '' }), false); +assert.strictEqual(util.isError([]), false); +assert.strictEqual(util.isError(Object.create(Error.prototype)), true); + +// isObject +assert.strictEqual(util.isObject({}), true); +assert.strictEqual(util.isObject([]), true); +assert.strictEqual(util.isObject(new Number(3)), true); +assert.strictEqual(util.isObject(Number(4)), false); +assert.strictEqual(util.isObject(1), false); + +// isPrimitive +assert.strictEqual(util.isPrimitive({}), false); +assert.strictEqual(util.isPrimitive(new Error()), false); +assert.strictEqual(util.isPrimitive(new Date()), false); +assert.strictEqual(util.isPrimitive([]), false); +assert.strictEqual(util.isPrimitive(/regexp/), false); +assert.strictEqual(util.isPrimitive(function() {}), false); +assert.strictEqual(util.isPrimitive(new Number(1)), false); +assert.strictEqual(util.isPrimitive(new String('bla')), false); +assert.strictEqual(util.isPrimitive(new Boolean(true)), false); +assert.strictEqual(util.isPrimitive(1), true); +assert.strictEqual(util.isPrimitive('bla'), true); +assert.strictEqual(util.isPrimitive(true), true); +assert.strictEqual(util.isPrimitive(undefined), true); +assert.strictEqual(util.isPrimitive(null), true); +assert.strictEqual(util.isPrimitive(Infinity), true); +assert.strictEqual(util.isPrimitive(NaN), true); +assert.strictEqual(util.isPrimitive(Symbol('symbol')), true); + +// isBuffer +assert.strictEqual(util.isBuffer('foo'), false); +assert.strictEqual(util.isBuffer(Buffer.from('foo')), true); + +// _extend +assert.deepStrictEqual(util._extend({ a: 1 }), { a: 1 }); +assert.deepStrictEqual(util._extend({ a: 1 }, []), { a: 1 }); +assert.deepStrictEqual(util._extend({ a: 1 }, null), { a: 1 }); +assert.deepStrictEqual(util._extend({ a: 1 }, true), { a: 1 }); +assert.deepStrictEqual(util._extend({ a: 1 }, false), { a: 1 }); +assert.deepStrictEqual(util._extend({ a: 1 }, { b: 2 }), { a: 1, b: 2 }); +assert.deepStrictEqual(util._extend({ a: 1, b: 2 }, { b: 3 }), { a: 1, b: 3 }); + +// deprecated +assert.strictEqual(util.isBoolean(true), true); +assert.strictEqual(util.isBoolean(false), true); +assert.strictEqual(util.isBoolean('string'), false); + +assert.strictEqual(util.isNull(null), true); +assert.strictEqual(util.isNull(undefined), false); +assert.strictEqual(util.isNull(), false); +assert.strictEqual(util.isNull('string'), false); + +assert.strictEqual(util.isUndefined(undefined), true); +assert.strictEqual(util.isUndefined(), true); +assert.strictEqual(util.isUndefined(null), false); +assert.strictEqual(util.isUndefined('string'), false); + +assert.strictEqual(util.isNullOrUndefined(null), true); +assert.strictEqual(util.isNullOrUndefined(undefined), true); +assert.strictEqual(util.isNullOrUndefined(), true); +assert.strictEqual(util.isNullOrUndefined('string'), false); + +assert.strictEqual(util.isNumber(42), true); +assert.strictEqual(util.isNumber(), false); +assert.strictEqual(util.isNumber('string'), false); + +assert.strictEqual(util.isString('string'), true); +assert.strictEqual(util.isString(), false); +assert.strictEqual(util.isString(42), false); + +assert.strictEqual(util.isSymbol(Symbol()), true); +assert.strictEqual(util.isSymbol(), false); +assert.strictEqual(util.isSymbol('string'), false); + +assert.strictEqual(util.isFunction(() => {}), true); +assert.strictEqual(util.isFunction(function() {}), true); +assert.strictEqual(util.isFunction(), false); +assert.strictEqual(util.isFunction('string'), false); + +assert.strictEqual(util.toUSVString('string\ud801'), 'string\ufffd'); + +{ + assert.strictEqual(util.types.isNativeError(new Error()), true); + assert.strictEqual(util.types.isNativeError(new TypeError()), true); + assert.strictEqual(util.types.isNativeError(new SyntaxError()), true); + // TODO(wafuwafu13): Enable this when "vm" is ready. + // assert.strictEqual(util.types.isNativeError(new (context('Error'))()), true); + // assert.strictEqual( + // util.types.isNativeError(new (context('TypeError'))()), + // true + // ); + // assert.strictEqual( + // util.types.isNativeError(new (context('SyntaxError'))()), + // true + // ); + assert.strictEqual(util.types.isNativeError({}), false); + assert.strictEqual( + util.types.isNativeError({ name: 'Error', message: '' }), + false + ); + assert.strictEqual(util.types.isNativeError([]), false); + assert.strictEqual( + util.types.isNativeError(Object.create(Error.prototype)), + false + ); + assert.strictEqual( + util.types.isNativeError(new errors.codes.ERR_IPC_CHANNEL_CLOSED()), + true + ); +} + +assert.throws(() => { + util.stripVTControlCharacters({}); +}, { + code: 'ERR_INVALID_ARG_TYPE', + message: 'The "str" argument must be of type string.' + + common.invalidArgTypeHelper({}) +}); diff --git a/tests/node_compat/test/parallel/test-vm-new-script-this-context.js b/tests/node_compat/test/parallel/test-vm-new-script-this-context.js new file mode 100644 index 000000000..9a9d8fb13 --- /dev/null +++ b/tests/node_compat/test/parallel/test-vm-new-script-this-context.js @@ -0,0 +1,75 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const Script = require('vm').Script; + +// Run a string +let script = new Script('\'passed\';'); +const result = script.runInThisContext(script); +assert.strictEqual(result, 'passed'); + +// Thrown error +script = new Script('throw new Error(\'test\');'); +assert.throws(() => { + script.runInThisContext(script); +}, /^Error: test$/); + +global.hello = 5; +script = new Script('hello = 2'); +script.runInThisContext(script); +assert.strictEqual(global.hello, 2); + + +// Pass values +global.code = 'foo = 1;' + + 'bar = 2;' + + 'if (typeof baz !== "undefined") throw new Error("test fail");'; +global.foo = 2; +global.obj = { foo: 0, baz: 3 }; +script = new Script(global.code); +script.runInThisContext(script); +assert.strictEqual(global.obj.foo, 0); +assert.strictEqual(global.bar, 2); +assert.strictEqual(global.foo, 1); + +// Call a function +global.f = function() { global.foo = 100; }; +script = new Script('f()'); +script.runInThisContext(script); +assert.strictEqual(global.foo, 100); + +common.allowGlobals( + global.hello, + global.code, + global.foo, + global.obj, + global.f +); diff --git a/tests/node_compat/test/parallel/test-vm-static-this.js b/tests/node_compat/test/parallel/test-vm-static-this.js new file mode 100644 index 000000000..c6804cfc0 --- /dev/null +++ b/tests/node_compat/test/parallel/test-vm-static-this.js @@ -0,0 +1,72 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +/* eslint-disable strict */ +const common = require('../common'); +const assert = require('assert'); +const vm = require('vm'); + +// Run a string +const result = vm.runInThisContext('\'passed\';'); +assert.strictEqual(result, 'passed'); + +// thrown error +assert.throws(function() { + vm.runInThisContext('throw new Error(\'test\');'); +}, /test/); + +global.hello = 5; +vm.runInThisContext('hello = 2'); +assert.strictEqual(global.hello, 2); + + +// pass values +const code = 'foo = 1;' + + 'bar = 2;' + + 'if (typeof baz !== \'undefined\')' + + 'throw new Error(\'test fail\');'; +global.foo = 2; +global.obj = { foo: 0, baz: 3 }; +/* eslint-disable no-unused-vars */ +const baz = vm.runInThisContext(code); +/* eslint-enable no-unused-vars */ +assert.strictEqual(global.obj.foo, 0); +assert.strictEqual(global.bar, 2); +assert.strictEqual(global.foo, 1); + +// call a function +global.f = function() { global.foo = 100; }; +vm.runInThisContext('f()'); +assert.strictEqual(global.foo, 100); + +common.allowGlobals( + global.hello, + global.foo, + global.obj, + global.f +); diff --git a/tests/node_compat/test/parallel/test-webcrypto-sign-verify.js b/tests/node_compat/test/parallel/test-webcrypto-sign-verify.js new file mode 100644 index 000000000..23df883ee --- /dev/null +++ b/tests/node_compat/test/parallel/test-webcrypto-sign-verify.js @@ -0,0 +1,154 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +'use strict'; + +const common = require('../common'); + +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const { subtle } = require('crypto').webcrypto; + +// This is only a partial test. The WebCrypto Web Platform Tests +// will provide much greater coverage. + +// Test Sign/Verify RSASSA-PKCS1-v1_5 +{ + async function test(data) { + const ec = new TextEncoder(); + const { publicKey, privateKey } = await subtle.generateKey({ + name: 'RSASSA-PKCS1-v1_5', + modulusLength: 1024, + publicExponent: new Uint8Array([1, 0, 1]), + hash: 'SHA-256' + }, true, ['sign', 'verify']); + + const signature = await subtle.sign({ + name: 'RSASSA-PKCS1-v1_5' + }, privateKey, ec.encode(data)); + + assert(await subtle.verify({ + name: 'RSASSA-PKCS1-v1_5' + }, publicKey, signature, ec.encode(data))); + } + + test('hello world').then(common.mustCall()); +} + +// Test Sign/Verify RSA-PSS +{ + async function test(data) { + const ec = new TextEncoder(); + const { publicKey, privateKey } = await subtle.generateKey({ + name: 'RSA-PSS', + modulusLength: 4096, + publicExponent: new Uint8Array([1, 0, 1]), + hash: 'SHA-256' + }, true, ['sign', 'verify']); + + const signature = await subtle.sign({ + name: 'RSA-PSS', + saltLength: 256, + }, privateKey, ec.encode(data)); + + assert(await subtle.verify({ + name: 'RSA-PSS', + saltLength: 256, + }, publicKey, signature, ec.encode(data))); + } + + test('hello world').then(common.mustCall()); +} + +// Test Sign/Verify ECDSA +{ + async function test(data) { + const ec = new TextEncoder(); + const { publicKey, privateKey } = await subtle.generateKey({ + name: 'ECDSA', + namedCurve: 'P-384', + }, true, ['sign', 'verify']); + + const signature = await subtle.sign({ + name: 'ECDSA', + hash: 'SHA-384', + }, privateKey, ec.encode(data)); + + assert(await subtle.verify({ + name: 'ECDSA', + hash: 'SHA-384', + }, publicKey, signature, ec.encode(data))); + } + + test('hello world').then(common.mustCall()); +} + +// Test Sign/Verify HMAC +{ + async function test(data) { + const ec = new TextEncoder(); + + const key = await subtle.generateKey({ + name: 'HMAC', + length: 256, + hash: 'SHA-256' + }, true, ['sign', 'verify']); + + const signature = await subtle.sign({ + name: 'HMAC', + }, key, ec.encode(data)); + + assert(await subtle.verify({ + name: 'HMAC', + }, key, signature, ec.encode(data))); + } + + test('hello world').then(common.mustCall()); +} + +// Test Sign/Verify Ed25519 +{ + async function test(data) { + const ec = new TextEncoder(); + const { publicKey, privateKey } = await subtle.generateKey({ + name: 'Ed25519', + }, true, ['sign', 'verify']); + + const signature = await subtle.sign({ + name: 'Ed25519', + }, privateKey, ec.encode(data)); + + assert(await subtle.verify({ + name: 'Ed25519', + }, publicKey, signature, ec.encode(data))); + } + + test('hello world').then(common.mustCall()); +} + +// Test Sign/Verify Ed448 +// TODO(cjihrig): Pending support in Deno core. +// { +// async function test(data) { +// const ec = new TextEncoder(); +// const { publicKey, privateKey } = await subtle.generateKey({ +// name: 'Ed448', +// }, true, ['sign', 'verify']); + +// const signature = await subtle.sign({ +// name: 'Ed448', +// }, privateKey, ec.encode(data)); + +// assert(await subtle.verify({ +// name: 'Ed448', +// }, publicKey, signature, ec.encode(data))); +// } + +// test('hello world').then(common.mustCall()); +// } diff --git a/tests/node_compat/test/parallel/test-whatwg-encoding-custom-api-basics.js b/tests/node_compat/test/parallel/test-whatwg-encoding-custom-api-basics.js new file mode 100644 index 000000000..e423c25d0 --- /dev/null +++ b/tests/node_compat/test/parallel/test-whatwg-encoding-custom-api-basics.js @@ -0,0 +1,68 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +// From: https://github.com/w3c/web-platform-tests/blob/master/encoding/api-basics.html +// This is the part that can be run without ICU + +require('../common'); + +const assert = require('assert'); + +function testDecodeSample(encoding, string, bytes) { + assert.strictEqual( + new TextDecoder(encoding).decode(new Uint8Array(bytes)), + string); + assert.strictEqual( + new TextDecoder(encoding).decode(new Uint8Array(bytes).buffer), + string); +} + +// `z` (ASCII U+007A), cent (Latin-1 U+00A2), CJK water (BMP U+6C34), +// G-Clef (non-BMP U+1D11E), PUA (BMP U+F8FF), PUA (non-BMP U+10FFFD) +// byte-swapped BOM (non-character U+FFFE) +const sample = 'z\xA2\u6C34\uD834\uDD1E\uF8FF\uDBFF\uDFFD\uFFFE'; + +{ + const encoding = 'utf-8'; + const string = sample; + const bytes = [ + 0x7A, 0xC2, 0xA2, 0xE6, 0xB0, 0xB4, + 0xF0, 0x9D, 0x84, 0x9E, 0xEF, 0xA3, + 0xBF, 0xF4, 0x8F, 0xBF, 0xBD, 0xEF, + 0xBF, 0xBE, + ]; + const encoded = new TextEncoder().encode(string); + assert.deepStrictEqual([].slice.call(encoded), bytes); + assert.strictEqual( + new TextDecoder(encoding).decode(new Uint8Array(bytes)), + string); + assert.strictEqual( + new TextDecoder(encoding).decode(new Uint8Array(bytes).buffer), + string); +} + +testDecodeSample( + 'utf-16le', + sample, + [ + 0x7A, 0x00, 0xA2, 0x00, 0x34, 0x6C, + 0x34, 0xD8, 0x1E, 0xDD, 0xFF, 0xF8, + 0xFF, 0xDB, 0xFD, 0xDF, 0xFE, 0xFF, + ] +); + +testDecodeSample( + 'utf-16', + sample, + [ + 0x7A, 0x00, 0xA2, 0x00, 0x34, 0x6C, + 0x34, 0xD8, 0x1E, 0xDD, 0xFF, 0xF8, + 0xFF, 0xDB, 0xFD, 0xDF, 0xFE, 0xFF, + ] +); diff --git a/tests/node_compat/test/parallel/test-whatwg-encoding-custom-textdecoder-ignorebom.js b/tests/node_compat/test/parallel/test-whatwg-encoding-custom-textdecoder-ignorebom.js new file mode 100644 index 000000000..58488d25d --- /dev/null +++ b/tests/node_compat/test/parallel/test-whatwg-encoding-custom-textdecoder-ignorebom.js @@ -0,0 +1,37 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +// From: https://github.com/w3c/web-platform-tests/blob/7f567fa29c/encoding/textdecoder-ignorebom.html +// This is the part that can be run without ICU + +require('../common'); + +const assert = require('assert'); + +const cases = [ + { + encoding: 'utf-8', + bytes: [0xEF, 0xBB, 0xBF, 0x61, 0x62, 0x63] + }, + { + encoding: 'utf-16le', + bytes: [0xFF, 0xFE, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00] + }, +]; + +cases.forEach((testCase) => { + const BOM = '\uFEFF'; + let decoder = new TextDecoder(testCase.encoding, { ignoreBOM: true }); + const bytes = new Uint8Array(testCase.bytes); + assert.strictEqual(decoder.decode(bytes), `${BOM}abc`); + decoder = new TextDecoder(testCase.encoding, { ignoreBOM: false }); + assert.strictEqual(decoder.decode(bytes), 'abc'); + decoder = new TextDecoder(testCase.encoding); + assert.strictEqual(decoder.decode(bytes), 'abc'); +}); diff --git a/tests/node_compat/test/parallel/test-whatwg-encoding-custom-textdecoder-streaming.js b/tests/node_compat/test/parallel/test-whatwg-encoding-custom-textdecoder-streaming.js new file mode 100644 index 000000000..ef9cecc0f --- /dev/null +++ b/tests/node_compat/test/parallel/test-whatwg-encoding-custom-textdecoder-streaming.js @@ -0,0 +1,45 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +// From: https://github.com/w3c/web-platform-tests/blob/fa9436d12c/encoding/textdecoder-streaming.html +// This is the part that can be run without ICU + +require('../common'); + +const assert = require('assert'); + +const string = + '\x00123ABCabc\x80\xFF\u0100\u1000\uFFFD\uD800\uDC00\uDBFF\uDFFF'; +const octets = { + 'utf-8': [ + 0x00, 0x31, 0x32, 0x33, 0x41, 0x42, 0x43, 0x61, 0x62, 0x63, 0xc2, 0x80, + 0xc3, 0xbf, 0xc4, 0x80, 0xe1, 0x80, 0x80, 0xef, 0xbf, 0xbd, 0xf0, 0x90, + 0x80, 0x80, 0xf4, 0x8f, 0xbf, 0xbf], + 'utf-16le': [ + 0x00, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x41, 0x00, 0x42, 0x00, + 0x43, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x80, 0x00, 0xFF, 0x00, + 0x00, 0x01, 0x00, 0x10, 0xFD, 0xFF, 0x00, 0xD8, 0x00, 0xDC, 0xFF, 0xDB, + 0xFF, 0xDF] +}; + +Object.keys(octets).forEach((encoding) => { + for (let len = 1; len <= 5; ++len) { + const encoded = octets[encoding]; + const decoder = new TextDecoder(encoding); + let out = ''; + for (let i = 0; i < encoded.length; i += len) { + const sub = []; + for (let j = i; j < encoded.length && j < i + len; ++j) + sub.push(encoded[j]); + out += decoder.decode(new Uint8Array(sub), { stream: true }); + } + out += decoder.decode(); + assert.strictEqual(out, string); + } +}); diff --git a/tests/node_compat/test/parallel/test-whatwg-events-add-event-listener-options-passive.js b/tests/node_compat/test/parallel/test-whatwg-events-add-event-listener-options-passive.js new file mode 100644 index 000000000..e2bc96139 --- /dev/null +++ b/tests/node_compat/test/parallel/test-whatwg-events-add-event-listener-options-passive.js @@ -0,0 +1,72 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); + +// Manually converted from https://github.com/web-platform-tests/wpt/blob/master/dom/events/AddEventListenerOptions-passive.html +// in order to define the `document` ourselves + +const { + fail, + ok, + strictEqual +} = require('assert'); + +{ + const document = new EventTarget(); + let supportsPassive = false; + const query_options = { + get passive() { + supportsPassive = true; + return false; + }, + get dummy() { + fail('dummy value getter invoked'); + return false; + } + }; + + document.addEventListener('test_event', null, query_options); + ok(supportsPassive); + + supportsPassive = false; + document.removeEventListener('test_event', null, query_options); + strictEqual(supportsPassive, false); +} +{ + function testPassiveValue(optionsValue, expectedDefaultPrevented) { + const document = new EventTarget(); + let defaultPrevented; + function handler(e) { + if (e.defaultPrevented) { + fail('Event prematurely marked defaultPrevented'); + } + e.preventDefault(); + defaultPrevented = e.defaultPrevented; + } + document.addEventListener('test', handler, optionsValue); + // TODO the WHATWG test is more extensive here and tests dispatching on + // document.body, if we ever support getParent we should amend this + const ev = new Event('test', { bubbles: true, cancelable: true }); + const uncanceled = document.dispatchEvent(ev); + + strictEqual(defaultPrevented, expectedDefaultPrevented); + strictEqual(uncanceled, !expectedDefaultPrevented); + + document.removeEventListener('test', handler, optionsValue); + } + testPassiveValue(undefined, true); + testPassiveValue({}, true); + testPassiveValue({ passive: false }, true); + + common.skip('TODO: passive listeners is still broken'); + testPassiveValue({ passive: 1 }, false); + testPassiveValue({ passive: true }, false); + testPassiveValue({ passive: 0 }, true); +} diff --git a/tests/node_compat/test/parallel/test-whatwg-events-add-event-listener-options-signal.js b/tests/node_compat/test/parallel/test-whatwg-events-add-event-listener-options-signal.js new file mode 100644 index 000000000..80d09c4b7 --- /dev/null +++ b/tests/node_compat/test/parallel/test-whatwg-events-add-event-listener-options-signal.js @@ -0,0 +1,166 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); + +const { + strictEqual, +} = require('assert'); + +// Manually ported from: wpt@dom/events/AddEventListenerOptions-signal.any.js + +{ + // Passing an AbortSignal to addEventListener does not prevent + // removeEventListener + let count = 0; + function handler() { + count++; + } + const et = new EventTarget(); + const controller = new AbortController(); + et.addEventListener('test', handler, { signal: controller.signal }); + et.dispatchEvent(new Event('test')); + strictEqual(count, 1, 'Adding a signal still adds a listener'); + et.dispatchEvent(new Event('test')); + strictEqual(count, 2, 'The listener was not added with the once flag'); + controller.abort(); + et.dispatchEvent(new Event('test')); + strictEqual(count, 2, 'Aborting on the controller removes the listener'); + // See: https://github.com/nodejs/node/pull/37696 , adding an event listener + // should always return undefined. + strictEqual( + et.addEventListener('test', handler, { signal: controller.signal }), + undefined); + et.dispatchEvent(new Event('test')); + strictEqual(count, 2, 'Passing an aborted signal never adds the handler'); +} + +{ + // Passing an AbortSignal to addEventListener works with the once flag + let count = 0; + function handler() { + count++; + } + const et = new EventTarget(); + const controller = new AbortController(); + et.addEventListener('test', handler, { signal: controller.signal }); + et.removeEventListener('test', handler); + et.dispatchEvent(new Event('test')); + strictEqual(count, 0, 'The listener was still removed'); +} + +{ + // Removing a once listener works with a passed signal + let count = 0; + function handler() { + count++; + } + const et = new EventTarget(); + const controller = new AbortController(); + const options = { signal: controller.signal, once: true }; + et.addEventListener('test', handler, options); + controller.abort(); + et.dispatchEvent(new Event('test')); + strictEqual(count, 0, 'The listener was still removed'); +} + +{ + let count = 0; + function handler() { + count++; + } + const et = new EventTarget(); + const controller = new AbortController(); + const options = { signal: controller.signal, once: true }; + et.addEventListener('test', handler, options); + et.removeEventListener('test', handler); + et.dispatchEvent(new Event('test')); + strictEqual(count, 0, 'The listener was still removed'); +} + +{ + // Passing an AbortSignal to multiple listeners + let count = 0; + function handler() { + count++; + } + const et = new EventTarget(); + const controller = new AbortController(); + const options = { signal: controller.signal, once: true }; + et.addEventListener('first', handler, options); + et.addEventListener('second', handler, options); + controller.abort(); + et.dispatchEvent(new Event('first')); + et.dispatchEvent(new Event('second')); + strictEqual(count, 0, 'The listener was still removed'); +} + +{ + // Passing an AbortSignal to addEventListener works with the capture flag + let count = 0; + function handler() { + count++; + } + const et = new EventTarget(); + const controller = new AbortController(); + const options = { signal: controller.signal, capture: true }; + et.addEventListener('test', handler, options); + controller.abort(); + et.dispatchEvent(new Event('test')); + strictEqual(count, 0, 'The listener was still removed'); +} + +{ + // Aborting from a listener does not call future listeners + let count = 0; + function handler() { + count++; + } + const et = new EventTarget(); + const controller = new AbortController(); + const options = { signal: controller.signal }; + et.addEventListener('test', () => { + controller.abort(); + }, options); + et.addEventListener('test', handler, options); + et.dispatchEvent(new Event('test')); + strictEqual(count, 0, 'The listener was still removed'); +} + +{ + // Adding then aborting a listener in another listener does not call it + let count = 0; + function handler() { + count++; + } + const et = new EventTarget(); + const controller = new AbortController(); + et.addEventListener('test', () => { + et.addEventListener('test', handler, { signal: controller.signal }); + controller.abort(); + }, { signal: controller.signal }); + et.dispatchEvent(new Event('test')); + strictEqual(count, 0, 'The listener was still removed'); +} + +{ + // Aborting from a nested listener should remove it + const et = new EventTarget(); + const ac = new AbortController(); + let count = 0; + et.addEventListener('foo', () => { + et.addEventListener('foo', () => { + count++; + if (count > 5) ac.abort(); + et.dispatchEvent(new Event('foo')); + }, { signal: ac.signal }); + et.dispatchEvent(new Event('foo')); + }, { once: true }); + et.dispatchEvent(new Event('foo')); +} diff --git a/tests/node_compat/test/parallel/test-whatwg-events-customevent.js b/tests/node_compat/test/parallel/test-whatwg-events-customevent.js new file mode 100644 index 000000000..749c838de --- /dev/null +++ b/tests/node_compat/test/parallel/test-whatwg-events-customevent.js @@ -0,0 +1,40 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); + +const { strictEqual, throws, equal } = require('assert'); + +// Manually converted from https://github.com/web-platform-tests/wpt/blob/master/dom/events/CustomEvent.html +// in order to define the `document` ourselves + +{ + const type = 'foo'; + const target = new EventTarget(); + + target.addEventListener(type, common.mustCall((evt) => { + strictEqual(evt.type, type); + })); + + target.dispatchEvent(new Event(type)); +} + +{ + throws(() => { + new Event(); + }, TypeError); +} + +{ + const event = new Event('foo'); + equal(event.type, 'foo'); + equal(event.bubbles, false); + equal(event.cancelable, false); + equal(event.detail, null); +} diff --git a/tests/node_compat/test/parallel/test-whatwg-url-custom-deepequal.js b/tests/node_compat/test/parallel/test-whatwg-url-custom-deepequal.js new file mode 100644 index 000000000..e33590530 --- /dev/null +++ b/tests/node_compat/test/parallel/test-whatwg-url-custom-deepequal.js @@ -0,0 +1,25 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +// This tests that the internal flags in URL objects are consistent, as manifest +// through assert libraries. +// See https://github.com/nodejs/node/issues/24211 + +// Tests below are not from WPT. + +require('../common'); +const assert = require('assert'); + +assert.deepStrictEqual( + new URL('./foo', 'https://example.com/'), + new URL('https://example.com/foo') +); +assert.deepStrictEqual( + new URL('./foo', 'https://user:pass@example.com/'), + new URL('https://user:pass@example.com/foo') +); diff --git a/tests/node_compat/test/parallel/test-whatwg-url-custom-global.js b/tests/node_compat/test/parallel/test-whatwg-url-custom-global.js new file mode 100644 index 000000000..b7880d8c2 --- /dev/null +++ b/tests/node_compat/test/parallel/test-whatwg-url-custom-global.js @@ -0,0 +1,33 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +// Tests below are not from WPT. + +require('../common'); +const assert = require('assert'); + +assert.deepStrictEqual( + Object.getOwnPropertyDescriptor(global, 'URL'), + { + value: URL, + writable: true, + configurable: true, + enumerable: false + } +); + +assert.deepStrictEqual( + Object.getOwnPropertyDescriptor(global, 'URLSearchParams'), + { + value: URLSearchParams, + writable: true, + configurable: true, + enumerable: false + } +); diff --git a/tests/node_compat/test/parallel/test-whatwg-url-custom-href-side-effect.js b/tests/node_compat/test/parallel/test-whatwg-url-custom-href-side-effect.js new file mode 100644 index 000000000..de175e357 --- /dev/null +++ b/tests/node_compat/test/parallel/test-whatwg-url-custom-href-side-effect.js @@ -0,0 +1,22 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +// Tests below are not from WPT. +require('../common'); +const assert = require('assert'); + +const ref = new URL('http://example.com/path'); +const url = new URL('http://example.com/path'); +assert.throws(() => { + url.href = ''; +}, { + name: 'TypeError' +}); + +assert.deepStrictEqual(url, ref); diff --git a/tests/node_compat/test/parallel/test-whatwg-url-custom-tostringtag.js b/tests/node_compat/test/parallel/test-whatwg-url-custom-tostringtag.js new file mode 100644 index 000000000..add70bc34 --- /dev/null +++ b/tests/node_compat/test/parallel/test-whatwg-url-custom-tostringtag.js @@ -0,0 +1,39 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +// Tests below are not from WPT. + +require('../common'); +const assert = require('assert'); + +const toString = Object.prototype.toString; + +const url = new URL('http://example.org'); +const sp = url.searchParams; +const spIterator = sp.entries(); + +const test = [ + [url, 'URL'], + [sp, 'URLSearchParams'], + [spIterator, 'URLSearchParams Iterator'], + // Web IDL spec says we have to return 'URLPrototype', but it is too + // expensive to implement; therefore, use Chrome's behavior for now, until + // spec is changed. + [Object.getPrototypeOf(url), 'URL'], + [Object.getPrototypeOf(sp), 'URLSearchParams'], + [Object.getPrototypeOf(spIterator), 'URLSearchParams Iterator'], +]; + +test.forEach(([obj, expected]) => { + assert.strictEqual(obj[Symbol.toStringTag], expected, + `${obj[Symbol.toStringTag]} !== ${expected}`); + const str = toString.call(obj); + assert.strictEqual(str, `[object ${expected}]`, + `${str} !== [object ${expected}]`); +}); diff --git a/tests/node_compat/test/parallel/test-whatwg-url-override-hostname.js b/tests/node_compat/test/parallel/test-whatwg-url-override-hostname.js new file mode 100644 index 000000000..1fcdefdf7 --- /dev/null +++ b/tests/node_compat/test/parallel/test-whatwg-url-override-hostname.js @@ -0,0 +1,27 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const assert = require('assert'); + +{ + const url = new (class extends URL { get hostname() { return 'bar.com'; } })('http://foo.com/'); + assert.strictEqual(url.href, 'http://foo.com/'); + assert.strictEqual(url.toString(), 'http://foo.com/'); + assert.strictEqual(url.toJSON(), 'http://foo.com/'); + assert.strictEqual(url.hash, ''); + assert.strictEqual(url.host, 'foo.com'); + assert.strictEqual(url.hostname, 'bar.com'); + assert.strictEqual(url.origin, 'http://foo.com'); + assert.strictEqual(url.password, ''); + assert.strictEqual(url.protocol, 'http:'); + assert.strictEqual(url.username, ''); + assert.strictEqual(url.search, ''); + assert.strictEqual(url.searchParams.toString(), ''); +} diff --git a/tests/node_compat/test/parallel/test-whatwg-url-properties.js b/tests/node_compat/test/parallel/test-whatwg-url-properties.js new file mode 100644 index 000000000..8a4f4e57b --- /dev/null +++ b/tests/node_compat/test/parallel/test-whatwg-url-properties.js @@ -0,0 +1,111 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +'use strict'; +require('../common'); +const assert = require('assert'); +const { URL, URLSearchParams } = require('url'); + +[ + { name: 'toString' }, + { name: 'toJSON' }, + // Deno's URL doesn't support nodejs custom inspect + // { name: Symbol.for('nodejs.util.inspect.custom') }, +].forEach(({ name }) => { + testMethod(URL.prototype, name); +}); + +[ + { name: 'href' }, + { name: 'protocol' }, + { name: 'username' }, + { name: 'password' }, + { name: 'host' }, + { name: 'hostname' }, + { name: 'port' }, + { name: 'pathname' }, + { name: 'search' }, + { name: 'hash' }, + { name: 'origin', readonly: true }, + { name: 'searchParams', readonly: true }, +].forEach(({ name, readonly = false }) => { + testAccessor(URL.prototype, name, readonly); +}); + +[ + { name: 'append' }, + { name: 'delete' }, + { name: 'get' }, + { name: 'getAll' }, + { name: 'has' }, + { name: 'set' }, + { name: 'sort' }, + { name: 'entries' }, + { name: 'forEach' }, + { name: 'keys' }, + { name: 'values' }, + { name: 'toString' }, + { name: Symbol.iterator, methodName: 'entries' }, + // Deno's URL doesn't support nodejs custom inspect + // { name: Symbol.for('nodejs.util.inspect.custom') }, +].forEach(({ name, methodName }) => { + testMethod(URLSearchParams.prototype, name, methodName); +}); + +function stringifyName(name) { + if (typeof name === 'symbol') { + const { description } = name; + if (description === undefined) { + return ''; + } + return `[${description}]`; + } + + return name; +} + +function testMethod(target, name, methodName = stringifyName(name)) { + const desc = Object.getOwnPropertyDescriptor(target, name); + assert.notStrictEqual(desc, undefined); + assert.strictEqual(desc.enumerable, typeof name === 'string'); + + const { value } = desc; + assert.strictEqual(typeof value, 'function'); + assert.strictEqual(value.name, methodName); + /* This can't pass with Deno's URL/URLSearchParams + assert.strictEqual( + Object.prototype.hasOwnProperty.call(value, 'prototype'), + false, + ); + */ +} + +function testAccessor(target, name, readonly = false) { + const desc = Object.getOwnPropertyDescriptor(target, name); + assert.notStrictEqual(desc, undefined); + assert.strictEqual(desc.enumerable, typeof name === 'string'); + + const methodName = stringifyName(name); + const { get, set } = desc; + assert.strictEqual(typeof get, 'function'); + assert.strictEqual(get.name, `get ${methodName}`); + assert.strictEqual( + Object.prototype.hasOwnProperty.call(get, 'prototype'), + false, + ); + + if (readonly) { + assert.strictEqual(set, undefined); + } else { + assert.strictEqual(typeof set, 'function'); + assert.strictEqual(set.name, `set ${methodName}`); + assert.strictEqual( + Object.prototype.hasOwnProperty.call(set, 'prototype'), + false, + ); + } +} diff --git a/tests/node_compat/test/parallel/test-zlib-close-after-error.js b/tests/node_compat/test/parallel/test-zlib-close-after-error.js new file mode 100644 index 000000000..55f1d6b02 --- /dev/null +++ b/tests/node_compat/test/parallel/test-zlib-close-after-error.js @@ -0,0 +1,23 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +// https://github.com/nodejs/node/issues/6034 + +const common = require('../common'); +const assert = require('assert'); +const zlib = require('zlib'); + +const decompress = zlib.createGunzip(15); + +decompress.on('error', common.mustCall((err) => { + assert.strictEqual(decompress._closed, true); + decompress.close(); +})); + +assert.strictEqual(decompress._closed, false); +decompress.write('something invalid'); diff --git a/tests/node_compat/test/parallel/test-zlib-close-after-write.js b/tests/node_compat/test/parallel/test-zlib-close-after-write.js new file mode 100644 index 000000000..94fa4eb20 --- /dev/null +++ b/tests/node_compat/test/parallel/test-zlib-close-after-write.js @@ -0,0 +1,37 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const zlib = require('zlib'); + +zlib.gzip('hello', common.mustCall((err, out) => { + const unzip = zlib.createGunzip(); + unzip.write(out); + unzip.close(common.mustCall()); +})); diff --git a/tests/node_compat/test/parallel/test-zlib-convenience-methods.js b/tests/node_compat/test/parallel/test-zlib-convenience-methods.js new file mode 100644 index 000000000..cf6694b1f --- /dev/null +++ b/tests/node_compat/test/parallel/test-zlib-convenience-methods.js @@ -0,0 +1,144 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +// Test convenience methods with and without options supplied + +const common = require('../common'); +const assert = require('assert'); +const zlib = require('zlib'); + +// Must be a multiple of 4 characters in total to test all ArrayBufferView +// types. +const expectStr = 'blah'.repeat(8); +const expectBuf = Buffer.from(expectStr); + +const opts = { + level: 9, + chunkSize: 1024, +}; + +const optsInfo = { + info: true +}; + +for (const [type, expect] of [ + ['string', expectStr], + ['Buffer', expectBuf], + // FIXME(bartlomieju): + // ...common.getBufferSources(expectBuf).map((obj) => + // [obj[Symbol.toStringTag], obj] + // ), +]) { + for (const method of [ + ['gzip', 'gunzip', 'Gzip', 'Gunzip'], + ['gzip', 'unzip', 'Gzip', 'Unzip'], + ['deflate', 'inflate', 'Deflate', 'Inflate'], + ['deflateRaw', 'inflateRaw', 'DeflateRaw', 'InflateRaw'], + // FIXME(bartlomieju): + // ['brotliCompress', 'brotliDecompress', + // 'BrotliCompress', 'BrotliDecompress'], + ]) { + zlib[method[0]](expect, opts, common.mustCall((err, result) => { + zlib[method[1]](result, opts, common.mustCall((err, result) => { + assert.strictEqual(result.toString(), expectStr, + `Should get original string after ${method[0]}/` + + `${method[1]} ${type} with options.`); + })); + })); + + zlib[method[0]](expect, common.mustCall((err, result) => { + zlib[method[1]](result, common.mustCall((err, result) => { + assert.strictEqual(result.toString(), expectStr, + `Should get original string after ${method[0]}/` + + `${method[1]} ${type} without options.`); + })); + })); + + // FIXME(bartlomieju): + // zlib[method[0]](expect, optsInfo, common.mustCall((err, result) => { + // assert.ok(result.engine instanceof zlib[method[2]], + // `Should get engine ${method[2]} after ${method[0]} ` + + // `${type} with info option.`); + + // const compressed = result.buffer; + // zlib[method[1]](compressed, optsInfo, common.mustCall((err, result) => { + // assert.strictEqual(result.buffer.toString(), expectStr, + // `Should get original string after ${method[0]}/` + + // `${method[1]} ${type} with info option.`); + // assert.ok(result.engine instanceof zlib[method[3]], + // `Should get engine ${method[3]} after ${method[0]} ` + + // `${type} with info option.`); + // })); + // })); + + { + const compressed = zlib[`${method[0]}Sync`](expect, opts); + const decompressed = zlib[`${method[1]}Sync`](compressed, opts); + assert.strictEqual(decompressed.toString(), expectStr, + `Should get original string after ${method[0]}Sync/` + + `${method[1]}Sync ${type} with options.`); + } + + + { + const compressed = zlib[`${method[0]}Sync`](expect); + const decompressed = zlib[`${method[1]}Sync`](compressed); + assert.strictEqual(decompressed.toString(), expectStr, + `Should get original string after ${method[0]}Sync/` + + `${method[1]}Sync ${type} without options.`); + } + + // FIXME(bartlomieju): + // { + // const compressed = zlib[`${method[0]}Sync`](expect, optsInfo); + // assert.ok(compressed.engine instanceof zlib[method[2]], + // `Should get engine ${method[2]} after ${method[0]} ` + + // `${type} with info option.`); + // const decompressed = zlib[`${method[1]}Sync`](compressed.buffer, + // optsInfo); + // assert.strictEqual(decompressed.buffer.toString(), expectStr, + // `Should get original string after ${method[0]}Sync/` + + // `${method[1]}Sync ${type} without options.`); + // assert.ok(decompressed.engine instanceof zlib[method[3]], + // `Should get engine ${method[3]} after ${method[0]} ` + + // `${type} with info option.`); + // } + } +} + +// FIXME(bartlomieju): +// assert.throws( +// () => zlib.gzip('abc'), +// { +// code: 'ERR_INVALID_ARG_TYPE', +// name: 'TypeError', +// message: 'The "callback" argument must be of type function. ' + +// 'Received undefined' +// } +// ); diff --git a/tests/node_compat/test/parallel/test-zlib-deflate-raw-inherits.js b/tests/node_compat/test/parallel/test-zlib-deflate-raw-inherits.js new file mode 100644 index 000000000..58c069c74 --- /dev/null +++ b/tests/node_compat/test/parallel/test-zlib-deflate-raw-inherits.js @@ -0,0 +1,34 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); +const { DeflateRaw } = require('zlib'); +const { Readable } = require('stream'); + +// Validates that zlib.DeflateRaw can be inherited +// with Object.setPrototypeOf + +function NotInitialized(options) { + DeflateRaw.call(this, options); + this.prop = true; +} +Object.setPrototypeOf(NotInitialized.prototype, DeflateRaw.prototype); +Object.setPrototypeOf(NotInitialized, DeflateRaw); + +const dest = new NotInitialized(); + +const read = new Readable({ + read() { + this.push(Buffer.from('a test string')); + this.push(null); + } +}); + +read.pipe(dest); +dest.resume(); diff --git a/tests/node_compat/test/parallel/test-zlib-destroy-pipe.js b/tests/node_compat/test/parallel/test-zlib-destroy-pipe.js new file mode 100644 index 000000000..274068f9f --- /dev/null +++ b/tests/node_compat/test/parallel/test-zlib-destroy-pipe.js @@ -0,0 +1,28 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +const common = require('../common'); +const zlib = require('zlib'); +const { Writable } = require('stream'); + +// Verify that the zlib transform does not error in case +// it is destroyed with data still in flight + +const ts = zlib.createGzip(); + +const ws = new Writable({ + write: common.mustCall((chunk, enc, cb) => { + setImmediate(cb); + ts.destroy(); + }) +}); + +const buf = Buffer.allocUnsafe(1024 * 1024 * 20); +ts.end(buf); +ts.pipe(ws); diff --git a/tests/node_compat/test/parallel/test-zlib-empty-buffer.js b/tests/node_compat/test/parallel/test-zlib-empty-buffer.js new file mode 100644 index 000000000..2281ba88e --- /dev/null +++ b/tests/node_compat/test/parallel/test-zlib-empty-buffer.js @@ -0,0 +1,35 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +'use strict'; +const common = require('../common'); +const zlib = require('zlib'); +const { inspect, promisify } = require('util'); +const assert = require('assert'); +const emptyBuffer = Buffer.alloc(0); + +(async function() { + for (const [ compress, decompress, method ] of [ + [ zlib.deflateRawSync, zlib.inflateRawSync, 'raw sync' ], + [ zlib.deflateSync, zlib.inflateSync, 'deflate sync' ], + [ zlib.gzipSync, zlib.gunzipSync, 'gzip sync' ], + // FIXME(bartlomieju): + // [ zlib.brotliCompressSync, zlib.brotliDecompressSync, 'br sync' ], + [ promisify(zlib.deflateRaw), promisify(zlib.inflateRaw), 'raw' ], + [ promisify(zlib.deflate), promisify(zlib.inflate), 'deflate' ], + [ promisify(zlib.gzip), promisify(zlib.gunzip), 'gzip' ], + // FIXME(bartlomieju): + // [ promisify(zlib.brotliCompress), promisify(zlib.brotliDecompress), 'br' ], + ]) { + const compressed = await compress(emptyBuffer); + const decompressed = await decompress(compressed); + assert.deepStrictEqual( + emptyBuffer, decompressed, + `Expected ${inspect(compressed)} to match ${inspect(decompressed)} ` + + `to match for ${method}`); + } +})().then(common.mustCall()); diff --git a/tests/node_compat/test/parallel/test-zlib-from-string.js b/tests/node_compat/test/parallel/test-zlib-from-string.js new file mode 100644 index 000000000..dc238220b --- /dev/null +++ b/tests/node_compat/test/parallel/test-zlib-from-string.js @@ -0,0 +1,90 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +// Test compressing and uncompressing a string with zlib + +const common = require('../common'); +const assert = require('assert'); +const zlib = require('zlib'); + +const inputString = 'ΩΩLorem ipsum dolor sit amet, consectetur adipiscing eli' + + 't. Morbi faucibus, purus at gravida dictum, libero arcu ' + + 'convallis lacus, in commodo libero metus eu nisi. Nullam' + + ' commodo, neque nec porta placerat, nisi est fermentum a' + + 'ugue, vitae gravida tellus sapien sit amet tellus. Aenea' + + 'n non diam orci. Proin quis elit turpis. Suspendisse non' + + ' diam ipsum. Suspendisse nec ullamcorper odio. Vestibulu' + + 'm arcu mi, sodales non suscipit id, ultrices ut massa. S' + + 'ed ac sem sit amet arcu malesuada fermentum. Nunc sed. '; +const expectedBase64Deflate = 'eJxdUUtOQzEMvMoc4OndgT0gJCT2buJWlpI4jePeqZfpmX' + + 'AKLRKbLOzx/HK73q6vOrhCunlF1qIDJhNUeW5I2ozT5OkD' + + 'lKWLJWkncJG5403HQXAkT3Jw29B9uIEmToMukglZ0vS6oc' + + 'iBh4JG8sV4oVLEUCitK2kxq1WzPnChHDzsaGKy491LofoA' + + 'bWh8do43oeuYhB5EPCjcLjzYJo48KrfQBvnJecNFJvHT1+' + + 'RSQsGoC7dn2t/xjhduTA1NWyQIZR0pbHwMDatnD+crPqKS' + + 'qGPHp1vnlsWM/07ubf7bheF7kqSj84Bm0R1fYTfaK8vqqq' + + 'fKBtNMhe3OZh6N95CTvMX5HJJi4xOVzCgUOIMSLH7wmeOH' + + 'aFE4RdpnGavKtrB5xzfO/Ll9'; +const expectedBase64Gzip = 'H4sIAAAAAAAAA11RS05DMQy8yhzg6d2BPSAkJPZu4laWkjiN4' + + '96pl+mZcAotEpss7PH8crverq86uEK6eUXWogMmE1R5bkjajN' + + 'Pk6QOUpYslaSdwkbnjTcdBcCRPcnDb0H24gSZOgy6SCVnS9Lq' + + 'hyIGHgkbyxXihUsRQKK0raTGrVbM+cKEcPOxoYrLj3Uuh+gBt' + + 'aHx2jjeh65iEHkQ8KNwuPNgmjjwqt9AG+cl5w0Um8dPX5FJCw' + + 'agLt2fa3/GOF25MDU1bJAhlHSlsfAwNq2cP5ys+opKoY8enW+' + + 'eWxYz/Tu5t/tuF4XuSpKPzgGbRHV9hN9ory+qqp8oG00yF7c5' + + 'mHo33kJO8xfkckmLjE5XMKBQ4gxIsfvCZ44doUThF2mcZq8q2' + + 'sHnHNzRtagj5AQAA'; + +zlib.deflate(inputString, common.mustCall((err, buffer) => { + zlib.inflate(buffer, common.mustCall((err, inflated) => { + assert.strictEqual(inflated.toString(), inputString); + })); +})); + +zlib.gzip(inputString, common.mustCall((err, buffer) => { + // Can't actually guarantee that we'll get exactly the same + // deflated bytes when we compress a string, since the header + // depends on stuff other than the input string itself. + // However, decrypting it should definitely yield the same + // result that we're expecting, and this should match what we get + // from inflating the known valid deflate data. + zlib.gunzip(buffer, common.mustCall((err, gunzipped) => { + assert.strictEqual(gunzipped.toString(), inputString); + })); +})); + +let buffer = Buffer.from(expectedBase64Deflate, 'base64'); +zlib.unzip(buffer, common.mustCall((err, buffer) => { + assert.strictEqual(buffer.toString(), inputString); +})); + +buffer = Buffer.from(expectedBase64Gzip, 'base64'); +zlib.unzip(buffer, common.mustCall((err, buffer) => { + assert.strictEqual(buffer.toString(), inputString); +})); diff --git a/tests/node_compat/test/parallel/test-zlib-invalid-input.js b/tests/node_compat/test/parallel/test-zlib-invalid-input.js new file mode 100644 index 000000000..d8ecae521 --- /dev/null +++ b/tests/node_compat/test/parallel/test-zlib-invalid-input.js @@ -0,0 +1,68 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +// Test uncompressing invalid input + +const common = require('../common'); +const assert = require('assert'); +const zlib = require('zlib'); + +const nonStringInputs = [ + 1, + true, + { a: 1 }, + ['a'], +]; + +// zlib.Unzip classes need to get valid data, or else they'll throw. +const unzips = [ + zlib.Unzip(), + zlib.Gunzip(), + zlib.Inflate(), + zlib.InflateRaw(), + // FIXME(bartlomieju): + // zlib.BrotliDecompress(), +]; + +nonStringInputs.forEach(common.mustCall((input) => { + assert.throws(() => { + zlib.gunzip(input); + }, { + name: 'TypeError', + code: 'ERR_INVALID_ARG_TYPE' + }); +}, nonStringInputs.length)); + +unzips.forEach(common.mustCall((uz, i) => { + uz.on('error', common.mustCall()); + uz.on('end', common.mustNotCall); + + // This will trigger error event + uz.write('this is not valid compressed data.'); +}, unzips.length)); diff --git a/tests/node_compat/test/parallel/test-zlib-no-stream.js b/tests/node_compat/test/parallel/test-zlib-no-stream.js new file mode 100644 index 000000000..27b352406 --- /dev/null +++ b/tests/node_compat/test/parallel/test-zlib-no-stream.js @@ -0,0 +1,21 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +/* eslint-disable node-core/required-modules */ +/* eslint-disable node-core/require-common-first */ + +'use strict'; + +// We are not loading common because it will load the stream module, +// defeating the purpose of this test. + +const { gzipSync } = require('zlib'); + +// Avoid regressions such as https://github.com/nodejs/node/issues/36615 + +// This must not throw +gzipSync('fooobar'); diff --git a/tests/node_compat/test/parallel/test-zlib-random-byte-pipes.js b/tests/node_compat/test/parallel/test-zlib-random-byte-pipes.js new file mode 100644 index 000000000..56409d411 --- /dev/null +++ b/tests/node_compat/test/parallel/test-zlib-random-byte-pipes.js @@ -0,0 +1,166 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const crypto = require('crypto'); +const stream = require('stream'); +const zlib = require('zlib'); + +const Stream = stream.Stream; + +// Emit random bytes, and keep a shasum +class RandomReadStream extends Stream { + constructor(opt) { + super(); + + this.readable = true; + this._paused = false; + this._processing = false; + + this._hasher = crypto.createHash('sha1'); + opt = opt || {}; + + // base block size. + opt.block = opt.block || 256 * 1024; + + // Total number of bytes to emit + opt.total = opt.total || 256 * 1024 * 1024; + this._remaining = opt.total; + + // How variable to make the block sizes + opt.jitter = opt.jitter || 1024; + + this._opt = opt; + + this._process = this._process.bind(this); + + process.nextTick(this._process); + } + + pause() { + this._paused = true; + this.emit('pause'); + } + + resume() { + // console.error("rrs resume"); + this._paused = false; + this.emit('resume'); + this._process(); + } + + _process() { + if (this._processing) return; + if (this._paused) return; + + this._processing = true; + + if (!this._remaining) { + this._hash = this._hasher.digest('hex').toLowerCase().trim(); + this._processing = false; + + this.emit('end'); + return; + } + + // Figure out how many bytes to output + // if finished, then just emit end. + let block = this._opt.block; + const jitter = this._opt.jitter; + if (jitter) { + block += Math.ceil(Math.random() * jitter - (jitter / 2)); + } + block = Math.min(block, this._remaining); + const buf = Buffer.allocUnsafe(block); + for (let i = 0; i < block; i++) { + buf[i] = Math.random() * 256; + } + + this._hasher.update(buf); + + this._remaining -= block; + + this._processing = false; + + this.emit('data', buf); + process.nextTick(this._process); + } +} + +// A filter that just verifies a shasum +class HashStream extends Stream { + constructor() { + super(); + this.readable = this.writable = true; + this._hasher = crypto.createHash('sha1'); + } + + write(c) { + // Simulate the way that an fs.ReadStream returns false + // on *every* write, only to resume a moment later. + this._hasher.update(c); + process.nextTick(() => this.resume()); + return false; + } + + resume() { + this.emit('resume'); + process.nextTick(() => this.emit('drain')); + } + + end(c) { + if (c) { + this.write(c); + } + this._hash = this._hasher.digest('hex').toLowerCase().trim(); + this.emit('data', this._hash); + this.emit('end'); + } +} + +for (const [ createCompress, createDecompress ] of [ + [ zlib.createGzip, zlib.createGunzip ], + // TODO(kt3k): Enable this when we support brotli in zlib + // [ zlib.createBrotliCompress, zlib.createBrotliDecompress ], +]) { + const inp = new RandomReadStream({ total: 1024, block: 256, jitter: 16 }); + const out = new HashStream(); + const gzip = createCompress(); + const gunz = createDecompress(); + + inp.pipe(gzip).pipe(gunz).pipe(out); + + out.on('data', common.mustCall((c) => { + assert.strictEqual(c, inp._hash, `Hash '${c}' equals '${inp._hash}'.`); + })); +} diff --git a/tests/node_compat/test/parallel/test-zlib-sync-no-event.js b/tests/node_compat/test/parallel/test-zlib-sync-no-event.js new file mode 100644 index 000000000..62019677c --- /dev/null +++ b/tests/node_compat/test/parallel/test-zlib-sync-no-event.js @@ -0,0 +1,26 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const zlib = require('zlib'); +const assert = require('assert'); + +const message = 'Come on, Fhqwhgads.'; +const buffer = Buffer.from(message); + +const zipper = new zlib.Gzip(); +zipper.on('close', common.mustNotCall()); + +const zipped = zipper._processChunk(buffer, zlib.constants.Z_FINISH); + +const unzipper = new zlib.Gunzip(); +unzipper.on('close', common.mustNotCall()); + +const unzipped = unzipper._processChunk(zipped, zlib.constants.Z_FINISH); +assert.notStrictEqual(zipped.toString(), message); +assert.strictEqual(unzipped.toString(), message); diff --git a/tests/node_compat/test/parallel/test-zlib-truncated.js b/tests/node_compat/test/parallel/test-zlib-truncated.js new file mode 100644 index 000000000..60e730171 --- /dev/null +++ b/tests/node_compat/test/parallel/test-zlib-truncated.js @@ -0,0 +1,71 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +// Tests zlib streams with truncated compressed input + +require('../common'); +const assert = require('assert'); +const zlib = require('zlib'); + +const inputString = 'ΩΩLorem ipsum dolor sit amet, consectetur adipiscing eli' + + 't. Morbi faucibus, purus at gravida dictum, libero arcu ' + + 'convallis lacus, in commodo libero metus eu nisi. Nullam' + + ' commodo, neque nec porta placerat, nisi est fermentum a' + + 'ugue, vitae gravida tellus sapien sit amet tellus. Aenea' + + 'n non diam orci. Proin quis elit turpis. Suspendisse non' + + ' diam ipsum. Suspendisse nec ullamcorper odio. Vestibulu' + + 'm arcu mi, sodales non suscipit id, ultrices ut massa. S' + + 'ed ac sem sit amet arcu malesuada fermentum. Nunc sed. '; + +const errMessage = /unexpected end of file/; + +[ + { comp: 'gzip', decomp: 'gunzip', decompSync: 'gunzipSync' }, + { comp: 'gzip', decomp: 'unzip', decompSync: 'unzipSync' }, + { comp: 'deflate', decomp: 'inflate', decompSync: 'inflateSync' }, + { comp: 'deflateRaw', decomp: 'inflateRaw', decompSync: 'inflateRawSync' }, +].forEach(function(methods) { + zlib[methods.comp](inputString, function(err, compressed) { + assert.ifError(err); + const truncated = compressed.slice(0, compressed.length / 2); + const toUTF8 = (buffer) => buffer.toString('utf-8'); + + // sync sanity + const decompressed = zlib[methods.decompSync](compressed); + assert.strictEqual(toUTF8(decompressed), inputString); + + // async sanity + zlib[methods.decomp](compressed, function(err, result) { + assert.ifError(err); + assert.strictEqual(toUTF8(result), inputString); + }); + + // Sync truncated input test + assert.throws(function() { + zlib[methods.decompSync](truncated); + }, errMessage); + + // Async truncated input test + zlib[methods.decomp](truncated, function(err, result) { + assert.match(err.message, errMessage); + }); + + const syncFlushOpt = { finishFlush: zlib.constants.Z_SYNC_FLUSH }; + + // Sync truncated input test, finishFlush = Z_SYNC_FLUSH + const result = toUTF8(zlib[methods.decompSync](truncated, syncFlushOpt)); + assert.strictEqual(result, inputString.substr(0, result.length)); + + // Async truncated input test, finishFlush = Z_SYNC_FLUSH + zlib[methods.decomp](truncated, syncFlushOpt, function(err, decompressed) { + assert.ifError(err); + const result = toUTF8(decompressed); + assert.strictEqual(result, inputString.substr(0, result.length)); + }); + }); +}); diff --git a/tests/node_compat/test/parallel/test-zlib-unzip-one-byte-chunks.js b/tests/node_compat/test/parallel/test-zlib-unzip-one-byte-chunks.js new file mode 100644 index 000000000..62b2050d3 --- /dev/null +++ b/tests/node_compat/test/parallel/test-zlib-unzip-one-byte-chunks.js @@ -0,0 +1,37 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const zlib = require('zlib'); + +const data = Buffer.concat([ + zlib.gzipSync('abc'), + zlib.gzipSync('def'), +]); + +const resultBuffers = []; + +const unzip = zlib.createUnzip() + .on('error', (err) => { + assert.ifError(err); + }) + .on('data', (data) => resultBuffers.push(data)) + .on('finish', common.mustCall(() => { + const unzipped = Buffer.concat(resultBuffers).toString(); + assert.strictEqual(unzipped, 'abcdef', + `'${unzipped}' should match 'abcdef' after zipping ` + + 'and unzipping'); + })); + +for (let i = 0; i < data.length; i++) { + // Write each single byte individually. + unzip.write(Buffer.from([data[i]])); +} + +unzip.end(); diff --git a/tests/node_compat/test/parallel/test-zlib-write-after-end.js b/tests/node_compat/test/parallel/test-zlib-write-after-end.js new file mode 100644 index 000000000..7c7e3ea35 --- /dev/null +++ b/tests/node_compat/test/parallel/test-zlib-write-after-end.js @@ -0,0 +1,23 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +const common = require('../common'); +const zlib = require('zlib'); + +// Regression test for https://github.com/nodejs/node/issues/30976 +// Writes to a stream should finish even after the readable side has been ended. + +const data = zlib.deflateRawSync('Welcome'); + +const inflate = zlib.createInflateRaw(); + +inflate.resume(); +inflate.write(data, common.mustCall()); +inflate.write(Buffer.from([0x00]), common.mustCall()); +inflate.write(Buffer.from([0x00]), common.mustCall()); +inflate.flush(common.mustCall()); diff --git a/tests/node_compat/test/parallel/test-zlib-write-after-flush.js b/tests/node_compat/test/parallel/test-zlib-write-after-flush.js new file mode 100644 index 000000000..6f33668c7 --- /dev/null +++ b/tests/node_compat/test/parallel/test-zlib-write-after-flush.js @@ -0,0 +1,57 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const zlib = require('zlib'); + +for (const [ createCompress, createDecompress ] of [ + [ zlib.createGzip, zlib.createGunzip ], + // FIXME(bartlomieju): + // [ zlib.createBrotliCompress, zlib.createBrotliDecompress ], +]) { + const gzip = createCompress(); + const gunz = createDecompress(); + + gzip.pipe(gunz); + + let output = ''; + const input = 'A line of data\n'; + gunz.setEncoding('utf8'); + gunz.on('data', (c) => output += c); + gunz.on('end', common.mustCall(() => { + assert.strictEqual(output, input); + })); + + // Make sure that flush/write doesn't trigger an assert failure + gzip.flush(); + gzip.write(input); + gzip.end(); + gunz.read(0); +} diff --git a/tests/node_compat/test/parallel/test-zlib-zero-byte.js b/tests/node_compat/test/parallel/test-zlib-zero-byte.js new file mode 100644 index 000000000..fb12b2280 --- /dev/null +++ b/tests/node_compat/test/parallel/test-zlib-zero-byte.js @@ -0,0 +1,53 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const zlib = require('zlib'); + +for (const Compressor of [ zlib.Gzip, + // FIXME(bartlomieju): + // zlib.BrotliCompress +]) { + const gz = Compressor(); + const emptyBuffer = Buffer.alloc(0); + let received = 0; + gz.on('data', function(c) { + received += c.length; + }); + + gz.on('end', common.mustCall(function() { + const expected = Compressor === zlib.Gzip ? 20 : 1; + assert.strictEqual(received, expected, + `${received}, ${expected}, ${Compressor.name}`); + })); + gz.on('finish', common.mustCall()); + gz.write(emptyBuffer); + gz.end(); +} diff --git a/tests/node_compat/test/parallel/test-zlib-zero-windowBits.js b/tests/node_compat/test/parallel/test-zlib-zero-windowBits.js new file mode 100644 index 000000000..fe74fe6d8 --- /dev/null +++ b/tests/node_compat/test/parallel/test-zlib-zero-windowBits.js @@ -0,0 +1,41 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 16.13.0 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +'use strict'; + +require('../common'); +const assert = require('assert'); +const zlib = require('zlib'); + + +// windowBits is a special case in zlib. On the compression side, 0 is invalid. +// On the decompression side, it indicates that zlib should use the value from +// the header of the compressed stream. +{ + const inflate = zlib.createInflate({ windowBits: 0 }); + assert(inflate instanceof zlib.Inflate); +} + +{ + const gunzip = zlib.createGunzip({ windowBits: 0 }); + assert(gunzip instanceof zlib.Gunzip); +} + +{ + const unzip = zlib.createUnzip({ windowBits: 0 }); + assert(unzip instanceof zlib.Unzip); +} + +// FIXME(bartlomieju): +// { +// assert.throws(() => zlib.createGzip({ windowBits: 0 }), { +// code: 'ERR_OUT_OF_RANGE', +// name: 'RangeError', +// message: 'The value of "options.windowBits" is out of range. ' + +// 'It must be >= 9 and <= 15. Received 0' +// }); +// } diff --git a/tests/node_compat/test/pseudo-tty/console-dumb-tty.js b/tests/node_compat/test/pseudo-tty/console-dumb-tty.js new file mode 100644 index 000000000..9b4bd1520 --- /dev/null +++ b/tests/node_compat/test/pseudo-tty/console-dumb-tty.js @@ -0,0 +1,16 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); + +process.env.TERM = 'dumb'; + +console.log({ foo: 'bar' }); +console.dir({ foo: 'bar' }); +console.log('%s q', 'string'); +console.log('%o with object format param', { foo: 'bar' }); diff --git a/tests/node_compat/test/pseudo-tty/console_colors.js b/tests/node_compat/test/pseudo-tty/console_colors.js new file mode 100644 index 000000000..2be464457 --- /dev/null +++ b/tests/node_compat/test/pseudo-tty/console_colors.js @@ -0,0 +1,29 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); +const vm = require('vm'); +// Make this test OS-independent by overriding stdio getColorDepth(). +process.stdout.getColorDepth = () => 8; +process.stderr.getColorDepth = () => 8; + +console.log({ foo: 'bar' }); +console.log('%s q', 'string'); +console.log('%o with object format param', { foo: 'bar' }); + +console.log( + new Error('test\n at abc (../fixtures/node_modules/bar.js:4:4)\nfoobar'), +); + +try { + require('../fixtures/node_modules/node_modules/bar.js'); +} catch (err) { + console.log(err); +} + +vm.runInThisContext('console.log(new Error())'); diff --git a/tests/node_compat/test/pseudo-tty/no_dropped_stdio.js b/tests/node_compat/test/pseudo-tty/no_dropped_stdio.js new file mode 100644 index 000000000..d2bbb92c5 --- /dev/null +++ b/tests/node_compat/test/pseudo-tty/no_dropped_stdio.js @@ -0,0 +1,26 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// https://github.com/nodejs/node/issues/6456#issuecomment-219320599 +// https://gist.github.com/isaacs/1495b91ec66b21d30b10572d72ad2cdd +'use strict'; +const common = require('../common'); + +// 1000 bytes wrapped at 50 columns +// \n turns into a double-byte character +// (48 + {2}) * 20 = 1000 +let out = `${'o'.repeat(48)}\n`.repeat(20); +// Add the remaining 24 bytes and terminate with an 'O'. +// This results in 1025 bytes, just enough to overflow the 1kb OS X TTY buffer. +out += `${'o'.repeat(24)}O`; + +// In AIX, the child exits even before the python parent +// can setup the readloop. Provide a reasonable delay. +setTimeout(function() { + process.stdout.write(out); + process.exit(0); +}, common.isAIX ? 200 : 0); diff --git a/tests/node_compat/test/pseudo-tty/no_interleaved_stdio.js b/tests/node_compat/test/pseudo-tty/no_interleaved_stdio.js new file mode 100644 index 000000000..895124420 --- /dev/null +++ b/tests/node_compat/test/pseudo-tty/no_interleaved_stdio.js @@ -0,0 +1,28 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +// https://github.com/nodejs/node/issues/6456#issuecomment-219320599 +// https://gist.github.com/isaacs/1495b91ec66b21d30b10572d72ad2cdd +'use strict'; +const common = require('../common'); + +// 1000 bytes wrapped at 50 columns +// \n turns into a double-byte character +// (48 + {2}) * 20 = 1000 +let out = `${'o'.repeat(48)}\n`.repeat(20); +// Add the remaining 24 bytes and terminate with an 'O'. +// This results in 1025 bytes, just enough to overflow the 1kb OS X TTY buffer. +out += `${'o'.repeat(24)}O`; + +const err = '__This is some stderr__'; + +// In AIX, the child exits even before the python parent +// can setup the readloop. Provide a reasonable delay. +setTimeout(function() { + process.stdout.write(out); + process.stderr.write(err); +}, common.isAIX ? 200 : 0); diff --git a/tests/node_compat/test/pseudo-tty/package.json b/tests/node_compat/test/pseudo-tty/package.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/tests/node_compat/test/pseudo-tty/package.json @@ -0,0 +1 @@ +{} diff --git a/tests/node_compat/test/pseudo-tty/test-tty-color-support-warning-2.js b/tests/node_compat/test/pseudo-tty/test-tty-color-support-warning-2.js new file mode 100644 index 000000000..6a969ac9e --- /dev/null +++ b/tests/node_compat/test/pseudo-tty/test-tty-color-support-warning-2.js @@ -0,0 +1,15 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); + +process.env.NODE_DISABLE_COLORS = '1'; +process.env.FORCE_COLOR = '3'; + +console.log(); diff --git a/tests/node_compat/test/pseudo-tty/test-tty-color-support-warning.js b/tests/node_compat/test/pseudo-tty/test-tty-color-support-warning.js new file mode 100644 index 000000000..a9338105c --- /dev/null +++ b/tests/node_compat/test/pseudo-tty/test-tty-color-support-warning.js @@ -0,0 +1,16 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; + +require('../common'); + +process.env.NO_COLOR = '1'; +process.env.NODE_DISABLE_COLORS = '1'; +process.env.FORCE_COLOR = '3'; + +console.log(); diff --git a/tests/node_compat/test/pseudo-tty/test-tty-stdin-end.js b/tests/node_compat/test/pseudo-tty/test-tty-stdin-end.js new file mode 100644 index 000000000..ee38cbd2c --- /dev/null +++ b/tests/node_compat/test/pseudo-tty/test-tty-stdin-end.js @@ -0,0 +1,14 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); + +// This test ensures that Node.js doesn't crash on `process.stdin.emit("end")`. +// https://github.com/nodejs/node/issues/1068 + +process.stdin.emit('end'); diff --git a/tests/node_compat/test/pseudo-tty/test-tty-stdout-end.js b/tests/node_compat/test/pseudo-tty/test-tty-stdout-end.js new file mode 100644 index 000000000..bd30a9a2e --- /dev/null +++ b/tests/node_compat/test/pseudo-tty/test-tty-stdout-end.js @@ -0,0 +1,11 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by `tools/node_compat/setup.ts`. Do not modify this file manually. + +'use strict'; +require('../common'); + +process.stdout.end(); diff --git a/tests/node_compat/test/pummel/package.json b/tests/node_compat/test/pummel/package.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/tests/node_compat/test/pummel/package.json @@ -0,0 +1 @@ +{} diff --git a/tests/node_compat/test/sequential/package.json b/tests/node_compat/test/sequential/package.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/tests/node_compat/test/sequential/package.json @@ -0,0 +1 @@ +{} diff --git a/tests/node_compat/test/sequential/test-child-process-exit.js b/tests/node_compat/test/sequential/test-child-process-exit.js new file mode 100644 index 000000000..c8930b059 --- /dev/null +++ b/tests/node_compat/test/sequential/test-child-process-exit.js @@ -0,0 +1,69 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file + +// Copyright Joyent and Node contributors. All rights reserved. MIT license. +// Taken from Node 18.12.1 +// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// TODO(PolarETech): The process.argv[3] to be assigned to gen should be argv[2], +// and the arguments array passed to spawn() should not need to include "require.ts". + +'use strict'; +require('../common'); + +// Open a chain of five Node processes each a child of the next. The final +// process exits immediately. Each process in the chain is instructed to exit +// when its child exits. +// https://github.com/joyent/node/issues/1726 + +const assert = require('assert'); +const ch = require('child_process'); + +const gen = +(process.argv[3] || 0); +const maxGen = 5; + + +if (gen === maxGen) { + console.error('hit maxGen, exiting', maxGen); + return; +} + +const child = ch.spawn(process.execPath, ['require.ts', __filename, gen + 1], { + stdio: [ 'ignore', 'pipe', 'ignore' ] +}); +assert.ok(!child.stdin); +assert.ok(child.stdout); +assert.ok(!child.stderr); + +console.error('gen=%d, pid=%d', gen, process.pid); + +child.on('exit', function(code) { + console.error('exit %d from gen %d', code, gen + 1); +}); + +child.stdout.pipe(process.stdout); + +child.stdout.on('close', function() { + console.error('child.stdout close gen=%d', gen); +}); diff --git a/tests/testdata/allow_run_allowlist_resolution.ts b/tests/testdata/allow_run_allowlist_resolution.ts new file mode 100644 index 000000000..c7369d928 --- /dev/null +++ b/tests/testdata/allow_run_allowlist_resolution.ts @@ -0,0 +1,66 @@ +// Testing the following (but with `deno` instead of `echo`): +// | `deno run --allow-run=echo` | `which path == "/usr/bin/echo"` at startup | `which path != "/usr/bin/echo"` at startup | +// |-------------------------------------|--------------------------------------------|--------------------------------------------| +// | **`Deno.Command("echo")`** | ✅ | ✅ | +// | **`Deno.Command("/usr/bin/echo")`** | ✅ | ❌ | + +// | `deno run --allow-run=/usr/bin/echo | `which path == "/usr/bin/echo"` at runtime | `which path != "/usr/bin/echo"` at runtime | +// |-------------------------------------|--------------------------------------------|--------------------------------------------| +// | **`Deno.Command("echo")`** | ✅ | ❌ | +// | **`Deno.Command("/usr/bin/echo")`** | ✅ | ✅ | + +const execPath = Deno.execPath(); +const execPathParent = execPath.replace(/[/\\][^/\\]+$/, ""); + +const testUrl = `data:application/typescript;base64,${ + btoa(` + console.log(await Deno.permissions.query({ name: "run", command: "deno" })); + console.log(await Deno.permissions.query({ name: "run", command: "${ + execPath.replaceAll("\\", "\\\\") + }" })); + Deno.env.set("PATH", ""); + console.log(await Deno.permissions.query({ name: "run", command: "deno" })); + console.log(await Deno.permissions.query({ name: "run", command: "${ + execPath.replaceAll("\\", "\\\\") + }" })); +`) +}`; + +const process1 = await new Deno.Command(Deno.execPath(), { + args: [ + "run", + "--quiet", + "--allow-env", + "--allow-run=deno", + testUrl, + ], + stderr: "null", + env: { "PATH": execPathParent }, +}).output(); +console.log(new TextDecoder().decode(process1.stdout)); + +const process2 = await new Deno.Command(Deno.execPath(), { + args: [ + "run", + "--quiet", + "--allow-env", + "--allow-run=deno", + testUrl, + ], + stderr: "null", + env: { "PATH": "" }, +}).output(); +console.log(new TextDecoder().decode(process2.stdout)); + +const process3 = await new Deno.Command(Deno.execPath(), { + args: [ + "run", + "--quiet", + "--allow-env", + `--allow-run=${execPath}`, + testUrl, + ], + stderr: "null", + env: { "PATH": execPathParent }, +}).output(); +console.log(new TextDecoder().decode(process3.stdout)); diff --git a/tests/testdata/allow_run_allowlist_resolution.ts.out b/tests/testdata/allow_run_allowlist_resolution.ts.out new file mode 100644 index 000000000..16ba6754a --- /dev/null +++ b/tests/testdata/allow_run_allowlist_resolution.ts.out @@ -0,0 +1,15 @@ +PermissionStatus { state: "granted", onchange: null } +PermissionStatus { state: "granted", onchange: null } +PermissionStatus { state: "granted", onchange: null } +PermissionStatus { state: "granted", onchange: null } + +PermissionStatus { state: "granted", onchange: null } +PermissionStatus { state: "prompt", onchange: null } +PermissionStatus { state: "granted", onchange: null } +PermissionStatus { state: "prompt", onchange: null } + +PermissionStatus { state: "granted", onchange: null } +PermissionStatus { state: "granted", onchange: null } +PermissionStatus { state: "prompt", onchange: null } +PermissionStatus { state: "granted", onchange: null } + diff --git a/tests/testdata/assets/DenoWinRunner.cs b/tests/testdata/assets/DenoWinRunner.cs new file mode 100644 index 000000000..2f9e9f89f --- /dev/null +++ b/tests/testdata/assets/DenoWinRunner.cs @@ -0,0 +1,127 @@ +using System; +using System.ComponentModel; +using System.Diagnostics; +using System.IO; +using System.Runtime.InteropServices; +using System.Threading.Tasks; + +[Flags] +public enum DenoConstraints : int +{ + None = 0, + NoStdin = 1, + NoStdout = 2, + NoStderr = 4 +} + +public class DenoWinRunner +{ + private const int STD_INPUT_HANDLE = -10; + private const int STD_OUTPUT_HANDLE = -11; + private const int STD_ERROR_HANDLE = -12; + + private const int FILE_NOT_FOUND = 2; + private const int WAIT_TIMEOUT = 258; + + [DllImport("kernel32.dll")] + private static extern void SetStdHandle(int nStdHandle, IntPtr handle); + + /// + /// Runs Deno.exe under the specified constraints + /// + /// Path to the Deno.exe file. Can be absolute or relative + /// Path to the script file Deno should run. + /// The constraints to apply to the Deno process + /// How long to wait for the Deno process to exit + /// The deno.exe exit code, or an exit code provided by the test runner + public static int RunDenoScript(string pathToDenoExe, string pathToTestScript, DenoConstraints constraints, uint timeoutMilliseconds = 1000) + { + try + { + if (!File.Exists(pathToDenoExe)) + { + Console.Error.WriteLine("Cannot find Deno.exe at " + pathToDenoExe); + return FILE_NOT_FOUND; + } + + if (!File.Exists(pathToTestScript)) + { + Console.Error.WriteLine("Cannot find test script at " + pathToTestScript); + return FILE_NOT_FOUND; + } + + ProcessStartInfo startInfo = new ProcessStartInfo(pathToDenoExe) + { + ErrorDialog = false, + UseShellExecute = false, + Arguments = @"run -A " + pathToTestScript, + RedirectStandardInput = !constraints.HasFlag(DenoConstraints.NoStdin), + RedirectStandardOutput = !constraints.HasFlag(DenoConstraints.NoStdout), + RedirectStandardError = !constraints.HasFlag(DenoConstraints.NoStderr) + }; + + startInfo.Environment.Add("RUST_BACKTRACE", "1"); + + if (constraints.HasFlag(DenoConstraints.NoStdin)) + { + SetStdHandle(STD_INPUT_HANDLE, (IntPtr)null); + } + + if (constraints.HasFlag(DenoConstraints.NoStdout)) + { + SetStdHandle(STD_OUTPUT_HANDLE, (IntPtr)null); + } + + if (constraints.HasFlag(DenoConstraints.NoStderr)) + { + SetStdHandle(STD_ERROR_HANDLE, (IntPtr)null); + } + + Process process = new Process { StartInfo = startInfo }; + process.Start(); + + Task stdErrTask = startInfo.RedirectStandardError ? + process.StandardError.ReadToEndAsync() : Task.FromResult(null); + Task stdOutTask = startInfo.RedirectStandardOutput ? + process.StandardOutput.ReadToEndAsync() : Task.FromResult(null); + + if (!process.WaitForExit((int)timeoutMilliseconds)) + { + Console.Error.WriteLine("Timed out waiting for Deno process to exit"); + try + { + process.Kill(); + } + catch + { + // Kill might fail, either because the process already exited or due to some other error + Console.Error.WriteLine("Failure killing the Deno process - possible Zombie Deno.exe process"); + } + return WAIT_TIMEOUT; + } + + // If the Deno process wrote to STDERR - append it to our STDERR + if (!constraints.HasFlag(DenoConstraints.NoStderr)) + { + string error = stdErrTask.Result; + if (!string.IsNullOrWhiteSpace(error)) + { + Console.Error.WriteLine(error); + } + } + + return process.ExitCode; + + } + catch (Win32Exception ex) + { + Console.Error.WriteLine("Win32Exception: code = " + ex.ErrorCode + ", message: " + ex.Message); + return ex.NativeErrorCode; + } + catch (Exception ex) + { + Console.Error.WriteLine("Exception: message: " + ex.Message); + return -1; + } + } +} diff --git a/tests/testdata/assets/DenoWinRunner.ps1 b/tests/testdata/assets/DenoWinRunner.ps1 new file mode 100644 index 000000000..203b5d36c --- /dev/null +++ b/tests/testdata/assets/DenoWinRunner.ps1 @@ -0,0 +1,10 @@ +$Source = [IO.File]::ReadAllText("$PSScriptRoot\DenoWinRunner.cs") +$denoExePath = $args[0] +$scriptPath = $args[1] +$constraints = $args[2] +$timeout = 5000; +Add-Type -TypeDefinition $Source -Language CSharp +Write-Output("Running Deno script: " + $args[1]) +$code = [DenoWinRunner]::RunDenoScript($denoExePath, $scriptPath, $constraints, $timeout) +Write-Output("Deno.exe or the test wrapper has exited with code: $code") +exit $code diff --git a/tests/testdata/assets/deno_dom_0.1.3-alpha2.wasm b/tests/testdata/assets/deno_dom_0.1.3-alpha2.wasm new file mode 100644 index 000000000..6dd9d0e91 Binary files /dev/null and b/tests/testdata/assets/deno_dom_0.1.3-alpha2.wasm differ diff --git a/tests/testdata/assets/fixture.json b/tests/testdata/assets/fixture.json new file mode 100644 index 000000000..56e056b6a --- /dev/null +++ b/tests/testdata/assets/fixture.json @@ -0,0 +1,14 @@ +{ + "name": "deno", + "private": true, + "devDependencies": { + "@types/prettier": "1.16.1", + "@typescript-eslint/eslint-plugin": "2.5.0", + "@typescript-eslint/parser": "2.5.0", + "eslint": "5.15.1", + "eslint-config-prettier": "4.1.0", + "magic-string": "0.25.2", + "prettier": "1.17.1", + "typescript": "3.6.3" + } +} diff --git a/tests/testdata/assets/hello.txt b/tests/testdata/assets/hello.txt new file mode 100644 index 000000000..6769dd60b --- /dev/null +++ b/tests/testdata/assets/hello.txt @@ -0,0 +1 @@ +Hello world! \ No newline at end of file diff --git a/tests/testdata/assets/lock_target.txt b/tests/testdata/assets/lock_target.txt new file mode 100644 index 000000000..5a29d1c26 --- /dev/null +++ b/tests/testdata/assets/lock_target.txt @@ -0,0 +1 @@ +This file is used for file locking tests and should not be used for anything else. \ No newline at end of file diff --git a/tests/testdata/assets/unreachable.wasm b/tests/testdata/assets/unreachable.wasm new file mode 100644 index 000000000..a4110ee39 Binary files /dev/null and b/tests/testdata/assets/unreachable.wasm differ diff --git a/tests/testdata/bench/allow_all.out b/tests/testdata/bench/allow_all.out new file mode 100644 index 000000000..b118856e9 --- /dev/null +++ b/tests/testdata/bench/allow_all.out @@ -0,0 +1,21 @@ +Check [WILDCARD]/bench/allow_all.ts +cpu: [WILDCARD] +runtime: deno [WILDCARD] ([WILDCARD]) + +[WILDCARD]/bench/allow_all.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +------------------------------------------------------------------ ----------------------------- +read false [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +read true [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +write false [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +write true [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +net false [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +net true [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +env false [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +env true [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +run false [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +run true [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +ffi false [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +ffi true [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +hrtime false [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +hrtime true [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] diff --git a/tests/testdata/bench/allow_all.ts b/tests/testdata/bench/allow_all.ts new file mode 100644 index 000000000..43e005b58 --- /dev/null +++ b/tests/testdata/bench/allow_all.ts @@ -0,0 +1,43 @@ +import { assertEquals } from "../../../test_util/std/assert/mod.ts"; + +const permissions: Deno.PermissionName[] = [ + "read", + "write", + "net", + "env", + "run", + "ffi", + "hrtime", +]; + +for (const name of permissions) { + Deno.bench({ + name: `${name} false`, + permissions: { + [name]: false, + }, + async fn() { + for await (const n of permissions) { + const status = await Deno.permissions.query({ name: n }); + assertEquals(status.state, "prompt"); + } + }, + }); + + Deno.bench({ + name: `${name} true`, + permissions: { + [name]: true, + }, + async fn() { + for await (const n of permissions) { + const status = await Deno.permissions.query({ name: n }); + if (n === name) { + assertEquals(status.state, "granted"); + } else { + assertEquals(status.state, "prompt"); + } + } + }, + }); +} diff --git a/tests/testdata/bench/allow_none.out b/tests/testdata/bench/allow_none.out new file mode 100644 index 000000000..7c443075b --- /dev/null +++ b/tests/testdata/bench/allow_none.out @@ -0,0 +1,22 @@ +Check [WILDCARD]/bench/allow_none.ts +cpu: [WILDCARD] +runtime: deno [WILDCARD] ([WILDCARD]) + +[WILDCARD]/bench/allow_none.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +--------------------------------------------------------------- ----------------------------- +read error: PermissionDenied: Can't escalate parent thread permissions +[WILDCARD] +write error: PermissionDenied: Can't escalate parent thread permissions +[WILDCARD] +net error: PermissionDenied: Can't escalate parent thread permissions +[WILDCARD] +env error: PermissionDenied: Can't escalate parent thread permissions +[WILDCARD] +run error: PermissionDenied: Can't escalate parent thread permissions +[WILDCARD] +ffi error: PermissionDenied: Can't escalate parent thread permissions +[WILDCARD] +hrtime error: PermissionDenied: Can't escalate parent thread permissions +[WILDCARD] +error: Bench failed diff --git a/tests/testdata/bench/allow_none.ts b/tests/testdata/bench/allow_none.ts new file mode 100644 index 000000000..62eb9c4c6 --- /dev/null +++ b/tests/testdata/bench/allow_none.ts @@ -0,0 +1,23 @@ +import { unreachable } from "../../../test_util/std/assert/mod.ts"; + +const permissions: Deno.PermissionName[] = [ + "read", + "write", + "net", + "env", + "run", + "ffi", + "hrtime", +]; + +for (const name of permissions) { + Deno.bench({ + name, + permissions: { + [name]: true, + }, + fn() { + unreachable(); + }, + }); +} diff --git a/tests/testdata/bench/before_unload_prevent_default.out b/tests/testdata/bench/before_unload_prevent_default.out new file mode 100644 index 000000000..dcb6d8194 --- /dev/null +++ b/tests/testdata/bench/before_unload_prevent_default.out @@ -0,0 +1,7 @@ +cpu: [WILDCARD] +runtime: deno [WILDCARD] + +[WILDCARD]/before_unload_prevent_default.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +--------------------------------------------------------------- ----------------------------- +foo [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] diff --git a/tests/testdata/bench/before_unload_prevent_default.ts b/tests/testdata/bench/before_unload_prevent_default.ts new file mode 100644 index 000000000..2759d4659 --- /dev/null +++ b/tests/testdata/bench/before_unload_prevent_default.ts @@ -0,0 +1,6 @@ +addEventListener("beforeunload", (e) => { + // The worker should be killed once benchmarks are done regardless of this. + e.preventDefault(); +}); + +Deno.bench("foo", () => {}); diff --git a/tests/testdata/bench/bench_formatting.out b/tests/testdata/bench/bench_formatting.out new file mode 100644 index 000000000..5e3eed1cd --- /dev/null +++ b/tests/testdata/bench/bench_formatting.out @@ -0,0 +1,8 @@ +Check [WILDCARD]/bench/bench_formatting.ts +cpu: [WILDCARD] +runtime: deno [WILDCARD] ([WILDCARD]) + +[WILDCARD]/bench/bench_formatting.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +--------------------------------------------------------------- ----------------------------- +[WILDCARD] [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] \ No newline at end of file diff --git a/tests/testdata/bench/bench_formatting.ts b/tests/testdata/bench/bench_formatting.ts new file mode 100644 index 000000000..fdee15abb --- /dev/null +++ b/tests/testdata/bench/bench_formatting.ts @@ -0,0 +1,3 @@ +Deno.bench("Date.now", () => { + Date.now(); +}); diff --git a/tests/testdata/bench/check_local_by_default.out b/tests/testdata/bench/check_local_by_default.out new file mode 100644 index 000000000..bf07bcc44 --- /dev/null +++ b/tests/testdata/bench/check_local_by_default.out @@ -0,0 +1,6 @@ +[WILDCARD] + +[WILDCARD]/bench/check_local_by_default.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +--------------------------------------------------------------- ----------------------------- + diff --git a/tests/testdata/bench/check_local_by_default.ts b/tests/testdata/bench/check_local_by_default.ts new file mode 100644 index 000000000..2ae8c2692 --- /dev/null +++ b/tests/testdata/bench/check_local_by_default.ts @@ -0,0 +1,3 @@ +import * as a from "http://localhost:4545/subdir/type_error.ts"; + +console.log(a.a); diff --git a/tests/testdata/bench/check_local_by_default2.out b/tests/testdata/bench/check_local_by_default2.out new file mode 100644 index 000000000..01aeda636 --- /dev/null +++ b/tests/testdata/bench/check_local_by_default2.out @@ -0,0 +1,4 @@ +error: TS2322 [ERROR]: Type '12' is not assignable to type '"b"'. +const b: "b" = 12; + ^ + at [WILDCARD]bench/check_local_by_default2.ts:3:7 diff --git a/tests/testdata/bench/check_local_by_default2.ts b/tests/testdata/bench/check_local_by_default2.ts new file mode 100644 index 000000000..5177ff944 --- /dev/null +++ b/tests/testdata/bench/check_local_by_default2.ts @@ -0,0 +1,6 @@ +import * as a from "http://localhost:4545/subdir/type_error.ts"; + +const b: "b" = 12; + +console.log(a.a); +console.log(b); diff --git a/tests/testdata/bench/clear_timeout.out b/tests/testdata/bench/clear_timeout.out new file mode 100644 index 000000000..fe17b4ae3 --- /dev/null +++ b/tests/testdata/bench/clear_timeout.out @@ -0,0 +1,10 @@ +Check [WILDCARD]/bench/clear_timeout.ts +cpu: [WILDCARD] +runtime: deno [WILDCARD] ([WILDCARD]) + +[WILDCARD]/bench/clear_timeout.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +--------------------------------------------------------------- ----------------------------- +bench1 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +bench2 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +bench3 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] diff --git a/tests/testdata/bench/clear_timeout.ts b/tests/testdata/bench/clear_timeout.ts new file mode 100644 index 000000000..4148263ac --- /dev/null +++ b/tests/testdata/bench/clear_timeout.ts @@ -0,0 +1,5 @@ +clearTimeout(setTimeout(() => {}, 1000)); + +Deno.bench("bench1", () => {}); +Deno.bench("bench2", () => {}); +Deno.bench("bench3", () => {}); diff --git a/tests/testdata/bench/collect.out b/tests/testdata/bench/collect.out new file mode 100644 index 000000000..03c75922b --- /dev/null +++ b/tests/testdata/bench/collect.out @@ -0,0 +1,18 @@ +Check [WILDCARD]/bench/collect/bench.ts +Check [WILDCARD]/bench/collect/include/2_bench.ts +Check [WILDCARD]/bench/collect/include/bench.ts +cpu: [WILDCARD] +runtime: deno [WILDCARD] ([WILDCARD]) + +[WILDCARD]/bench/collect/bench.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +--------------------------------------------------------------- ----------------------------- + +[WILDCARD]/bench/collect/include/2_bench.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +--------------------------------------------------------------- ----------------------------- + +[WILDCARD]/bench/collect/include/bench.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +--------------------------------------------------------------- ----------------------------- + diff --git a/tests/testdata/bench/collect/bench.ts b/tests/testdata/bench/collect/bench.ts new file mode 100644 index 000000000..e69de29bb diff --git a/tests/testdata/bench/collect/deno.jsonc b/tests/testdata/bench/collect/deno.jsonc new file mode 100644 index 000000000..7f8f190d3 --- /dev/null +++ b/tests/testdata/bench/collect/deno.jsonc @@ -0,0 +1,5 @@ +{ + "bench": { + "exclude": ["./ignore"] + } +} diff --git a/tests/testdata/bench/collect/deno.malformed.jsonc b/tests/testdata/bench/collect/deno.malformed.jsonc new file mode 100644 index 000000000..8e558fbcf --- /dev/null +++ b/tests/testdata/bench/collect/deno.malformed.jsonc @@ -0,0 +1,5 @@ +{ + "bench": { + "dont_know_this_field": {} + } +} diff --git a/tests/testdata/bench/collect/deno2.jsonc b/tests/testdata/bench/collect/deno2.jsonc new file mode 100644 index 000000000..653ab1e31 --- /dev/null +++ b/tests/testdata/bench/collect/deno2.jsonc @@ -0,0 +1,6 @@ +{ + "bench": { + "include": ["./include/"], + "exclude": ["./ignore", "./include/2_bench.ts"] + } +} diff --git a/tests/testdata/bench/collect/ignore/bench.ts b/tests/testdata/bench/collect/ignore/bench.ts new file mode 100644 index 000000000..16fb63ba7 --- /dev/null +++ b/tests/testdata/bench/collect/ignore/bench.ts @@ -0,0 +1 @@ +throw new Error("this module should be ignored"); diff --git a/tests/testdata/bench/collect/include/2_bench.ts b/tests/testdata/bench/collect/include/2_bench.ts new file mode 100644 index 000000000..e69de29bb diff --git a/tests/testdata/bench/collect/include/bench.ts b/tests/testdata/bench/collect/include/bench.ts new file mode 100644 index 000000000..e69de29bb diff --git a/tests/testdata/bench/collect2.out b/tests/testdata/bench/collect2.out new file mode 100644 index 000000000..00b8bfc0d --- /dev/null +++ b/tests/testdata/bench/collect2.out @@ -0,0 +1,13 @@ +Check [WILDCARD]/bench/collect/bench.ts +Check [WILDCARD]/bench/collect/include/bench.ts +cpu: [WILDCARD] +runtime: deno [WILDCARD] ([WILDCARD]) + +[WILDCARD]/bench/collect/bench.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +--------------------------------------------------------------- ----------------------------- + +[WILDCARD]/bench/collect/include/bench.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +--------------------------------------------------------------- ----------------------------- + diff --git a/tests/testdata/bench/collect_with_malformed_config.out b/tests/testdata/bench/collect_with_malformed_config.out new file mode 100644 index 000000000..92e5e29d2 --- /dev/null +++ b/tests/testdata/bench/collect_with_malformed_config.out @@ -0,0 +1,4 @@ +error: Failed to parse "bench" configuration + +Caused by: + unknown field `dont_know_this_field`, expected one of `include`, `exclude`, `files` diff --git a/tests/testdata/bench/exit_sanitizer.out b/tests/testdata/bench/exit_sanitizer.out new file mode 100644 index 000000000..9f15d3f26 --- /dev/null +++ b/tests/testdata/bench/exit_sanitizer.out @@ -0,0 +1,14 @@ +Check [WILDCARD]/bench/exit_sanitizer.ts +cpu: [WILDCARD] +runtime: deno [WILDCARD] ([WILDCARD]) + +[WILDCARD]/bench/exit_sanitizer.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +--------------------------------------------------------------- ----------------------------- +exit(0) error: Error: Bench attempted to exit with exit code: 0 +[WILDCARD] +exit(1) error: Error: Bench attempted to exit with exit code: 1 +[WILDCARD] +exit(2) error: Error: Bench attempted to exit with exit code: 2 +[WILDCARD] +error: Bench failed diff --git a/tests/testdata/bench/exit_sanitizer.ts b/tests/testdata/bench/exit_sanitizer.ts new file mode 100644 index 000000000..8e596b310 --- /dev/null +++ b/tests/testdata/bench/exit_sanitizer.ts @@ -0,0 +1,11 @@ +Deno.bench("exit(0)", function () { + Deno.exit(0); +}); + +Deno.bench("exit(1)", function () { + Deno.exit(1); +}); + +Deno.bench("exit(2)", function () { + Deno.exit(2); +}); diff --git a/tests/testdata/bench/explicit_start_and_end.out b/tests/testdata/bench/explicit_start_and_end.out new file mode 100644 index 000000000..fa118540c --- /dev/null +++ b/tests/testdata/bench/explicit_start_and_end.out @@ -0,0 +1,25 @@ +cpu: [WILDCARD] +runtime: deno [WILDCARD] ([WILDCARD]) + +[WILDCARD]/explicit_start_and_end.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +------------------------------------------------------------------- ----------------------------- +start and end [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +start only [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +end only [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +double start error: TypeError: BenchContext::start() has already been invoked. + t.start(); + ^ + at BenchContext.start ([WILDCARD]) + at [WILDCARD]/explicit_start_and_end.ts:[WILDCARD] +double end error: TypeError: BenchContext::end() has already been invoked. + t.end(); + ^ + at BenchContext.end ([WILDCARD]) + at [WILDCARD]/explicit_start_and_end.ts:[WILDCARD] +captured error: TypeError: The benchmark which this context belongs to is not being executed. + captured!.start(); + ^ + at BenchContext.start ([WILDCARD]) + at [WILDCARD]/explicit_start_and_end.ts:[WILDCARD] +error: Bench failed diff --git a/tests/testdata/bench/explicit_start_and_end.ts b/tests/testdata/bench/explicit_start_and_end.ts new file mode 100644 index 000000000..60a3d10d7 --- /dev/null +++ b/tests/testdata/bench/explicit_start_and_end.ts @@ -0,0 +1,50 @@ +Deno.bench("start and end", (t) => { + const id = setInterval(() => {}, 1000); + t.start(); + Deno.inspect(id); + t.end(); + clearInterval(id); +}); + +Deno.bench("start only", (t) => { + const id = setInterval(() => {}, 1000); + t.start(); + Deno.inspect(id); + clearInterval(id); +}); + +Deno.bench("end only", (t) => { + const id = setInterval(() => {}, 1000); + Deno.inspect(id); + t.end(); + clearInterval(id); +}); + +Deno.bench("double start", (t) => { + const id = setInterval(() => {}, 1000); + t.start(); + t.start(); + Deno.inspect(id); + t.end(); + clearInterval(id); +}); + +let captured: Deno.BenchContext; + +Deno.bench("double end", (t) => { + captured = t; + const id = setInterval(() => {}, 1000); + t.start(); + Deno.inspect(id); + t.end(); + t.end(); + clearInterval(id); +}); + +Deno.bench("captured", () => { + const id = setInterval(() => {}, 1000); + captured!.start(); + Deno.inspect(id); + captured!.end(); + clearInterval(id); +}); diff --git a/tests/testdata/bench/explicit_start_and_end_low_precision.out b/tests/testdata/bench/explicit_start_and_end_low_precision.out new file mode 100644 index 000000000..6dc66cfcc --- /dev/null +++ b/tests/testdata/bench/explicit_start_and_end_low_precision.out @@ -0,0 +1,10 @@ +cpu: [WILDCARD] +runtime: deno [WILDCARD] ([WILDCARD]) + +[WILDCARD]/explicit_start_and_end_low_precision.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +----------------------------------------------------------------------------- ----------------------------- +noop with start and end [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +Warning: start() and end() calls in "noop with start and end" are ignored because it averages less +than 10µs per iteration. Remove them for better results. + diff --git a/tests/testdata/bench/explicit_start_and_end_low_precision.ts b/tests/testdata/bench/explicit_start_and_end_low_precision.ts new file mode 100644 index 000000000..23bdf19fe --- /dev/null +++ b/tests/testdata/bench/explicit_start_and_end_low_precision.ts @@ -0,0 +1,4 @@ +Deno.bench("noop with start and end", (b) => { + b.start(); + b.end(); +}); diff --git a/tests/testdata/bench/fail.out b/tests/testdata/bench/fail.out new file mode 100644 index 000000000..ff3c29b92 --- /dev/null +++ b/tests/testdata/bench/fail.out @@ -0,0 +1,28 @@ +Check [WILDCARD]/bench/fail.ts +cpu: [WILDCARD] +runtime: deno [WILDCARD] ([WILDCARD]) + +[WILDCARD]/bench/fail.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +--------------------------------------------------------------- ----------------------------- +bench0 error: Error +[WILDCARD] +bench1 error: Error +[WILDCARD] +bench2 error: Error +[WILDCARD] +bench3 error: Error +[WILDCARD] +bench4 error: Error +[WILDCARD] +bench5 error: Error +[WILDCARD] +bench6 error: Error +[WILDCARD] +bench7 error: Error +[WILDCARD] +bench8 error: Error +[WILDCARD] +bench9 error: Error +[WILDCARD] +error: Bench failed diff --git a/tests/testdata/bench/fail.ts b/tests/testdata/bench/fail.ts new file mode 100644 index 000000000..33d70ce55 --- /dev/null +++ b/tests/testdata/bench/fail.ts @@ -0,0 +1,30 @@ +Deno.bench("bench0", () => { + throw new Error(); +}); +Deno.bench("bench1", () => { + throw new Error(); +}); +Deno.bench("bench2", () => { + throw new Error(); +}); +Deno.bench("bench3", () => { + throw new Error(); +}); +Deno.bench("bench4", () => { + throw new Error(); +}); +Deno.bench("bench5", () => { + throw new Error(); +}); +Deno.bench("bench6", () => { + throw new Error(); +}); +Deno.bench("bench7", () => { + throw new Error(); +}); +Deno.bench("bench8", () => { + throw new Error(); +}); +Deno.bench("bench9", () => { + throw new Error(); +}); diff --git a/tests/testdata/bench/file_protocol.out b/tests/testdata/bench/file_protocol.out new file mode 100644 index 000000000..7086c861c --- /dev/null +++ b/tests/testdata/bench/file_protocol.out @@ -0,0 +1,8 @@ +Check file://[WILDCARD]/bench/file_protocol.ts +cpu: [WILDCARD] +runtime: deno [WILDCARD] ([WILDCARD]) + +[WILDCARD]/bench/file_protocol.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +--------------------------------------------------------------- ----------------------------- +bench0 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] diff --git a/tests/testdata/bench/file_protocol.ts b/tests/testdata/bench/file_protocol.ts new file mode 100644 index 000000000..06a07bb38 --- /dev/null +++ b/tests/testdata/bench/file_protocol.ts @@ -0,0 +1 @@ +Deno.bench("bench0", () => {}); diff --git a/tests/testdata/bench/filter.out b/tests/testdata/bench/filter.out new file mode 100644 index 000000000..970171e0b --- /dev/null +++ b/tests/testdata/bench/filter.out @@ -0,0 +1,20 @@ +Check [WILDCARD]/bench/filter/a_bench.ts +Check [WILDCARD]/bench/filter/b_bench.ts +Check [WILDCARD]/bench/filter/c_bench.ts +cpu: [WILDCARD] +runtime: deno [WILDCARD] ([WILDCARD]) + +[WILDCARD]/bench/filter/a_bench.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +--------------------------------------------------------------- ----------------------------- +foo [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] + +[WILDCARD]/bench/filter/b_bench.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +--------------------------------------------------------------- ----------------------------- +foo [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] + +[WILDCARD]/bench/filter/c_bench.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +--------------------------------------------------------------- ----------------------------- +foo [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] diff --git a/tests/testdata/bench/filter/a_bench.ts b/tests/testdata/bench/filter/a_bench.ts new file mode 100644 index 000000000..fc4ef859c --- /dev/null +++ b/tests/testdata/bench/filter/a_bench.ts @@ -0,0 +1,3 @@ +Deno.bench("foo", function () {}); +Deno.bench("bar", function () {}); +Deno.bench("baz", function () {}); diff --git a/tests/testdata/bench/filter/b_bench.ts b/tests/testdata/bench/filter/b_bench.ts new file mode 100644 index 000000000..fc4ef859c --- /dev/null +++ b/tests/testdata/bench/filter/b_bench.ts @@ -0,0 +1,3 @@ +Deno.bench("foo", function () {}); +Deno.bench("bar", function () {}); +Deno.bench("baz", function () {}); diff --git a/tests/testdata/bench/filter/c_bench.ts b/tests/testdata/bench/filter/c_bench.ts new file mode 100644 index 000000000..fc4ef859c --- /dev/null +++ b/tests/testdata/bench/filter/c_bench.ts @@ -0,0 +1,3 @@ +Deno.bench("foo", function () {}); +Deno.bench("bar", function () {}); +Deno.bench("baz", function () {}); diff --git a/tests/testdata/bench/finally_timeout.out b/tests/testdata/bench/finally_timeout.out new file mode 100644 index 000000000..96bec017d --- /dev/null +++ b/tests/testdata/bench/finally_timeout.out @@ -0,0 +1,11 @@ +Check [WILDCARD]/bench/finally_timeout.ts +cpu: [WILDCARD] +runtime: deno [WILDCARD] ([WILDCARD]) + +[WILDCARD]/bench/finally_timeout.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +--------------------------------------------------------------- ----------------------------- +error error: Error: fail +[WILDCARD] +success [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +error: Bench failed diff --git a/tests/testdata/bench/finally_timeout.ts b/tests/testdata/bench/finally_timeout.ts new file mode 100644 index 000000000..c49eb8da2 --- /dev/null +++ b/tests/testdata/bench/finally_timeout.ts @@ -0,0 +1,11 @@ +Deno.bench("error", function () { + const timer = setTimeout(() => null, 10000); + try { + throw new Error("fail"); + } finally { + clearTimeout(timer); + } +}); + +Deno.bench("success", function () { +}); diff --git a/tests/testdata/bench/group_baseline.out b/tests/testdata/bench/group_baseline.out new file mode 100644 index 000000000..5de0ac1fe --- /dev/null +++ b/tests/testdata/bench/group_baseline.out @@ -0,0 +1,20 @@ +[WILDCARD]/bench/group_baseline.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +-------------------------------------------------------------------- ----------------------------- +noop [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +noop2 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] + +summary + noo[WILDCARD] + [WILDCARD]x [WILDCARD] than noo[WILDCARD] + +group url +noop3 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +parse url 2x [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +parse url 200x [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] + +summary + parse url 2x + [WILDCARD]x slower than noop3 + [WILDCARD]x faster than parse url 200x + diff --git a/tests/testdata/bench/group_baseline.ts b/tests/testdata/bench/group_baseline.ts new file mode 100644 index 000000000..a86f6455c --- /dev/null +++ b/tests/testdata/bench/group_baseline.ts @@ -0,0 +1,15 @@ +Deno.bench("noop", () => {}); +Deno.bench("noop2", { baseline: true }, () => {}); + +Deno.bench("noop3", { group: "url" }, () => {}); + +Deno.bench("parse url 2x", { group: "url", baseline: true }, () => { + new URL("https://deno.land/std/http/server.ts"); + new URL("https://deno.land/std/http/server.ts"); +}); + +Deno.bench("parse url 200x", { group: "url" }, () => { + for (let i = 0; i < 200; i++) { + new URL("https://deno.land/std/http/server.ts"); + } +}); diff --git a/tests/testdata/bench/ignore.out b/tests/testdata/bench/ignore.out new file mode 100644 index 000000000..0693a7fc8 --- /dev/null +++ b/tests/testdata/bench/ignore.out @@ -0,0 +1,8 @@ +Check [WILDCARD]/bench/ignore.ts +cpu: [WILDCARD] +runtime: deno [WILDCARD] ([WILDCARD]) + +[WILDCARD]/bench/ignore.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +--------------------------------------------------------------- ----------------------------- + diff --git a/tests/testdata/bench/ignore.ts b/tests/testdata/bench/ignore.ts new file mode 100644 index 000000000..0226fe76f --- /dev/null +++ b/tests/testdata/bench/ignore.ts @@ -0,0 +1,9 @@ +for (let i = 0; i < 10; i++) { + Deno.bench({ + name: `bench${i}`, + ignore: true, + fn() { + throw new Error("unreachable"); + }, + }); +} diff --git a/tests/testdata/bench/ignore_permissions.out b/tests/testdata/bench/ignore_permissions.out new file mode 100644 index 000000000..1c8e93535 --- /dev/null +++ b/tests/testdata/bench/ignore_permissions.out @@ -0,0 +1,8 @@ +Check [WILDCARD]/bench/ignore_permissions.ts +cpu: [WILDCARD] +runtime: deno [WILDCARD] ([WILDCARD]) + +[WILDCARD]/bench/ignore_permissions.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +--------------------------------------------------------------- ----------------------------- + diff --git a/tests/testdata/bench/ignore_permissions.ts b/tests/testdata/bench/ignore_permissions.ts new file mode 100644 index 000000000..0dcd9299f --- /dev/null +++ b/tests/testdata/bench/ignore_permissions.ts @@ -0,0 +1,16 @@ +Deno.bench({ + name: "ignore", + permissions: { + read: true, + write: true, + net: true, + env: true, + run: true, + ffi: true, + hrtime: true, + }, + ignore: true, + fn() { + throw new Error("unreachable"); + }, +}); diff --git a/tests/testdata/bench/interval.out b/tests/testdata/bench/interval.out new file mode 100644 index 000000000..389b89162 --- /dev/null +++ b/tests/testdata/bench/interval.out @@ -0,0 +1,8 @@ +Check [WILDCARD]/bench/interval.ts +cpu: [WILDCARD] +runtime: deno [WILDCARD] ([WILDCARD]) + +[WILDCARD]/bench/interval.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +--------------------------------------------------------------- ----------------------------- + diff --git a/tests/testdata/bench/interval.ts b/tests/testdata/bench/interval.ts new file mode 100644 index 000000000..7eb588c59 --- /dev/null +++ b/tests/testdata/bench/interval.ts @@ -0,0 +1 @@ +setInterval(function () {}, 0); diff --git a/tests/testdata/bench/load_unload.out b/tests/testdata/bench/load_unload.out new file mode 100644 index 000000000..e5bc6b29e --- /dev/null +++ b/tests/testdata/bench/load_unload.out @@ -0,0 +1,8 @@ +Check [WILDCARD]/bench/load_unload.ts +cpu: [WILDCARD] +runtime: deno [WILDCARD] ([WILDCARD]) + +[WILDCARD]/bench/load_unload.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +--------------------------------------------------------------- ----------------------------- +bench [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] diff --git a/tests/testdata/bench/load_unload.ts b/tests/testdata/bench/load_unload.ts new file mode 100644 index 000000000..3653c135d --- /dev/null +++ b/tests/testdata/bench/load_unload.ts @@ -0,0 +1,22 @@ +let interval: number | null = null; +addEventListener("load", () => { + if (interval) { + throw new Error("Interval is already set"); + } + + interval = setInterval(() => {}, 0); +}); + +addEventListener("unload", () => { + if (!interval) { + throw new Error("Interval was not set"); + } + + clearInterval(interval); +}); + +Deno.bench("bench", () => { + if (!interval) { + throw new Error("Interval was not set"); + } +}); diff --git a/tests/testdata/bench/meta.out b/tests/testdata/bench/meta.out new file mode 100644 index 000000000..8c9aa9123 --- /dev/null +++ b/tests/testdata/bench/meta.out @@ -0,0 +1,10 @@ +Check [WILDCARD]/bench/meta.ts +import.meta.main: false +import.meta.url: [WILDCARD]/bench/meta.ts +cpu: [WILDCARD] +runtime: deno [WILDCARD] ([WILDCARD]) + +[WILDCARD]/bench/meta.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +--------------------------------------------------------------- ----------------------------- + diff --git a/tests/testdata/bench/meta.ts b/tests/testdata/bench/meta.ts new file mode 100644 index 000000000..e32fdeea6 --- /dev/null +++ b/tests/testdata/bench/meta.ts @@ -0,0 +1,2 @@ +console.log("import.meta.main: %s", import.meta.main); +console.log("import.meta.url: %s", import.meta.url); diff --git a/tests/testdata/bench/multifile_summary.out b/tests/testdata/bench/multifile_summary.out new file mode 100644 index 000000000..37aebe187 --- /dev/null +++ b/tests/testdata/bench/multifile_summary.out @@ -0,0 +1,64 @@ +Check [WILDCARD]/bench/group_baseline.ts +Check [WILDCARD]/bench/pass.ts +Check [WILDCARD]/bench/multiple_group.ts +cpu: [WILDCARD] +runtime: deno [WILDCARD] ([WILDCARD]) + +[WILDCARD]/bench/group_baseline.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +-------------------------------------------------------------------- ----------------------------- +noop [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +noop2 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] + +summary + noo[WILDCARD] + [WILDCARD]x [WILDCARD] than noo[WILDCARD] + +group url +noop3 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +parse url 2x [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +parse url 200x [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] + +summary + parse url 2x + [WILDCARD]x slower than noop3 + [WILDCARD]x faster than parse url 200x + + +[WILDCARD]/bench/pass.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +--------------------------------------------------------------- ----------------------------- +bench0 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +bench1 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +bench2 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +bench3 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +bench4 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +bench5 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +bench6 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +bench7 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +bench8 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +bench9 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] + + +[WILDCARD]/bench/multiple_group.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +-------------------------------------------------------------------- ----------------------------- + +group noop +noop [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +noop2 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] + +summary + noo[WILDCARD] + [WILDCARD]x [WILDCARD] than noo[WILDCARD] + +group url +noop3 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +parse url 2x [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +parse url 200x [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] + +summary + parse url 2x + [WILDCARD]x slower than noop3 + [WILDCARD]x faster than parse url 200x + diff --git a/tests/testdata/bench/multiple_group.ts b/tests/testdata/bench/multiple_group.ts new file mode 100644 index 000000000..69e73a7f2 --- /dev/null +++ b/tests/testdata/bench/multiple_group.ts @@ -0,0 +1,15 @@ +Deno.bench("noop", { group: "noop" }, () => {}); +Deno.bench("noop2", { group: "noop", baseline: true }, () => {}); + +Deno.bench("noop3", { group: "url" }, () => {}); + +Deno.bench("parse url 2x", { group: "url", baseline: true }, () => { + new URL("https://deno.land/std/http/server.ts"); + new URL("https://deno.land/std/http/server.ts"); +}); + +Deno.bench("parse url 200x", { group: "url" }, () => { + for (let i = 0; i < 200; i++) { + new URL("https://deno.land/std/http/server.ts"); + } +}); diff --git a/tests/testdata/bench/no_check.out b/tests/testdata/bench/no_check.out new file mode 100644 index 000000000..6dc016458 --- /dev/null +++ b/tests/testdata/bench/no_check.out @@ -0,0 +1,9 @@ +error: (in promise) TypeError: Cannot read properties of undefined (reading 'fn') +Deno.bench(); + ^ + at [WILDCARD] + at [WILDCARD]/bench/no_check.ts:1:6 +This error was not caught from a benchmark and caused the bench runner to fail on the referenced module. +It most likely originated from a dangling promise, event/timeout handler or top-level code. + +error: Bench failed diff --git a/tests/testdata/bench/no_check.ts b/tests/testdata/bench/no_check.ts new file mode 100644 index 000000000..b159cabd6 --- /dev/null +++ b/tests/testdata/bench/no_check.ts @@ -0,0 +1 @@ +Deno.bench(); diff --git a/tests/testdata/bench/no_color.ts b/tests/testdata/bench/no_color.ts new file mode 100644 index 000000000..d15bf3572 --- /dev/null +++ b/tests/testdata/bench/no_color.ts @@ -0,0 +1,17 @@ +Deno.bench({ + name: "success", + fn() {}, +}); + +Deno.bench({ + name: "fail", + fn() { + throw new Error("fail"); + }, +}); + +Deno.bench({ + name: "ignored", + ignore: true, + fn() {}, +}); diff --git a/tests/testdata/bench/no_prompt_by_default.out b/tests/testdata/bench/no_prompt_by_default.out new file mode 100644 index 000000000..4c7e7f146 --- /dev/null +++ b/tests/testdata/bench/no_prompt_by_default.out @@ -0,0 +1,9 @@ +[WILDCARD]cpu: [WILDCARD] +runtime: deno [WILDCARD] ([WILDCARD]) + +[WILDCARD]/bench/no_prompt_by_default.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +--------------------------------------------------------------- ----------------------------- +no prompt error: PermissionDenied: Requires read access to "./some_file.txt", run again with the --allow-read flag +[WILDCARD] +error: Bench failed diff --git a/tests/testdata/bench/no_prompt_by_default.ts b/tests/testdata/bench/no_prompt_by_default.ts new file mode 100644 index 000000000..59359eebd --- /dev/null +++ b/tests/testdata/bench/no_prompt_by_default.ts @@ -0,0 +1,3 @@ +Deno.bench("no prompt", async () => { + await Deno.readTextFile("./some_file.txt"); +}); diff --git a/tests/testdata/bench/no_prompt_with_denied_perms.out b/tests/testdata/bench/no_prompt_with_denied_perms.out new file mode 100644 index 000000000..74400dafe --- /dev/null +++ b/tests/testdata/bench/no_prompt_with_denied_perms.out @@ -0,0 +1,9 @@ +[WILDCARD]cpu: [WILDCARD] +runtime: deno [WILDCARD] ([WILDCARD]) + +[WILDCARD]/bench/no_prompt_with_denied_perms.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +--------------------------------------------------------------- ----------------------------- +no prompt error: PermissionDenied: Requires read access to "./some_file.txt", run again with the --allow-read flag +[WILDCARD] +error: Bench failed diff --git a/tests/testdata/bench/no_prompt_with_denied_perms.ts b/tests/testdata/bench/no_prompt_with_denied_perms.ts new file mode 100644 index 000000000..2f0d63bbe --- /dev/null +++ b/tests/testdata/bench/no_prompt_with_denied_perms.ts @@ -0,0 +1,3 @@ +Deno.bench("no prompt", { permissions: { read: false } }, async () => { + await Deno.readTextFile("./some_file.txt"); +}); diff --git a/tests/testdata/bench/no_run.out b/tests/testdata/bench/no_run.out new file mode 100644 index 000000000..5d40f1d3b --- /dev/null +++ b/tests/testdata/bench/no_run.out @@ -0,0 +1,5 @@ +Check [WILDCARD]/bench/no_run.ts +error: TS2322 [ERROR]: Type 'number' is not assignable to type 'string'. +const _value: string = 1; + ~~~~~~ + at [WILDCARD]/bench/no_run.ts:1:7 diff --git a/tests/testdata/bench/no_run.ts b/tests/testdata/bench/no_run.ts new file mode 100644 index 000000000..c7a5dc1e8 --- /dev/null +++ b/tests/testdata/bench/no_run.ts @@ -0,0 +1,2 @@ +const _value: string = 1; +console.log("this should not be run"); diff --git a/tests/testdata/bench/only.out b/tests/testdata/bench/only.out new file mode 100644 index 000000000..00338af8e --- /dev/null +++ b/tests/testdata/bench/only.out @@ -0,0 +1,9 @@ +Check [WILDCARD]/bench/only.ts +cpu: [WILDCARD] +runtime: deno [WILDCARD] ([WILDCARD]) + +[WILDCARD]/bench/only.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +--------------------------------------------------------------- ----------------------------- +only [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +error: Bench failed because the "only" option was used diff --git a/tests/testdata/bench/only.ts b/tests/testdata/bench/only.ts new file mode 100644 index 000000000..0129c024c --- /dev/null +++ b/tests/testdata/bench/only.ts @@ -0,0 +1,15 @@ +Deno.bench({ + name: "before", + fn() {}, +}); + +Deno.bench({ + only: true, + name: "only", + fn() {}, +}); + +Deno.bench({ + name: "after", + fn() {}, +}); diff --git a/tests/testdata/bench/overloads.out b/tests/testdata/bench/overloads.out new file mode 100644 index 000000000..289c8dde6 --- /dev/null +++ b/tests/testdata/bench/overloads.out @@ -0,0 +1,12 @@ +Check [WILDCARD]/bench/overloads.ts +cpu: [WILDCARD] +runtime: deno [WILDCARD] ([WILDCARD]) + +[WILDCARD]/bench/overloads.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +--------------------------------------------------------------- ----------------------------- +bench0 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +bench1 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +bench2 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +bench3 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +bench4 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] diff --git a/tests/testdata/bench/overloads.ts b/tests/testdata/bench/overloads.ts new file mode 100644 index 000000000..4f5887f79 --- /dev/null +++ b/tests/testdata/bench/overloads.ts @@ -0,0 +1,6 @@ +Deno.bench("bench0", () => {}); +Deno.bench(function bench1() {}); +Deno.bench({ name: "bench2", fn: () => {} }); +Deno.bench("bench3", { permissions: "none" }, () => {}); +Deno.bench({ name: "bench4" }, () => {}); +Deno.bench({ ignore: true }, function bench5() {}); diff --git a/tests/testdata/bench/pass.json.out b/tests/testdata/bench/pass.json.out new file mode 100644 index 000000000..73daa7202 --- /dev/null +++ b/tests/testdata/bench/pass.json.out @@ -0,0 +1,28 @@ +Check file:///[WILDCARD]testdata/bench/pass.ts +{ + "runtime": "Deno/[WILDCARD]", + "cpu": "[WILDCARD]", + "benches": [ + { + "origin": "file:///[WILDCARD]testdata/bench/pass.ts", + "group": null, + "name": "bench0", + "baseline": false, + "results": [ + { + "ok": { + "n": [WILDCARD], + "min": [WILDCARD], + "max": [WILDCARD], + "avg": [WILDCARD], + "p75": [WILDCARD], + "p99": [WILDCARD], + "p995": [WILDCARD], + "p999": [WILDCARD] + } + } + ] + }, +[WILDCARD] + ] +} diff --git a/tests/testdata/bench/pass.out b/tests/testdata/bench/pass.out new file mode 100644 index 000000000..19ea6fd13 --- /dev/null +++ b/tests/testdata/bench/pass.out @@ -0,0 +1,17 @@ +Check [WILDCARD]/bench/pass.ts +cpu: [WILDCARD] +runtime: deno [WILDCARD] ([WILDCARD]) + +[WILDCARD]/bench/pass.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +--------------------------------------------------------------- ----------------------------- +bench0 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +bench1 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +bench2 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +bench3 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +bench4 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +bench5 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +bench6 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +bench7 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +bench8 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +bench9 [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] diff --git a/tests/testdata/bench/pass.ts b/tests/testdata/bench/pass.ts new file mode 100644 index 000000000..48348d447 --- /dev/null +++ b/tests/testdata/bench/pass.ts @@ -0,0 +1,10 @@ +Deno.bench("bench0", () => {}); +Deno.bench("bench1", () => {}); +Deno.bench("bench2", () => {}); +Deno.bench("bench3", () => {}); +Deno.bench("bench4", () => {}); +Deno.bench("bench5", () => {}); +Deno.bench("bench6", () => {}); +Deno.bench("bench7", () => {}); +Deno.bench("bench8", () => {}); +Deno.bench("bench9", () => {}); diff --git a/tests/testdata/bench/quiet.out b/tests/testdata/bench/quiet.out new file mode 100644 index 000000000..ed9e06c84 --- /dev/null +++ b/tests/testdata/bench/quiet.out @@ -0,0 +1,10 @@ +cpu: [WILDCARD] +runtime: deno [WILDCARD] ([WILDCARD]) + +[WILDCARD]/bench/quiet.ts +benchmark time (avg) iter/s (min … max) p75 p99 p995 +------------------------------------------------------------------- ----------------------------- +console.log [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +console.error [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +console.info [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] +console.warn [WILDCARD] [WILDCARD]/iter[WILDCARD]([WILDCARD] … [WILDCARD]) [WILDCARD] diff --git a/tests/testdata/bench/quiet.ts b/tests/testdata/bench/quiet.ts new file mode 100644 index 000000000..efeb366ff --- /dev/null +++ b/tests/testdata/bench/quiet.ts @@ -0,0 +1,15 @@ +Deno.bench("console.log", function () { + console.log("log"); +}); + +Deno.bench("console.error", function () { + console.error("error"); +}); + +Deno.bench("console.info", function () { + console.info("info"); +}); + +Deno.bench("console.warn", function () { + console.info("warn"); +}); diff --git a/tests/testdata/bench/recursive_permissions_pledge.js b/tests/testdata/bench/recursive_permissions_pledge.js new file mode 100644 index 000000000..9bf320c37 --- /dev/null +++ b/tests/testdata/bench/recursive_permissions_pledge.js @@ -0,0 +1,6 @@ +Deno[Deno.internal].core.ops.op_pledge_test_permissions( + "none", +); +Deno[Deno.internal].core.ops.op_pledge_test_permissions( + "inherit", +); diff --git a/tests/testdata/bench/unhandled_rejection.out b/tests/testdata/bench/unhandled_rejection.out new file mode 100644 index 000000000..dba6d9ed4 --- /dev/null +++ b/tests/testdata/bench/unhandled_rejection.out @@ -0,0 +1,11 @@ +Check [WILDCARD]/bench/unhandled_rejection.ts +error: (in promise) Error: rejection + reject(new Error("rejection")); + ^ + at [WILDCARD]/bench/unhandled_rejection.ts:2:10 + at new Promise () + at [WILDCARD]/bench/unhandled_rejection.ts:1:1 +This error was not caught from a benchmark and caused the bench runner to fail on the referenced module. +It most likely originated from a dangling promise, event/timeout handler or top-level code. + +error: Bench failed diff --git a/tests/testdata/bench/unhandled_rejection.ts b/tests/testdata/bench/unhandled_rejection.ts new file mode 100644 index 000000000..32f3111ea --- /dev/null +++ b/tests/testdata/bench/unhandled_rejection.ts @@ -0,0 +1,3 @@ +new Promise((_resolve, reject) => { + reject(new Error("rejection")); +}); diff --git a/tests/testdata/bench/unresolved_promise.out b/tests/testdata/bench/unresolved_promise.out new file mode 100644 index 000000000..e5c53836a --- /dev/null +++ b/tests/testdata/bench/unresolved_promise.out @@ -0,0 +1,9 @@ +Check [WILDCARD]/bench/unresolved_promise.ts +error: Top-level await promise never resolved +await new Promise((_resolve, _reject) => {}); +^ + at ([WILDCARD]bench/unresolved_promise.ts:1:1) +This error was not caught from a benchmark and caused the bench runner to fail on the referenced module. +It most likely originated from a dangling promise, event/timeout handler or top-level code. + +error: Bench failed diff --git a/tests/testdata/bench/unresolved_promise.ts b/tests/testdata/bench/unresolved_promise.ts new file mode 100644 index 000000000..25fe70762 --- /dev/null +++ b/tests/testdata/bench/unresolved_promise.ts @@ -0,0 +1 @@ +await new Promise((_resolve, _reject) => {}); diff --git a/tests/testdata/benches/response_string_perf.js b/tests/testdata/benches/response_string_perf.js new file mode 100644 index 000000000..f55376c77 --- /dev/null +++ b/tests/testdata/benches/response_string_perf.js @@ -0,0 +1,34 @@ +const mixed = "@Ā๐😀"; + +function generateRandom(bytes) { + let result = ""; + let i = 0; + while (i < bytes) { + const toAdd = Math.floor(Math.random() * Math.min(4, bytes - i)); + switch (toAdd) { + case 0: + result += mixed[0]; + i++; + break; + case 1: + result += mixed[1]; + i++; + break; + case 2: + result += mixed[2]; + i++; + break; + case 3: + result += mixed[3]; + result += mixed[4]; + i += 2; + break; + } + } + return result; +} + +const randomData = generateRandom(1024); +for (let i = 0; i < 10_000; i++) { + new Response(randomData); +} diff --git a/tests/testdata/benches/text_decoder_perf.js b/tests/testdata/benches/text_decoder_perf.js new file mode 100644 index 000000000..2e52b1f8b --- /dev/null +++ b/tests/testdata/benches/text_decoder_perf.js @@ -0,0 +1,38 @@ +const mixed = new TextEncoder().encode("@Ā๐😀"); + +function generateRandom(bytes) { + const result = new Uint8Array(bytes); + let i = 0; + while (i < bytes) { + const toAdd = Math.floor(Math.random() * Math.min(4, bytes - i)); + switch (toAdd) { + case 0: + result[i] = mixed[0]; + i++; + break; + case 1: + result[i] = mixed[1]; + result[i + 1] = mixed[2]; + i += 2; + break; + case 2: + result[i] = mixed[3]; + result[i + 1] = mixed[4]; + result[i + 2] = mixed[5]; + i += 3; + break; + case 3: + result[i] = mixed[6]; + result[i + 1] = mixed[7]; + result[i + 2] = mixed[8]; + result[i + 3] = mixed[9]; + i += 4; + break; + } + } + return result; +} + +const randomData = generateRandom(1024); +const decoder = new TextDecoder(); +for (let i = 0; i < 10_000; i++) decoder.decode(randomData); diff --git a/tests/testdata/benches/text_encoder_into_perf.js b/tests/testdata/benches/text_encoder_into_perf.js new file mode 100644 index 000000000..8d60e9f00 --- /dev/null +++ b/tests/testdata/benches/text_encoder_into_perf.js @@ -0,0 +1,34 @@ +const mixed = "@Ā๐😀"; + +function generateRandom(bytes) { + let result = ""; + let i = 0; + while (i < bytes) { + const toAdd = Math.floor(Math.random() * Math.min(4, bytes - i)); + switch (toAdd) { + case 0: + result += mixed[0]; + i++; + break; + case 1: + result += mixed[1]; + i++; + break; + case 2: + result += mixed[2]; + i++; + break; + case 3: + result += mixed[3]; + result += mixed[4]; + i += 2; + break; + } + } + return result; +} + +const randomData = generateRandom(1024); +const encoder = new TextEncoder(); +const targetBuffer = new Uint8Array(randomData.length * 4); +for (let i = 0; i < 10_000; i++) encoder.encodeInto(randomData, targetBuffer); diff --git a/tests/testdata/benches/text_encoder_perf.js b/tests/testdata/benches/text_encoder_perf.js new file mode 100644 index 000000000..6f61f019e --- /dev/null +++ b/tests/testdata/benches/text_encoder_perf.js @@ -0,0 +1,33 @@ +const mixed = "@Ā๐😀"; + +function generateRandom(bytes) { + let result = ""; + let i = 0; + while (i < bytes) { + const toAdd = Math.floor(Math.random() * Math.min(4, bytes - i)); + switch (toAdd) { + case 0: + result += mixed[0]; + i++; + break; + case 1: + result += mixed[1]; + i++; + break; + case 2: + result += mixed[2]; + i++; + break; + case 3: + result += mixed[3]; + result += mixed[4]; + i += 2; + break; + } + } + return result; +} + +const randomData = generateRandom(1024); +const encoder = new TextEncoder(); +for (let i = 0; i < 10_000; i++) encoder.encode(randomData); diff --git a/tests/testdata/bundle/bare_imports/error_with_bare_import.ts b/tests/testdata/bundle/bare_imports/error_with_bare_import.ts new file mode 100644 index 000000000..c0748305d --- /dev/null +++ b/tests/testdata/bundle/bare_imports/error_with_bare_import.ts @@ -0,0 +1 @@ +import "foo"; diff --git a/tests/testdata/bundle/bare_imports/error_with_bare_import.ts.out b/tests/testdata/bundle/bare_imports/error_with_bare_import.ts.out new file mode 100644 index 000000000..44d063a5e --- /dev/null +++ b/tests/testdata/bundle/bare_imports/error_with_bare_import.ts.out @@ -0,0 +1,2 @@ +[WILDCARD]error: Relative import path "foo" not prefixed with / or ./ or ../ + at file:///[WILDCARD]/error_with_bare_import.ts:[WILDCARD] diff --git a/tests/testdata/bundle/bundle.test.out b/tests/testdata/bundle/bundle.test.out new file mode 100644 index 000000000..6b1c109d3 --- /dev/null +++ b/tests/testdata/bundle/bundle.test.out @@ -0,0 +1,27 @@ +[WILDCARD] +function printHello() { + console.log("Hello"); +} +function returnsFoo() { + return "Foo"; +} +function printHello2() { + printHello(); +} +function returnsHi() { + return "Hi"; +} +function returnsFoo2() { + return returnsFoo(); +} +function printHello3() { + printHello2(); +} +function throwsError() { + throw Error("exception from mod1"); +} +export { returnsHi as returnsHi }; +export { returnsFoo2 as returnsFoo2 }; +export { printHello3 as printHello3 }; +export { throwsError as throwsError }; + diff --git a/tests/testdata/bundle/check_local_by_default/no_errors.out b/tests/testdata/bundle/check_local_by_default/no_errors.out new file mode 100644 index 000000000..c4559d1fa --- /dev/null +++ b/tests/testdata/bundle/check_local_by_default/no_errors.out @@ -0,0 +1,6 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file +// This code was bundled using `deno bundle` and it's not recommended to edit it manually + +console.log(12); + diff --git a/tests/testdata/bundle/check_local_by_default/no_errors.ts b/tests/testdata/bundle/check_local_by_default/no_errors.ts new file mode 100644 index 000000000..2ae8c2692 --- /dev/null +++ b/tests/testdata/bundle/check_local_by_default/no_errors.ts @@ -0,0 +1,3 @@ +import * as a from "http://localhost:4545/subdir/type_error.ts"; + +console.log(a.a); diff --git a/tests/testdata/bundle/check_local_by_default/type_error.out b/tests/testdata/bundle/check_local_by_default/type_error.out new file mode 100644 index 000000000..6d53e9498 --- /dev/null +++ b/tests/testdata/bundle/check_local_by_default/type_error.out @@ -0,0 +1,4 @@ +error: TS2322 [ERROR]: Type '12' is not assignable to type '"b"'. +const b: "b" = 12; + ^ + at [WILDCARD]bundle/check_local_by_default/type_error.ts:3:7 diff --git a/tests/testdata/bundle/check_local_by_default/type_error.ts b/tests/testdata/bundle/check_local_by_default/type_error.ts new file mode 100644 index 000000000..5177ff944 --- /dev/null +++ b/tests/testdata/bundle/check_local_by_default/type_error.ts @@ -0,0 +1,6 @@ +import * as a from "http://localhost:4545/subdir/type_error.ts"; + +const b: "b" = 12; + +console.log(a.a); +console.log(b); diff --git a/tests/testdata/bundle/decorators/ts_decorators.out b/tests/testdata/bundle/decorators/ts_decorators.out new file mode 100644 index 000000000..e988aadd3 --- /dev/null +++ b/tests/testdata/bundle/decorators/ts_decorators.out @@ -0,0 +1,49 @@ +[WILDCARD] +// deno-fmt-ignore-file +// deno-lint-ignore-file +// This code was bundled using `deno bundle` and it's not recommended to edit it manually + +function _ts_decorate(decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +} +function a() { + console.log("a(): evaluated"); + return (_target, _propertyKey, _descriptor)=>{ + console.log("a(): called"); + }; +} +class B { + method() { + console.log("method"); + } +} +_ts_decorate([ + a() +], B.prototype, "method", null); +function _ts_decorate1(decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +} +function Decorator() { + return function(target, propertyKey, descriptor) { + const originalFn = descriptor.value; + descriptor.value = async function(...args) { + return await originalFn.apply(this, args); + }; + return descriptor; + }; +} +class SomeClass { + async test() {} +} +_ts_decorate1([ + Decorator() +], SomeClass.prototype, "test", null); +new SomeClass().test(); +new B().method(); +[WILDCARD] \ No newline at end of file diff --git a/tests/testdata/bundle/decorators/ts_decorators.ts b/tests/testdata/bundle/decorators/ts_decorators.ts new file mode 100644 index 000000000..61299bccf --- /dev/null +++ b/tests/testdata/bundle/decorators/ts_decorators.ts @@ -0,0 +1,25 @@ +// deno-lint-ignore-file + +import { B } from "../../subdir/more_decorators.ts"; + +function Decorator() { + return function ( + target: Record, + propertyKey: string, + descriptor: TypedPropertyDescriptor, + ) { + const originalFn: Function = descriptor.value as Function; + descriptor.value = async function (...args: any[]) { + return await originalFn.apply(this, args); + }; + return descriptor; + }; +} + +class SomeClass { + @Decorator() + async test() {} +} + +new SomeClass().test(); +new B().method(); diff --git a/tests/testdata/bundle/dynamic_import.ts b/tests/testdata/bundle/dynamic_import.ts new file mode 100644 index 000000000..d8c7d08ec --- /dev/null +++ b/tests/testdata/bundle/dynamic_import.ts @@ -0,0 +1,3 @@ +const mod1 = await import("http://localhost:4545/subdir/mod1.ts"); + +mod1.printHello3(); diff --git a/tests/testdata/bundle/file_extensions/js_without_extension.out b/tests/testdata/bundle/file_extensions/js_without_extension.out new file mode 100644 index 000000000..0273e6207 --- /dev/null +++ b/tests/testdata/bundle/file_extensions/js_without_extension.out @@ -0,0 +1,8 @@ +[WILDCARD] +// deno-fmt-ignore-file +// deno-lint-ignore-file +// This code was bundled using `deno bundle` and it's not recommended to edit it manually + +"hello"; +console.log("executing javascript with no extension"); + diff --git a/tests/testdata/bundle/file_extensions/ts_without_extension.out b/tests/testdata/bundle/file_extensions/ts_without_extension.out new file mode 100644 index 000000000..39e355d14 --- /dev/null +++ b/tests/testdata/bundle/file_extensions/ts_without_extension.out @@ -0,0 +1,7 @@ +[WILDCARD] +// deno-fmt-ignore-file +// deno-lint-ignore-file +// This code was bundled using `deno bundle` and it's not recommended to edit it manually + +console.log("executing typescript with no extension"); + diff --git a/tests/testdata/bundle/file_tests-fixture01.ts b/tests/testdata/bundle/file_tests-fixture01.ts new file mode 100644 index 000000000..3598d0298 --- /dev/null +++ b/tests/testdata/bundle/file_tests-fixture01.ts @@ -0,0 +1,3 @@ +import * as a from "./subdir/a.ts"; + +console.log(a); diff --git a/tests/testdata/bundle/file_tests-fixture02.ts b/tests/testdata/bundle/file_tests-fixture02.ts new file mode 100644 index 000000000..0cd291329 --- /dev/null +++ b/tests/testdata/bundle/file_tests-fixture02.ts @@ -0,0 +1,4 @@ +import * as b from "./subdir/b.ts"; + +console.log(b.b); // "b" +console.log(b.c); // { c: "c", default: class C } diff --git a/tests/testdata/bundle/file_tests-fixture03.ts b/tests/testdata/bundle/file_tests-fixture03.ts new file mode 100644 index 000000000..78365ce13 --- /dev/null +++ b/tests/testdata/bundle/file_tests-fixture03.ts @@ -0,0 +1,3 @@ +import { d } from "./subdir/d.ts"; + +console.log(d); diff --git a/tests/testdata/bundle/file_tests-fixture04.ts b/tests/testdata/bundle/file_tests-fixture04.ts new file mode 100644 index 000000000..590f4fef9 --- /dev/null +++ b/tests/testdata/bundle/file_tests-fixture04.ts @@ -0,0 +1,3 @@ +const a = await import("./subdir/a.ts"); + +console.log(a); diff --git a/tests/testdata/bundle/file_tests-fixture05.ts b/tests/testdata/bundle/file_tests-fixture05.ts new file mode 100644 index 000000000..19541ce59 --- /dev/null +++ b/tests/testdata/bundle/file_tests-fixture05.ts @@ -0,0 +1,3 @@ +import { a } from "./subdir/e.ts"; + +console.log(a); diff --git a/tests/testdata/bundle/file_tests-fixture06.ts b/tests/testdata/bundle/file_tests-fixture06.ts new file mode 100644 index 000000000..3d94332df --- /dev/null +++ b/tests/testdata/bundle/file_tests-fixture06.ts @@ -0,0 +1,4 @@ +import { isMain, modUrl } from "./subdir/f.ts"; + +console.log(isMain, modUrl); +console.log(import.meta.main, import.meta.url); diff --git a/tests/testdata/bundle/file_tests-fixture07.ts b/tests/testdata/bundle/file_tests-fixture07.ts new file mode 100644 index 000000000..0475a6c53 --- /dev/null +++ b/tests/testdata/bundle/file_tests-fixture07.ts @@ -0,0 +1,4 @@ +import { G } from "./subdir/g.ts"; +import { H } from "./subdir/h.ts"; + +console.log(new G(true), new H(true)); diff --git a/tests/testdata/bundle/file_tests-fixture08.ts b/tests/testdata/bundle/file_tests-fixture08.ts new file mode 100644 index 000000000..6af5d172e --- /dev/null +++ b/tests/testdata/bundle/file_tests-fixture08.ts @@ -0,0 +1 @@ +export * as a from "./subdir/a.ts"; diff --git a/tests/testdata/bundle/file_tests-fixture09.ts b/tests/testdata/bundle/file_tests-fixture09.ts new file mode 100644 index 000000000..30ba983ee --- /dev/null +++ b/tests/testdata/bundle/file_tests-fixture09.ts @@ -0,0 +1 @@ +export { a } from "./subdir/k.ts"; diff --git a/tests/testdata/bundle/file_tests-fixture10.ts b/tests/testdata/bundle/file_tests-fixture10.ts new file mode 100644 index 000000000..bec555da8 --- /dev/null +++ b/tests/testdata/bundle/file_tests-fixture10.ts @@ -0,0 +1,7 @@ +import { a as defaultA } from "./subdir/l.ts"; + +const o: { a?: string } = {}; + +const { a = defaultA } = o; + +console.log(a); diff --git a/tests/testdata/bundle/file_tests-fixture11.ts b/tests/testdata/bundle/file_tests-fixture11.ts new file mode 100644 index 000000000..1c361438f --- /dev/null +++ b/tests/testdata/bundle/file_tests-fixture11.ts @@ -0,0 +1,32 @@ +import { a as defaultA, O } from "./subdir/m.ts"; +export { O } from "./subdir/m.ts"; + +interface AOptions { + a?(); + c?: O; +} + +class A { + #a: () => void; + #c?: O; + constructor(o: AOptions = {}) { + const { + a = defaultA, + c, + } = o; + this.#a = a; + this.#c = c; + } + + a() { + this.#a(); + } + + c() { + console.log(this.#c); + } +} + +const a = new A(); +a.a(); +a.c(); diff --git a/tests/testdata/bundle/file_tests-fixture12.ts b/tests/testdata/bundle/file_tests-fixture12.ts new file mode 100644 index 000000000..32b9566bd --- /dev/null +++ b/tests/testdata/bundle/file_tests-fixture12.ts @@ -0,0 +1,7 @@ +import { a } from "./subdir/p.ts"; + +function b() { + a(); +} + +b(); diff --git a/tests/testdata/bundle/file_tests-fixture13.ts b/tests/testdata/bundle/file_tests-fixture13.ts new file mode 100644 index 000000000..7dc13534c --- /dev/null +++ b/tests/testdata/bundle/file_tests-fixture13.ts @@ -0,0 +1,11 @@ +import { D, d } from "./subdir/q.ts"; + +class A { + private s: D = d(); + + a() { + this.s.resolve(); + } +} + +new A(); diff --git a/tests/testdata/bundle/file_tests-fixture14.ts b/tests/testdata/bundle/file_tests-fixture14.ts new file mode 100644 index 000000000..aa8eef1b8 --- /dev/null +++ b/tests/testdata/bundle/file_tests-fixture14.ts @@ -0,0 +1,4 @@ +// @deno-types="https://deno.land/x/lib/mod.d.ts" +import * as lib from "https://deno.land/x/lib/mod.js"; + +console.log(lib); diff --git a/tests/testdata/bundle/file_tests-fixture15.ts b/tests/testdata/bundle/file_tests-fixture15.ts new file mode 100644 index 000000000..c1dd3bc89 --- /dev/null +++ b/tests/testdata/bundle/file_tests-fixture15.ts @@ -0,0 +1,3 @@ +export function getIndex(c: string): number { + return "\x00\r\n\x85\u2028\u2029".indexOf(c); +} diff --git a/tests/testdata/bundle/file_tests-fixture16.ts b/tests/testdata/bundle/file_tests-fixture16.ts new file mode 100644 index 000000000..5d0b05e92 --- /dev/null +++ b/tests/testdata/bundle/file_tests-fixture16.ts @@ -0,0 +1,6 @@ +// todo(dsherret): use ./subdir/a.ts once fixtures are restored +export { a as test1 } from "./file_tests-fixture16_2.ts"; +export { a as test2 } from "./file_tests-fixture16_2.ts"; +import { a } from "./file_tests-fixture16_2.ts"; + +console.log(a); diff --git a/tests/testdata/bundle/file_tests-fixture16_2.ts b/tests/testdata/bundle/file_tests-fixture16_2.ts new file mode 100644 index 000000000..7115949c9 --- /dev/null +++ b/tests/testdata/bundle/file_tests-fixture16_2.ts @@ -0,0 +1,2 @@ +// todo(dsherret): delete this and use ./subdir/a.ts in the file once fixtures are restored +export const a = "a"; diff --git a/tests/testdata/bundle/file_tests-subdir-a.ts b/tests/testdata/bundle/file_tests-subdir-a.ts new file mode 100644 index 000000000..9233cce2f --- /dev/null +++ b/tests/testdata/bundle/file_tests-subdir-a.ts @@ -0,0 +1 @@ +export const a = "a"; diff --git a/tests/testdata/bundle/file_tests-subdir-b.ts b/tests/testdata/bundle/file_tests-subdir-b.ts new file mode 100644 index 000000000..1cf751c22 --- /dev/null +++ b/tests/testdata/bundle/file_tests-subdir-b.ts @@ -0,0 +1,3 @@ +export * as c from "./c.ts"; + +export const b = "b"; diff --git a/tests/testdata/bundle/file_tests-subdir-c.ts b/tests/testdata/bundle/file_tests-subdir-c.ts new file mode 100644 index 000000000..7cc01f993 --- /dev/null +++ b/tests/testdata/bundle/file_tests-subdir-c.ts @@ -0,0 +1,2 @@ +export const c = "c"; +export default class C {} diff --git a/tests/testdata/bundle/file_tests-subdir-d.ts b/tests/testdata/bundle/file_tests-subdir-d.ts new file mode 100644 index 000000000..9f1ba7f67 --- /dev/null +++ b/tests/testdata/bundle/file_tests-subdir-d.ts @@ -0,0 +1,3 @@ +import { a } from "./a.ts"; + +export const d = { a }; diff --git a/tests/testdata/bundle/file_tests-subdir-e.ts b/tests/testdata/bundle/file_tests-subdir-e.ts new file mode 100644 index 000000000..55e8e0e18 --- /dev/null +++ b/tests/testdata/bundle/file_tests-subdir-e.ts @@ -0,0 +1 @@ +export * from "./a.ts"; diff --git a/tests/testdata/bundle/file_tests-subdir-f.ts b/tests/testdata/bundle/file_tests-subdir-f.ts new file mode 100644 index 000000000..8bc8d9bf4 --- /dev/null +++ b/tests/testdata/bundle/file_tests-subdir-f.ts @@ -0,0 +1,2 @@ +export const isMain = import.meta.main; +export const modUrl = import.meta.url; diff --git a/tests/testdata/bundle/file_tests-subdir-g.ts b/tests/testdata/bundle/file_tests-subdir-g.ts new file mode 100644 index 000000000..3eb4cd3cc --- /dev/null +++ b/tests/testdata/bundle/file_tests-subdir-g.ts @@ -0,0 +1,12 @@ +const g: number[] = []; + +export class G { + #g!: number[]; + constructor(shared: boolean) { + if (shared) { + this.#g = g; + } else { + this.#g = []; + } + } +} diff --git a/tests/testdata/bundle/file_tests-subdir-h.ts b/tests/testdata/bundle/file_tests-subdir-h.ts new file mode 100644 index 000000000..9c86dd5c5 --- /dev/null +++ b/tests/testdata/bundle/file_tests-subdir-h.ts @@ -0,0 +1,12 @@ +const g: number[] = []; + +export class H { + #g!: number[]; + constructor(shared: boolean) { + if (shared) { + this.#g = g; + } else { + this.#g = []; + } + } +} diff --git a/tests/testdata/bundle/file_tests-subdir-i.ts b/tests/testdata/bundle/file_tests-subdir-i.ts new file mode 100644 index 000000000..4ad9ce449 --- /dev/null +++ b/tests/testdata/bundle/file_tests-subdir-i.ts @@ -0,0 +1,3 @@ +export function a(...d: string[]): string { + return d.join(" "); +} diff --git a/tests/testdata/bundle/file_tests-subdir-j.ts b/tests/testdata/bundle/file_tests-subdir-j.ts new file mode 100644 index 000000000..ac7bce0ea --- /dev/null +++ b/tests/testdata/bundle/file_tests-subdir-j.ts @@ -0,0 +1,3 @@ +export function a(...d: string[]): string { + return d.join("/"); +} diff --git a/tests/testdata/bundle/file_tests-subdir-k.ts b/tests/testdata/bundle/file_tests-subdir-k.ts new file mode 100644 index 000000000..1b8a533f1 --- /dev/null +++ b/tests/testdata/bundle/file_tests-subdir-k.ts @@ -0,0 +1,11 @@ +import * as _i from "./i.ts"; +import * as _j from "./j.ts"; + +const k = globalThis.value ? _i : _j; + +export const i = _i; +export const j = _j; + +export const { + a, +} = k; diff --git a/tests/testdata/bundle/file_tests-subdir-l.ts b/tests/testdata/bundle/file_tests-subdir-l.ts new file mode 100644 index 000000000..d767e6ad0 --- /dev/null +++ b/tests/testdata/bundle/file_tests-subdir-l.ts @@ -0,0 +1 @@ +export { a } from "./a.ts"; diff --git a/tests/testdata/bundle/file_tests-subdir-m.ts b/tests/testdata/bundle/file_tests-subdir-m.ts new file mode 100644 index 000000000..21e86d07c --- /dev/null +++ b/tests/testdata/bundle/file_tests-subdir-m.ts @@ -0,0 +1,2 @@ +export { a } from "./n.ts"; +export { O } from "./o.ts"; diff --git a/tests/testdata/bundle/file_tests-subdir-n.ts b/tests/testdata/bundle/file_tests-subdir-n.ts new file mode 100644 index 000000000..ac3c37005 --- /dev/null +++ b/tests/testdata/bundle/file_tests-subdir-n.ts @@ -0,0 +1,3 @@ +export function a() { + console.log("a"); +} diff --git a/tests/testdata/bundle/file_tests-subdir-o.ts b/tests/testdata/bundle/file_tests-subdir-o.ts new file mode 100644 index 000000000..ab9753fea --- /dev/null +++ b/tests/testdata/bundle/file_tests-subdir-o.ts @@ -0,0 +1,5 @@ +export enum O { + A, + B, + C, +} diff --git a/tests/testdata/bundle/file_tests-subdir-p.ts b/tests/testdata/bundle/file_tests-subdir-p.ts new file mode 100644 index 000000000..19b486f71 --- /dev/null +++ b/tests/testdata/bundle/file_tests-subdir-p.ts @@ -0,0 +1 @@ +export * from "./i.ts"; diff --git a/tests/testdata/bundle/file_tests-subdir-q.ts b/tests/testdata/bundle/file_tests-subdir-q.ts new file mode 100644 index 000000000..eebe0a38b --- /dev/null +++ b/tests/testdata/bundle/file_tests-subdir-q.ts @@ -0,0 +1,13 @@ +// deno-lint-ignore-file +export interface D { + resolve: any; + reject: any; +} + +export function d(): D { + let methods; + const promise = new Promise((resolve, reject) => { + methods = { resolve, reject }; + }); + return Object.assign(promise, methods); +} diff --git a/tests/testdata/bundle/fixture01.out b/tests/testdata/bundle/fixture01.out new file mode 100644 index 000000000..a825140b7 --- /dev/null +++ b/tests/testdata/bundle/fixture01.out @@ -0,0 +1,7 @@ +const a = "a"; +const mod = function() { + return { + a: a + }; +}(); +console.log(mod); diff --git a/tests/testdata/bundle/fixture02.out b/tests/testdata/bundle/fixture02.out new file mode 100644 index 000000000..5c502e2f0 --- /dev/null +++ b/tests/testdata/bundle/fixture02.out @@ -0,0 +1,12 @@ +const c = "c"; +class C { +} +const mod = function() { + return { + default: C, + c: c + }; +}(); +const b = "b"; +console.log(b); +console.log(mod); diff --git a/tests/testdata/bundle/fixture03.out b/tests/testdata/bundle/fixture03.out new file mode 100644 index 000000000..524e77abb --- /dev/null +++ b/tests/testdata/bundle/fixture03.out @@ -0,0 +1,5 @@ +const a = "a"; +const d = { + a +}; +console.log(d); diff --git a/tests/testdata/bundle/fixture04.out b/tests/testdata/bundle/fixture04.out new file mode 100644 index 000000000..37869205b --- /dev/null +++ b/tests/testdata/bundle/fixture04.out @@ -0,0 +1,2 @@ +const a = await import("./subdir/a.ts"); +console.log(a); diff --git a/tests/testdata/bundle/fixture05.out b/tests/testdata/bundle/fixture05.out new file mode 100644 index 000000000..1289cca5f --- /dev/null +++ b/tests/testdata/bundle/fixture05.out @@ -0,0 +1,2 @@ +const a = "a"; +console.log(a); diff --git a/tests/testdata/bundle/fixture06.out b/tests/testdata/bundle/fixture06.out new file mode 100644 index 000000000..47288d5e4 --- /dev/null +++ b/tests/testdata/bundle/fixture06.out @@ -0,0 +1,12 @@ +const importMeta = { + url: "file:///tests/subdir/f.ts", + main: false +}; +const isMain = importMeta.main; +const modUrl = importMeta.url; +const importMeta1 = { + url: "file:///tests/fixture06.ts", + main: import.meta.main +}; +console.log(isMain, modUrl); +console.log(importMeta1.main, importMeta1.url); diff --git a/tests/testdata/bundle/fixture07.out b/tests/testdata/bundle/fixture07.out new file mode 100644 index 000000000..39e6a11e8 --- /dev/null +++ b/tests/testdata/bundle/fixture07.out @@ -0,0 +1,23 @@ +const g = []; +class G { + #g; + constructor(shared){ + if (shared) { + this.#g = g; + } else { + this.#g = []; + } + } +} +const g1 = []; +class H { + #g; + constructor(shared1){ + if (shared1) { + this.#g = g1; + } else { + this.#g = []; + } + } +} +console.log(new G(true), new H(true)); diff --git a/tests/testdata/bundle/fixture08.out b/tests/testdata/bundle/fixture08.out new file mode 100644 index 000000000..bfe40aa37 --- /dev/null +++ b/tests/testdata/bundle/fixture08.out @@ -0,0 +1,7 @@ +const a1 = "a"; +const mod = function() { + return { + a: a1 + }; +}(); +export { mod as a }; diff --git a/tests/testdata/bundle/fixture09.out b/tests/testdata/bundle/fixture09.out new file mode 100644 index 000000000..e06cc92de --- /dev/null +++ b/tests/testdata/bundle/fixture09.out @@ -0,0 +1,19 @@ +function a3(...d) { + return d.join(" "); +} +const mod = function() { + return { + a: a3 + }; +}(); +function a1(...d) { + return d.join("/"); +} +const mod1 = function() { + return { + a: a1 + }; +}(); +const k = globalThis.value ? mod : mod1; +const { a: a2 , } = k; +export { a2 as a }; diff --git a/tests/testdata/bundle/fixture10.out b/tests/testdata/bundle/fixture10.out new file mode 100644 index 000000000..5491e5e7f --- /dev/null +++ b/tests/testdata/bundle/fixture10.out @@ -0,0 +1,5 @@ +const a = "a"; +const o = { +}; +const { a: a1 = a } = o; +console.log(a1); diff --git a/tests/testdata/bundle/fixture11.out b/tests/testdata/bundle/fixture11.out new file mode 100644 index 000000000..4f333a513 --- /dev/null +++ b/tests/testdata/bundle/fixture11.out @@ -0,0 +1,30 @@ +function a() { + console.log("a"); +} +var O1; +(function(O) { + O[O["A"] = 0] = "A"; + O[O["B"] = 1] = "B"; + O[O["C"] = 2] = "C"; +})(O1 || (O1 = { +})); +export { O1 as O }; +class A { + #a; + #c; + constructor(o = { + }){ + const { a: a1 = a , c , } = o; + this.#a = a1; + this.#c = c; + } + a() { + this.#a(); + } + c() { + console.log(this.#c); + } +} +const a2 = new A(); +a2.a(); +a2.c(); diff --git a/tests/testdata/bundle/fixture12.out b/tests/testdata/bundle/fixture12.out new file mode 100644 index 000000000..64e2d6cdb --- /dev/null +++ b/tests/testdata/bundle/fixture12.out @@ -0,0 +1,7 @@ +function a(...d) { + return d.join(" "); +} +function b() { + a(); +} +b(); diff --git a/tests/testdata/bundle/fixture13.out b/tests/testdata/bundle/fixture13.out new file mode 100644 index 000000000..1c7a8c991 --- /dev/null +++ b/tests/testdata/bundle/fixture13.out @@ -0,0 +1,17 @@ +function d() { + let methods; + const promise = new Promise((resolve, reject)=>{ + methods = { + resolve, + reject + }; + }); + return Object.assign(promise, methods); +} +class A { + s = d(); + a() { + this.s.resolve(); + } +} +new A(); diff --git a/tests/testdata/bundle/fixture14.out b/tests/testdata/bundle/fixture14.out new file mode 100644 index 000000000..392bb6478 --- /dev/null +++ b/tests/testdata/bundle/fixture14.out @@ -0,0 +1,2 @@ +const mod = []; +console.log(mod); diff --git a/tests/testdata/bundle/fixture15.out b/tests/testdata/bundle/fixture15.out new file mode 100644 index 000000000..dc72fdeff --- /dev/null +++ b/tests/testdata/bundle/fixture15.out @@ -0,0 +1,4 @@ +function getIndex1(c) { + return "\x00\r\n\x85\u2028\u2029".indexOf(c); +} +export { getIndex1 as getIndex }; diff --git a/tests/testdata/bundle/fixture16.out b/tests/testdata/bundle/fixture16.out new file mode 100644 index 000000000..5e21c2a71 --- /dev/null +++ b/tests/testdata/bundle/fixture16.out @@ -0,0 +1,6 @@ +[WILDCARD] +const a = "a"; +export { a as test1 }; +export { a as test2 }; +console.log(a); + diff --git a/tests/testdata/bundle/https_deno.land-x-lib-a.ts b/tests/testdata/bundle/https_deno.land-x-lib-a.ts new file mode 100644 index 000000000..a0a6f8e94 --- /dev/null +++ b/tests/testdata/bundle/https_deno.land-x-lib-a.ts @@ -0,0 +1 @@ +export const a: string[] = []; diff --git a/tests/testdata/bundle/https_deno.land-x-lib-b.js b/tests/testdata/bundle/https_deno.land-x-lib-b.js new file mode 100644 index 000000000..13cacdd8b --- /dev/null +++ b/tests/testdata/bundle/https_deno.land-x-lib-b.js @@ -0,0 +1 @@ +export const b = []; diff --git a/tests/testdata/bundle/https_deno.land-x-lib-c.d.ts b/tests/testdata/bundle/https_deno.land-x-lib-c.d.ts new file mode 100644 index 000000000..fac988e49 --- /dev/null +++ b/tests/testdata/bundle/https_deno.land-x-lib-c.d.ts @@ -0,0 +1 @@ +export const c: string[]; diff --git a/tests/testdata/bundle/https_deno.land-x-lib-c.js b/tests/testdata/bundle/https_deno.land-x-lib-c.js new file mode 100644 index 000000000..620ca0b66 --- /dev/null +++ b/tests/testdata/bundle/https_deno.land-x-lib-c.js @@ -0,0 +1,3 @@ +/// + +export const c = []; diff --git a/tests/testdata/bundle/https_deno.land-x-lib-mod.d.ts b/tests/testdata/bundle/https_deno.land-x-lib-mod.d.ts new file mode 100644 index 000000000..76ed81df0 --- /dev/null +++ b/tests/testdata/bundle/https_deno.land-x-lib-mod.d.ts @@ -0,0 +1,9 @@ +export * as a from "./a.ts"; +export * as b from "./b.js"; +export * as c from "./c.js"; + +export interface A { + a: string; +} + +export const mod: A[]; diff --git a/tests/testdata/bundle/https_deno.land-x-lib-mod.js b/tests/testdata/bundle/https_deno.land-x-lib-mod.js new file mode 100644 index 000000000..505162094 --- /dev/null +++ b/tests/testdata/bundle/https_deno.land-x-lib-mod.js @@ -0,0 +1,5 @@ +export * as a from "./a.ts"; +export * as b from "./b.js"; +export * as c from "./c.js"; + +export const mod = []; diff --git a/tests/testdata/bundle/ignore_directives.test.out b/tests/testdata/bundle/ignore_directives.test.out new file mode 100644 index 000000000..b69c2632c --- /dev/null +++ b/tests/testdata/bundle/ignore_directives.test.out @@ -0,0 +1,6 @@ +[WILDCARD] +// deno-fmt-ignore-file +// deno-lint-ignore-file +// This code was bundled using `deno bundle` and it's not recommended to edit it manually + +[WILDCARD] diff --git a/tests/testdata/bundle/import_map/import_map.json b/tests/testdata/bundle/import_map/import_map.json new file mode 100644 index 000000000..c02f72718 --- /dev/null +++ b/tests/testdata/bundle/import_map/import_map.json @@ -0,0 +1,5 @@ +{ + "imports": { + "mod2": "../../subdir/subdir2/mod2.ts" + } +} diff --git a/tests/testdata/bundle/import_map/main.ts b/tests/testdata/bundle/import_map/main.ts new file mode 100644 index 000000000..74834de20 --- /dev/null +++ b/tests/testdata/bundle/import_map/main.ts @@ -0,0 +1,17 @@ +import { printHello2, returnsFoo } from "mod2"; + +export function returnsHi(): string { + return "Hi"; +} + +export function returnsFoo2(): string { + return returnsFoo(); +} + +export function printHello3() { + printHello2(); +} + +export function throwsError() { + throw Error("exception from mod1"); +} diff --git a/tests/testdata/bundle/jsx.out b/tests/testdata/bundle/jsx.out new file mode 100644 index 000000000..da83cde82 --- /dev/null +++ b/tests/testdata/bundle/jsx.out @@ -0,0 +1,9 @@ +[WILDCARD] +const React = { + createElement () {} +}; +function app() { + return React.createElement("div", null, React.createElement("h2", null, "asdf")); +} +console.log(app); + diff --git a/tests/testdata/bundle/lockfile/check_error.json b/tests/testdata/bundle/lockfile/check_error.json new file mode 100644 index 000000000..a218d7000 --- /dev/null +++ b/tests/testdata/bundle/lockfile/check_error.json @@ -0,0 +1,5 @@ +{ + "http://127.0.0.1:4545/subdir/mod1.ts": "bfc1037b02c99abc20367f739bca7455813a5950066abd77965bff33b6eece0f", + "http://127.0.0.1:4545/subdir/print_hello.ts": "fa6692c8f9ff3fb107e773c3ece5274e9d08be282867a1e3ded1d9c00fcaa63c", + "http://127.0.0.1:4545/subdir/subdir2/mod2.ts": "bad" +} diff --git a/tests/testdata/bundle/lockfile/check_error.out b/tests/testdata/bundle/lockfile/check_error.out new file mode 100644 index 000000000..9299bc27e --- /dev/null +++ b/tests/testdata/bundle/lockfile/check_error.out @@ -0,0 +1,4 @@ +[WILDCARD] +error: The source code is invalid, as it does not match the expected hash in the lock file. + Specifier: http://127.0.0.1:4545/subdir/subdir2/mod2.ts + Lock file: bundle/lockfile/check_error.json diff --git a/tests/testdata/bundle/shebang_file.bundle.out b/tests/testdata/bundle/shebang_file.bundle.out new file mode 100644 index 000000000..d3369bc9c --- /dev/null +++ b/tests/testdata/bundle/shebang_file.bundle.out @@ -0,0 +1,12 @@ +⚠️ Warning: `deno bundle` is deprecated and will be removed in Deno 2.0. +Use an alternative bundler like "deno_emit", "esbuild" or "rollup" instead. +Bundle file:///[WILDCARD]/subdir/shebang_file.js +#!/usr/bin/env -S deno run --allow-read +// deno-fmt-ignore-file +// deno-lint-ignore-file +// This code was bundled using `deno bundle` and it's not recommended to edit it manually + +for (const item of Deno.readDirSync(".")){ + console.log(item.name); +} + diff --git a/tests/testdata/cache/036_import_map_fetch.out b/tests/testdata/cache/036_import_map_fetch.out new file mode 100644 index 000000000..e69de29bb diff --git a/tests/testdata/cache/037_fetch_multiple.out b/tests/testdata/cache/037_fetch_multiple.out new file mode 100644 index 000000000..f4c0c314b --- /dev/null +++ b/tests/testdata/cache/037_fetch_multiple.out @@ -0,0 +1,5 @@ +Download http://localhost:4545/subdir/mod2.ts +Download http://localhost:4545/subdir/mt_text_typescript.t1.ts +Download http://localhost:4545/subdir/print_hello.ts +Check [WILDCARD]/fetch/test.ts +Check [WILDCARD]/fetch/other.ts diff --git a/tests/testdata/cache/095_cache_with_bare_import.ts b/tests/testdata/cache/095_cache_with_bare_import.ts new file mode 100644 index 000000000..c0748305d --- /dev/null +++ b/tests/testdata/cache/095_cache_with_bare_import.ts @@ -0,0 +1 @@ +import "foo"; diff --git a/tests/testdata/cache/095_cache_with_bare_import.ts.out b/tests/testdata/cache/095_cache_with_bare_import.ts.out new file mode 100644 index 000000000..2668a6e08 --- /dev/null +++ b/tests/testdata/cache/095_cache_with_bare_import.ts.out @@ -0,0 +1,2 @@ +[WILDCARD]error: Relative import path "foo" not prefixed with / or ./ or ../ + at file:///[WILDCARD]/095_cache_with_bare_import.ts:[WILDCARD] diff --git a/tests/testdata/cache/cache_extensionless.out b/tests/testdata/cache/cache_extensionless.out new file mode 100644 index 000000000..3694c67cb --- /dev/null +++ b/tests/testdata/cache/cache_extensionless.out @@ -0,0 +1,2 @@ +[WILDCARD] +Check http://localhost:4545/subdir/no_js_ext diff --git a/tests/testdata/cache/cache_random_extension.out b/tests/testdata/cache/cache_random_extension.out new file mode 100644 index 000000000..745a2e0e3 --- /dev/null +++ b/tests/testdata/cache/cache_random_extension.out @@ -0,0 +1,2 @@ +[WILDCARD] +Check http://localhost:4545/subdir/no_js_ext@1.0.0 diff --git a/tests/testdata/cache/check_local_by_default.out b/tests/testdata/cache/check_local_by_default.out new file mode 100644 index 000000000..e69de29bb diff --git a/tests/testdata/cache/check_local_by_default.ts b/tests/testdata/cache/check_local_by_default.ts new file mode 100644 index 000000000..2ae8c2692 --- /dev/null +++ b/tests/testdata/cache/check_local_by_default.ts @@ -0,0 +1,3 @@ +import * as a from "http://localhost:4545/subdir/type_error.ts"; + +console.log(a.a); diff --git a/tests/testdata/cache/check_local_by_default2.out b/tests/testdata/cache/check_local_by_default2.out new file mode 100644 index 000000000..e69de29bb diff --git a/tests/testdata/cache/check_local_by_default2.ts b/tests/testdata/cache/check_local_by_default2.ts new file mode 100644 index 000000000..5177ff944 --- /dev/null +++ b/tests/testdata/cache/check_local_by_default2.ts @@ -0,0 +1,6 @@ +import * as a from "http://localhost:4545/subdir/type_error.ts"; + +const b: "b" = 12; + +console.log(a.a); +console.log(b); diff --git a/tests/testdata/cache/ignore_require.js b/tests/testdata/cache/ignore_require.js new file mode 100644 index 000000000..a8ef15021 --- /dev/null +++ b/tests/testdata/cache/ignore_require.js @@ -0,0 +1,2 @@ +// deno-lint-ignore-file +require("invalid module specifier"); diff --git a/tests/testdata/cache/json_import/main.ts b/tests/testdata/cache/json_import/main.ts new file mode 100644 index 000000000..78273558f --- /dev/null +++ b/tests/testdata/cache/json_import/main.ts @@ -0,0 +1,2 @@ +import asdf from "./test.json" assert { type: "json" }; +console.log(asdf); diff --git a/tests/testdata/cache/json_import/test.json b/tests/testdata/cache/json_import/test.json new file mode 100644 index 000000000..258849a68 --- /dev/null +++ b/tests/testdata/cache/json_import/test.json @@ -0,0 +1,5 @@ +{ + "foo": { + "bar": 1 + } +} diff --git a/tests/testdata/cache/performance_stats.out b/tests/testdata/cache/performance_stats.out new file mode 100644 index 000000000..141829ee6 --- /dev/null +++ b/tests/testdata/cache/performance_stats.out @@ -0,0 +1,16 @@ +[WILDCARD] +DEBUG RS - [WILDCARD] - Compilation statistics: + Files: [WILDCARD] + Nodes: [WILDCARD] + Identifiers: [WILDCARD] + Symbols: [WILDCARD] + Types: [WILDCARD] + Instantiations: [WILDCARD] + Parse time: [WILDCARD] + Bind time: [WILDCARD] + Check time: [WILDCARD] + Emit time: [WILDCARD] + Total TS time: [WILDCARD] + Compile time: [WILDCARD] + +[WILDCARD] diff --git a/tests/testdata/cache/redirect_cache.out b/tests/testdata/cache/redirect_cache.out new file mode 100644 index 000000000..8905c4529 --- /dev/null +++ b/tests/testdata/cache/redirect_cache.out @@ -0,0 +1,5 @@ +Download http://localhost:4548/subdir/redirects/a.ts +Download http://localhost:4546/subdir/redirects/a.ts +Download http://localhost:4545/subdir/redirects/a.ts +Download http://localhost:4545/subdir/redirects/b.ts +Check http://localhost:4548/subdir/redirects/a.ts diff --git a/tests/testdata/cat.ts b/tests/testdata/cat.ts new file mode 100644 index 000000000..f0205451e --- /dev/null +++ b/tests/testdata/cat.ts @@ -0,0 +1,10 @@ +import { copy } from "../../test_util/std/streams/copy.ts"; +async function main() { + for (let i = 1; i < Deno.args.length; i++) { + const filename = Deno.args[i]; + const file = await Deno.open(filename); + await copy(file, Deno.stdout); + } +} + +main(); diff --git a/tests/testdata/cert/cafile_info.ts b/tests/testdata/cert/cafile_info.ts new file mode 100644 index 000000000..b41873f73 --- /dev/null +++ b/tests/testdata/cert/cafile_info.ts @@ -0,0 +1,24 @@ +// When run against the test HTTP server, it will serve different media types +// based on the URL containing `.t#.` strings, which exercises the different +// mapping of media types end to end. + +import { loaded as loadedTs1 } from "https://localhost:5545/subdir/mt_text_typescript.t1.ts"; +import { loaded as loadedTs2 } from "https://localhost:5545/subdir/mt_video_vdn.t2.ts"; +import { loaded as loadedTs3 } from "https://localhost:5545/subdir/mt_video_mp2t.t3.ts"; +import { loaded as loadedTs4 } from "https://localhost:5545/subdir/mt_application_x_typescript.t4.ts"; +import { loaded as loadedJs1 } from "https://localhost:5545/subdir/mt_text_javascript.j1.js"; +import { loaded as loadedJs2 } from "https://localhost:5545/subdir/mt_application_ecmascript.j2.js"; +import { loaded as loadedJs3 } from "https://localhost:5545/subdir/mt_text_ecmascript.j3.js"; +import { loaded as loadedJs4 } from "https://localhost:5545/subdir/mt_application_x_javascript.j4.js"; + +console.log( + "success", + loadedTs1, + loadedTs2, + loadedTs3, + loadedTs4, + loadedJs1, + loadedJs2, + loadedJs3, + loadedJs4, +); diff --git a/tests/testdata/cert/cafile_info.ts.out b/tests/testdata/cert/cafile_info.ts.out new file mode 100644 index 000000000..279453f88 --- /dev/null +++ b/tests/testdata/cert/cafile_info.ts.out @@ -0,0 +1,14 @@ +local: [WILDCARD]https[WILDCARD]localhost_PORT5545[WILDCARD] +type: TypeScript +dependencies: 8 unique +size: [WILDCARD] + +https://localhost:5545/cert/cafile_info.ts ([WILDCARD]) +├── https://localhost:5545/subdir/mt_text_typescript.t1.ts ([WILDCARD]) +├── https://localhost:5545/subdir/mt_video_vdn.t2.ts ([WILDCARD]) +├── https://localhost:5545/subdir/mt_video_mp2t.t3.ts ([WILDCARD]) +├── https://localhost:5545/subdir/mt_application_x_typescript.t4.ts ([WILDCARD]) +├── https://localhost:5545/subdir/mt_text_javascript.j1.js ([WILDCARD]) +├── https://localhost:5545/subdir/mt_application_ecmascript.j2.js ([WILDCARD]) +├── https://localhost:5545/subdir/mt_text_ecmascript.j3.js ([WILDCARD]) +└── https://localhost:5545/subdir/mt_application_x_javascript.j4.js ([WILDCARD]) diff --git a/tests/testdata/cert/cafile_ts_fetch.ts b/tests/testdata/cert/cafile_ts_fetch.ts new file mode 100644 index 000000000..12fcda007 --- /dev/null +++ b/tests/testdata/cert/cafile_ts_fetch.ts @@ -0,0 +1,3 @@ +fetch("https://localhost:5545/cert/cafile_ts_fetch.ts.out") + .then((r) => r.text()) + .then((t) => console.log(t.trimEnd())); diff --git a/tests/testdata/cert/cafile_ts_fetch.ts.out b/tests/testdata/cert/cafile_ts_fetch.ts.out new file mode 100644 index 000000000..699b756ed --- /dev/null +++ b/tests/testdata/cert/cafile_ts_fetch.ts.out @@ -0,0 +1,2 @@ +[WILDCARD] +Hello diff --git a/tests/testdata/cert/cafile_ts_fetch_unsafe_ssl.ts.out b/tests/testdata/cert/cafile_ts_fetch_unsafe_ssl.ts.out new file mode 100644 index 000000000..a0934e584 --- /dev/null +++ b/tests/testdata/cert/cafile_ts_fetch_unsafe_ssl.ts.out @@ -0,0 +1,3 @@ +DANGER: TLS certificate validation is disabled for all hostnames +[WILDCARD] +Hello diff --git a/tests/testdata/cert/cafile_url_imports.ts b/tests/testdata/cert/cafile_url_imports.ts new file mode 100644 index 000000000..2355a8628 --- /dev/null +++ b/tests/testdata/cert/cafile_url_imports.ts @@ -0,0 +1,3 @@ +import { printHello } from "https://localhost:5545/subdir/mod2.ts"; +printHello(); +console.log("success"); diff --git a/tests/testdata/cert/cafile_url_imports.ts.out b/tests/testdata/cert/cafile_url_imports.ts.out new file mode 100644 index 000000000..989ce33e9 --- /dev/null +++ b/tests/testdata/cert/cafile_url_imports.ts.out @@ -0,0 +1,2 @@ +Hello +success diff --git a/tests/testdata/cert/cafile_url_imports_unsafe_ssl.ts.out b/tests/testdata/cert/cafile_url_imports_unsafe_ssl.ts.out new file mode 100644 index 000000000..daebcd766 --- /dev/null +++ b/tests/testdata/cert/cafile_url_imports_unsafe_ssl.ts.out @@ -0,0 +1,3 @@ +DANGER: TLS certificate validation is disabled for: localhost +Hello +success diff --git a/tests/testdata/cert/deno_land_unsafe_ssl.ts b/tests/testdata/cert/deno_land_unsafe_ssl.ts new file mode 100644 index 000000000..f5e8dcc80 --- /dev/null +++ b/tests/testdata/cert/deno_land_unsafe_ssl.ts @@ -0,0 +1,2 @@ +const r = await fetch("https://google.com"); +console.log(r.status); diff --git a/tests/testdata/cert/deno_land_unsafe_ssl.ts.out b/tests/testdata/cert/deno_land_unsafe_ssl.ts.out new file mode 100644 index 000000000..cbf52b076 --- /dev/null +++ b/tests/testdata/cert/deno_land_unsafe_ssl.ts.out @@ -0,0 +1,2 @@ +DANGER: TLS certificate validation is disabled for: deno.land +200 diff --git a/tests/testdata/cert/ip_address_unsafe_ssl.ts b/tests/testdata/cert/ip_address_unsafe_ssl.ts new file mode 100644 index 000000000..a3268888f --- /dev/null +++ b/tests/testdata/cert/ip_address_unsafe_ssl.ts @@ -0,0 +1,2 @@ +const r = await fetch("https://1.1.1.1"); +console.log(r.status); diff --git a/tests/testdata/cert/ip_address_unsafe_ssl.ts.out b/tests/testdata/cert/ip_address_unsafe_ssl.ts.out new file mode 100644 index 000000000..d4ebb2617 --- /dev/null +++ b/tests/testdata/cert/ip_address_unsafe_ssl.ts.out @@ -0,0 +1,2 @@ +DANGER: TLS certificate validation is disabled for: 1.1.1.1 +200 diff --git a/tests/testdata/cert/listen_tls_alpn.ts b/tests/testdata/cert/listen_tls_alpn.ts new file mode 100644 index 000000000..6b92364ba --- /dev/null +++ b/tests/testdata/cert/listen_tls_alpn.ts @@ -0,0 +1,14 @@ +const listener = Deno.listenTls({ + port: Number(Deno.args[0]), + cert: Deno.readTextFileSync("./tls/localhost.crt"), + key: Deno.readTextFileSync("./tls/localhost.key"), + alpnProtocols: ["h2", "http/1.1", "foobar"], +}); + +console.log("READY"); + +const conn = await listener.accept() as Deno.TlsConn; +await conn.handshake(); +conn.close(); + +listener.close(); diff --git a/tests/testdata/cert/listen_tls_alpn_fail.ts b/tests/testdata/cert/listen_tls_alpn_fail.ts new file mode 100644 index 000000000..f52316cbc --- /dev/null +++ b/tests/testdata/cert/listen_tls_alpn_fail.ts @@ -0,0 +1,20 @@ +import { assertRejects } from "../../../test_util/std/assert/mod.ts"; + +const listener = Deno.listenTls({ + port: Number(Deno.args[0]), + cert: Deno.readTextFileSync("./tls/localhost.crt"), + key: Deno.readTextFileSync("./tls/localhost.key"), + alpnProtocols: ["h2", "http/1.1", "foobar"], +}); + +console.log("READY"); + +const conn = await listener.accept() as Deno.TlsConn; +await assertRejects( + () => conn.handshake(), + Deno.errors.InvalidData, + "peer doesn't support any known protocol", +); +conn.close(); + +listener.close(); diff --git a/tests/testdata/cert/localhost_unsafe_ssl.ts.out b/tests/testdata/cert/localhost_unsafe_ssl.ts.out new file mode 100644 index 000000000..81e490c1c --- /dev/null +++ b/tests/testdata/cert/localhost_unsafe_ssl.ts.out @@ -0,0 +1,3 @@ +DANGER: TLS certificate validation is disabled for: deno.land +error: Import 'https://localhost:5545/subdir/mod2.ts' failed: error sending request for url (https://localhost:5545/subdir/mod2.ts): error trying to connect: invalid peer certificate: UnknownIssuer + at file:///[WILDCARD]/cafile_url_imports.ts:[WILDCARD] diff --git a/tests/testdata/check/all/check_all.out b/tests/testdata/check/all/check_all.out new file mode 100644 index 000000000..344264634 --- /dev/null +++ b/tests/testdata/check/all/check_all.out @@ -0,0 +1,4 @@ +error: TS2322 [ERROR]: Type '12' is not assignable to type '"a"'. +export const a: "a" = 12; + ^ + at http://localhost:4545/subdir/type_error.ts:1:14 diff --git a/tests/testdata/check/all/check_all.ts b/tests/testdata/check/all/check_all.ts new file mode 100644 index 000000000..2ae8c2692 --- /dev/null +++ b/tests/testdata/check/all/check_all.ts @@ -0,0 +1,3 @@ +import * as a from "http://localhost:4545/subdir/type_error.ts"; + +console.log(a.a); diff --git a/tests/testdata/check/broadcast_channel.ts b/tests/testdata/check/broadcast_channel.ts new file mode 100644 index 000000000..6c75b4a8e --- /dev/null +++ b/tests/testdata/check/broadcast_channel.ts @@ -0,0 +1 @@ +const _channel = new BroadcastChannel("foo"); diff --git a/tests/testdata/check/cache_config_on_off/deno.json b/tests/testdata/check/cache_config_on_off/deno.json new file mode 100644 index 000000000..8ad9c9801 --- /dev/null +++ b/tests/testdata/check/cache_config_on_off/deno.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "strict": false + } +} diff --git a/tests/testdata/check/cache_config_on_off/main.ts b/tests/testdata/check/cache_config_on_off/main.ts new file mode 100644 index 000000000..0f3785f91 --- /dev/null +++ b/tests/testdata/check/cache_config_on_off/main.ts @@ -0,0 +1 @@ +console.log(5); diff --git a/tests/testdata/check/declaration_header_file_with_no_exports.ts b/tests/testdata/check/declaration_header_file_with_no_exports.ts new file mode 100644 index 000000000..ef5da7a38 --- /dev/null +++ b/tests/testdata/check/declaration_header_file_with_no_exports.ts @@ -0,0 +1,2 @@ +import * as foo from "./declaration_header_file_with_no_exports_js.js"; +console.log(foo); diff --git a/tests/testdata/check/declaration_header_file_with_no_exports_js.d.ts b/tests/testdata/check/declaration_header_file_with_no_exports_js.d.ts new file mode 100644 index 000000000..e69de29bb diff --git a/tests/testdata/check/declaration_header_file_with_no_exports_js.js b/tests/testdata/check/declaration_header_file_with_no_exports_js.js new file mode 100644 index 000000000..b8ae2bcef --- /dev/null +++ b/tests/testdata/check/declaration_header_file_with_no_exports_js.js @@ -0,0 +1 @@ +/// diff --git a/tests/testdata/check/deno_not_found/main.out b/tests/testdata/check/deno_not_found/main.out new file mode 100644 index 000000000..dc4a682c7 --- /dev/null +++ b/tests/testdata/check/deno_not_found/main.out @@ -0,0 +1,4 @@ +error: TS2304 [ERROR]: Cannot find name 'Deno'. Do you need to change your target library? Try changing the 'lib' compiler option to include 'deno.ns' or add a triple-slash directive to the top of your entrypoint (main file): /// +Deno; +~~~~ + at file:///[WILDCARD]/check/deno_not_found/main.ts:4:1 diff --git a/tests/testdata/check/deno_not_found/main.ts b/tests/testdata/check/deno_not_found/main.ts new file mode 100644 index 000000000..3269f047a --- /dev/null +++ b/tests/testdata/check/deno_not_found/main.ts @@ -0,0 +1,4 @@ +/// +/// + +Deno; diff --git a/tests/testdata/check/dts/check_dts.d.ts b/tests/testdata/check/dts/check_dts.d.ts new file mode 100644 index 000000000..9cf60f063 --- /dev/null +++ b/tests/testdata/check/dts/check_dts.d.ts @@ -0,0 +1,2 @@ +// TS1039 [ERROR]: Initializers are not allowed in ambient contexts. +export const a: string = Deno.version.deno; diff --git a/tests/testdata/check/dts/check_dts.out b/tests/testdata/check/dts/check_dts.out new file mode 100644 index 000000000..e7ff9a009 --- /dev/null +++ b/tests/testdata/check/dts/check_dts.out @@ -0,0 +1,4 @@ +error: TS1039 [ERROR]: Initializers are not allowed in ambient contexts. +export const a: string = Deno.version.deno; + ~~~~~~~~~~~~~~~~~ + at file:///[WILDCARD]/check_dts.d.ts:2:26 diff --git a/tests/testdata/check/exclude_option/deno.exclude_dir.json b/tests/testdata/check/exclude_option/deno.exclude_dir.json new file mode 100644 index 000000000..2019f8953 --- /dev/null +++ b/tests/testdata/check/exclude_option/deno.exclude_dir.json @@ -0,0 +1,5 @@ +{ + "exclude": [ + "ignored" + ] +} diff --git a/tests/testdata/check/exclude_option/deno.exclude_glob.json b/tests/testdata/check/exclude_option/deno.exclude_glob.json new file mode 100644 index 000000000..1d203ba08 --- /dev/null +++ b/tests/testdata/check/exclude_option/deno.exclude_glob.json @@ -0,0 +1,5 @@ +{ + "exclude": [ + "ignored/**/*" + ] +} diff --git a/tests/testdata/check/exclude_option/deno.json b/tests/testdata/check/exclude_option/deno.json new file mode 100644 index 000000000..a9eca74ca --- /dev/null +++ b/tests/testdata/check/exclude_option/deno.json @@ -0,0 +1,3 @@ +{ + "exclude": [] +} diff --git a/tests/testdata/check/exclude_option/exclude_option.ts.error.out b/tests/testdata/check/exclude_option/exclude_option.ts.error.out new file mode 100644 index 000000000..abd1c1258 --- /dev/null +++ b/tests/testdata/check/exclude_option/exclude_option.ts.error.out @@ -0,0 +1,4 @@ +error: TS2304 [ERROR]: Cannot find name 'nothing'. +export { nothing }; + ~~~~~~~ + at [WILDCARD] diff --git a/tests/testdata/check/exclude_option/ignored/index.ts b/tests/testdata/check/exclude_option/ignored/index.ts new file mode 100644 index 000000000..0419cf073 --- /dev/null +++ b/tests/testdata/check/exclude_option/ignored/index.ts @@ -0,0 +1 @@ +export { nothing }; diff --git a/tests/testdata/check/exclude_option/index.ts b/tests/testdata/check/exclude_option/index.ts new file mode 100644 index 000000000..8335ca3a2 --- /dev/null +++ b/tests/testdata/check/exclude_option/index.ts @@ -0,0 +1,5 @@ +import { nothing } from "./ignored/index.ts"; + +const foo = 1; + +export { foo, nothing }; diff --git a/tests/testdata/check/excluded_file_specified/check.out b/tests/testdata/check/excluded_file_specified/check.out new file mode 100644 index 000000000..2bc26aaaf --- /dev/null +++ b/tests/testdata/check/excluded_file_specified/check.out @@ -0,0 +1 @@ +Warning No matching files found. diff --git a/tests/testdata/check/excluded_file_specified/deno.json b/tests/testdata/check/excluded_file_specified/deno.json new file mode 100644 index 000000000..039be18df --- /dev/null +++ b/tests/testdata/check/excluded_file_specified/deno.json @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "types": ["./lib/types.d.ts"] + }, + "exclude": ["lib"] +} diff --git a/tests/testdata/check/excluded_file_specified/lib/types.d.ts b/tests/testdata/check/excluded_file_specified/lib/types.d.ts new file mode 100644 index 000000000..a02ad0cbe --- /dev/null +++ b/tests/testdata/check/excluded_file_specified/lib/types.d.ts @@ -0,0 +1,2 @@ +// deno-lint-ignore-file +declare var test: number; diff --git a/tests/testdata/check/export_equals_declaration_file/main.ts b/tests/testdata/check/export_equals_declaration_file/main.ts new file mode 100644 index 000000000..e20a735d5 --- /dev/null +++ b/tests/testdata/check/export_equals_declaration_file/main.ts @@ -0,0 +1,6 @@ +// @deno-types="./other.d.ts" +import Test, { type Attributes } from "./other.js"; + +const other: Attributes = {}; +console.log(Test()); +console.log(other); diff --git a/tests/testdata/check/export_equals_declaration_file/other.d.ts b/tests/testdata/check/export_equals_declaration_file/other.d.ts new file mode 100644 index 000000000..5e1274fa5 --- /dev/null +++ b/tests/testdata/check/export_equals_declaration_file/other.d.ts @@ -0,0 +1,9 @@ +export = other; + +declare function other(): string; + +declare namespace other { + interface Attributes { + [attr: string]: string; + } +} diff --git a/tests/testdata/check/export_equals_declaration_file/other.js b/tests/testdata/check/export_equals_declaration_file/other.js new file mode 100644 index 000000000..f66c03162 --- /dev/null +++ b/tests/testdata/check/export_equals_declaration_file/other.js @@ -0,0 +1,3 @@ +export default function other() { + return "test"; +} diff --git a/tests/testdata/check/jsx_not_checked/main.jsx b/tests/testdata/check/jsx_not_checked/main.jsx new file mode 100644 index 000000000..8de05f9f7 --- /dev/null +++ b/tests/testdata/check/jsx_not_checked/main.jsx @@ -0,0 +1,21 @@ +// should not error about jsx-runtime not being found in types here +/** @jsxImportSource npm:react@18.2.0 */ + +import "./other.ts"; + +export default ( + <> +

Hello world

+

This is a JSX page

+ +); + +/** + * @param {number} a + * @param {number} b + */ +function add(a, b) { + return a + b; +} + +console.log(add("1", "2")); diff --git a/tests/testdata/check/jsx_not_checked/main.out b/tests/testdata/check/jsx_not_checked/main.out new file mode 100644 index 000000000..82c1c2358 --- /dev/null +++ b/tests/testdata/check/jsx_not_checked/main.out @@ -0,0 +1,13 @@ +[UNORDERED_START] +Download http://localhost:4545/npm/registry/react +Download http://localhost:4545/npm/registry/loose-envify +Download http://localhost:4545/npm/registry/js-tokens +Download http://localhost:4545/npm/registry/react/react-18.2.0.tgz +Download http://localhost:4545/npm/registry/loose-envify/loose-envify-1.4.0.tgz +Download http://localhost:4545/npm/registry/js-tokens/js-tokens-4.0.0.tgz +[UNORDERED_END] +Check file:///[WILDCARD]/jsx_not_checked/main.jsx +error: TS2345 [ERROR]: Argument of type 'string' is not assignable to parameter of type 'number'. +console.log(add("1", "2")); + ~~~ + at file:///[WILDCARD]/other.ts:5:17 diff --git a/tests/testdata/check/jsx_not_checked/other.ts b/tests/testdata/check/jsx_not_checked/other.ts new file mode 100644 index 000000000..47995cb0f --- /dev/null +++ b/tests/testdata/check/jsx_not_checked/other.ts @@ -0,0 +1,5 @@ +function add(a: number, b: number) { + return a + b; +} + +console.log(add("1", "2")); diff --git a/tests/testdata/check/jsximportsource_importmap_config/deno.json b/tests/testdata/check/jsximportsource_importmap_config/deno.json new file mode 100644 index 000000000..6d837af7c --- /dev/null +++ b/tests/testdata/check/jsximportsource_importmap_config/deno.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "jsx": "react-jsx", + "jsxImportSource": "jsx" + }, + "importMap": "./import_map.json" +} diff --git a/tests/testdata/check/jsximportsource_importmap_config/import_map.json b/tests/testdata/check/jsximportsource_importmap_config/import_map.json new file mode 100644 index 000000000..e926207af --- /dev/null +++ b/tests/testdata/check/jsximportsource_importmap_config/import_map.json @@ -0,0 +1,5 @@ +{ + "imports": { + "jsx/jsx-runtime": "./jsx_runtime.ts" + } +} diff --git a/tests/testdata/check/jsximportsource_importmap_config/jsx_runtime.ts b/tests/testdata/check/jsximportsource_importmap_config/jsx_runtime.ts new file mode 100644 index 000000000..33a07ca73 --- /dev/null +++ b/tests/testdata/check/jsximportsource_importmap_config/jsx_runtime.ts @@ -0,0 +1,4 @@ +// deno-lint-ignore no-namespace +export namespace JSX { + export type IntrinsicElements = { [key: string]: unknown }; +} diff --git a/tests/testdata/check/jsximportsource_importmap_config/main.bundle.js b/tests/testdata/check/jsximportsource_importmap_config/main.bundle.js new file mode 100644 index 000000000..6f39c876e --- /dev/null +++ b/tests/testdata/check/jsximportsource_importmap_config/main.bundle.js @@ -0,0 +1,9 @@ +// deno-fmt-ignore-file +// deno-lint-ignore-file +// This code was bundled using `deno bundle` and it's not recommended to edit it manually + +const makeParagraph = ()=>jsx("p", { + children: "A paragraph!" + }); +export { makeParagraph as makeParagraph }; + diff --git a/tests/testdata/check/jsximportsource_importmap_config/main.tsx b/tests/testdata/check/jsximportsource_importmap_config/main.tsx new file mode 100644 index 000000000..a1eb24f0b --- /dev/null +++ b/tests/testdata/check/jsximportsource_importmap_config/main.tsx @@ -0,0 +1 @@ +export const makeParagraph = () =>

A paragraph!

; diff --git a/tests/testdata/check/module_detection_force.ts b/tests/testdata/check/module_detection_force.ts new file mode 100644 index 000000000..185ceb816 --- /dev/null +++ b/tests/testdata/check/module_detection_force.ts @@ -0,0 +1,3 @@ +const a = 1; +await import("./module_detection_force/import.ts"); +console.log(a); diff --git a/tests/testdata/check/module_detection_force/import.ts b/tests/testdata/check/module_detection_force/import.ts new file mode 100644 index 000000000..66b229870 --- /dev/null +++ b/tests/testdata/check/module_detection_force/import.ts @@ -0,0 +1,2 @@ +const a = 2; +console.log(a); diff --git a/tests/testdata/check/module_detection_force/main.ts b/tests/testdata/check/module_detection_force/main.ts new file mode 100644 index 000000000..a55c9962b --- /dev/null +++ b/tests/testdata/check/module_detection_force/main.ts @@ -0,0 +1,3 @@ +const a = 1; +await import("./import.ts"); +console.log(a); diff --git a/tests/testdata/check/no_error_truncation/deno.json b/tests/testdata/check/no_error_truncation/deno.json new file mode 100644 index 000000000..643707ccc --- /dev/null +++ b/tests/testdata/check/no_error_truncation/deno.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "noErrorTruncation": true + } +} diff --git a/tests/testdata/check/no_error_truncation/main.out b/tests/testdata/check/no_error_truncation/main.out new file mode 100644 index 000000000..13fd5aae4 --- /dev/null +++ b/tests/testdata/check/no_error_truncation/main.out @@ -0,0 +1,11 @@ +error: TS2322 [ERROR]: Type '{ propertyWithAnExceedinglyLongName1: string; propertyWithAnExceedinglyLongName2: string; propertyWithAnExceedinglyLongName3: string; propertyWithAnExceedinglyLongName4: string; propertyWithAnExceedinglyLongName5: string; propertyWithAnExceedinglyLongName6: string; propertyWithAnExceedinglyLongName7: string; propertyWithAnExceedinglyLongName8: string; }' is not assignable to type 'string'. +const _s: string = x; + ~~ + at file:///[WILDCARD]/no_error_truncation/main.ts:12:7 + +TS2454 [ERROR]: Variable 'x' is used before being assigned. +const _s: string = x; + ^ + at file:///[WILDCARD]/no_error_truncation/main.ts:12:20 + +Found 2 errors. diff --git a/tests/testdata/check/no_error_truncation/main.ts b/tests/testdata/check/no_error_truncation/main.ts new file mode 100644 index 000000000..bb1856602 --- /dev/null +++ b/tests/testdata/check/no_error_truncation/main.ts @@ -0,0 +1,12 @@ +let x: { + propertyWithAnExceedinglyLongName1: string; + propertyWithAnExceedinglyLongName2: string; + propertyWithAnExceedinglyLongName3: string; + propertyWithAnExceedinglyLongName4: string; + propertyWithAnExceedinglyLongName5: string; + propertyWithAnExceedinglyLongName6: string; + propertyWithAnExceedinglyLongName7: string; + propertyWithAnExceedinglyLongName8: string; +}; + +const _s: string = x; diff --git a/tests/testdata/check/node_builtin_modules/mod.js b/tests/testdata/check/node_builtin_modules/mod.js new file mode 100644 index 000000000..196fb9be9 --- /dev/null +++ b/tests/testdata/check/node_builtin_modules/mod.js @@ -0,0 +1,3 @@ +// @ts-check +import fs from "node:fs"; +const _data = fs.readFileSync("./node_builtin.js", 123); diff --git a/tests/testdata/check/node_builtin_modules/mod.js.out b/tests/testdata/check/node_builtin_modules/mod.js.out new file mode 100644 index 000000000..97786ebae --- /dev/null +++ b/tests/testdata/check/node_builtin_modules/mod.js.out @@ -0,0 +1,5 @@ +error: TS2769 [ERROR]: No overload matches this call. + [WILDCARD] +const _data = fs.readFileSync("./node_builtin.js", 123); + ~~~ + at file:///[WILDCARD]/node_builtin_modules/mod.js:3:52 diff --git a/tests/testdata/check/node_builtin_modules/mod.ts b/tests/testdata/check/node_builtin_modules/mod.ts new file mode 100644 index 000000000..0e62353fe --- /dev/null +++ b/tests/testdata/check/node_builtin_modules/mod.ts @@ -0,0 +1,9 @@ +import fs from "node:fs"; +const _data = fs.readFileSync("./node_builtin.js", 123); + +// check node:module specifically because for deno check it should +// resolve to the @types/node package, but at runtime it uses a different +// builtin object than deno_std +import { builtinModules } from "node:module"; +// should error about being string[] +const _testString: number[] = builtinModules; diff --git a/tests/testdata/check/node_builtin_modules/mod.ts.out b/tests/testdata/check/node_builtin_modules/mod.ts.out new file mode 100644 index 000000000..49b762cff --- /dev/null +++ b/tests/testdata/check/node_builtin_modules/mod.ts.out @@ -0,0 +1,13 @@ +error: TS2769 [ERROR]: No overload matches this call. + [WILDCARD] +const _data = fs.readFileSync("./node_builtin.js", 123); + ~~~ + at file:///[WILDCARD]/node_builtin_modules/mod.ts:2:52 + +TS2322 [ERROR]: Type 'string[]' is not assignable to type 'number[]'. + Type 'string' is not assignable to type 'number'. +const _testString: number[] = builtinModules; + ~~~~~~~~~~~ + at file:///[WILDCARD]/node_builtin_modules/mod.ts:9:7 + +Found 2 errors. diff --git a/tests/testdata/check/npm_install_diagnostics/main.out b/tests/testdata/check/npm_install_diagnostics/main.out new file mode 100644 index 000000000..fe46f0e42 --- /dev/null +++ b/tests/testdata/check/npm_install_diagnostics/main.out @@ -0,0 +1,11 @@ +error: TS2581 [ERROR]: Cannot find name '$'. Did you mean to import jQuery? Try adding `import $ from "npm:jquery";`. +$; +^ + at file:///[WILDCARD]/npm_install_diagnostics/main.ts:1:1 + +TS2580 [ERROR]: Cannot find name 'process'. +process; +~~~~~~~ + at file:///[WILDCARD]/npm_install_diagnostics/main.ts:2:1 + +Found 2 errors. diff --git a/tests/testdata/check/npm_install_diagnostics/main.ts b/tests/testdata/check/npm_install_diagnostics/main.ts new file mode 100644 index 000000000..62c0c5619 --- /dev/null +++ b/tests/testdata/check/npm_install_diagnostics/main.ts @@ -0,0 +1,2 @@ +$; +process; diff --git a/tests/testdata/check/response_json.ts b/tests/testdata/check/response_json.ts new file mode 100644 index 000000000..e936f7bff --- /dev/null +++ b/tests/testdata/check/response_json.ts @@ -0,0 +1,5 @@ +/// +/// +/// + +Response.json({}); diff --git a/tests/testdata/check/types_dts/deno.json b/tests/testdata/check/types_dts/deno.json new file mode 100644 index 000000000..85f1549e0 --- /dev/null +++ b/tests/testdata/check/types_dts/deno.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "types": [ + "./types.d.ts" + ] + } +} diff --git a/tests/testdata/check/types_dts/main.out b/tests/testdata/check/types_dts/main.out new file mode 100644 index 000000000..c769989e3 --- /dev/null +++ b/tests/testdata/check/types_dts/main.out @@ -0,0 +1 @@ +Check file:///[WILDCARD]/check/types_dts/main.ts diff --git a/tests/testdata/check/types_dts/main.ts b/tests/testdata/check/types_dts/main.ts new file mode 100644 index 000000000..ca375a094 --- /dev/null +++ b/tests/testdata/check/types_dts/main.ts @@ -0,0 +1,3 @@ +console.log("Hello world!"); + +test.test(); diff --git a/tests/testdata/check/types_dts/types.d.ts b/tests/testdata/check/types_dts/types.d.ts new file mode 100644 index 000000000..141c2a3d3 --- /dev/null +++ b/tests/testdata/check/types_dts/types.d.ts @@ -0,0 +1,3 @@ +declare class test { + static test(): void; +} diff --git a/tests/testdata/commonjs/data.json b/tests/testdata/commonjs/data.json new file mode 100644 index 000000000..f2a886f39 --- /dev/null +++ b/tests/testdata/commonjs/data.json @@ -0,0 +1,3 @@ +{ + "hello": "world" +} diff --git a/tests/testdata/commonjs/example.js b/tests/testdata/commonjs/example.js new file mode 100644 index 000000000..d2f89d3f0 --- /dev/null +++ b/tests/testdata/commonjs/example.js @@ -0,0 +1,11 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +// deno-lint-ignore no-undef +const processMod = require("process"); +const osMod = require("node:os"); +console.log("process.pid", processMod.pid); +console.log("os.EOL", osMod.EOL); +const leftPad = require("left-pad"); +const json = require("./data"); +console.log(json); +console.log(leftPad("foo", 5)); // => " foo" +console.log("main module", processMod.mainModule.filename); diff --git a/tests/testdata/commonjs/node_modules/colorette/index.cjs b/tests/testdata/commonjs/node_modules/colorette/index.cjs new file mode 100644 index 000000000..0590d668d --- /dev/null +++ b/tests/testdata/commonjs/node_modules/colorette/index.cjs @@ -0,0 +1,74 @@ +// Copyright Jorge Bucaran. All rights reserved. MIT license. +let enabled = !("NO_COLOR" in process.env) && + ("FORCE_COLOR" in process.env || + process.platform === "win32" || + (process.stdout != null && + process.stdout.isTTY && + process.env.TERM && + process.env.TERM !== "dumb")); + +const raw = (open, close, searchRegex, replaceValue) => + (s) => + enabled + ? open + + (~(s += "").indexOf(close, 4) // skip opening \x1b[ + ? s.replace(searchRegex, replaceValue) + : s) + + close + : s; + +const init = (open, close) => { + return raw( + `\x1b[${open}m`, + `\x1b[${close}m`, + new RegExp(`\\x1b\\[${close}m`, "g"), + `\x1b[${open}m`, + ); +}; + +exports.options = Object.defineProperty({}, "enabled", { + get: () => enabled, + set: (value) => (enabled = value), +}); + +exports.reset = init(0, 0); +exports.bold = raw("\x1b[1m", "\x1b[22m", /\x1b\[22m/g, "\x1b[22m\x1b[1m"); +exports.dim = raw("\x1b[2m", "\x1b[22m", /\x1b\[22m/g, "\x1b[22m\x1b[2m"); +exports.italic = init(3, 23); +exports.underline = init(4, 24); +exports.inverse = init(7, 27); +exports.hidden = init(8, 28); +exports.strikethrough = init(9, 29); +exports.black = init(30, 39); +exports.red = init(31, 39); +exports.green = init(32, 39); +exports.yellow = init(33, 39); +exports.blue = init(34, 39); +exports.magenta = init(35, 39); +exports.cyan = init(36, 39); +exports.white = init(37, 39); +exports.gray = init(90, 39); +exports.bgBlack = init(40, 49); +exports.bgRed = init(41, 49); +exports.bgGreen = init(42, 49); +exports.bgYellow = init(43, 49); +exports.bgBlue = init(44, 49); +exports.bgMagenta = init(45, 49); +exports.bgCyan = init(46, 49); +exports.bgWhite = init(47, 49); +exports.blackBright = init(90, 39); +exports.redBright = init(91, 39); +exports.greenBright = init(92, 39); +exports.yellowBright = init(93, 39); +exports.blueBright = init(94, 39); +exports.magentaBright = init(95, 39); +exports.cyanBright = init(96, 39); +exports.whiteBright = init(97, 39); +exports.bgBlackBright = init(100, 49); +exports.bgRedBright = init(101, 49); +exports.bgGreenBright = init(102, 49); +exports.bgYellowBright = init(103, 49); +exports.bgBlueBright = init(104, 49); +exports.bgMagentaBright = init(105, 49); +exports.bgCyanBright = init(106, 49); +exports.bgWhiteBright = init(107, 49); diff --git a/tests/testdata/commonjs/node_modules/colorette/index.js b/tests/testdata/commonjs/node_modules/colorette/index.js new file mode 100644 index 000000000..6e83866f3 --- /dev/null +++ b/tests/testdata/commonjs/node_modules/colorette/index.js @@ -0,0 +1,75 @@ +// Copyright Jorge Bucaran. All rights reserved. MIT license. +// deno-lint-ignore-file no-undef no-control-regex +let enabled = !("NO_COLOR" in process.env) && + ("FORCE_COLOR" in process.env || + process.platform === "win32" || + (process.stdout != null && + process.stdout.isTTY && + process.env.TERM && + process.env.TERM !== "dumb")); + +const raw = (open, close, searchRegex, replaceValue) => + (s) => + enabled + ? open + + (~(s += "").indexOf(close, 4) // skip opening \x1b[ + ? s.replace(searchRegex, replaceValue) + : s) + + close + : s; + +const init = (open, close) => { + return raw( + `\x1b[${open}m`, + `\x1b[${close}m`, + new RegExp(`\\x1b\\[${close}m`, "g"), + `\x1b[${open}m`, + ); +}; + +export const options = Object.defineProperty({}, "enabled", { + get: () => enabled, + set: (value) => (enabled = value), +}); + +export const reset = init(0, 0); +export const bold = raw("\x1b[1m", "\x1b[22m", /\x1b\[22m/g, "\x1b[22m\x1b[1m"); +export const dim = raw("\x1b[2m", "\x1b[22m", /\x1b\[22m/g, "\x1b[22m\x1b[2m"); +export const italic = init(3, 23); +export const underline = init(4, 24); +export const inverse = init(7, 27); +export const hidden = init(8, 28); +export const strikethrough = init(9, 29); +export const black = init(30, 39); +export const red = init(31, 39); +export const green = init(32, 39); +export const yellow = init(33, 39); +export const blue = init(34, 39); +export const magenta = init(35, 39); +export const cyan = init(36, 39); +export const white = init(37, 39); +export const gray = init(90, 39); +export const bgBlack = init(40, 49); +export const bgRed = init(41, 49); +export const bgGreen = init(42, 49); +export const bgYellow = init(43, 49); +export const bgBlue = init(44, 49); +export const bgMagenta = init(45, 49); +export const bgCyan = init(46, 49); +export const bgWhite = init(47, 49); +export const blackBright = init(90, 39); +export const redBright = init(91, 39); +export const greenBright = init(92, 39); +export const yellowBright = init(93, 39); +export const blueBright = init(94, 39); +export const magentaBright = init(95, 39); +export const cyanBright = init(96, 39); +export const whiteBright = init(97, 39); +export const bgBlackBright = init(100, 49); +export const bgRedBright = init(101, 49); +export const bgGreenBright = init(102, 49); +export const bgYellowBright = init(103, 49); +export const bgBlueBright = init(104, 49); +export const bgMagentaBright = init(105, 49); +export const bgCyanBright = init(106, 49); +export const bgWhiteBright = init(107, 49); diff --git a/tests/testdata/commonjs/node_modules/colorette/package.json b/tests/testdata/commonjs/node_modules/colorette/package.json new file mode 100644 index 000000000..fdca1aa24 --- /dev/null +++ b/tests/testdata/commonjs/node_modules/colorette/package.json @@ -0,0 +1,23 @@ +{ + "author": { + "name": "Jorge Bucaran" + }, + "description": "Color your terminal using pure idiomatic JavaScript.", + "exports": { + "./package.json": "./package.json", + ".": { + "require": "./index.cjs", + "import": "./index.js" + } + }, + "license": "MIT", + "main": "index.cjs", + "module": "index.js", + "name": "colorette", + "repository": { + "type": "git", + "url": "git+https://github.com/jorgebucaran/colorette.git" + }, + "type": "module", + "version": "1.2.1" +} diff --git a/tests/testdata/commonjs/node_modules/imports_exports/import_export.js b/tests/testdata/commonjs/node_modules/imports_exports/import_export.js new file mode 100644 index 000000000..3ebd222ea --- /dev/null +++ b/tests/testdata/commonjs/node_modules/imports_exports/import_export.js @@ -0,0 +1,6 @@ +import dep from "#dep"; + +export default { + bar: "bar", + dep, +}; diff --git a/tests/testdata/commonjs/node_modules/imports_exports/import_polyfill.js b/tests/testdata/commonjs/node_modules/imports_exports/import_polyfill.js new file mode 100644 index 000000000..76716a3ef --- /dev/null +++ b/tests/testdata/commonjs/node_modules/imports_exports/import_polyfill.js @@ -0,0 +1,3 @@ +export default { + polyfill: "import", +}; diff --git a/tests/testdata/commonjs/node_modules/imports_exports/package.json b/tests/testdata/commonjs/node_modules/imports_exports/package.json new file mode 100644 index 000000000..5d26359db --- /dev/null +++ b/tests/testdata/commonjs/node_modules/imports_exports/package.json @@ -0,0 +1,17 @@ +{ + "version": "1.0.0", + "name": "imports_exports", + "main": "./require_export.cjs", + "imports": { + "#dep": { + "import": "./import_polyfill.js", + "require": "./require_polyfill.js" + } + }, + "exports": { + ".": { + "import": "./import_export.js", + "require": "./require_export.cjs" + } + } +} diff --git a/tests/testdata/commonjs/node_modules/imports_exports/require_export.cjs b/tests/testdata/commonjs/node_modules/imports_exports/require_export.cjs new file mode 100644 index 000000000..48923b8d8 --- /dev/null +++ b/tests/testdata/commonjs/node_modules/imports_exports/require_export.cjs @@ -0,0 +1,6 @@ +const dep = require("#dep"); + +module.exports = { + foo: "foo", + dep, +}; diff --git a/tests/testdata/commonjs/node_modules/imports_exports/require_polyfill.js b/tests/testdata/commonjs/node_modules/imports_exports/require_polyfill.js new file mode 100644 index 000000000..1023fd65c --- /dev/null +++ b/tests/testdata/commonjs/node_modules/imports_exports/require_polyfill.js @@ -0,0 +1,3 @@ +module.exports = { + polyfill: "require", +}; diff --git a/tests/testdata/commonjs/node_modules/left-pad/README.md b/tests/testdata/commonjs/node_modules/left-pad/README.md new file mode 100644 index 000000000..0e70d461e --- /dev/null +++ b/tests/testdata/commonjs/node_modules/left-pad/README.md @@ -0,0 +1,41 @@ +## left-pad + +String left pad + +[![Build Status][travis-image]][travis-url] + +## Install + +```bash +$ npm install left-pad +``` + +## Usage + +```js +const leftPad = require("left-pad"); + +leftPad("foo", 5); +// => " foo" + +leftPad("foobar", 6); +// => "foobar" + +leftPad(1, 2, "0"); +// => "01" + +leftPad(17, 5, 0); +// => "00017" +``` + +**NOTE:** The third argument should be a single `char`. However the module +doesn't throw an error if you supply more than one `char`s. See +[#28](https://github.com/stevemao/left-pad/pull/28). + +**NOTE:** Characters having code points outside of +[BMP plan](https://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_Multilingual_Plane) +are considered a two distinct characters. See +[#58](https://github.com/stevemao/left-pad/issues/58). + +[travis-image]: https://travis-ci.org/stevemao/left-pad.svg?branch=master +[travis-url]: https://travis-ci.org/stevemao/left-pad diff --git a/tests/testdata/commonjs/node_modules/left-pad/index.js b/tests/testdata/commonjs/node_modules/left-pad/index.js new file mode 100644 index 000000000..a439e91de --- /dev/null +++ b/tests/testdata/commonjs/node_modules/left-pad/index.js @@ -0,0 +1,54 @@ +// deno-lint-ignore-file + +/* This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://www.wtfpl.net/ for more details. */ +"use strict"; +module.exports = leftPad; + +var cache = [ + "", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", +]; + +function leftPad(str, len, ch) { + // convert `str` to a `string` + str = str + ""; + // `len` is the `pad`'s length now + len = len - str.length; + // doesn't need to pad + if (len <= 0) return str; + // `ch` defaults to `' '` + if (!ch && ch !== 0) ch = " "; + // convert `ch` to a `string` cuz it could be a number + ch = ch + ""; + // cache common use cases + if (ch === " " && len < 10) return cache[len] + str; + // `pad` starts with an empty string + var pad = ""; + // loop + while (true) { + // add `ch` to `pad` if `len` is odd + if (len & 1) pad += ch; + // divide `len` by 2, ditch the remainder + len >>= 1; + // "double" the `ch` so this operation count grows logarithmically on `len` + // each time `ch` is "doubled", the `len` would need to be "doubled" too + // similar to finding a value in binary search tree, hence O(log(n)) + if (len) ch += ch; + // `len` is 0, exit the loop + else break; + } + // pad `str`! + return pad + str; +} diff --git a/tests/testdata/commonjs/node_modules/left-pad/package.json b/tests/testdata/commonjs/node_modules/left-pad/package.json new file mode 100644 index 000000000..57be04271 --- /dev/null +++ b/tests/testdata/commonjs/node_modules/left-pad/package.json @@ -0,0 +1,68 @@ +{ + "_from": "left-pad", + "_id": "left-pad@1.3.0", + "_inBundle": false, + "_integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==", + "_location": "/left-pad", + "_phantomChildren": {}, + "_requested": { + "type": "tag", + "registry": true, + "raw": "left-pad", + "name": "left-pad", + "escapedName": "left-pad", + "rawSpec": "", + "saveSpec": null, + "fetchSpec": "latest" + }, + "_requiredBy": [ + "#USER", + "/" + ], + "_resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz", + "_shasum": "5b8a3a7765dfe001261dde915589e782f8c94d1e", + "_spec": "left-pad", + "_where": "/Users/kun/Projects/Deno/deno/std/node/tests", + "author": { + "name": "azer" + }, + "bugs": { + "url": "https://github.com/stevemao/left-pad/issues" + }, + "bundleDependencies": false, + "deprecated": "use String.prototype.padStart()", + "description": "String left pad", + "devDependencies": { + "benchmark": "^2.1.0", + "fast-check": "0.0.8", + "tape": "*" + }, + "homepage": "https://github.com/stevemao/left-pad#readme", + "keywords": [ + "leftpad", + "left", + "pad", + "padding", + "string", + "repeat" + ], + "license": "WTFPL", + "main": "index.js", + "maintainers": [ + { + "name": "Cameron Westland", + "email": "camwest@gmail.com" + } + ], + "name": "left-pad", + "repository": { + "url": "git+ssh://git@github.com/stevemao/left-pad.git", + "type": "git" + }, + "scripts": { + "bench": "node perf/perf.js", + "test": "node test" + }, + "types": "index.d.ts", + "version": "1.3.0" +} diff --git a/tests/testdata/commonjs/package.json b/tests/testdata/commonjs/package.json new file mode 100644 index 000000000..9ce08a900 --- /dev/null +++ b/tests/testdata/commonjs/package.json @@ -0,0 +1,17 @@ +{ + "name": "example", + "version": "0.0.1", + "description": "", + "main": "example.js", + "dependencies": { + "colorette": "1.2.1", + "left-pad": "1.3.0", + "imports_exports": "1.0.0" + }, + "devDependencies": {}, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC" +} diff --git a/tests/testdata/compile/args.ts b/tests/testdata/compile/args.ts new file mode 100644 index 000000000..ec41d52f9 --- /dev/null +++ b/tests/testdata/compile/args.ts @@ -0,0 +1,3 @@ +Deno.args.forEach((arg) => { + console.log(arg); +}); diff --git a/tests/testdata/compile/check_local_by_default.ts b/tests/testdata/compile/check_local_by_default.ts new file mode 100644 index 000000000..2ae8c2692 --- /dev/null +++ b/tests/testdata/compile/check_local_by_default.ts @@ -0,0 +1,3 @@ +import * as a from "http://localhost:4545/subdir/type_error.ts"; + +console.log(a.a); diff --git a/tests/testdata/compile/check_local_by_default2.ts b/tests/testdata/compile/check_local_by_default2.ts new file mode 100644 index 000000000..5177ff944 --- /dev/null +++ b/tests/testdata/compile/check_local_by_default2.ts @@ -0,0 +1,6 @@ +import * as a from "http://localhost:4545/subdir/type_error.ts"; + +const b: "b" = 12; + +console.log(a.a); +console.log(b); diff --git a/tests/testdata/compile/dynamic_imports/import1.ts b/tests/testdata/compile/dynamic_imports/import1.ts new file mode 100644 index 000000000..2d9dde2a4 --- /dev/null +++ b/tests/testdata/compile/dynamic_imports/import1.ts @@ -0,0 +1,3 @@ +import "./import2.ts"; + +console.log("import1.ts"); diff --git a/tests/testdata/compile/dynamic_imports/import2.ts b/tests/testdata/compile/dynamic_imports/import2.ts new file mode 100644 index 000000000..22321a5a7 --- /dev/null +++ b/tests/testdata/compile/dynamic_imports/import2.ts @@ -0,0 +1 @@ +console.log("import2.ts"); diff --git a/tests/testdata/compile/dynamic_imports/import_path b/tests/testdata/compile/dynamic_imports/import_path new file mode 100644 index 000000000..98222a208 --- /dev/null +++ b/tests/testdata/compile/dynamic_imports/import_path @@ -0,0 +1 @@ +./import1.ts diff --git a/tests/testdata/compile/dynamic_imports/main.out b/tests/testdata/compile/dynamic_imports/main.out new file mode 100644 index 000000000..4304fb06f --- /dev/null +++ b/tests/testdata/compile/dynamic_imports/main.out @@ -0,0 +1,5 @@ +Starting the main module +Dynamic importing +import2.ts +import1.ts +Dynamic import done. diff --git a/tests/testdata/compile/dynamic_imports/main.ts b/tests/testdata/compile/dynamic_imports/main.ts new file mode 100644 index 000000000..b889e2203 --- /dev/null +++ b/tests/testdata/compile/dynamic_imports/main.ts @@ -0,0 +1,6 @@ +console.log("Starting the main module"); + +setTimeout(() => { + console.log("Dynamic importing"); + import("./import1.ts").then(() => console.log("Dynamic import done.")); +}, 0); diff --git a/tests/testdata/compile/dynamic_imports/main_unanalyzable.ts b/tests/testdata/compile/dynamic_imports/main_unanalyzable.ts new file mode 100644 index 000000000..7880fa4a6 --- /dev/null +++ b/tests/testdata/compile/dynamic_imports/main_unanalyzable.ts @@ -0,0 +1,18 @@ +import { join } from "../../../../test_util/std/path/mod.ts"; + +console.log("Starting the main module"); + +// We load the dynamic import path from the file system, to make sure any +// improvements in static analysis can't defeat the purpose of this test, which +// is to make sure the `--include` flag works to add non-analyzed imports to the +// module graph. +const IMPORT_PATH_FILE_PATH = join( + Deno.cwd(), + "tests/testdata/compile/dynamic_imports/import_path", +); + +setTimeout(async () => { + console.log("Dynamic importing"); + const importPath = (await Deno.readTextFile(IMPORT_PATH_FILE_PATH)).trim(); + import(importPath).then(() => console.log("Dynamic import done.")); +}, 0); diff --git a/tests/testdata/compile/dynamic_imports_tmp_lit/main.info.out b/tests/testdata/compile/dynamic_imports_tmp_lit/main.info.out new file mode 100644 index 000000000..57d730a64 --- /dev/null +++ b/tests/testdata/compile/dynamic_imports_tmp_lit/main.info.out @@ -0,0 +1,10 @@ +local: [WILDCARD]main.js +type: JavaScript +dependencies: 4 unique +size: [WILDCARD] + +file:///[WILDCARD]/dynamic_imports_tmp_lit/main.js ([WILDCARD]) +├── file:///[WILDCARD]/dynamic_imports_tmp_lit/sub/a.js ([WILDCARD]) +├── file:///[WILDCARD]/dynamic_imports_tmp_lit/sub/b.ts ([WILDCARD]) +├── file:///[WILDCARD]/dynamic_imports_tmp_lit/other/data.json ([WILDCARD]) +└── file:///[WILDCARD]/dynamic_imports_tmp_lit/other/sub/data2.json ([WILDCARD]) diff --git a/tests/testdata/compile/dynamic_imports_tmp_lit/main.js b/tests/testdata/compile/dynamic_imports_tmp_lit/main.js new file mode 100644 index 000000000..3bda59772 --- /dev/null +++ b/tests/testdata/compile/dynamic_imports_tmp_lit/main.js @@ -0,0 +1,14 @@ +const fileNames = [ + "a.js", + "b.ts", +]; + +for (const fileName of fileNames) { + await import(`./sub/${fileName}`); +} + +const jsonFileNames = ["data.json", "sub/data2.json"]; +for (const fileName of jsonFileNames) { + const mod = await import(`./other/${fileName}`, { with: { type: "json" } }); + console.log(mod.default); +} diff --git a/tests/testdata/compile/dynamic_imports_tmp_lit/other/data.json b/tests/testdata/compile/dynamic_imports_tmp_lit/other/data.json new file mode 100644 index 000000000..0131e01e4 --- /dev/null +++ b/tests/testdata/compile/dynamic_imports_tmp_lit/other/data.json @@ -0,0 +1,3 @@ +{ + "data": 5 +} diff --git a/tests/testdata/compile/dynamic_imports_tmp_lit/other/sub/data2.json b/tests/testdata/compile/dynamic_imports_tmp_lit/other/sub/data2.json new file mode 100644 index 000000000..858a13cdd --- /dev/null +++ b/tests/testdata/compile/dynamic_imports_tmp_lit/other/sub/data2.json @@ -0,0 +1,3 @@ +{ + "data": 1 +} diff --git a/tests/testdata/compile/dynamic_imports_tmp_lit/sub/a.js b/tests/testdata/compile/dynamic_imports_tmp_lit/sub/a.js new file mode 100644 index 000000000..7b2a34601 --- /dev/null +++ b/tests/testdata/compile/dynamic_imports_tmp_lit/sub/a.js @@ -0,0 +1 @@ +console.log("a"); diff --git a/tests/testdata/compile/dynamic_imports_tmp_lit/sub/b.ts b/tests/testdata/compile/dynamic_imports_tmp_lit/sub/b.ts new file mode 100644 index 000000000..6d012e7f1 --- /dev/null +++ b/tests/testdata/compile/dynamic_imports_tmp_lit/sub/b.ts @@ -0,0 +1 @@ +console.log("b"); diff --git a/tests/testdata/compile/node_modules_symlink_outside/main.out b/tests/testdata/compile/node_modules_symlink_outside/main.out new file mode 100644 index 000000000..61c83cba4 --- /dev/null +++ b/tests/testdata/compile/node_modules_symlink_outside/main.out @@ -0,0 +1,2 @@ +4 +5 diff --git a/tests/testdata/compile/node_modules_symlink_outside/main.ts b/tests/testdata/compile/node_modules_symlink_outside/main.ts new file mode 100644 index 000000000..45f681f7c --- /dev/null +++ b/tests/testdata/compile/node_modules_symlink_outside/main.ts @@ -0,0 +1,6 @@ +import { getValue, setValue } from "npm:@denotest/esm-basic"; + +setValue(4); + +console.log(getValue()); +console.log(Deno.readTextFileSync("./node_modules/test.txt")); diff --git a/tests/testdata/compile/node_modules_symlink_outside/main_compile_file.out b/tests/testdata/compile/node_modules_symlink_outside/main_compile_file.out new file mode 100644 index 000000000..1154c3256 --- /dev/null +++ b/tests/testdata/compile/node_modules_symlink_outside/main_compile_file.out @@ -0,0 +1,2 @@ +Compile file:///[WILDCARD]/node_modules_symlink_outside/main.ts to [WILDCARD] +Warning Symlink target is outside '[WILDCARD]node_modules_symlink_outside[WILDCARD]node_modules'. Inlining symlink at '[WILDCARD]node_modules_symlink_outside[WILDCARD]node_modules[WILDCARD]test.txt' to '[WILDCARD]node_modules_symlink_outside[WILDCARD]test.txt' as file. diff --git a/tests/testdata/compile/node_modules_symlink_outside/main_compile_folder.out b/tests/testdata/compile/node_modules_symlink_outside/main_compile_folder.out new file mode 100644 index 000000000..e88b95834 --- /dev/null +++ b/tests/testdata/compile/node_modules_symlink_outside/main_compile_folder.out @@ -0,0 +1,6 @@ +Download http://localhost:4545/npm/registry/@denotest/esm-basic +Download http://localhost:4545/npm/registry/@denotest/esm-basic/1.0.0.tgz +Initialize @denotest/esm-basic@1.0.0 +Check file:///[WILDCARD]/node_modules_symlink_outside/main.ts +Compile file:///[WILDCARD]/node_modules_symlink_outside/main.ts to [WILDCARD] +Warning Symlink target is outside '[WILDCARD]node_modules_symlink_outside[WILDCARD]node_modules'. Excluding symlink at '[WILDCARD]node_modules_symlink_outside[WILDCARD]node_modules[WILDCARD]some_folder' with target '[WILDCARD]node_modules_symlink_outside[WILDCARD]some_folder'. diff --git a/tests/testdata/compile/npm_fs/main.out b/tests/testdata/compile/npm_fs/main.out new file mode 100644 index 000000000..2e9ba477f --- /dev/null +++ b/tests/testdata/compile/npm_fs/main.out @@ -0,0 +1 @@ +success diff --git a/tests/testdata/compile/npm_fs/main.ts b/tests/testdata/compile/npm_fs/main.ts new file mode 100644 index 000000000..6361610a9 --- /dev/null +++ b/tests/testdata/compile/npm_fs/main.ts @@ -0,0 +1,259 @@ +import { url } from "npm:@denotest/esm-basic"; +import { fileURLToPath } from "node:url"; +import path from "node:path"; +import assert from "node:assert/strict"; + +// will be at node_modules\.deno\@denotest+esm-basic@1.0.0\node_modules\@denotest\esm-basic +const dirPath = path.dirname(fileURLToPath(url)); +const nodeModulesPath = path.join(dirPath, "../../../../../"); +const packageJsonText = `{ + "name": "@denotest/esm-basic", + "version": "1.0.0", + "type": "module", + "main": "main.mjs", + "types": "main.d.mts" +} +`; +const vfsPackageJsonPath = path.join(dirPath, "package.json"); + +// reading a file in vfs +{ + const text = Deno.readTextFileSync(vfsPackageJsonPath); + assert.equal(text, packageJsonText); +} + +// reading a file async in vfs +{ + const text = await Deno.readTextFile(vfsPackageJsonPath); + assert.equal(text, packageJsonText); +} + +// copy file from vfs to real fs +{ + Deno.copyFileSync(vfsPackageJsonPath, "package.json"); + assert.equal(Deno.readTextFileSync("package.json"), packageJsonText); +} + +// copy to vfs +assert.throws( + () => Deno.copyFileSync("package.json", vfsPackageJsonPath), + Deno.errors.NotSupported, +); +Deno.removeSync("package.json"); + +// copy file async from vfs to real fs +{ + await Deno.copyFile(vfsPackageJsonPath, "package.json"); + assert.equal(Deno.readTextFileSync("package.json"), packageJsonText); +} + +// copy to vfs async +await assert.rejects( + () => Deno.copyFile("package.json", vfsPackageJsonPath), + Deno.errors.NotSupported, +); +Deno.removeSync("package.json"); + +// open +{ + const file = Deno.openSync(vfsPackageJsonPath); + const bytes = new Uint8Array(10); + file.seekSync(2, Deno.SeekMode.Start); + assert.equal(file.readSync(bytes), 10); + const text = new TextDecoder().decode(bytes); + assert.equal(text, packageJsonText.slice(2, 12)); +} +{ + const file = await Deno.open(vfsPackageJsonPath); + const bytes = new Uint8Array(10); + await file.seek(2, Deno.SeekMode.Start); + assert.equal(await file.read(bytes), 10); + const text = new TextDecoder().decode(bytes); + assert.equal(text, packageJsonText.slice(2, 12)); +} + +// chdir +assert.throws(() => Deno.chdir(dirPath), Deno.errors.NotSupported); + +// mkdir +assert.throws( + () => Deno.mkdirSync(path.join(dirPath, "subDir")), + Deno.errors.NotSupported, +); +await assert.rejects( + () => Deno.mkdir(path.join(dirPath, "subDir")), + Deno.errors.NotSupported, +); + +// chmod +assert.throws( + () => Deno.chmodSync(vfsPackageJsonPath, 0o777), + Deno.errors.NotSupported, +); +await assert.rejects( + () => Deno.chmod(vfsPackageJsonPath, 0o777), + Deno.errors.NotSupported, +); + +// chown +assert.throws( + () => Deno.chownSync(vfsPackageJsonPath, 1000, 1000), + Deno.errors.NotSupported, +); +await assert.rejects( + () => Deno.chown(vfsPackageJsonPath, 1000, 1000), + Deno.errors.NotSupported, +); + +// remove +assert.throws( + () => Deno.removeSync(vfsPackageJsonPath), + Deno.errors.NotSupported, +); +await assert.rejects( + () => Deno.remove(vfsPackageJsonPath), + Deno.errors.NotSupported, +); + +// stat +{ + const result = Deno.statSync(vfsPackageJsonPath); + assert(result.isFile); +} +{ + const result = await Deno.stat(vfsPackageJsonPath); + assert(result.isFile); +} + +// lstat +{ + const result = Deno.lstatSync( + path.join(nodeModulesPath, "@denotest", "esm-basic"), + ); + assert(result.isSymlink); +} +{ + const result = await Deno.lstat( + path.join(nodeModulesPath, "@denotest", "esm-basic"), + ); + assert(result.isSymlink); +} + +// realpath +{ + const result = Deno.realPathSync( + path.join(nodeModulesPath, "@denotest", "esm-basic", "package.json"), + ); + assert.equal(result, vfsPackageJsonPath); +} +{ + const result = await Deno.realPath( + path.join(nodeModulesPath, "@denotest", "esm-basic", "package.json"), + ); + assert.equal(result, vfsPackageJsonPath); +} + +// read dir +const readDirNames = ["main.d.mts", "main.mjs", "other.mjs", "package.json"]; +{ + const names = Array.from(Deno.readDirSync(dirPath)) + .map((e) => e.name); + assert.deepEqual(readDirNames, names); +} +{ + const names = []; + for await (const entry of Deno.readDir(dirPath)) { + names.push(entry.name); + } + assert.deepEqual(readDirNames, names); +} + +// rename +assert.throws( + () => Deno.renameSync("package.json", vfsPackageJsonPath), + Deno.errors.NotSupported, +); +assert.throws( + () => Deno.renameSync(vfsPackageJsonPath, "package.json"), + Deno.errors.NotSupported, +); +await assert.rejects( + () => Deno.rename("package.json", vfsPackageJsonPath), + Deno.errors.NotSupported, +); +await assert.rejects( + () => Deno.rename(vfsPackageJsonPath, "package.json"), + Deno.errors.NotSupported, +); + +// link +assert.throws( + () => Deno.linkSync("package.json", vfsPackageJsonPath), + Deno.errors.NotSupported, +); +assert.throws( + () => Deno.linkSync(vfsPackageJsonPath, "package.json"), + Deno.errors.NotSupported, +); +await assert.rejects( + () => Deno.link("package.json", vfsPackageJsonPath), + Deno.errors.NotSupported, +); +await assert.rejects( + () => Deno.link(vfsPackageJsonPath, "package.json"), + Deno.errors.NotSupported, +); + +// symlink +assert.throws( + () => Deno.symlinkSync("package.json", vfsPackageJsonPath), + Deno.errors.NotSupported, +); +assert.throws( + () => Deno.symlinkSync(vfsPackageJsonPath, "package.json"), + Deno.errors.NotSupported, +); +await assert.rejects( + () => Deno.symlink("package.json", vfsPackageJsonPath), + Deno.errors.NotSupported, +); +await assert.rejects( + () => Deno.symlink(vfsPackageJsonPath, "package.json"), + Deno.errors.NotSupported, +); + +// read link +{ + const result = Deno.readLinkSync( + path.join(nodeModulesPath, "@denotest", "esm-basic"), + ); + assert.equal(result, dirPath); +} +{ + const result = await Deno.readLink( + path.join(nodeModulesPath, "@denotest", "esm-basic"), + ); + assert.equal(result, dirPath); +} + +// truncate +assert.throws( + () => Deno.truncateSync(vfsPackageJsonPath, 0), + Deno.errors.NotSupported, +); +await assert.rejects( + () => Deno.truncate(vfsPackageJsonPath, 0), + Deno.errors.NotSupported, +); + +// utime +assert.throws( + () => Deno.utimeSync(vfsPackageJsonPath, 0, 0), + Deno.errors.NotSupported, +); +await assert.rejects( + () => Deno.utime(vfsPackageJsonPath, 0, 0), + Deno.errors.NotSupported, +); + +console.log("success"); diff --git a/tests/testdata/compile/standalone_error.ts b/tests/testdata/compile/standalone_error.ts new file mode 100644 index 000000000..279398113 --- /dev/null +++ b/tests/testdata/compile/standalone_error.ts @@ -0,0 +1,9 @@ +function boom() { + throw new Error("boom!"); +} + +function foo() { + boom(); +} + +foo(); diff --git a/tests/testdata/compile/standalone_error_module_with_imports_1.ts b/tests/testdata/compile/standalone_error_module_with_imports_1.ts new file mode 100644 index 000000000..bf38f7263 --- /dev/null +++ b/tests/testdata/compile/standalone_error_module_with_imports_1.ts @@ -0,0 +1 @@ +import "./standalone_error_module_with_imports_2.ts"; diff --git a/tests/testdata/compile/standalone_error_module_with_imports_2.ts b/tests/testdata/compile/standalone_error_module_with_imports_2.ts new file mode 100644 index 000000000..ef052b512 --- /dev/null +++ b/tests/testdata/compile/standalone_error_module_with_imports_2.ts @@ -0,0 +1,2 @@ +console.log("hello"); +throw new Error("boom!"); diff --git a/tests/testdata/compile/standalone_follow_redirects.ts b/tests/testdata/compile/standalone_follow_redirects.ts new file mode 100644 index 000000000..f0957bc3d --- /dev/null +++ b/tests/testdata/compile/standalone_follow_redirects.ts @@ -0,0 +1,2 @@ +import "./standalone_follow_redirects_2.js"; +console.log("Hello"); diff --git a/tests/testdata/compile/standalone_follow_redirects_2.js b/tests/testdata/compile/standalone_follow_redirects_2.js new file mode 100644 index 000000000..765dda153 --- /dev/null +++ b/tests/testdata/compile/standalone_follow_redirects_2.js @@ -0,0 +1,5 @@ +// unversioned import redirects with dependencies. +import { + assertNotEquals as _a, + assertStrictEquals as _b, +} from "../../../test_util/std/assert/mod.ts"; diff --git a/tests/testdata/compile/standalone_import_datauri.ts b/tests/testdata/compile/standalone_import_datauri.ts new file mode 100644 index 000000000..68f348828 --- /dev/null +++ b/tests/testdata/compile/standalone_import_datauri.ts @@ -0,0 +1,4 @@ +const c = await import( + "data:text/javascript;base64,ZXhwb3J0IGRlZmF1bHQgJ0hlbGxvIERlbm8hJw==" +); +console.log(c.default); // Output: "Hello Deno!" diff --git a/tests/testdata/compile/standalone_import_map.json b/tests/testdata/compile/standalone_import_map.json new file mode 100644 index 000000000..9e5b90bd7 --- /dev/null +++ b/tests/testdata/compile/standalone_import_map.json @@ -0,0 +1,5 @@ +{ + "imports": { + "hello": "../run/001_hello.js" + } +} diff --git a/tests/testdata/compile/standalone_import_map.ts b/tests/testdata/compile/standalone_import_map.ts new file mode 100644 index 000000000..097b96356 --- /dev/null +++ b/tests/testdata/compile/standalone_import_map.ts @@ -0,0 +1 @@ +import "hello"; diff --git a/tests/testdata/compile/standalone_import_map_config.json b/tests/testdata/compile/standalone_import_map_config.json new file mode 100644 index 000000000..4959827f4 --- /dev/null +++ b/tests/testdata/compile/standalone_import_map_config.json @@ -0,0 +1,3 @@ +{ + "importMap": "./standalone_import_map.json" +} diff --git a/tests/testdata/compile/standalone_runtime_flags.ts b/tests/testdata/compile/standalone_runtime_flags.ts new file mode 100644 index 000000000..0154c7f4e --- /dev/null +++ b/tests/testdata/compile/standalone_runtime_flags.ts @@ -0,0 +1,3 @@ +console.log(Math.random()); +await Deno.stat("."); +await Deno.create("foo.txt"); diff --git a/tests/testdata/compile/unstable_features.ts b/tests/testdata/compile/unstable_features.ts new file mode 100644 index 000000000..819a3d187 --- /dev/null +++ b/tests/testdata/compile/unstable_features.ts @@ -0,0 +1,2 @@ +const db = await Deno.openKv(); +console.log(db); diff --git a/tests/testdata/compile/vfs_implicit_read_permission/main.out b/tests/testdata/compile/vfs_implicit_read_permission/main.out new file mode 100644 index 000000000..17d05159c --- /dev/null +++ b/tests/testdata/compile/vfs_implicit_read_permission/main.out @@ -0,0 +1,8 @@ + __________________ +< Hello from Deno! > + ------------------ + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || diff --git a/tests/testdata/compile/vfs_implicit_read_permission/main.ts b/tests/testdata/compile/vfs_implicit_read_permission/main.ts new file mode 100644 index 000000000..56ad1e095 --- /dev/null +++ b/tests/testdata/compile/vfs_implicit_read_permission/main.ts @@ -0,0 +1,3 @@ +// this will read a file from the package +import { say } from "npm:cowsay@1.5.0"; +console.log(say({ text: "Hello from Deno!" })); diff --git a/tests/testdata/compile/workers/basic.out b/tests/testdata/compile/workers/basic.out new file mode 100644 index 000000000..9cf9aa18f --- /dev/null +++ b/tests/testdata/compile/workers/basic.out @@ -0,0 +1,5 @@ +worker.js imported from main thread +Starting worker +Hello from worker! +Received 42 +Closing diff --git a/tests/testdata/compile/workers/basic.ts b/tests/testdata/compile/workers/basic.ts new file mode 100644 index 000000000..8edf58de9 --- /dev/null +++ b/tests/testdata/compile/workers/basic.ts @@ -0,0 +1,11 @@ +import "./worker.ts"; + +console.log("Starting worker"); +const worker = new Worker( + new URL("./worker.ts", import.meta.url), + { type: "module" }, +); + +setTimeout(() => { + worker.postMessage(42); +}, 500); diff --git a/tests/testdata/compile/workers/not_in_module_map.ts b/tests/testdata/compile/workers/not_in_module_map.ts new file mode 100644 index 000000000..b43f8cb1f --- /dev/null +++ b/tests/testdata/compile/workers/not_in_module_map.ts @@ -0,0 +1,11 @@ +// This time ./worker.ts is not in the module map, so the worker +// initialization will fail unless worker.js is passed as a side module. + +const worker = new Worker( + new URL("./worker.ts", import.meta.url), + { type: "module" }, +); + +setTimeout(() => { + worker.postMessage(42); +}, 500); diff --git a/tests/testdata/compile/workers/worker.ts b/tests/testdata/compile/workers/worker.ts new file mode 100644 index 000000000..a1c357ab1 --- /dev/null +++ b/tests/testdata/compile/workers/worker.ts @@ -0,0 +1,14 @@ +/// +/// + +if (import.meta.main) { + console.log("Hello from worker!"); + + addEventListener("message", (evt) => { + console.log(`Received ${evt.data}`); + console.log("Closing"); + self.close(); + }); +} else { + console.log("worker.js imported from main thread"); +} diff --git a/tests/testdata/coverage/branch.ts b/tests/testdata/coverage/branch.ts new file mode 100644 index 000000000..352167109 --- /dev/null +++ b/tests/testdata/coverage/branch.ts @@ -0,0 +1,15 @@ +export function branch(condition: boolean): boolean { + if (condition) { + return true; + } else { + return false; + } +} + +export function unused(condition: boolean): boolean { + if (condition) { + return false; + } else { + return true; + } +} diff --git a/tests/testdata/coverage/branch_expected.lcov b/tests/testdata/coverage/branch_expected.lcov new file mode 100644 index 000000000..fb3454210 --- /dev/null +++ b/tests/testdata/coverage/branch_expected.lcov @@ -0,0 +1,27 @@ +SF:[WILDCARD]branch.ts +FN:1,branch +FN:9,unused +FNDA:1,branch +FNDA:0,unused +FNF:2 +FNH:1 +BRDA:4,1,0,0 +BRF:1 +BRH:0 +DA:1,1 +DA:2,2 +DA:3,2 +DA:4,0 +DA:5,0 +DA:6,0 +DA:7,2 +DA:9,0 +DA:10,0 +DA:11,0 +DA:12,0 +DA:13,0 +DA:14,0 +DA:15,0 +LH:4 +LF:14 +end_of_record diff --git a/tests/testdata/coverage/branch_expected.out b/tests/testdata/coverage/branch_expected.out new file mode 100644 index 000000000..630ea93b2 --- /dev/null +++ b/tests/testdata/coverage/branch_expected.out @@ -0,0 +1,12 @@ +cover [WILDCARD]/coverage/branch.ts ... 28.571% (4/14) + 4 | } else { + 5 | return false; + 6 | } +-----|----- + 9 | export function unused(condition: boolean): boolean { + 10 | if (condition) { + 11 | return false; + 12 | } else { + 13 | return true; + 14 | } + 15 | } diff --git a/tests/testdata/coverage/branch_test.ts b/tests/testdata/coverage/branch_test.ts new file mode 100644 index 000000000..2a44c8071 --- /dev/null +++ b/tests/testdata/coverage/branch_test.ts @@ -0,0 +1,5 @@ +import { branch } from "./branch.ts"; + +Deno.test("branch", function () { + branch(true); +}); diff --git a/tests/testdata/coverage/complex.ts b/tests/testdata/coverage/complex.ts new file mode 100644 index 000000000..d128b5437 --- /dev/null +++ b/tests/testdata/coverage/complex.ts @@ -0,0 +1,74 @@ +// This entire interface should be completely ignored by the coverage tool. +export interface Complex { + // These comments should be ignored. + foo: string; + + // But this is a stub, so this isn't really documentation. + bar: string; + + // Really all these are doing is padding the line count. + baz: string; +} + +// Lets add some wide characters to ensure that the absolute byte offsets are +// being matched properly. +// +// 패딩에 대한 더 많은 문자. +function dependency( + foo: string, + bar: string, + baz: string, +): Complex { + return { + foo, + bar, + baz, + }; +} + +// Again just more wide characters for padding. +// +// 良い対策のためにいくつかのユニコード文字を投げる。 +export function complex( + foo: string, + bar: string, + baz: string, +): Complex { + return dependency( + foo, + bar, + baz, + ); +} + +// And yet again for good measure. +// 更多用於填充的字元。 +export function unused( + foo: string, + bar: string, + baz: string, +): Complex { + return complex( + foo, + bar, + baz, + ); +} + +// Using a non-ascii name again to ensure that the byte offsets match up +// correctly. +export const π = Math.PI; + +// And same applies for this one, this one is unused and will show up in +// lacking coverage. +export function ƒ(): number { + return ( + 0 + ); +} + +// This arrow function should also show up as uncovered. +console.log("%s", () => 1); + +// Make sure emojis work properly +console.log("📣❓"); diff --git a/tests/testdata/coverage/complex_expected.lcov b/tests/testdata/coverage/complex_expected.lcov new file mode 100644 index 000000000..94b86465a --- /dev/null +++ b/tests/testdata/coverage/complex_expected.lcov @@ -0,0 +1,67 @@ +SF:[WILDCARD]complex.ts +FN:17,dependency +FN:32,complex +FN:46,unused +FN:64,ƒ +FNDA:1,dependency +FNDA:1,complex +FNDA:0,unused +FNDA:0,ƒ +FNF:4 +FNH:2 +BRF:0 +BRH:0 +DA:1,1 +DA:13,1 +DA:14,1 +DA:15,1 +DA:16,1 +DA:17,2 +DA:18,2 +DA:19,2 +DA:20,2 +DA:22,2 +DA:23,2 +DA:24,2 +DA:25,2 +DA:26,2 +DA:27,2 +DA:29,1 +DA:30,1 +DA:31,1 +DA:32,1 +DA:33,1 +DA:34,1 +DA:35,1 +DA:37,2 +DA:38,2 +DA:39,2 +DA:40,2 +DA:42,2 +DA:44,1 +DA:45,1 +DA:46,0 +DA:47,0 +DA:48,0 +DA:49,0 +DA:51,0 +DA:52,0 +DA:53,0 +DA:54,0 +DA:56,0 +DA:58,1 +DA:59,1 +DA:60,1 +DA:62,1 +DA:63,1 +DA:64,0 +DA:65,0 +DA:66,0 +DA:68,0 +DA:70,1 +DA:71,0 +DA:73,1 +DA:74,1 +LH:37 +LF:51 +end_of_record diff --git a/tests/testdata/coverage/complex_expected.out b/tests/testdata/coverage/complex_expected.out new file mode 100644 index 000000000..3d5f6a0ab --- /dev/null +++ b/tests/testdata/coverage/complex_expected.out @@ -0,0 +1,20 @@ +cover [WILDCARD]/coverage/complex.ts ... 72.549% (37/51) + 46 | export function unused( + 47 | foo: string, + 48 | bar: string, + 49 | baz: string, +-----|----- + 51 | return complex( + 52 | foo, + 53 | bar, + 54 | baz, +-----|----- + 56 | } +-----|----- + 64 | export function ƒ(): number { + 65 | return ( + 66 | 0 +-----|----- + 68 | } +-----|----- + 71 | console.log("%s", () => 1); diff --git a/tests/testdata/coverage/complex_test.ts b/tests/testdata/coverage/complex_test.ts new file mode 100644 index 000000000..d6e9c2691 --- /dev/null +++ b/tests/testdata/coverage/complex_test.ts @@ -0,0 +1,39 @@ +import { complex } from "./complex.ts"; + +Deno.test("complex", function () { + complex("foo", "bar", "baz"); +}); + +Deno.test("sub process with stdin", async () => { + // ensure launching deno run with stdin doesn't affect coverage + const code = "console.log('5')"; + // deno-lint-ignore no-deprecated-deno-api + const p = await Deno.run({ + cmd: [Deno.execPath(), "run", "-"], + stdin: "piped", + stdout: "piped", + }); + const encoder = new TextEncoder(); + await p.stdin.write(encoder.encode(code)); + await p.stdin.close(); + const output = new TextDecoder().decode(await p.output()); + p.close(); + if (output.trim() !== "5") { + throw new Error("Failed"); + } +}); + +Deno.test("sub process with deno eval", async () => { + // ensure launching deno eval doesn't affect coverage + const code = "console.log('5')"; + // deno-lint-ignore no-deprecated-deno-api + const p = await Deno.run({ + cmd: [Deno.execPath(), "eval", code], + stdout: "piped", + }); + const output = new TextDecoder().decode(await p.output()); + p.close(); + if (output.trim() !== "5") { + throw new Error("Failed"); + } +}); diff --git a/tests/testdata/coverage/doesnt_exist.out b/tests/testdata/coverage/doesnt_exist.out new file mode 100644 index 000000000..0b679bcb4 --- /dev/null +++ b/tests/testdata/coverage/doesnt_exist.out @@ -0,0 +1 @@ +error: No coverage files found diff --git a/tests/testdata/coverage/final_blankline.js b/tests/testdata/coverage/final_blankline.js new file mode 100644 index 000000000..bb5ab0378 --- /dev/null +++ b/tests/testdata/coverage/final_blankline.js @@ -0,0 +1,5 @@ +// deno-fmt-ignore-file - has blankline at end +export default function example() { + return true; +} + diff --git a/tests/testdata/coverage/final_blankline_expected.lcov b/tests/testdata/coverage/final_blankline_expected.lcov new file mode 100644 index 000000000..48af66180 --- /dev/null +++ b/tests/testdata/coverage/final_blankline_expected.lcov @@ -0,0 +1,16 @@ +SF:[WILDCARD]final_blankline.js +FN:2,example +FNDA:1,example +FNF:1 +FNH:1 +BRF:0 +BRH:0 +DA:1,1 +DA:2,1 +DA:3,2 +DA:4,2 +DA:5,1 +DA:6,1 +LH:6 +LF:6 +end_of_record diff --git a/tests/testdata/coverage/final_blankline_expected.out b/tests/testdata/coverage/final_blankline_expected.out new file mode 100644 index 000000000..8dc5ce30d --- /dev/null +++ b/tests/testdata/coverage/final_blankline_expected.out @@ -0,0 +1 @@ +cover file:///[WILDCARD]final_blankline.js ... 100.000% (6/6) diff --git a/tests/testdata/coverage/final_blankline_test.js b/tests/testdata/coverage/final_blankline_test.js new file mode 100644 index 000000000..e7331c537 --- /dev/null +++ b/tests/testdata/coverage/final_blankline_test.js @@ -0,0 +1,5 @@ +import example from "./final_blankline.js"; + +Deno.test("Example.", () => { + example(); +}); diff --git a/tests/testdata/coverage/invalid_cache/mod.test.ts b/tests/testdata/coverage/invalid_cache/mod.test.ts new file mode 100644 index 000000000..5815d07a3 --- /dev/null +++ b/tests/testdata/coverage/invalid_cache/mod.test.ts @@ -0,0 +1,2 @@ +import { test } from "./mod.ts"; +Deno.test("test", () => void test()); diff --git a/tests/testdata/coverage/invalid_cache/mod_after.ts b/tests/testdata/coverage/invalid_cache/mod_after.ts new file mode 100644 index 000000000..294dc0843 --- /dev/null +++ b/tests/testdata/coverage/invalid_cache/mod_after.ts @@ -0,0 +1,6 @@ +export function test() { + return 42; +} +if (import.meta.main) { + test(); +} diff --git a/tests/testdata/coverage/invalid_cache/mod_before.ts b/tests/testdata/coverage/invalid_cache/mod_before.ts new file mode 100644 index 000000000..ea52ccbce --- /dev/null +++ b/tests/testdata/coverage/invalid_cache/mod_before.ts @@ -0,0 +1,15 @@ +export function test() { + console.log("1"); + console.log("2"); + console.log("3"); + console.log("4"); + console.log("5"); + console.log("6"); + console.log("7"); + console.log("8"); + console.log("9"); + return 42; +} +if (import.meta.main) { + test(); +} diff --git a/tests/testdata/coverage/multifile/a_test.js b/tests/testdata/coverage/multifile/a_test.js new file mode 100644 index 000000000..d5d9c3533 --- /dev/null +++ b/tests/testdata/coverage/multifile/a_test.js @@ -0,0 +1,8 @@ +import { test } from "./mod.js"; + +Deno.test({ + name: "bugrepo a", + fn: () => { + test(true); + }, +}); diff --git a/tests/testdata/coverage/multifile/b_test.js b/tests/testdata/coverage/multifile/b_test.js new file mode 100644 index 000000000..d93b15a17 --- /dev/null +++ b/tests/testdata/coverage/multifile/b_test.js @@ -0,0 +1,8 @@ +import { test } from "./mod.js"; + +Deno.test({ + name: "bugrepo b", + fn: () => { + test(false); + }, +}); diff --git a/tests/testdata/coverage/multifile/expected.lcov b/tests/testdata/coverage/multifile/expected.lcov new file mode 100644 index 000000000..03ad5e7bd --- /dev/null +++ b/tests/testdata/coverage/multifile/expected.lcov @@ -0,0 +1,18 @@ +SF:[WILDCARD]mod.js +FN:1,test +FNDA:2,test +FNF:1 +FNH:1 +BRDA:2,1,0,1 +BRF:1 +BRH:1 +DA:1,2 +DA:2,4 +DA:3,5 +DA:4,5 +DA:5,5 +DA:6,4 +DA:7,1 +LH:7 +LF:7 +end_of_record diff --git a/tests/testdata/coverage/multifile/expected.out b/tests/testdata/coverage/multifile/expected.out new file mode 100644 index 000000000..fde26e165 --- /dev/null +++ b/tests/testdata/coverage/multifile/expected.out @@ -0,0 +1 @@ +cover [WILDCARD]/multifile/mod.js ... 100.000% (7/7) diff --git a/tests/testdata/coverage/multifile/mod.js b/tests/testdata/coverage/multifile/mod.js new file mode 100644 index 000000000..b9f8d627a --- /dev/null +++ b/tests/testdata/coverage/multifile/mod.js @@ -0,0 +1,6 @@ +export function test(a) { + if (a) { + return 0; + } + return 1; +} diff --git a/tests/testdata/coverage/multisource/bar.ts b/tests/testdata/coverage/multisource/bar.ts new file mode 100644 index 000000000..123937b0b --- /dev/null +++ b/tests/testdata/coverage/multisource/bar.ts @@ -0,0 +1,7 @@ +export function bar(cond: T) { + if (cond) { + return 1; + } else { + return 2; + } +} diff --git a/tests/testdata/coverage/multisource/baz/quux.ts b/tests/testdata/coverage/multisource/baz/quux.ts new file mode 100644 index 000000000..6032f6f3c --- /dev/null +++ b/tests/testdata/coverage/multisource/baz/quux.ts @@ -0,0 +1,14 @@ +export function quux(cond: boolean) { + if (cond) { + const a = 1; + const b = a; + const c = b; + const d = c; + const e = d; + const f = e; + const g = f; + return g; + } else { + return 2; + } +} diff --git a/tests/testdata/coverage/multisource/baz/qux.ts b/tests/testdata/coverage/multisource/baz/qux.ts new file mode 100644 index 000000000..973f48c61 --- /dev/null +++ b/tests/testdata/coverage/multisource/baz/qux.ts @@ -0,0 +1,7 @@ +export function qux(cond: boolean) { + if (cond) { + return 1; + } else { + return 2; + } +} diff --git a/tests/testdata/coverage/multisource/foo.ts b/tests/testdata/coverage/multisource/foo.ts new file mode 100644 index 000000000..0559cadd8 --- /dev/null +++ b/tests/testdata/coverage/multisource/foo.ts @@ -0,0 +1,14 @@ +export function foo(cond: boolean) { + let a = 0; + if (cond) { + a = 1; + } else { + a = 2; + } + + if (a == 4) { + return 1; + } else { + return 2; + } +} diff --git a/tests/testdata/coverage/multisource/test.ts b/tests/testdata/coverage/multisource/test.ts new file mode 100644 index 000000000..350421177 --- /dev/null +++ b/tests/testdata/coverage/multisource/test.ts @@ -0,0 +1,22 @@ +import { foo } from "./foo.ts"; +import { bar } from "./bar.ts"; +import { qux } from "./baz/qux.ts"; +import { quux } from "./baz/quux.ts"; + +Deno.test("foo", () => { + foo(true); + foo(false); +}); + +Deno.test("bar", () => { + bar(false); +}); + +Deno.test("qux", () => { + qux(true); + qux(false); +}); + +Deno.test("quux", () => { + quux(false); +}); diff --git a/tests/testdata/coverage/no_internal_code_test.ts b/tests/testdata/coverage/no_internal_code_test.ts new file mode 100644 index 000000000..0cf46d252 --- /dev/null +++ b/tests/testdata/coverage/no_internal_code_test.ts @@ -0,0 +1,7 @@ +const add = (a: number, b: number) => a + b; + +Deno.test(function addTest() { + if (add(2, 3) !== 5) { + throw new Error("fail"); + } +}); diff --git a/tests/testdata/coverage/no_internal_node_code_test.ts b/tests/testdata/coverage/no_internal_node_code_test.ts new file mode 100644 index 000000000..dc53e0c52 --- /dev/null +++ b/tests/testdata/coverage/no_internal_node_code_test.ts @@ -0,0 +1,8 @@ +import * as path from "node:path"; + +Deno.test(function test() { + const res = path.join("foo", "bar"); + if (!res.includes("foo")) { + throw new Error("fail"); + } +}); diff --git a/tests/testdata/coverage/no_npm_coverage/expected.out b/tests/testdata/coverage/no_npm_coverage/expected.out new file mode 100644 index 000000000..ca4511277 --- /dev/null +++ b/tests/testdata/coverage/no_npm_coverage/expected.out @@ -0,0 +1 @@ +cover [WILDCARD]/no_npm_coverage/no_npm_coverage.ts ... 100.000% (4/4) diff --git a/tests/testdata/coverage/no_npm_coverage/no_npm_coverage.ts b/tests/testdata/coverage/no_npm_coverage/no_npm_coverage.ts new file mode 100644 index 000000000..4233b2e5d --- /dev/null +++ b/tests/testdata/coverage/no_npm_coverage/no_npm_coverage.ts @@ -0,0 +1,4 @@ +import chalk from "npm:chalk"; +export function main() { + console.log(chalk.red("RED")); +} diff --git a/tests/testdata/coverage/no_npm_coverage/no_npm_coverage_test.ts b/tests/testdata/coverage/no_npm_coverage/no_npm_coverage_test.ts new file mode 100644 index 000000000..8305f9597 --- /dev/null +++ b/tests/testdata/coverage/no_npm_coverage/no_npm_coverage_test.ts @@ -0,0 +1,4 @@ +import { main } from "./no_npm_coverage.ts"; +Deno.test("main", () => { + main(); +}); diff --git a/tests/testdata/coverage/no_snaps_included/__snapshots__/no_snaps_included_test.ts.snap b/tests/testdata/coverage/no_snaps_included/__snapshots__/no_snaps_included_test.ts.snap new file mode 100644 index 000000000..b7bfe6b8b --- /dev/null +++ b/tests/testdata/coverage/no_snaps_included/__snapshots__/no_snaps_included_test.ts.snap @@ -0,0 +1,3 @@ +export const snapshot = {}; + +snapshot[`snapshot excluded from coverage 1`] = `{}`; diff --git a/tests/testdata/coverage/no_snaps_included/expected.out b/tests/testdata/coverage/no_snaps_included/expected.out new file mode 100644 index 000000000..83979a752 --- /dev/null +++ b/tests/testdata/coverage/no_snaps_included/expected.out @@ -0,0 +1 @@ +cover [WILDCARD]/no_snaps_included/no_snaps_included.ts ... 100.000% (3/3) diff --git a/tests/testdata/coverage/no_snaps_included/no_snaps_included.ts b/tests/testdata/coverage/no_snaps_included/no_snaps_included.ts new file mode 100644 index 000000000..2d844150b --- /dev/null +++ b/tests/testdata/coverage/no_snaps_included/no_snaps_included.ts @@ -0,0 +1,3 @@ +export function truth() { + return true; +} diff --git a/tests/testdata/coverage/no_snaps_included/no_snaps_included_test.ts b/tests/testdata/coverage/no_snaps_included/no_snaps_included_test.ts new file mode 100644 index 000000000..6fb44fcc6 --- /dev/null +++ b/tests/testdata/coverage/no_snaps_included/no_snaps_included_test.ts @@ -0,0 +1,11 @@ +import { assertSnapshot } from "../../../../test_util/std/testing/snapshot.ts"; +import { truth } from "./no_snaps_included.ts"; + +Deno.test("the truth", () => { + truth(); +}); + +// Create snapshot in .snap file, but it shouldn't be in the coverage output +Deno.test("snapshot excluded from coverage", async (context) => { + await assertSnapshot(context, {}); +}); diff --git a/tests/testdata/coverage/no_tests_included/expected.out b/tests/testdata/coverage/no_tests_included/expected.out new file mode 100644 index 000000000..3b2469f2d --- /dev/null +++ b/tests/testdata/coverage/no_tests_included/expected.out @@ -0,0 +1 @@ +cover [WILDCARD]/no_tests_included/foo.ts ... 100.000% (3/3) diff --git a/tests/testdata/coverage/no_tests_included/foo.test.js b/tests/testdata/coverage/no_tests_included/foo.test.js new file mode 100644 index 000000000..46dd037be --- /dev/null +++ b/tests/testdata/coverage/no_tests_included/foo.test.js @@ -0,0 +1,6 @@ +import { addNumbers } from "./foo.ts"; +import { assertEquals } from "../../../../test_util/std/assert/mod.ts"; + +Deno.test("addNumbers works", () => { + assertEquals(addNumbers(1, 2), 3); +}); diff --git a/tests/testdata/coverage/no_tests_included/foo.test.mts b/tests/testdata/coverage/no_tests_included/foo.test.mts new file mode 100644 index 000000000..46dd037be --- /dev/null +++ b/tests/testdata/coverage/no_tests_included/foo.test.mts @@ -0,0 +1,6 @@ +import { addNumbers } from "./foo.ts"; +import { assertEquals } from "../../../../test_util/std/assert/mod.ts"; + +Deno.test("addNumbers works", () => { + assertEquals(addNumbers(1, 2), 3); +}); diff --git a/tests/testdata/coverage/no_tests_included/foo.test.ts b/tests/testdata/coverage/no_tests_included/foo.test.ts new file mode 100644 index 000000000..46dd037be --- /dev/null +++ b/tests/testdata/coverage/no_tests_included/foo.test.ts @@ -0,0 +1,6 @@ +import { addNumbers } from "./foo.ts"; +import { assertEquals } from "../../../../test_util/std/assert/mod.ts"; + +Deno.test("addNumbers works", () => { + assertEquals(addNumbers(1, 2), 3); +}); diff --git a/tests/testdata/coverage/no_tests_included/foo.ts b/tests/testdata/coverage/no_tests_included/foo.ts new file mode 100644 index 000000000..fc2860ef0 --- /dev/null +++ b/tests/testdata/coverage/no_tests_included/foo.ts @@ -0,0 +1,3 @@ +export function addNumbers(a: number, b: number): number { + return a + b; +} diff --git a/tests/testdata/coverage/no_transpiled_lines/expected.lcov b/tests/testdata/coverage/no_transpiled_lines/expected.lcov new file mode 100644 index 000000000..480945d14 --- /dev/null +++ b/tests/testdata/coverage/no_transpiled_lines/expected.lcov @@ -0,0 +1,10 @@ +SF:[WILDCARD]index.ts +FNF:0 +FNH:0 +BRF:0 +BRH:0 +DA:1,1 +DA:3,1 +LH:2 +LF:2 +end_of_record diff --git a/tests/testdata/coverage/no_transpiled_lines/expected.out b/tests/testdata/coverage/no_transpiled_lines/expected.out new file mode 100644 index 000000000..3438a045c --- /dev/null +++ b/tests/testdata/coverage/no_transpiled_lines/expected.out @@ -0,0 +1 @@ +cover [WILDCARD]index.ts ... 100.000% (2/2) diff --git a/tests/testdata/coverage/no_transpiled_lines/index.ts b/tests/testdata/coverage/no_transpiled_lines/index.ts new file mode 100644 index 000000000..8b87e7680 --- /dev/null +++ b/tests/testdata/coverage/no_transpiled_lines/index.ts @@ -0,0 +1,3 @@ +export { assertStrictEquals } from "../../../../test_util/std/assert/mod.ts"; + +export * from "./interface.ts"; diff --git a/tests/testdata/coverage/no_transpiled_lines/interface.ts b/tests/testdata/coverage/no_transpiled_lines/interface.ts new file mode 100644 index 000000000..6e58a7b2f --- /dev/null +++ b/tests/testdata/coverage/no_transpiled_lines/interface.ts @@ -0,0 +1,3 @@ +export interface TestInterface { + id: string; +} diff --git a/tests/testdata/coverage/no_transpiled_lines/repro_test.ts b/tests/testdata/coverage/no_transpiled_lines/repro_test.ts new file mode 100644 index 000000000..ca4a0d17f --- /dev/null +++ b/tests/testdata/coverage/no_transpiled_lines/repro_test.ts @@ -0,0 +1,7 @@ +import { assertStrictEquals, TestInterface } from "./index.ts"; + +Deno.test(function noTranspiledLines() { + const foo: TestInterface = { id: "id" }; + + assertStrictEquals(foo.id, "id"); +}); diff --git a/tests/testdata/doc/060_deno_doc_displays_all_overloads_in_details_view.ts b/tests/testdata/doc/060_deno_doc_displays_all_overloads_in_details_view.ts new file mode 100644 index 000000000..854c1b464 --- /dev/null +++ b/tests/testdata/doc/060_deno_doc_displays_all_overloads_in_details_view.ts @@ -0,0 +1,6 @@ +// deno-lint-ignore-file +export namespace NS { + export function test(name: string, fn: Function): void; + export function test(options: object): void; + export function test(name: string | object, fn?: Function): void {} +} diff --git a/tests/testdata/doc/060_deno_doc_displays_all_overloads_in_details_view.ts.out b/tests/testdata/doc/060_deno_doc_displays_all_overloads_in_details_view.ts.out new file mode 100644 index 000000000..28d1cb921 --- /dev/null +++ b/tests/testdata/doc/060_deno_doc_displays_all_overloads_in_details_view.ts.out @@ -0,0 +1,9 @@ +Defined in [WILDCARD]/060_deno_doc_displays_all_overloads_in_details_view.ts:3:3 + +function test(name: string, fn: Function): void + +Defined in [WILDCARD]/060_deno_doc_displays_all_overloads_in_details_view.ts:4:3 + +function test(options: object): void + + diff --git a/tests/testdata/doc/deno_doc.ts b/tests/testdata/doc/deno_doc.ts new file mode 100644 index 000000000..fb3c50957 --- /dev/null +++ b/tests/testdata/doc/deno_doc.ts @@ -0,0 +1,3 @@ +/** Some JSDoc */ +export function foo() { +} diff --git a/tests/testdata/doc/deno_doc2.ts b/tests/testdata/doc/deno_doc2.ts new file mode 100644 index 000000000..ee6fc22dc --- /dev/null +++ b/tests/testdata/doc/deno_doc2.ts @@ -0,0 +1,3 @@ +/** Some JSDoc */ +export function bar() { +} diff --git a/tests/testdata/doc/deno_doc_builtin.out b/tests/testdata/doc/deno_doc_builtin.out new file mode 100644 index 000000000..b4a90d6bc --- /dev/null +++ b/tests/testdata/doc/deno_doc_builtin.out @@ -0,0 +1,3 @@ +[WILDCARD] +namespace Deno +[WILDCARD] \ No newline at end of file diff --git a/tests/testdata/doc/import_map.json b/tests/testdata/doc/import_map.json new file mode 100644 index 000000000..244a30296 --- /dev/null +++ b/tests/testdata/doc/import_map.json @@ -0,0 +1,5 @@ +{ + "imports": { + "rex/": "./module/" + } +} diff --git a/tests/testdata/doc/invalid_url.out b/tests/testdata/doc/invalid_url.out new file mode 100644 index 000000000..038c53177 --- /dev/null +++ b/tests/testdata/doc/invalid_url.out @@ -0,0 +1,4 @@ +error: Invalid URL 'https://raw.githubusercontent.com%2Fdyedgreen%2Fdeno-sqlite%2Frework_api%2Fmod.ts' + +Caused by: + invalid domain character diff --git a/tests/testdata/doc/lint_success.out b/tests/testdata/doc/lint_success.out new file mode 100644 index 000000000..c05ac45a1 --- /dev/null +++ b/tests/testdata/doc/lint_success.out @@ -0,0 +1 @@ +Checked 1 file diff --git a/tests/testdata/doc/lint_success.ts b/tests/testdata/doc/lint_success.ts new file mode 100644 index 000000000..42c44b2d7 --- /dev/null +++ b/tests/testdata/doc/lint_success.ts @@ -0,0 +1,5 @@ +/** My test class. */ +export class Test { + /** My property. */ + prop: string; +} diff --git a/tests/testdata/doc/lint_success_html.out b/tests/testdata/doc/lint_success_html.out new file mode 100644 index 000000000..9503a335f --- /dev/null +++ b/tests/testdata/doc/lint_success_html.out @@ -0,0 +1 @@ +Written 9 files to "./docs/" diff --git a/tests/testdata/doc/lint_success_json.out b/tests/testdata/doc/lint_success_json.out new file mode 100644 index 000000000..050b2540c --- /dev/null +++ b/tests/testdata/doc/lint_success_json.out @@ -0,0 +1,50 @@ +[ + { + "kind": "class", + "name": "Test", + "location": { + "filename": "file:///[WILDCARD]/lint_success.ts", + "line": 2, + "col": 0, + "byteIndex": 22 + }, + "declarationKind": "export", + "jsDoc": { + "doc": "My test class." + }, + "classDef": { + "isAbstract": false, + "constructors": [], + "properties": [ + { + "jsDoc": { + "doc": "My property." + }, + "tsType": { + "repr": "string", + "kind": "keyword", + "keyword": "string" + }, + "readonly": false, + "accessibility": null, + "optional": false, + "isAbstract": false, + "isStatic": false, + "name": "prop", + "location": { + "filename": "file:///[WILDCARD]/lint_success.ts", + "line": 4, + "col": 2, + "byteIndex": 66 + } + } + ], + "indexSignatures": [], + "methods": [], + "extends": null, + "implements": [], + "typeParams": [], + "superTypeParams": [] + } + } +] diff --git a/tests/testdata/doc/module/fun.js b/tests/testdata/doc/module/fun.js new file mode 100644 index 000000000..28901d945 --- /dev/null +++ b/tests/testdata/doc/module/fun.js @@ -0,0 +1,2 @@ +/** This is some documentation */ +export function fun(_a, _b) {} diff --git a/tests/testdata/doc/referenced_private_types.out b/tests/testdata/doc/referenced_private_types.out new file mode 100644 index 000000000..3c91dbe15 --- /dev/null +++ b/tests/testdata/doc/referenced_private_types.out @@ -0,0 +1,12 @@ +Defined in file:///[WILDCARD]/doc/referenced_private_types.ts:5:1 + +class MyClass + + prop: MyInterface + +Defined in file:///[WILDCARD]/doc/referenced_private_types.ts:1:1 + +private interface MyInterface + + prop?: string + diff --git a/tests/testdata/doc/referenced_private_types.ts b/tests/testdata/doc/referenced_private_types.ts new file mode 100644 index 000000000..9570d4625 --- /dev/null +++ b/tests/testdata/doc/referenced_private_types.ts @@ -0,0 +1,7 @@ +interface MyInterface { + prop?: string; +} + +export class MyClass { + prop: MyInterface = {}; +} diff --git a/tests/testdata/doc/referenced_private_types_fixed.out b/tests/testdata/doc/referenced_private_types_fixed.out new file mode 100644 index 000000000..c05ac45a1 --- /dev/null +++ b/tests/testdata/doc/referenced_private_types_fixed.out @@ -0,0 +1 @@ +Checked 1 file diff --git a/tests/testdata/doc/referenced_private_types_fixed.ts b/tests/testdata/doc/referenced_private_types_fixed.ts new file mode 100644 index 000000000..cd99bc76e --- /dev/null +++ b/tests/testdata/doc/referenced_private_types_fixed.ts @@ -0,0 +1,11 @@ +/** Doc comment */ +export interface MyInterface { + /** Doc comment */ + prop?: string; +} + +/** Doc comment */ +export class MyClass { + /** Doc comment */ + prop: MyInterface = {}; +} diff --git a/tests/testdata/doc/referenced_private_types_lint.out b/tests/testdata/doc/referenced_private_types_lint.out new file mode 100644 index 000000000..328435cd7 --- /dev/null +++ b/tests/testdata/doc/referenced_private_types_lint.out @@ -0,0 +1,28 @@ +error[missing-jsdoc]: exported symbol is missing JSDoc documentation + --> [WILDCARD]:5:1 + | +5 | export class MyClass { + | ^ + + +error[private-type-ref]: public type 'MyClass.prototype.prop' references private type 'MyInterface' + --> [WILDCARD]:6:3 + | +6 | prop: MyInterface = {}; + | ^ + = hint: make the referenced type public or remove the reference + | +1 | interface MyInterface { + | - this is the referenced type + + info: to ensure documentation is complete all types that are exposed in the public API must be public + + +error[missing-jsdoc]: exported symbol is missing JSDoc documentation + --> [WILDCARD]:6:3 + | +6 | prop: MyInterface = {}; + | ^ + + +error: Found 3 documentation lint errors. diff --git a/tests/testdata/doc/types_header.out b/tests/testdata/doc/types_header.out new file mode 100644 index 000000000..a97b35dd7 --- /dev/null +++ b/tests/testdata/doc/types_header.out @@ -0,0 +1,6 @@ +Download http://127.0.0.1:4545/xTypeScriptTypes.js +Download http://127.0.0.1:4545/xTypeScriptTypes.d.ts +Defined in http://127.0.0.1:4545/xTypeScriptTypes.d.ts:1:14 + +const foo: "foo" + diff --git a/tests/testdata/doc/types_header.ts b/tests/testdata/doc/types_header.ts new file mode 100644 index 000000000..b64c8d000 --- /dev/null +++ b/tests/testdata/doc/types_header.ts @@ -0,0 +1 @@ +export * from "http://127.0.0.1:4545/xTypeScriptTypes.js"; diff --git a/tests/testdata/doc/types_hint.out b/tests/testdata/doc/types_hint.out new file mode 100644 index 000000000..bfd5191a1 --- /dev/null +++ b/tests/testdata/doc/types_hint.out @@ -0,0 +1,5 @@ +Defined in [WILDCARD]/type_definitions/foo.d.ts:2:14 + +const foo: string + An exported value. + diff --git a/tests/testdata/doc/types_hint.ts b/tests/testdata/doc/types_hint.ts new file mode 100644 index 000000000..bacea46db --- /dev/null +++ b/tests/testdata/doc/types_hint.ts @@ -0,0 +1,2 @@ +// @deno-types="../type_definitions/foo.d.ts" +export * from "../type_definitions/foo.js"; diff --git a/tests/testdata/doc/types_ref.js b/tests/testdata/doc/types_ref.js new file mode 100644 index 000000000..03d8b5570 --- /dev/null +++ b/tests/testdata/doc/types_ref.js @@ -0,0 +1,2 @@ +/// +export const foo = "foo"; diff --git a/tests/testdata/doc/types_ref.out b/tests/testdata/doc/types_ref.out new file mode 100644 index 000000000..bfd5191a1 --- /dev/null +++ b/tests/testdata/doc/types_ref.out @@ -0,0 +1,5 @@ +Defined in [WILDCARD]/type_definitions/foo.d.ts:2:14 + +const foo: string + An exported value. + diff --git a/tests/testdata/doc/use_import_map.js b/tests/testdata/doc/use_import_map.js new file mode 100644 index 000000000..672a7a7bd --- /dev/null +++ b/tests/testdata/doc/use_import_map.js @@ -0,0 +1 @@ +export { fun } from "rex/fun.js"; diff --git a/tests/testdata/doc/use_import_map.out b/tests/testdata/doc/use_import_map.out new file mode 100644 index 000000000..9509d5bfe --- /dev/null +++ b/tests/testdata/doc/use_import_map.out @@ -0,0 +1,5 @@ +Defined in [WILDCARD]/doc/module/fun.js:2:1 + +function fun(_a, _b): void + This is some documentation + diff --git a/tests/testdata/dynamic_import/b.js b/tests/testdata/dynamic_import/b.js new file mode 100644 index 000000000..6ea50d360 --- /dev/null +++ b/tests/testdata/dynamic_import/b.js @@ -0,0 +1,2 @@ +import "./bad.mjs"; +export default () => "error"; diff --git a/tests/testdata/dynamic_import/c.js b/tests/testdata/dynamic_import/c.js new file mode 100644 index 000000000..20546455e --- /dev/null +++ b/tests/testdata/dynamic_import/c.js @@ -0,0 +1,2 @@ +await import("./bad2.mjs"); +export default () => "error"; diff --git a/tests/testdata/dynamic_import/empty_1.ts b/tests/testdata/dynamic_import/empty_1.ts new file mode 100644 index 000000000..e69de29bb diff --git a/tests/testdata/dynamic_import/empty_2.ts b/tests/testdata/dynamic_import/empty_2.ts new file mode 100644 index 000000000..e69de29bb diff --git a/tests/testdata/dynamic_import/permissions_blob_local.ts b/tests/testdata/dynamic_import/permissions_blob_local.ts new file mode 100644 index 000000000..9ef4158ce --- /dev/null +++ b/tests/testdata/dynamic_import/permissions_blob_local.ts @@ -0,0 +1,6 @@ +// This file doesn't really exist, but it doesn't matter, a "PermissionsDenied" error should be thrown. +const code = `import "file:///${ + Deno.build.os == "windows" ? "C:/" : "" +}local_file.ts";`; +const blob = new Blob([code]); +await import(URL.createObjectURL(blob)); diff --git a/tests/testdata/dynamic_import/permissions_blob_local.ts.out b/tests/testdata/dynamic_import/permissions_blob_local.ts.out new file mode 100644 index 000000000..b7b246ba2 --- /dev/null +++ b/tests/testdata/dynamic_import/permissions_blob_local.ts.out @@ -0,0 +1,5 @@ +error: Uncaught (in promise) TypeError: Requires read access to "[WILDCARD]local_file.ts", run again with the --allow-read flag + at blob:null/[WILDCARD]:1:8 +await import(URL.createObjectURL(blob)); +^ + at async file://[WILDCARD]/permissions_blob_local.ts:6:1 diff --git a/tests/testdata/dynamic_import/permissions_blob_remote.ts b/tests/testdata/dynamic_import/permissions_blob_remote.ts new file mode 100644 index 000000000..1e2c8c21a --- /dev/null +++ b/tests/testdata/dynamic_import/permissions_blob_remote.ts @@ -0,0 +1,4 @@ +// This file doesn't really exist, but it doesn't matter, a "PermissionsDenied" error should be thrown. +const code = `import "https://example.com/some/file.ts";`; +const blob = new Blob([code]); +await import(URL.createObjectURL(blob)); diff --git a/tests/testdata/dynamic_import/permissions_blob_remote.ts.out b/tests/testdata/dynamic_import/permissions_blob_remote.ts.out new file mode 100644 index 000000000..a00c02d72 --- /dev/null +++ b/tests/testdata/dynamic_import/permissions_blob_remote.ts.out @@ -0,0 +1,5 @@ +error: Uncaught (in promise) TypeError: Requires net access to "example.com", run again with the --allow-net flag + at blob:null/[WILDCARD]:1:8 +await import(URL.createObjectURL(blob)); +^ + at async file:///[WILDCARD]/dynamic_import/permissions_blob_remote.ts:4:1 diff --git a/tests/testdata/dynamic_import/permissions_data_local.ts b/tests/testdata/dynamic_import/permissions_data_local.ts new file mode 100644 index 000000000..be4fc1c34 --- /dev/null +++ b/tests/testdata/dynamic_import/permissions_data_local.ts @@ -0,0 +1,5 @@ +// This file doesn't really exist, but it doesn't matter, a "PermissionsDenied" error should be thrown. +const code = `import "file:///${ + Deno.build.os == "windows" ? "C:/" : "" +}local_file.ts";`; +await import(`data:application/javascript;base64,${btoa(code)}`); diff --git a/tests/testdata/dynamic_import/permissions_data_local.ts.out b/tests/testdata/dynamic_import/permissions_data_local.ts.out new file mode 100644 index 000000000..98c8a7310 --- /dev/null +++ b/tests/testdata/dynamic_import/permissions_data_local.ts.out @@ -0,0 +1,5 @@ +error: Uncaught (in promise) TypeError: Requires read access to "[WILDCARD]local_file.ts", run again with the --allow-read flag + at data:application/javascript;base64,[WILDCARD]:1:8 +await import(`data:application/javascript;base64,${btoa(code)}`); +^ + at async file:///[WILDCARD]/dynamic_import/permissions_data_local.ts:5:1 diff --git a/tests/testdata/dynamic_import/permissions_data_remote.ts b/tests/testdata/dynamic_import/permissions_data_remote.ts new file mode 100644 index 000000000..b0a9540c3 --- /dev/null +++ b/tests/testdata/dynamic_import/permissions_data_remote.ts @@ -0,0 +1,3 @@ +// This file doesn't really exist, but it doesn't matter, a "PermissionsDenied" error should be thrown. +const code = `import "https://example.com/some/file.ts";`; +await import(`data:application/javascript;base64,${btoa(code)}`); diff --git a/tests/testdata/dynamic_import/permissions_data_remote.ts.out b/tests/testdata/dynamic_import/permissions_data_remote.ts.out new file mode 100644 index 000000000..cb2a7ccf7 --- /dev/null +++ b/tests/testdata/dynamic_import/permissions_data_remote.ts.out @@ -0,0 +1,5 @@ +error: Uncaught (in promise) TypeError: Requires net access to "example.com", run again with the --allow-net flag + at data:application/javascript;base64,aW1wb3J0ICJodHRwczovL2V4YW1wbGUuY29tL3NvbWUvZmlsZS50cyI7:1:8 +await import(`data:application/javascript;base64,${btoa(code)}`); +^ + at async file:///[WILDCARD]/dynamic_import/permissions_data_remote.ts:3:1 diff --git a/tests/testdata/dynamic_import/permissions_remote_remote.ts b/tests/testdata/dynamic_import/permissions_remote_remote.ts new file mode 100644 index 000000000..65a254191 --- /dev/null +++ b/tests/testdata/dynamic_import/permissions_remote_remote.ts @@ -0,0 +1,3 @@ +await import( + "" + "http://localhost:4545/dynamic_import/static_remote.ts" +); diff --git a/tests/testdata/dynamic_import/permissions_remote_remote.ts.out b/tests/testdata/dynamic_import/permissions_remote_remote.ts.out new file mode 100644 index 000000000..bd88dd4d9 --- /dev/null +++ b/tests/testdata/dynamic_import/permissions_remote_remote.ts.out @@ -0,0 +1,5 @@ +error: Uncaught (in promise) TypeError: Requires net access to "example.com", run again with the --allow-net flag + at http://localhost:4545/dynamic_import/static_remote.ts:2:8 +await import( +^ + at async file:///[WILDCARD]/dynamic_import/permissions_remote_remote.ts:1:1 diff --git a/tests/testdata/dynamic_import/static_analysis_no_permissions.ts b/tests/testdata/dynamic_import/static_analysis_no_permissions.ts new file mode 100644 index 000000000..de75ba87b --- /dev/null +++ b/tests/testdata/dynamic_import/static_analysis_no_permissions.ts @@ -0,0 +1,13 @@ +try { + await import("./empty_1.ts"); + console.log("✅ Succeeded importing statically analyzable specifier"); +} catch { + console.log("❌ Failed importing statically analyzable specifier"); +} + +try { + await import("" + "./empty_2.ts"); + console.log("❌ Succeeded importing non-statically analyzable specifier"); +} catch { + console.log("✅ Failed importing non-statically analyzable specifier"); +} diff --git a/tests/testdata/dynamic_import/static_analysis_no_permissions.ts.out b/tests/testdata/dynamic_import/static_analysis_no_permissions.ts.out new file mode 100644 index 000000000..ba9249ab0 --- /dev/null +++ b/tests/testdata/dynamic_import/static_analysis_no_permissions.ts.out @@ -0,0 +1,2 @@ +✅ Succeeded importing statically analyzable specifier +✅ Failed importing non-statically analyzable specifier diff --git a/tests/testdata/dynamic_import/static_remote.ts b/tests/testdata/dynamic_import/static_remote.ts new file mode 100644 index 000000000..2d6e820fd --- /dev/null +++ b/tests/testdata/dynamic_import/static_remote.ts @@ -0,0 +1,2 @@ +// This file doesn't really exist, but it doesn't matter, a "PermissionsDenied" error should be thrown. +import "https://example.com/some/file.ts"; diff --git a/tests/testdata/echo.ts b/tests/testdata/echo.ts new file mode 100644 index 000000000..84a645433 --- /dev/null +++ b/tests/testdata/echo.ts @@ -0,0 +1,6 @@ +function echo(args: string[]) { + const msg = args.join(", "); + Deno.stdout.write(new TextEncoder().encode(msg)); +} + +echo(Deno.args); diff --git a/tests/testdata/echo_server.ts b/tests/testdata/echo_server.ts new file mode 100644 index 000000000..e7622c7aa --- /dev/null +++ b/tests/testdata/echo_server.ts @@ -0,0 +1,12 @@ +import { copy } from "../../test_util/std/streams/copy.ts"; +const addr = Deno.args[0] || "0.0.0.0:4544"; +const [hostname, port] = addr.split(":"); +const listener = Deno.listen({ hostname, port: Number(port) }); +console.log("listening on", addr); +listener.accept().then( + async (conn) => { + console.log("received bytes:", await copy(conn, conn)); + conn.close(); + listener.close(); + }, +); diff --git a/tests/testdata/encoding/utf-16be.ts b/tests/testdata/encoding/utf-16be.ts new file mode 100644 index 000000000..3d0144d7c Binary files /dev/null and b/tests/testdata/encoding/utf-16be.ts differ diff --git a/tests/testdata/encoding/utf-16le.ts b/tests/testdata/encoding/utf-16le.ts new file mode 100644 index 000000000..6f0e415f2 Binary files /dev/null and b/tests/testdata/encoding/utf-16le.ts differ diff --git a/tests/testdata/encoding/utf-8.ts b/tests/testdata/encoding/utf-8.ts new file mode 100644 index 000000000..bf889aeb7 --- /dev/null +++ b/tests/testdata/encoding/utf-8.ts @@ -0,0 +1 @@ +console.log("Hello World"); diff --git a/tests/testdata/encoding/windows-1255 b/tests/testdata/encoding/windows-1255 new file mode 100644 index 000000000..ec5cad7fd --- /dev/null +++ b/tests/testdata/encoding/windows-1255 @@ -0,0 +1 @@ +console.log(" "); diff --git a/tests/testdata/env b/tests/testdata/env new file mode 100644 index 000000000..c41732d30 --- /dev/null +++ b/tests/testdata/env @@ -0,0 +1,4 @@ +FOO=BAR +ANOTHER_FOO=ANOTHER_${FOO} +MULTILINE="First Line +Second Line" \ No newline at end of file diff --git a/tests/testdata/error_cause_recursive_aggregate.ts b/tests/testdata/error_cause_recursive_aggregate.ts new file mode 100644 index 000000000..4bb2ae064 --- /dev/null +++ b/tests/testdata/error_cause_recursive_aggregate.ts @@ -0,0 +1,9 @@ +const foo = new Error("foo"); +const bar = new Error("bar", { cause: foo }); +foo.cause = bar; + +const qux = new Error("qux"); +const quux = new Error("quux", { cause: qux }); +qux.cause = quux; + +throw new AggregateError([bar, quux]); diff --git a/tests/testdata/error_cause_recursive_aggregate.ts.out b/tests/testdata/error_cause_recursive_aggregate.ts.out new file mode 100644 index 000000000..4ae20055a --- /dev/null +++ b/tests/testdata/error_cause_recursive_aggregate.ts.out @@ -0,0 +1,14 @@ +error: Uncaught (in promise) AggregateError + Error: bar + at file:///[WILDCARD]/error_cause_recursive_aggregate.ts:2:13 + Caused by: Error: foo + at file:///[WILDCARD]/error_cause_recursive_aggregate.ts:1:13 + Caused by: [Circular *1] + Error: quux + at file:///[WILDCARD]/error_cause_recursive_aggregate.ts:6:14 + Caused by: Error: qux + at file:///[WILDCARD]/error_cause_recursive_aggregate.ts:5:13 + Caused by: [Circular *2] +throw new AggregateError([bar, quux]); + ^ + at file:///[WILDCARD]/error_cause_recursive_aggregate.ts:9:7 diff --git a/tests/testdata/error_cause_recursive_tail.ts b/tests/testdata/error_cause_recursive_tail.ts new file mode 100644 index 000000000..51e7fa6d9 --- /dev/null +++ b/tests/testdata/error_cause_recursive_tail.ts @@ -0,0 +1,5 @@ +const foo = new Error("foo"); +const bar = new Error("bar", { cause: foo }); +const baz = new Error("baz", { cause: bar }); +foo.cause = bar; +throw baz; diff --git a/tests/testdata/error_cause_recursive_tail.ts.out b/tests/testdata/error_cause_recursive_tail.ts.out new file mode 100644 index 000000000..04b15e91a --- /dev/null +++ b/tests/testdata/error_cause_recursive_tail.ts.out @@ -0,0 +1,9 @@ +error: Uncaught (in promise) Error: baz +const baz = new Error("baz", { cause: bar }); + ^ + at file:///[WILDCARD]/error_cause_recursive_tail.ts:3:13 +Caused by: Error: bar + at file:///[WILDCARD]/error_cause_recursive_tail.ts:2:13 +Caused by: Error: foo + at file:///[WILDCARD]/error_cause_recursive_tail.ts:1:13 +Caused by: [Circular *1] diff --git a/tests/testdata/eval/check_local_by_default.out b/tests/testdata/eval/check_local_by_default.out new file mode 100644 index 000000000..52d98849f --- /dev/null +++ b/tests/testdata/eval/check_local_by_default.out @@ -0,0 +1 @@ +[Module: null prototype] { a: 12 } diff --git a/tests/testdata/eval/check_local_by_default2.out b/tests/testdata/eval/check_local_by_default2.out new file mode 100644 index 000000000..26a1fe6f8 --- /dev/null +++ b/tests/testdata/eval/check_local_by_default2.out @@ -0,0 +1,3 @@ +12 +12 +[Module: null prototype] { } diff --git a/tests/testdata/eval/check_local_by_default2.ts b/tests/testdata/eval/check_local_by_default2.ts new file mode 100644 index 000000000..5177ff944 --- /dev/null +++ b/tests/testdata/eval/check_local_by_default2.ts @@ -0,0 +1,6 @@ +import * as a from "http://localhost:4545/subdir/type_error.ts"; + +const b: "b" = 12; + +console.log(a.a); +console.log(b); diff --git a/tests/testdata/eval/dyn_import_eval.out b/tests/testdata/eval/dyn_import_eval.out new file mode 100644 index 000000000..89e16b478 --- /dev/null +++ b/tests/testdata/eval/dyn_import_eval.out @@ -0,0 +1 @@ +[Module: null prototype] { isMod4: true } diff --git a/tests/testdata/eval/env_file_missing.out b/tests/testdata/eval/env_file_missing.out new file mode 100644 index 000000000..221acab93 --- /dev/null +++ b/tests/testdata/eval/env_file_missing.out @@ -0,0 +1,2 @@ +Warning The `--env` flag was used, but the dotenv file 'missing' was not found. +undefined diff --git a/tests/testdata/file_extensions/js_without_extension b/tests/testdata/file_extensions/js_without_extension new file mode 100644 index 000000000..4774be326 --- /dev/null +++ b/tests/testdata/file_extensions/js_without_extension @@ -0,0 +1,3 @@ +let i = 123; +i = "hello" +console.log("executing javascript with no extension"); diff --git a/tests/testdata/file_extensions/js_without_extension.out b/tests/testdata/file_extensions/js_without_extension.out new file mode 100644 index 000000000..1236c1e53 --- /dev/null +++ b/tests/testdata/file_extensions/js_without_extension.out @@ -0,0 +1 @@ +executing javascript with no extension diff --git a/tests/testdata/file_extensions/ts_with_extension.out b/tests/testdata/file_extensions/ts_with_extension.out new file mode 100644 index 000000000..181959ee2 --- /dev/null +++ b/tests/testdata/file_extensions/ts_with_extension.out @@ -0,0 +1 @@ +executing typescript with extension diff --git a/tests/testdata/file_extensions/ts_with_extension.ts b/tests/testdata/file_extensions/ts_with_extension.ts new file mode 100644 index 000000000..3c49f7484 --- /dev/null +++ b/tests/testdata/file_extensions/ts_with_extension.ts @@ -0,0 +1,5 @@ +interface Lollipop { + _: number; +} + +console.log("executing typescript with extension"); diff --git a/tests/testdata/file_extensions/ts_with_js_extension.js b/tests/testdata/file_extensions/ts_with_js_extension.js new file mode 100644 index 000000000..3c49f7484 --- /dev/null +++ b/tests/testdata/file_extensions/ts_with_js_extension.js @@ -0,0 +1,5 @@ +interface Lollipop { + _: number; +} + +console.log("executing typescript with extension"); diff --git a/tests/testdata/file_extensions/ts_with_js_extension.out b/tests/testdata/file_extensions/ts_with_js_extension.out new file mode 100644 index 000000000..1c3739bb9 --- /dev/null +++ b/tests/testdata/file_extensions/ts_with_js_extension.out @@ -0,0 +1,2 @@ +Check [WILDCARD]/file_extensions/ts_with_js_extension.js +executing typescript with extension diff --git a/tests/testdata/file_extensions/ts_without_extension b/tests/testdata/file_extensions/ts_without_extension new file mode 100644 index 000000000..f10891d7a --- /dev/null +++ b/tests/testdata/file_extensions/ts_without_extension @@ -0,0 +1,3 @@ +interface Lollipop {} + +console.log("executing typescript with no extension"); diff --git a/tests/testdata/file_extensions/ts_without_extension.out b/tests/testdata/file_extensions/ts_without_extension.out new file mode 100644 index 000000000..e1f019f9e --- /dev/null +++ b/tests/testdata/file_extensions/ts_without_extension.out @@ -0,0 +1,2 @@ +Check [WILDCARD]/file_extensions/ts_without_extension +executing typescript with no extension diff --git a/tests/testdata/fmt/badly_formatted.ipynb b/tests/testdata/fmt/badly_formatted.ipynb new file mode 100644 index 000000000..c8600564f --- /dev/null +++ b/tests/testdata/fmt/badly_formatted.ipynb @@ -0,0 +1,105 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Hello Markdown\n", + "this isn't formatted properly" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello World\n" + ] + } + ], + "source": [ + "console.log(\"Hello World\"\n", + "\n", + ");" + ] + }, + { + "cell_type": "raw", + "metadata": {}, + "source": [ + "raw text\n", + " here too\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "alice\n" + ] + } + ], + "source": [ + "function hello(name: string ) {\n", + " console.log(name);\n", + "};\n", + "\n", + "hello( \"alice\");\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "function foo(): number {\n", + " return 2;\n", + "}\n" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong\n" + ] + } + ], + "source": [ + "console.log(\"loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong\");" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Deno", + "language": "typescript", + "name": "deno" + }, + "language_info": { + "file_extension": ".ts", + "mimetype": "text/x.typescript", + "name": "typescript", + "nb_converter": "script", + "pygments_lexer": "typescript", + "version": "5.2.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/tests/testdata/fmt/badly_formatted.json b/tests/testdata/fmt/badly_formatted.json new file mode 100644 index 000000000..f2bacf73d --- /dev/null +++ b/tests/testdata/fmt/badly_formatted.json @@ -0,0 +1,12 @@ +{ + + + "key1": "value1", + "key2": true, + "key3": ["value2", "value3", false], + "keys": { + "more": "values" + } + + +} \ No newline at end of file diff --git a/tests/testdata/fmt/badly_formatted.md b/tests/testdata/fmt/badly_formatted.md new file mode 100644 index 000000000..26afe483b --- /dev/null +++ b/tests/testdata/fmt/badly_formatted.md @@ -0,0 +1,46 @@ +# Hello Markdown + +```js +console.log("Hello World" + +) +``` + +```javascript +console.log("Hello World2" + +) +``` + +```ts + +function hello(name: string ) { + console.log(name); +}; + +hello( "alice"); +``` + +```typescript +function foo(): number { + return 2; +} +``` + +```jsonc + +{ + // Comment in JSON + "key": "value", + "key2": + "value2", +} + +``` + +```json +{ + "numbers": + ["1", "2"] +} +``` \ No newline at end of file diff --git a/tests/testdata/fmt/badly_formatted.mjs b/tests/testdata/fmt/badly_formatted.mjs new file mode 100644 index 000000000..bc515a330 --- /dev/null +++ b/tests/testdata/fmt/badly_formatted.mjs @@ -0,0 +1,4 @@ +// Deliberately using .mjs to avoid triggering dprint +console.log("Hello World" + +) diff --git a/tests/testdata/fmt/badly_formatted_fixed.ipynb b/tests/testdata/fmt/badly_formatted_fixed.ipynb new file mode 100644 index 000000000..a26a95e24 --- /dev/null +++ b/tests/testdata/fmt/badly_formatted_fixed.ipynb @@ -0,0 +1,106 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Hello Markdown\n", + "\n", + "this isn't formatted properly" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello World\n" + ] + } + ], + "source": [ + "console.log(\"Hello World\");" + ] + }, + { + "cell_type": "raw", + "metadata": {}, + "source": [ + "raw text\n", + " here too\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "alice\n" + ] + } + ], + "source": [ + "function hello(name: string) {\n", + " console.log(name);\n", + "}\n", + "\n", + "hello(\"alice\");" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "function foo(): number {\n", + " return 2;\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong\n" + ] + } + ], + "source": [ + "console.log(\n", + " \"loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong\",\n", + ");" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Deno", + "language": "typescript", + "name": "deno" + }, + "language_info": { + "file_extension": ".ts", + "mimetype": "text/x.typescript", + "name": "typescript", + "nb_converter": "script", + "pygments_lexer": "typescript", + "version": "5.2.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/tests/testdata/fmt/badly_formatted_fixed.js b/tests/testdata/fmt/badly_formatted_fixed.js new file mode 100644 index 000000000..e9062ba85 --- /dev/null +++ b/tests/testdata/fmt/badly_formatted_fixed.js @@ -0,0 +1,2 @@ +// Deliberately using .mjs to avoid triggering dprint +console.log("Hello World"); diff --git a/tests/testdata/fmt/badly_formatted_fixed.json b/tests/testdata/fmt/badly_formatted_fixed.json new file mode 100644 index 000000000..0d697a2c6 --- /dev/null +++ b/tests/testdata/fmt/badly_formatted_fixed.json @@ -0,0 +1,8 @@ +{ + "key1": "value1", + "key2": true, + "key3": ["value2", "value3", false], + "keys": { + "more": "values" + } +} diff --git a/tests/testdata/fmt/badly_formatted_fixed.md b/tests/testdata/fmt/badly_formatted_fixed.md new file mode 100644 index 000000000..8ba74cac3 --- /dev/null +++ b/tests/testdata/fmt/badly_formatted_fixed.md @@ -0,0 +1,37 @@ +# Hello Markdown + +```js +console.log("Hello World"); +``` + +```javascript +console.log("Hello World2"); +``` + +```ts +function hello(name: string) { + console.log(name); +} + +hello("alice"); +``` + +```typescript +function foo(): number { + return 2; +} +``` + +```jsonc +{ + // Comment in JSON + "key": "value", + "key2": "value2" +} +``` + +```json +{ + "numbers": ["1", "2"] +} +``` diff --git a/tests/testdata/fmt/deno.glob.json b/tests/testdata/fmt/deno.glob.json new file mode 100644 index 000000000..ff74e9d2b --- /dev/null +++ b/tests/testdata/fmt/deno.glob.json @@ -0,0 +1,11 @@ +{ + "fmt": { + "include": [ + "glob/data/test1.?s", + "glob/nested/foo/*.ts", + "glob/nested/fizz/*.ts", + "glob/pages/[id].ts" + ], + "exclude": ["glob/nested/**/*bazz.ts"] + } +} diff --git a/tests/testdata/fmt/deno.malformed.jsonc b/tests/testdata/fmt/deno.malformed.jsonc new file mode 100644 index 000000000..e326edb1f --- /dev/null +++ b/tests/testdata/fmt/deno.malformed.jsonc @@ -0,0 +1,10 @@ +{ + "fmt": { + "include": ["fmt_with_config/"], + "exclude": ["fmt_with_config/b.ts"], + "dont_know_this_field": {}, + "options": { + "useTabs": true + } + } +} diff --git a/tests/testdata/fmt/deno.malformed2.jsonc b/tests/testdata/fmt/deno.malformed2.jsonc new file mode 100644 index 000000000..e326edb1f --- /dev/null +++ b/tests/testdata/fmt/deno.malformed2.jsonc @@ -0,0 +1,10 @@ +{ + "fmt": { + "include": ["fmt_with_config/"], + "exclude": ["fmt_with_config/b.ts"], + "dont_know_this_field": {}, + "options": { + "useTabs": true + } + } +} diff --git a/tests/testdata/fmt/expected_fmt_check_formatted_files.out b/tests/testdata/fmt/expected_fmt_check_formatted_files.out new file mode 100644 index 000000000..5a4833dd4 --- /dev/null +++ b/tests/testdata/fmt/expected_fmt_check_formatted_files.out @@ -0,0 +1 @@ +Checked 4 files diff --git a/tests/testdata/fmt/expected_fmt_check_ignore.out b/tests/testdata/fmt/expected_fmt_check_ignore.out new file mode 100644 index 000000000..7c1e471b9 --- /dev/null +++ b/tests/testdata/fmt/expected_fmt_check_ignore.out @@ -0,0 +1 @@ +Checked 3 files diff --git a/tests/testdata/fmt/expected_fmt_check_verbose_formatted_files.out b/tests/testdata/fmt/expected_fmt_check_verbose_formatted_files.out new file mode 100644 index 000000000..158c556c2 --- /dev/null +++ b/tests/testdata/fmt/expected_fmt_check_verbose_formatted_files.out @@ -0,0 +1 @@ +Checked 2 files diff --git a/tests/testdata/fmt/fmt_check_parse_error.out b/tests/testdata/fmt/fmt_check_parse_error.out new file mode 100644 index 000000000..9854b6c97 --- /dev/null +++ b/tests/testdata/fmt/fmt_check_parse_error.out @@ -0,0 +1,6 @@ +Error checking: [WILDCARD]parse_error.ts + Expected '{', got '' at [WILDCARD]parse_error.ts:2:7 + + class Test + ~~~~ +error: Found 1 not formatted file in 1 file diff --git a/tests/testdata/fmt/fmt_with_config.out b/tests/testdata/fmt/fmt_with_config.out new file mode 100644 index 000000000..158c556c2 --- /dev/null +++ b/tests/testdata/fmt/fmt_with_config.out @@ -0,0 +1 @@ +Checked 2 files diff --git a/tests/testdata/fmt/fmt_with_config_and_flags.out b/tests/testdata/fmt/fmt_with_config_and_flags.out new file mode 100644 index 000000000..c05ac45a1 --- /dev/null +++ b/tests/testdata/fmt/fmt_with_config_and_flags.out @@ -0,0 +1 @@ +Checked 1 file diff --git a/tests/testdata/fmt/fmt_with_config_default.out b/tests/testdata/fmt/fmt_with_config_default.out new file mode 100644 index 000000000..faad9352b --- /dev/null +++ b/tests/testdata/fmt/fmt_with_config_default.out @@ -0,0 +1,2 @@ +Config file found at '[WILDCARD]deno.jsonc' +Checked 2 files diff --git a/tests/testdata/fmt/fmt_with_deprecated_config.out b/tests/testdata/fmt/fmt_with_deprecated_config.out new file mode 100644 index 000000000..793fac1bc --- /dev/null +++ b/tests/testdata/fmt/fmt_with_deprecated_config.out @@ -0,0 +1,3 @@ +Warning: "options" configuration is deprecated. Please use "flat" options instead. +Warning: "files" configuration is deprecated. Please use "include" and "exclude" instead. +Checked 2 files diff --git a/tests/testdata/fmt/fmt_with_malformed_config.out b/tests/testdata/fmt/fmt_with_malformed_config.out new file mode 100644 index 000000000..c269053a6 --- /dev/null +++ b/tests/testdata/fmt/fmt_with_malformed_config.out @@ -0,0 +1,4 @@ +error: Failed to parse "fmt" configuration + +Caused by: + unknown field `dont_know_this_field`, expected one of `useTabs`, `lineWidth`, `indentWidth`, `singleQuote`, `proseWrap`, `semiColons`, `options`, `include`, `exclude`, `files` diff --git a/tests/testdata/fmt/fmt_with_malformed_config2.out b/tests/testdata/fmt/fmt_with_malformed_config2.out new file mode 100644 index 000000000..c269053a6 --- /dev/null +++ b/tests/testdata/fmt/fmt_with_malformed_config2.out @@ -0,0 +1,4 @@ +error: Failed to parse "fmt" configuration + +Caused by: + unknown field `dont_know_this_field`, expected one of `useTabs`, `lineWidth`, `indentWidth`, `singleQuote`, `proseWrap`, `semiColons`, `options`, `include`, `exclude`, `files` diff --git a/tests/testdata/fmt/glob/data/tes.ts b/tests/testdata/fmt/glob/data/tes.ts new file mode 100644 index 000000000..0127c4af3 --- /dev/null +++ b/tests/testdata/fmt/glob/data/tes.ts @@ -0,0 +1,3 @@ + function foo() { + +} \ No newline at end of file diff --git a/tests/testdata/fmt/glob/data/test1.js b/tests/testdata/fmt/glob/data/test1.js new file mode 100644 index 000000000..e939e4595 --- /dev/null +++ b/tests/testdata/fmt/glob/data/test1.js @@ -0,0 +1,2 @@ + function foo() { +} diff --git a/tests/testdata/fmt/glob/data/test1.ts b/tests/testdata/fmt/glob/data/test1.ts new file mode 100644 index 000000000..e939e4595 --- /dev/null +++ b/tests/testdata/fmt/glob/data/test1.ts @@ -0,0 +1,2 @@ + function foo() { +} diff --git a/tests/testdata/fmt/glob/data/test12.ts b/tests/testdata/fmt/glob/data/test12.ts new file mode 100644 index 000000000..0127c4af3 --- /dev/null +++ b/tests/testdata/fmt/glob/data/test12.ts @@ -0,0 +1,3 @@ + function foo() { + +} \ No newline at end of file diff --git a/tests/testdata/fmt/glob/nested/fizz/bar.ts b/tests/testdata/fmt/glob/nested/fizz/bar.ts new file mode 100644 index 000000000..e939e4595 --- /dev/null +++ b/tests/testdata/fmt/glob/nested/fizz/bar.ts @@ -0,0 +1,2 @@ + function foo() { +} diff --git a/tests/testdata/fmt/glob/nested/fizz/bazz.ts b/tests/testdata/fmt/glob/nested/fizz/bazz.ts new file mode 100644 index 000000000..0127c4af3 --- /dev/null +++ b/tests/testdata/fmt/glob/nested/fizz/bazz.ts @@ -0,0 +1,3 @@ + function foo() { + +} \ No newline at end of file diff --git a/tests/testdata/fmt/glob/nested/fizz/fizz.ts b/tests/testdata/fmt/glob/nested/fizz/fizz.ts new file mode 100644 index 000000000..e939e4595 --- /dev/null +++ b/tests/testdata/fmt/glob/nested/fizz/fizz.ts @@ -0,0 +1,2 @@ + function foo() { +} diff --git a/tests/testdata/fmt/glob/nested/fizz/foo.ts b/tests/testdata/fmt/glob/nested/fizz/foo.ts new file mode 100644 index 000000000..e939e4595 --- /dev/null +++ b/tests/testdata/fmt/glob/nested/fizz/foo.ts @@ -0,0 +1,2 @@ + function foo() { +} diff --git a/tests/testdata/fmt/glob/nested/foo/bar.ts b/tests/testdata/fmt/glob/nested/foo/bar.ts new file mode 100644 index 000000000..e939e4595 --- /dev/null +++ b/tests/testdata/fmt/glob/nested/foo/bar.ts @@ -0,0 +1,2 @@ + function foo() { +} diff --git a/tests/testdata/fmt/glob/nested/foo/bazz.ts b/tests/testdata/fmt/glob/nested/foo/bazz.ts new file mode 100644 index 000000000..0127c4af3 --- /dev/null +++ b/tests/testdata/fmt/glob/nested/foo/bazz.ts @@ -0,0 +1,3 @@ + function foo() { + +} \ No newline at end of file diff --git a/tests/testdata/fmt/glob/nested/foo/fizz.ts b/tests/testdata/fmt/glob/nested/foo/fizz.ts new file mode 100644 index 000000000..e939e4595 --- /dev/null +++ b/tests/testdata/fmt/glob/nested/foo/fizz.ts @@ -0,0 +1,2 @@ + function foo() { +} diff --git a/tests/testdata/fmt/glob/nested/foo/foo.ts b/tests/testdata/fmt/glob/nested/foo/foo.ts new file mode 100644 index 000000000..e939e4595 --- /dev/null +++ b/tests/testdata/fmt/glob/nested/foo/foo.ts @@ -0,0 +1,2 @@ + function foo() { +} diff --git a/tests/testdata/fmt/glob/pages/[id].ts b/tests/testdata/fmt/glob/pages/[id].ts new file mode 100644 index 000000000..e939e4595 --- /dev/null +++ b/tests/testdata/fmt/glob/pages/[id].ts @@ -0,0 +1,2 @@ + function foo() { +} diff --git a/tests/testdata/fmt/invalid_data.json b/tests/testdata/fmt/invalid_data.json new file mode 100644 index 000000000..fb9bec94f Binary files /dev/null and b/tests/testdata/fmt/invalid_data.json differ diff --git a/tests/testdata/fmt/invalid_data.out b/tests/testdata/fmt/invalid_data.out new file mode 100644 index 000000000..dee00fcc5 --- /dev/null +++ b/tests/testdata/fmt/invalid_data.out @@ -0,0 +1,4 @@ +error: [WILDCARD] is not a valid UTF-8 file + +Caused by: + invalid data diff --git a/tests/testdata/fmt/parse_error/parse_error.ts b/tests/testdata/fmt/parse_error/parse_error.ts new file mode 100644 index 000000000..136d16508 --- /dev/null +++ b/tests/testdata/fmt/parse_error/parse_error.ts @@ -0,0 +1,2 @@ +// a file that purposefully will cause an error +class Test diff --git a/tests/testdata/fmt/regular/formatted1.js b/tests/testdata/fmt/regular/formatted1.js new file mode 100644 index 000000000..587aa5b96 --- /dev/null +++ b/tests/testdata/fmt/regular/formatted1.js @@ -0,0 +1,5 @@ +function foo() { + return 42; +} + +foo(); diff --git a/tests/testdata/fmt/regular/formatted2.ts b/tests/testdata/fmt/regular/formatted2.ts new file mode 100644 index 000000000..4a8036806 --- /dev/null +++ b/tests/testdata/fmt/regular/formatted2.ts @@ -0,0 +1,5 @@ +function bar(): number { + return 42; +} + +bar(); diff --git a/tests/testdata/fmt/regular/formatted3.markdown b/tests/testdata/fmt/regular/formatted3.markdown new file mode 100644 index 000000000..e6e616584 --- /dev/null +++ b/tests/testdata/fmt/regular/formatted3.markdown @@ -0,0 +1,17 @@ +# Hello + +```js +function foo() { + return 42; +} + +foo(); +``` + +```ts +function bar(): number { + return 42; +} + +bar(); +``` diff --git a/tests/testdata/fmt/regular/formatted4.jsonc b/tests/testdata/fmt/regular/formatted4.jsonc new file mode 100644 index 000000000..f0f72a6ed --- /dev/null +++ b/tests/testdata/fmt/regular/formatted4.jsonc @@ -0,0 +1,4 @@ +{ + // Comment + "key": "value" +} diff --git a/tests/testdata/fmt/with_config/deno.deprecated.jsonc b/tests/testdata/fmt/with_config/deno.deprecated.jsonc new file mode 100644 index 000000000..e053233fd --- /dev/null +++ b/tests/testdata/fmt/with_config/deno.deprecated.jsonc @@ -0,0 +1,20 @@ +{ + "fmt": { + "files": { + "include": [ + "./subdir/" + ], + "exclude": [ + "./subdir/b.ts" + ] + }, + "options": { + "useTabs": true, + "lineWidth": 40, + "indentWidth": 8, + "singleQuote": true, + "proseWrap": "always", + "semiColons": false + } + } +} diff --git a/tests/testdata/fmt/with_config/deno.jsonc b/tests/testdata/fmt/with_config/deno.jsonc new file mode 100644 index 000000000..ffd265dcd --- /dev/null +++ b/tests/testdata/fmt/with_config/deno.jsonc @@ -0,0 +1,16 @@ +{ + "fmt": { + "include": [ + "./subdir/" + ], + "exclude": [ + "./subdir/b.ts" + ], + "useTabs": true, + "lineWidth": 40, + "indentWidth": 8, + "singleQuote": true, + "proseWrap": "always", + "semiColons": false + } +} diff --git a/tests/testdata/fmt/with_config/subdir/a.ts b/tests/testdata/fmt/with_config/subdir/a.ts new file mode 100644 index 000000000..5474b3aa3 --- /dev/null +++ b/tests/testdata/fmt/with_config/subdir/a.ts @@ -0,0 +1,46 @@ +Deno.test( + { perms: { net: true } }, + async function responseClone() { + const response = + await fetch( + 'http://localhost:4545/assets/fixture.json', + ) + const response1 = + response.clone() + assert( + response !== + response1, + ) + assertEquals( + response.status, + response1 + .status, + ) + assertEquals( + response.statusText, + response1 + .statusText, + ) + const u8a = + new Uint8Array( + await response + .arrayBuffer(), + ) + const u8a1 = + new Uint8Array( + await response1 + .arrayBuffer(), + ) + for ( + let i = 0; + i < + u8a.byteLength; + i++ + ) { + assertEquals( + u8a[i], + u8a1[i], + ) + } + }, +) diff --git a/tests/testdata/fmt/with_config/subdir/b.ts b/tests/testdata/fmt/with_config/subdir/b.ts new file mode 100644 index 000000000..d7eb08b09 --- /dev/null +++ b/tests/testdata/fmt/with_config/subdir/b.ts @@ -0,0 +1,15 @@ +// This file should be excluded from formatting +Deno.test( + { perms: { net: true } }, + async function fetchBodyUsedCancelStream() { + const response = await fetch( + "http://localhost:4545/assets/fixture.json", + ); + assert(response.body !== null); + + assertEquals(response.bodyUsed, false); + const promise = response.body.cancel(); + assertEquals(response.bodyUsed, true); + await promise; + }, +); \ No newline at end of file diff --git a/tests/testdata/fmt/with_config/subdir/c.md b/tests/testdata/fmt/with_config/subdir/c.md new file mode 100644 index 000000000..012f7e3d4 --- /dev/null +++ b/tests/testdata/fmt/with_config/subdir/c.md @@ -0,0 +1,17 @@ +## Permissions + +Deno is secure by default. Therefore, +unless you specifically enable it, a +program run with Deno has no file, +network, or environment access. Access +to security sensitive functionality +requires that permisisons have been +granted to an executing script through +command line flags, or a runtime +permission prompt. + +For the following example `mod.ts` has +been granted read-only access to the +file system. It cannot write to the file +system, or perform any other security +sensitive functions. diff --git a/tests/testdata/import_attributes/data.json b/tests/testdata/import_attributes/data.json new file mode 100644 index 000000000..37b3ee1e0 --- /dev/null +++ b/tests/testdata/import_attributes/data.json @@ -0,0 +1,6 @@ +{ + "a": "b", + "c": { + "d": 10 + } +} diff --git a/tests/testdata/import_attributes/dynamic_error.out b/tests/testdata/import_attributes/dynamic_error.out new file mode 100644 index 000000000..24f29de72 --- /dev/null +++ b/tests/testdata/import_attributes/dynamic_error.out @@ -0,0 +1,4 @@ +error: Uncaught (in promise) TypeError: Attempted to load JSON module without specifying "type": "json" attribute in the import statement. +const data = await import("./data.json"); + ^ + at async [WILDCARD]dynamic_error.ts:1:14 diff --git a/tests/testdata/import_attributes/dynamic_error.ts b/tests/testdata/import_attributes/dynamic_error.ts new file mode 100644 index 000000000..2d9c6757f --- /dev/null +++ b/tests/testdata/import_attributes/dynamic_error.ts @@ -0,0 +1,3 @@ +const data = await import("./data.json"); + +console.log(data); diff --git a/tests/testdata/import_attributes/dynamic_import.out b/tests/testdata/import_attributes/dynamic_import.out new file mode 100644 index 000000000..01bc76c8a --- /dev/null +++ b/tests/testdata/import_attributes/dynamic_import.out @@ -0,0 +1,3 @@ +[WILDCARD] +[Module: null prototype] { default: { a: "b", c: { d: 10 } } } +[Module: null prototype] { default: { a: "b", c: { d: 10 } } } diff --git a/tests/testdata/import_attributes/dynamic_import.ts b/tests/testdata/import_attributes/dynamic_import.ts new file mode 100644 index 000000000..73f348697 --- /dev/null +++ b/tests/testdata/import_attributes/dynamic_import.ts @@ -0,0 +1,5 @@ +const data1 = await import("./data.json", { with: { type: "json" } }); +const data2 = await import("./data.json", { assert: { type: "json" } }); + +console.log(data1); +console.log(data2); diff --git a/tests/testdata/import_attributes/json_with_shebang.json b/tests/testdata/import_attributes/json_with_shebang.json new file mode 100644 index 000000000..b695e4457 --- /dev/null +++ b/tests/testdata/import_attributes/json_with_shebang.json @@ -0,0 +1,4 @@ +#!/usr/env -S deno run +{ + "test": null +} diff --git a/tests/testdata/import_attributes/json_with_shebang.ts b/tests/testdata/import_attributes/json_with_shebang.ts new file mode 100644 index 000000000..523bf8772 --- /dev/null +++ b/tests/testdata/import_attributes/json_with_shebang.ts @@ -0,0 +1,3 @@ +import json from "./json_with_shebang.json" assert { type: "json" }; + +console.log(json); diff --git a/tests/testdata/import_attributes/json_with_shebang.ts.out b/tests/testdata/import_attributes/json_with_shebang.ts.out new file mode 100644 index 000000000..23eb03720 --- /dev/null +++ b/tests/testdata/import_attributes/json_with_shebang.ts.out @@ -0,0 +1 @@ +error: Uncaught SyntaxError: Unexpected token '#', "#!/usr/env"... is not valid JSON diff --git a/tests/testdata/import_attributes/static_error.out b/tests/testdata/import_attributes/static_error.out new file mode 100644 index 000000000..29b24b965 --- /dev/null +++ b/tests/testdata/import_attributes/static_error.out @@ -0,0 +1,3 @@ +error: Expected a JavaScript or TypeScript module, but identified a Json module. Consider importing Json modules with an import attribute with the type of "json". + Specifier: [WILDCARD]/data.json + at [WILDCARD]static_error.ts:1:18 diff --git a/tests/testdata/import_attributes/static_error.ts b/tests/testdata/import_attributes/static_error.ts new file mode 100644 index 000000000..0bc3a93f8 --- /dev/null +++ b/tests/testdata/import_attributes/static_error.ts @@ -0,0 +1,3 @@ +import data from "./data.json"; + +console.log(data); diff --git a/tests/testdata/import_attributes/static_export.out b/tests/testdata/import_attributes/static_export.out new file mode 100644 index 000000000..41af79d7c --- /dev/null +++ b/tests/testdata/import_attributes/static_export.out @@ -0,0 +1 @@ +{ a: "b", c: { d: 10 } } diff --git a/tests/testdata/import_attributes/static_export.ts b/tests/testdata/import_attributes/static_export.ts new file mode 100644 index 000000000..ac3ee694f --- /dev/null +++ b/tests/testdata/import_attributes/static_export.ts @@ -0,0 +1,3 @@ +import data from "./static_reexport.ts"; + +console.log(data); diff --git a/tests/testdata/import_attributes/static_import.out b/tests/testdata/import_attributes/static_import.out new file mode 100644 index 000000000..e57dffa99 --- /dev/null +++ b/tests/testdata/import_attributes/static_import.out @@ -0,0 +1,2 @@ +{ a: "b", c: { d: 10 } } +{ a: "b", c: { d: 10 } } diff --git a/tests/testdata/import_attributes/static_import.ts b/tests/testdata/import_attributes/static_import.ts new file mode 100644 index 000000000..d46d93b4a --- /dev/null +++ b/tests/testdata/import_attributes/static_import.ts @@ -0,0 +1,5 @@ +import data1 from "./data.json" with { type: "json" }; +import data2 from "./data.json" assert { type: "json" }; + +console.log(data1); +console.log(data2); diff --git a/tests/testdata/import_attributes/static_reexport.ts b/tests/testdata/import_attributes/static_reexport.ts new file mode 100644 index 000000000..81af428be --- /dev/null +++ b/tests/testdata/import_attributes/static_reexport.ts @@ -0,0 +1 @@ +export { default } from "./data.json" assert { type: "json" }; diff --git a/tests/testdata/import_attributes/type_check.out b/tests/testdata/import_attributes/type_check.out new file mode 100644 index 000000000..5ecdec82d --- /dev/null +++ b/tests/testdata/import_attributes/type_check.out @@ -0,0 +1,12 @@ +Check file:///[WILDCARD]/type_check.ts +error: TS2339 [ERROR]: Property 'foo' does not exist on type '{ a: string; c: { d: number; }; }'. +console.log(data1.foo); + ~~~ + at [WILDCARD]type_check.ts:4:19 + +TS2339 [ERROR]: Property 'foo' does not exist on type '{ a: string; c: { d: number; }; }'. +console.log(data2.foo); + ~~~ + at [WILDCARD]type_check.ts:5:19 + +Found 2 errors. diff --git a/tests/testdata/import_attributes/type_check.ts b/tests/testdata/import_attributes/type_check.ts new file mode 100644 index 000000000..ddf28e67a --- /dev/null +++ b/tests/testdata/import_attributes/type_check.ts @@ -0,0 +1,5 @@ +import data1 from "./data.json" with { type: "json" }; +import data2 from "./data.json" assert { type: "json" }; + +console.log(data1.foo); +console.log(data2.foo); diff --git a/tests/testdata/import_maps/config.json b/tests/testdata/import_maps/config.json new file mode 100644 index 000000000..b296a63c7 --- /dev/null +++ b/tests/testdata/import_maps/config.json @@ -0,0 +1,15 @@ +{ + "importMap": "./import_map.json", + "imports": { + "moment": "./moment/moment.ts", + "moment/": "./moment/", + "lodash": "./lodash/lodash.ts", + "lodash/": "./lodash/", + "https://www.unpkg.com/vue/dist/vue.runtime.esm.js": "./vue.ts" + }, + "scopes": { + "scope/": { + "moment": "./scoped_moment.ts" + } + } +} diff --git a/tests/testdata/import_maps/import_map.json b/tests/testdata/import_maps/import_map.json new file mode 100644 index 000000000..40d1d4ec2 --- /dev/null +++ b/tests/testdata/import_maps/import_map.json @@ -0,0 +1,15 @@ +{ + "imports": { + "print_hello": "./print_hello.ts", + "moment": "./moment/moment.ts", + "moment/": "./moment/", + "lodash": "./lodash/lodash.ts", + "lodash/": "./lodash/", + "https://www.unpkg.com/vue/dist/vue.runtime.esm.js": "./vue.ts" + }, + "scopes": { + "scope/": { + "moment": "./scoped_moment.ts" + } + } +} diff --git a/tests/testdata/import_maps/import_map_invalid.json b/tests/testdata/import_maps/import_map_invalid.json new file mode 100644 index 000000000..a09d280c5 --- /dev/null +++ b/tests/testdata/import_maps/import_map_invalid.json @@ -0,0 +1,7 @@ +{ + "imports": { + "https://www.unpkg.com/vue/dist/vue.runtime.esm.js": "./vue.ts" + }, + "scopes": { + } +} diff --git a/tests/testdata/import_maps/import_map_remote.json b/tests/testdata/import_maps/import_map_remote.json new file mode 100644 index 000000000..51f90f69c --- /dev/null +++ b/tests/testdata/import_maps/import_map_remote.json @@ -0,0 +1,9 @@ +{ + "imports": { + "moment": "./moment/moment.ts", + "moment/": "./moment/", + "lodash": "./lodash/lodash.ts", + "lodash/": "./lodash/", + "https://www.unpkg.com/vue/dist/vue.runtime.esm.js": "./vue.ts" + } +} diff --git a/tests/testdata/import_maps/lodash/lodash.ts b/tests/testdata/import_maps/lodash/lodash.ts new file mode 100644 index 000000000..2ec04ed3c --- /dev/null +++ b/tests/testdata/import_maps/lodash/lodash.ts @@ -0,0 +1 @@ +console.log("Hello from remapped lodash!"); diff --git a/tests/testdata/import_maps/lodash/other_file.ts b/tests/testdata/import_maps/lodash/other_file.ts new file mode 100644 index 000000000..714adae3f --- /dev/null +++ b/tests/testdata/import_maps/lodash/other_file.ts @@ -0,0 +1 @@ +console.log("Hello from remapped lodash dir!"); diff --git a/tests/testdata/import_maps/moment/moment.ts b/tests/testdata/import_maps/moment/moment.ts new file mode 100644 index 000000000..2b54a431e --- /dev/null +++ b/tests/testdata/import_maps/moment/moment.ts @@ -0,0 +1 @@ +console.log("Hello from remapped moment!"); diff --git a/tests/testdata/import_maps/moment/other_file.ts b/tests/testdata/import_maps/moment/other_file.ts new file mode 100644 index 000000000..24f3a0226 --- /dev/null +++ b/tests/testdata/import_maps/moment/other_file.ts @@ -0,0 +1 @@ +console.log("Hello from remapped moment dir!"); diff --git a/tests/testdata/import_maps/print_hello.ts b/tests/testdata/import_maps/print_hello.ts new file mode 100644 index 000000000..794257390 --- /dev/null +++ b/tests/testdata/import_maps/print_hello.ts @@ -0,0 +1,3 @@ +export function printHello() { + console.log("Hello, world!"); +} diff --git a/tests/testdata/import_maps/scope/scoped.ts b/tests/testdata/import_maps/scope/scoped.ts new file mode 100644 index 000000000..9a0b5d8e3 --- /dev/null +++ b/tests/testdata/import_maps/scope/scoped.ts @@ -0,0 +1,2 @@ +import "moment"; +console.log("Hello from scoped!"); diff --git a/tests/testdata/import_maps/scoped_moment.ts b/tests/testdata/import_maps/scoped_moment.ts new file mode 100644 index 000000000..9f67f88d4 --- /dev/null +++ b/tests/testdata/import_maps/scoped_moment.ts @@ -0,0 +1 @@ +console.log("Hello from scoped moment!"); diff --git a/tests/testdata/import_maps/test.ts b/tests/testdata/import_maps/test.ts new file mode 100644 index 000000000..9b09e9953 --- /dev/null +++ b/tests/testdata/import_maps/test.ts @@ -0,0 +1,6 @@ +import "moment"; +import "moment/other_file.ts"; +import "lodash"; +import "lodash/other_file.ts"; +import "https://www.unpkg.com/vue/dist/vue.runtime.esm.js"; +import "./scope/scoped.ts"; diff --git a/tests/testdata/import_maps/test_remote.ts b/tests/testdata/import_maps/test_remote.ts new file mode 100644 index 000000000..206bdbd5f --- /dev/null +++ b/tests/testdata/import_maps/test_remote.ts @@ -0,0 +1,5 @@ +import "moment"; +import "moment/other_file.ts"; +import "lodash"; +import "lodash/other_file.ts"; +import "https://www.unpkg.com/vue/dist/vue.runtime.esm.js"; diff --git a/tests/testdata/import_maps/vue.ts b/tests/testdata/import_maps/vue.ts new file mode 100644 index 000000000..76dbe1917 --- /dev/null +++ b/tests/testdata/import_maps/vue.ts @@ -0,0 +1 @@ +console.log("Hello from remapped Vue!"); diff --git a/tests/testdata/info/031_info_ts_error.out b/tests/testdata/info/031_info_ts_error.out new file mode 100644 index 000000000..81edd0032 --- /dev/null +++ b/tests/testdata/info/031_info_ts_error.out @@ -0,0 +1,6 @@ +local: [WILDCARD]031_info_ts_error.ts +type: TypeScript +dependencies: 0 unique +size: [WILDCARD] + +[WILDCARD]031_info_ts_error.ts ([WILDCARD]) diff --git a/tests/testdata/info/031_info_ts_error.ts b/tests/testdata/info/031_info_ts_error.ts new file mode 100644 index 000000000..9b7492dbe --- /dev/null +++ b/tests/testdata/info/031_info_ts_error.ts @@ -0,0 +1 @@ +const _foo: string = 1; diff --git a/tests/testdata/info/041_info_flag.out b/tests/testdata/info/041_info_flag.out new file mode 100644 index 000000000..3506a29e4 --- /dev/null +++ b/tests/testdata/info/041_info_flag.out @@ -0,0 +1,6 @@ +DENO_DIR location: [WILDCARD] +Remote modules cache: [WILDCARD]deps +npm modules cache: [WILDCARD]npm +Emitted modules cache: [WILDCARD]gen +Language server registries cache: [WILDCARD]registries +Origin storage: [WILDCARD]location_data diff --git a/tests/testdata/info/041_info_flag_location.out b/tests/testdata/info/041_info_flag_location.out new file mode 100644 index 000000000..b9e72f659 --- /dev/null +++ b/tests/testdata/info/041_info_flag_location.out @@ -0,0 +1,7 @@ +DENO_DIR location: [WILDCARD] +Remote modules cache: [WILDCARD]deps +npm modules cache: [WILDCARD]npm +Emitted modules cache: [WILDCARD]gen +Language server registries cache: [WILDCARD]registries +Origin storage: [WILDCARD]location_data[WILDCARD] +Local Storage: [WILDCARD]location_data[WILDCARD]local_storage diff --git a/tests/testdata/info/049_info_flag_script_jsx.out b/tests/testdata/info/049_info_flag_script_jsx.out new file mode 100644 index 000000000..f49fc2356 --- /dev/null +++ b/tests/testdata/info/049_info_flag_script_jsx.out @@ -0,0 +1,15 @@ +[WILDCARD] +local: [WILDCARD]http[WILDCARD]127.0.0.1_PORT4545[WILDCARD] +type: TypeScript +dependencies: 8 unique +size: [WILDCARD] + +http://127.0.0.1:4545/run/048_media_types_jsx.ts ([WILDCARD]) +├── http://localhost:4545/subdir/mt_text_typescript_tsx.t1.tsx ([WILDCARD]) +├── http://localhost:4545/subdir/mt_video_vdn_tsx.t2.tsx ([WILDCARD]) +├── http://localhost:4545/subdir/mt_video_mp2t_tsx.t3.tsx ([WILDCARD]) +├── http://localhost:4545/subdir/mt_application_x_typescript_tsx.t4.tsx ([WILDCARD]) +├── http://localhost:4545/subdir/mt_text_javascript_jsx.j1.jsx ([WILDCARD]) +├── http://localhost:4545/subdir/mt_application_ecmascript_jsx.j2.jsx ([WILDCARD]) +├── http://localhost:4545/subdir/mt_text_ecmascript_jsx.j3.jsx ([WILDCARD]) +└── http://localhost:4545/subdir/mt_application_x_javascript_jsx.j4.jsx ([WILDCARD]) diff --git a/tests/testdata/info/054_info_local_imports.out b/tests/testdata/info/054_info_local_imports.out new file mode 100644 index 000000000..ee1773b76 --- /dev/null +++ b/tests/testdata/info/054_info_local_imports.out @@ -0,0 +1,9 @@ +local: [WILDCARD]005_more_imports.ts +type: TypeScript +dependencies: 3 unique +size: [WILDCARD] + +file://[WILDCARD]/005_more_imports.ts ([WILDCARD]) +└─┬ file://[WILDCARD]/subdir/mod1.ts ([WILDCARD]) + └─┬ file://[WILDCARD]/subdir/subdir2/mod2.ts ([WILDCARD]) + └── file://[WILDCARD]/subdir/print_hello.ts ([WILDCARD]) diff --git a/tests/testdata/info/065_import_map_info.out b/tests/testdata/info/065_import_map_info.out new file mode 100644 index 000000000..68d98f14a --- /dev/null +++ b/tests/testdata/info/065_import_map_info.out @@ -0,0 +1,6 @@ +local: [WILDCARD]test.ts +type: TypeScript +dependencies: 7 unique +size: [WILDCARD] + +[WILDCARD] diff --git a/tests/testdata/info/076_info_json_deps_order.out b/tests/testdata/info/076_info_json_deps_order.out new file mode 100644 index 000000000..a1b15e00c --- /dev/null +++ b/tests/testdata/info/076_info_json_deps_order.out @@ -0,0 +1,164 @@ +{ + "roots": [ + "file://[WILDCARD]/076_info_json_deps_order.ts" + ], + "modules": [ + { + "kind": "esm", + "dependencies": [ + { + "specifier": "./recursive_imports/A.ts", + "code": { + "specifier": "file://[WILDCARD]/recursive_imports/A.ts", + "span": { + "start": { + "line": 1, + "character": 18 + }, + "end": { + "line": 1, + "character": 44 + } + } + } + } + ], + "local": "[WILDCARD]076_info_json_deps_order.ts", + [WILDCARD] + "mediaType": "TypeScript", + "specifier": "file://[WILDCARD]/076_info_json_deps_order.ts" + }, + { + "kind": "esm", + "dependencies": [ + { + "specifier": "./B.ts", + "code": { + "specifier": "file://[WILDCARD]/recursive_imports/B.ts", + "span": { + "start": { + "line": 0, + "character": 18 + }, + "end": { + "line": 0, + "character": 26 + } + } + } + }, + { + "specifier": "./common.ts", + "code": { + "specifier": "file://[WILDCARD]/recursive_imports/common.ts", + "span": { + "start": { + "line": 1, + "character": 22 + }, + "end": { + "line": 1, + "character": 35 + } + } + } + } + ], + "local": "[WILDCARD]A.ts", + [WILDCARD] + "mediaType": "TypeScript", + "specifier": "file://[WILDCARD]/recursive_imports/A.ts" + }, + { + "kind": "esm", + "dependencies": [ + { + "specifier": "./C.ts", + "code": { + "specifier": "file://[WILDCARD]/recursive_imports/C.ts", + "span": { + "start": { + "line": 0, + "character": 18 + }, + "end": { + "line": 0, + "character": 26 + } + } + } + }, + { + "specifier": "./common.ts", + "code": { + "specifier": "file://[WILDCARD]/recursive_imports/common.ts", + "span": { + "start": { + "line": 1, + "character": 22 + }, + "end": { + "line": 1, + "character": 35 + } + } + } + } + ], + "local": "[WILDCARD]B.ts", + [WILDCARD] + "mediaType": "TypeScript", + "specifier": "file://[WILDCARD]/recursive_imports/B.ts" + }, + { + "kind": "esm", + "dependencies": [ + { + "specifier": "./A.ts", + "code": { + "specifier": "file://[WILDCARD]/recursive_imports/A.ts", + "span": { + "start": { + "line": 0, + "character": 18 + }, + "end": { + "line": 0, + "character": 26 + } + } + } + }, + { + "specifier": "./common.ts", + "code": { + "specifier": "file://[WILDCARD]/recursive_imports/common.ts", + "span": { + "start": { + "line": 1, + "character": 22 + }, + "end": { + "line": 1, + "character": 35 + } + } + } + } + ], + "local": "[WILDCARD]C.ts", + [WILDCARD] + "mediaType": "TypeScript", + "specifier": "file://[WILDCARD]/recursive_imports/C.ts" + }, + { + "kind": "esm", + "local": "[WILDCARD]common.ts", + [WILDCARD] + "mediaType": "TypeScript", + "specifier": "file://[WILDCARD]/recursive_imports/common.ts" + } + ], + "redirects": {}, + "npmPackages": {} +} diff --git a/tests/testdata/info/076_info_json_deps_order.ts b/tests/testdata/info/076_info_json_deps_order.ts new file mode 100644 index 000000000..b1ae75e68 --- /dev/null +++ b/tests/testdata/info/076_info_json_deps_order.ts @@ -0,0 +1,2 @@ +// deno-lint-ignore no-unused-vars +import { A } from "./recursive_imports/A.ts"; diff --git a/tests/testdata/info/data_null_error/data_null_error.out b/tests/testdata/info/data_null_error/data_null_error.out new file mode 100644 index 000000000..065396f18 --- /dev/null +++ b/tests/testdata/info/data_null_error/data_null_error.out @@ -0,0 +1,7 @@ +local: [WILDCARD]mod.ts +type: TypeScript +dependencies: 1 unique +size: [WILDCARD] + +file://[WILDCARD]/mod.ts ([WILDCARD]) +└── file://[WILDCARD]/types.d.ts ([WILDCARD]) diff --git a/tests/testdata/info/data_null_error/mod.ts b/tests/testdata/info/data_null_error/mod.ts new file mode 100644 index 000000000..6e3e99bd4 --- /dev/null +++ b/tests/testdata/info/data_null_error/mod.ts @@ -0,0 +1 @@ +/// diff --git a/tests/testdata/info/data_null_error/types.d.ts b/tests/testdata/info/data_null_error/types.d.ts new file mode 100644 index 000000000..6ecc85676 --- /dev/null +++ b/tests/testdata/info/data_null_error/types.d.ts @@ -0,0 +1 @@ +declare class Test {} diff --git a/tests/testdata/info/error_009_missing_js_module.js b/tests/testdata/info/error_009_missing_js_module.js new file mode 100644 index 000000000..e6ca88934 --- /dev/null +++ b/tests/testdata/info/error_009_missing_js_module.js @@ -0,0 +1 @@ +import "./bad-module.js"; diff --git a/tests/testdata/info/error_009_missing_js_module.js.out b/tests/testdata/info/error_009_missing_js_module.js.out new file mode 100644 index 000000000..edb08da1c --- /dev/null +++ b/tests/testdata/info/error_009_missing_js_module.js.out @@ -0,0 +1 @@ +Cannot resolve module "./bad-module.js" from "[WILDCARD]error_009_missing_js_module.js" diff --git a/tests/testdata/info/info_json.out b/tests/testdata/info/info_json.out new file mode 100644 index 000000000..3215af742 --- /dev/null +++ b/tests/testdata/info/info_json.out @@ -0,0 +1,8 @@ +{ + "denoDir": "[WILDCARD]", + "modulesCache": "[WILDCARD]deps", + "npmCache": "[WILDCARD]npm", + "typescriptCache": "[WILDCARD]gen", + "registryCache": "[WILDCARD]registries", + "originStorage": "[WILDCARD]location_data" +} diff --git a/tests/testdata/info/info_json_location.out b/tests/testdata/info/info_json_location.out new file mode 100644 index 000000000..510fa7749 --- /dev/null +++ b/tests/testdata/info/info_json_location.out @@ -0,0 +1,9 @@ +{ + "denoDir": "[WILDCARD]", + "modulesCache": "[WILDCARD]deps", + "npmCache": "[WILDCARD]npm", + "typescriptCache": "[WILDCARD]gen", + "registryCache": "[WILDCARD]registries", + "originStorage": "[WILDCARD]location_data[WILDCARD]", + "localStorage": "[WILDCARD]location_data[WILDCARD]local_storage" +} diff --git a/tests/testdata/info/info_missing_module.out b/tests/testdata/info/info_missing_module.out new file mode 100644 index 000000000..c62d690c1 --- /dev/null +++ b/tests/testdata/info/info_missing_module.out @@ -0,0 +1,7 @@ +local: [WILDCARD]error_009_missing_js_module.js +type: JavaScript +dependencies: 0 unique +size: 26B + +file://[WILDCARD]/error_009_missing_js_module.js (26B) +└── file://[WILDCARD]/bad-module.js (missing) diff --git a/tests/testdata/info/info_recursive_imports_test.out b/tests/testdata/info/info_recursive_imports_test.out new file mode 100644 index 000000000..3340f3859 --- /dev/null +++ b/tests/testdata/info/info_recursive_imports_test.out @@ -0,0 +1,13 @@ +local: [WILDCARD]info_recursive_imports_test.ts +type: TypeScript +dependencies: 4 unique +size: [WILDCARD] + +file://[WILDCARD]/info_recursive_imports_test.ts ([WILDCARD]) +└─┬ file://[WILDCARD]/recursive_imports/A.ts ([WILDCARD]) + ├─┬ file://[WILDCARD]/recursive_imports/B.ts ([WILDCARD]) + │ ├─┬ file://[WILDCARD]/recursive_imports/C.ts ([WILDCARD]) + │ │ ├── file://[WILDCARD]/recursive_imports/A.ts * + │ │ └── file://[WILDCARD]/recursive_imports/common.ts ([WILDCARD]) + │ └── file://[WILDCARD]/recursive_imports/common.ts * + └── file://[WILDCARD]/recursive_imports/common.ts * diff --git a/tests/testdata/info/info_recursive_imports_test.ts b/tests/testdata/info/info_recursive_imports_test.ts new file mode 100644 index 000000000..c9ba44755 --- /dev/null +++ b/tests/testdata/info/info_recursive_imports_test.ts @@ -0,0 +1,5 @@ +import { A } from "./recursive_imports/A.ts"; + +export function test() { + A(); +} diff --git a/tests/testdata/info/info_type_import.out b/tests/testdata/info/info_type_import.out new file mode 100644 index 000000000..0423efe82 --- /dev/null +++ b/tests/testdata/info/info_type_import.out @@ -0,0 +1,7 @@ +local: [WILDCARD]info_type_import.ts +type: TypeScript +dependencies: 1 unique +size: [WILDCARD] + +[WILDCARD]info_type_import.ts ([WILDCARD]) +└── [WILDCARD]type_and_code.ts ([WILDCARD]) diff --git a/tests/testdata/info/info_type_import.ts b/tests/testdata/info/info_type_import.ts new file mode 100644 index 000000000..4db9f3387 --- /dev/null +++ b/tests/testdata/info/info_type_import.ts @@ -0,0 +1,3 @@ +import { AnInterface as _, isAnInterface } from "../subdir/type_and_code.ts"; + +isAnInterface({}); diff --git a/tests/testdata/info/json_output/main.out b/tests/testdata/info/json_output/main.out new file mode 100644 index 000000000..5a89d5cab --- /dev/null +++ b/tests/testdata/info/json_output/main.out @@ -0,0 +1,91 @@ +{ + "roots": [ + "file://[WILDCARD]/info/json_output/main.ts" + ], + "modules": [ + { + "kind": "esm", + "dependencies": [ + { + "specifier": "../../subdir/mod1.ts", + "code": { + "specifier": "file://[WILDCARD]/subdir/mod1.ts", + "span": { + "start": { + "line": 0, + "character": 52 + }, + "end": { + "line": 0, + "character": 74 + } + } + } + } + ], + "local": "[WILDCARD]main.ts", + [WILDCARD] + "mediaType": "TypeScript", + "specifier": "file://[WILDCARD]/json_output/main.ts" + }, + { + "kind": "esm", + "dependencies": [ + { + "specifier": "./subdir2/mod2.ts", + "code": { + "specifier": "file://[WILDCARD]/subdir/subdir2/mod2.ts", + "span": { + "start": { + "line": 0, + "character": 40 + }, + "end": { + "line": 0, + "character": 59 + } + } + } + } + ], + "local": "[WILDCARD]mod1.ts", + [WILDCARD] + "mediaType": "TypeScript", + "specifier": "file://[WILDCARD]/subdir/mod1.ts" + }, + { + "kind": "esm", + "local": "[WILDCARD]print_hello.ts", + [WILDCARD] + "mediaType": "TypeScript", + "specifier": "file://[WILDCARD]/subdir/print_hello.ts" + }, + { + "kind": "esm", + "dependencies": [ + { + "specifier": "../print_hello.ts", + "code": { + "specifier": "file://[WILDCARD]/subdir/print_hello.ts", + "span": { + "start": { + "line": 0, + "character": 27 + }, + "end": { + "line": 0, + "character": 46 + } + } + } + } + ], + "local": "[WILDCARD]mod2.ts", + [WILDCARD] + "mediaType": "TypeScript", + "specifier": "file://[WILDCARD]/subdir/subdir2/mod2.ts" + } + ], + "redirects": {}, + "npmPackages": {} +} diff --git a/tests/testdata/info/json_output/main.ts b/tests/testdata/info/json_output/main.ts new file mode 100644 index 000000000..927bc55ed --- /dev/null +++ b/tests/testdata/info/json_output/main.ts @@ -0,0 +1,11 @@ +import { printHello3, returnsFoo2, returnsHi } from "../../subdir/mod1.ts"; + +printHello3(); + +if (returnsHi() !== "Hi") { + throw Error("Unexpected"); +} + +if (returnsFoo2() !== "Foo") { + throw Error("Unexpected"); +} diff --git a/tests/testdata/info/multiple_imports.out b/tests/testdata/info/multiple_imports.out new file mode 100644 index 000000000..cb13318ca --- /dev/null +++ b/tests/testdata/info/multiple_imports.out @@ -0,0 +1,15 @@ +[WILDCARD] +local: [WILDCARD]http[WILDCARD]127.0.0.1_PORT4545[WILDCARD] +type: TypeScript +dependencies: 8 unique +size: [WILDCARD] + +http://127.0.0.1:4545/run/019_media_types.ts ([WILDCARD]) +├── http://localhost:4545/subdir/mt_text_typescript.t1.ts ([WILDCARD]) +├── http://localhost:4545/subdir/mt_video_vdn.t2.ts ([WILDCARD]) +├── http://localhost:4545/subdir/mt_video_mp2t.t3.ts ([WILDCARD]) +├── http://localhost:4545/subdir/mt_application_x_typescript.t4.ts ([WILDCARD]) +├── http://localhost:4545/subdir/mt_text_javascript.j1.js ([WILDCARD]) +├── http://localhost:4545/subdir/mt_application_ecmascript.j2.js ([WILDCARD]) +├── http://localhost:4545/subdir/mt_text_ecmascript.j3.js ([WILDCARD]) +└── http://localhost:4545/subdir/mt_application_x_javascript.j4.js ([WILDCARD]) diff --git a/tests/testdata/info/recursive_imports/A.ts b/tests/testdata/info/recursive_imports/A.ts new file mode 100644 index 000000000..43ecdbe5e --- /dev/null +++ b/tests/testdata/info/recursive_imports/A.ts @@ -0,0 +1,7 @@ +import { B } from "./B.ts"; +import { thing } from "./common.ts"; + +export function A() { + thing(); + B(); +} diff --git a/tests/testdata/info/recursive_imports/B.ts b/tests/testdata/info/recursive_imports/B.ts new file mode 100644 index 000000000..9fff0fdc9 --- /dev/null +++ b/tests/testdata/info/recursive_imports/B.ts @@ -0,0 +1,7 @@ +import { C } from "./C.ts"; +import { thing } from "./common.ts"; + +export function B() { + thing(); + C(); +} diff --git a/tests/testdata/info/recursive_imports/C.ts b/tests/testdata/info/recursive_imports/C.ts new file mode 100644 index 000000000..e47e77b41 --- /dev/null +++ b/tests/testdata/info/recursive_imports/C.ts @@ -0,0 +1,8 @@ +import { A } from "./A.ts"; +import { thing } from "./common.ts"; + +export function C() { + if (A != null) { + thing(); + } +} diff --git a/tests/testdata/info/recursive_imports/common.ts b/tests/testdata/info/recursive_imports/common.ts new file mode 100644 index 000000000..2b16a7bf1 --- /dev/null +++ b/tests/testdata/info/recursive_imports/common.ts @@ -0,0 +1,2 @@ +export function thing() { +} diff --git a/tests/testdata/info/types_header.out b/tests/testdata/info/types_header.out new file mode 100644 index 000000000..722e02f77 --- /dev/null +++ b/tests/testdata/info/types_header.out @@ -0,0 +1,9 @@ +[WILDCARD] +local: [WILDCARD]type_directives_01.ts +type: TypeScript +dependencies: 2 unique +size: [WILDCARD] + +[WILDCARD]/type_directives_01.ts ([WILDCARD]) +└─┬ http://127.0.0.1:4545/xTypeScriptTypes.js ([WILDCARD]) + └── http://127.0.0.1:4545/xTypeScriptTypes.d.ts ([WILDCARD]) diff --git a/tests/testdata/info/with_config/deno-override.json b/tests/testdata/info/with_config/deno-override.json new file mode 100644 index 000000000..ee44ba947 --- /dev/null +++ b/tests/testdata/info/with_config/deno-override.json @@ -0,0 +1,3 @@ +{ + "importMap": "import_map.json" +} diff --git a/tests/testdata/info/with_config/deno.json b/tests/testdata/info/with_config/deno.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/tests/testdata/info/with_config/deno.json @@ -0,0 +1 @@ +{} diff --git a/tests/testdata/info/with_config/import_map.json b/tests/testdata/info/with_config/import_map.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/tests/testdata/info/with_config/import_map.json @@ -0,0 +1 @@ +{} diff --git a/tests/testdata/info/with_config/test.ts b/tests/testdata/info/with_config/test.ts new file mode 100644 index 000000000..85ce559e8 --- /dev/null +++ b/tests/testdata/info/with_config/test.ts @@ -0,0 +1 @@ +console.log("foo"); diff --git a/tests/testdata/info/with_config/with_config.out b/tests/testdata/info/with_config/with_config.out new file mode 100644 index 000000000..95a1f30bc --- /dev/null +++ b/tests/testdata/info/with_config/with_config.out @@ -0,0 +1,7 @@ +Warning the configuration file "[WILDCARD]/deno-override.json" contains an entry for "importMap" that is being ignored. +local: [WILDCARD]test.ts +type: TypeScript +dependencies: 0 unique +size: [WILDCARD] + +file:///[WILDCARD]/test.ts ([WILDCARD]) diff --git a/tests/testdata/info/with_import_map/deno.json b/tests/testdata/info/with_import_map/deno.json new file mode 100644 index 000000000..aaf7260c6 --- /dev/null +++ b/tests/testdata/info/with_import_map/deno.json @@ -0,0 +1,6 @@ +{ + "imports": { + "preact": "https://esm.sh/preact@10.15.1", + "preact/": "https://esm.sh/preact@10.15.1/" + } +} diff --git a/tests/testdata/info/with_import_map/deno.lock b/tests/testdata/info/with_import_map/deno.lock new file mode 100644 index 000000000..78080ede2 --- /dev/null +++ b/tests/testdata/info/with_import_map/deno.lock @@ -0,0 +1,7 @@ +{ + "version": "2", + "remote": { + "https://esm.sh/preact@10.15.1": "2b79349676a4942fbcf835c4efa909791c2f0aeca195225bf22bac9866e94b4e", + "https://esm.sh/stable/preact@10.15.1/denonext/preact.mjs": "30710ac1d5ff3711ae0c04eddbeb706f34f82d97489f61aaf09897bc75d2a628" + } +} diff --git a/tests/testdata/info/with_import_map/main.tsx b/tests/testdata/info/with_import_map/main.tsx new file mode 100644 index 000000000..e38f14a58 --- /dev/null +++ b/tests/testdata/info/with_import_map/main.tsx @@ -0,0 +1,2 @@ +import { render } from "preact"; +console.log(render); diff --git a/tests/testdata/info/with_import_map/with_import_map.out b/tests/testdata/info/with_import_map/with_import_map.out new file mode 100644 index 000000000..29dc17737 --- /dev/null +++ b/tests/testdata/info/with_import_map/with_import_map.out @@ -0,0 +1,16 @@ +Download https://esm.sh/preact@10.15.1/debug +Download https://esm.sh/stable/preact@10.15.1/denonext/preact.mjs +Download https://esm.sh/stable/preact@10.15.1/denonext/devtools.js +Download https://esm.sh/stable/preact@10.15.1/denonext/debug.js +local: [WILDCARD] +type: JavaScript +dependencies: 3 unique +size: [WILDCARD] + +https://esm.sh/preact@10.15.1/debug [WILDCARD] +├── https://esm.sh/stable/preact@10.15.1/denonext/preact.mjs [WILDCARD] +├─┬ https://esm.sh/stable/preact@10.15.1/denonext/devtools.js [WILDCARD] +│ └── https://esm.sh/stable/preact@10.15.1/denonext/preact.mjs [WILDCARD] +└─┬ https://esm.sh/stable/preact@10.15.1/denonext/debug.js [WILDCARD] + ├── https://esm.sh/stable/preact@10.15.1/denonext/preact.mjs [WILDCARD] + └── https://esm.sh/stable/preact@10.15.1/denonext/devtools.js [WILDCARD] diff --git a/tests/testdata/inspector/bar.js b/tests/testdata/inspector/bar.js new file mode 100644 index 000000000..278fc9030 --- /dev/null +++ b/tests/testdata/inspector/bar.js @@ -0,0 +1,3 @@ +export function bar() { + return "world"; +} diff --git a/tests/testdata/inspector/error_with_npm_import.js b/tests/testdata/inspector/error_with_npm_import.js new file mode 100644 index 000000000..9244f2cf2 --- /dev/null +++ b/tests/testdata/inspector/error_with_npm_import.js @@ -0,0 +1,7 @@ +// deno-lint-ignore-file + +import chalk from "npm:chalk"; + +console.log("hello"); + +throw new Error("boom!"); diff --git a/tests/testdata/inspector/foo.ts b/tests/testdata/inspector/foo.ts new file mode 100644 index 000000000..c0735926f --- /dev/null +++ b/tests/testdata/inspector/foo.ts @@ -0,0 +1,10 @@ +class Foo { + hello(): string { + return "hello"; + } +} + +export function foo(): string { + const f = new Foo(); + return f.hello(); +} diff --git a/tests/testdata/inspector/inspect_wait.js b/tests/testdata/inspector/inspect_wait.js new file mode 100644 index 000000000..e2b10199c --- /dev/null +++ b/tests/testdata/inspector/inspect_wait.js @@ -0,0 +1,2 @@ +Deno.writeTextFileSync("./hello.txt", "hello world"); +console.error("did run"); diff --git a/tests/testdata/inspector/inspector1.js b/tests/testdata/inspector/inspector1.js new file mode 100644 index 000000000..5cb059def --- /dev/null +++ b/tests/testdata/inspector/inspector1.js @@ -0,0 +1,3 @@ +setInterval(() => { + console.log("hello"); +}, 1000); diff --git a/tests/testdata/inspector/inspector2.js b/tests/testdata/inspector/inspector2.js new file mode 100644 index 000000000..57f80ef94 --- /dev/null +++ b/tests/testdata/inspector/inspector2.js @@ -0,0 +1,4 @@ +console.log("hello from the script"); + +// This process will be killed before the timeout is over. +await new Promise((res, _) => setTimeout(res, 1000)); diff --git a/tests/testdata/inspector/inspector3.js b/tests/testdata/inspector/inspector3.js new file mode 100644 index 000000000..8d605a286 --- /dev/null +++ b/tests/testdata/inspector/inspector3.js @@ -0,0 +1,13 @@ +// deno-lint-ignore-file + +// check that console methods provided by V8 are available in the inspector +console.timeStamp("foo"); +console.profile("foo"); +console.profileEnd("foo"); + +for (let i = 0; i < 128; i++) { + console.log(i); + debugger; +} +await new Promise((res, _) => setTimeout(res, 100)); +console.log("done"); diff --git a/tests/testdata/inspector/inspector4.js b/tests/testdata/inspector/inspector4.js new file mode 100644 index 000000000..1bf419650 --- /dev/null +++ b/tests/testdata/inspector/inspector4.js @@ -0,0 +1,5 @@ +console.log("hello"); + +setInterval(() => { + console.log("hello from interval"); +}, 1000); diff --git a/tests/testdata/inspector/inspector_test.js b/tests/testdata/inspector/inspector_test.js new file mode 100644 index 000000000..86cd48854 --- /dev/null +++ b/tests/testdata/inspector/inspector_test.js @@ -0,0 +1,3 @@ +Deno.test("basic test", () => { + console.log("test has finished running"); +}); diff --git a/tests/testdata/inspector/memory.js b/tests/testdata/inspector/memory.js new file mode 100644 index 000000000..082d6367c --- /dev/null +++ b/tests/testdata/inspector/memory.js @@ -0,0 +1,13 @@ +const objs = []; + +class Foo { + foo() { + return "foo"; + } +} + +setInterval(() => { + objs.push(new Foo()); +}, 1000); + +console.log("hello!"); diff --git a/tests/testdata/inspector/test.ts b/tests/testdata/inspector/test.ts new file mode 100644 index 000000000..2b33f22e5 --- /dev/null +++ b/tests/testdata/inspector/test.ts @@ -0,0 +1,5 @@ +import { foo } from "./foo.ts"; +import { bar } from "./bar.js"; + +console.log(foo()); +console.log(bar()); diff --git a/tests/testdata/install/check_local_by_default.ts b/tests/testdata/install/check_local_by_default.ts new file mode 100644 index 000000000..2ae8c2692 --- /dev/null +++ b/tests/testdata/install/check_local_by_default.ts @@ -0,0 +1,3 @@ +import * as a from "http://localhost:4545/subdir/type_error.ts"; + +console.log(a.a); diff --git a/tests/testdata/install/check_local_by_default2.ts b/tests/testdata/install/check_local_by_default2.ts new file mode 100644 index 000000000..5177ff944 --- /dev/null +++ b/tests/testdata/install/check_local_by_default2.ts @@ -0,0 +1,6 @@ +import * as a from "http://localhost:4545/subdir/type_error.ts"; + +const b: "b" = 12; + +console.log(a.a); +console.log(b); diff --git a/tests/testdata/jsr/deps/main.out b/tests/testdata/jsr/deps/main.out new file mode 100644 index 000000000..621703c4b --- /dev/null +++ b/tests/testdata/jsr/deps/main.out @@ -0,0 +1,13 @@ +Download http://127.0.0.1:4250/@denotest/deps/meta.json +Download http://127.0.0.1:4250/@denotest/deps/1.0.0_meta.json +Download http://127.0.0.1:4250/@denotest/module_graph/meta.json +Download http://127.0.0.1:4250/@denotest/no_module_graph/meta.json +Download http://127.0.0.1:4250/@denotest/module_graph/1.4.0_meta.json +Download http://127.0.0.1:4250/@denotest/no_module_graph/0.1.1_meta.json +[UNORDERED_START] +Download http://127.0.0.1:4250/@denotest/deps/1.0.0/mod.ts +Download http://127.0.0.1:4250/@denotest/module_graph/1.4.0/other.ts +Download http://127.0.0.1:4250/@denotest/no_module_graph/0.1.1/mod.ts +Download http://127.0.0.1:4250/@denotest/no_module_graph/0.1.1/TestClass.ts +[UNORDERED_END] +{ version: "0.1.1", other: Other {} } diff --git a/tests/testdata/jsr/deps/main.ts b/tests/testdata/jsr/deps/main.ts new file mode 100644 index 000000000..f48255299 --- /dev/null +++ b/tests/testdata/jsr/deps/main.ts @@ -0,0 +1,3 @@ +import value from "jsr:@denotest/deps"; + +console.log(value); diff --git a/tests/testdata/jsr/deps/main_info.out b/tests/testdata/jsr/deps/main_info.out new file mode 100644 index 000000000..c4d412707 --- /dev/null +++ b/tests/testdata/jsr/deps/main_info.out @@ -0,0 +1,22 @@ +Download http://127.0.0.1:4250/@denotest/deps/meta.json +Download http://127.0.0.1:4250/@denotest/deps/1.0.0_meta.json +Download http://127.0.0.1:4250/@denotest/module_graph/meta.json +Download http://127.0.0.1:4250/@denotest/no_module_graph/meta.json +Download http://127.0.0.1:4250/@denotest/module_graph/1.4.0_meta.json +Download http://127.0.0.1:4250/@denotest/no_module_graph/0.1.1_meta.json +[UNORDERED_START] +Download http://127.0.0.1:4250/@denotest/deps/1.0.0/mod.ts +Download http://127.0.0.1:4250/@denotest/module_graph/1.4.0/other.ts +Download http://127.0.0.1:4250/@denotest/no_module_graph/0.1.1/mod.ts +Download http://127.0.0.1:4250/@denotest/no_module_graph/0.1.1/TestClass.ts +[UNORDERED_END] +local: [WILDCARD]main.ts +type: TypeScript +dependencies: 4 unique +size: [WILDCARD] + +file:///[WILDCARD]main.ts ([WILDCARD]) +└─┬ http://127.0.0.1:4250/@denotest/deps/1.0.0/mod.ts ([WILDCARD]) + ├── http://127.0.0.1:4250/@denotest/module_graph/1.4.0/other.ts ([WILDCARD]) + └─┬ http://127.0.0.1:4250/@denotest/no_module_graph/0.1.1/mod.ts ([WILDCARD]) + └── http://127.0.0.1:4250/@denotest/no_module_graph/0.1.1/TestClass.ts ([WILDCARD]) diff --git a/tests/testdata/jsr/module_graph/main.out b/tests/testdata/jsr/module_graph/main.out new file mode 100644 index 000000000..1cd0115b9 --- /dev/null +++ b/tests/testdata/jsr/module_graph/main.out @@ -0,0 +1,7 @@ +Download http://127.0.0.1:4250/@denotest/module_graph/meta.json +Download http://127.0.0.1:4250/@denotest/module_graph/1.4.0_meta.json +[UNORDERED_START] +Download http://127.0.0.1:4250/@denotest/module_graph/1.4.0/other.ts +Download http://127.0.0.1:4250/@denotest/module_graph/1.4.0/mod.ts +[UNORDERED_END] +Test { other: Other {} } diff --git a/tests/testdata/jsr/module_graph/main.ts b/tests/testdata/jsr/module_graph/main.ts new file mode 100644 index 000000000..c92823cc2 --- /dev/null +++ b/tests/testdata/jsr/module_graph/main.ts @@ -0,0 +1,3 @@ +import { Test } from "jsr:@denotest/module_graph"; + +console.log(new Test()); diff --git a/tests/testdata/jsr/module_graph/main_info.out b/tests/testdata/jsr/module_graph/main_info.out new file mode 100644 index 000000000..c35cca5b4 --- /dev/null +++ b/tests/testdata/jsr/module_graph/main_info.out @@ -0,0 +1,14 @@ +Download http://127.0.0.1:4250/@denotest/module_graph/meta.json +Download http://127.0.0.1:4250/@denotest/module_graph/1.4.0_meta.json +[UNORDERED_START] +Download http://127.0.0.1:4250/@denotest/module_graph/1.4.0/mod.ts +Download http://127.0.0.1:4250/@denotest/module_graph/1.4.0/other.ts +[UNORDERED_END] +local: [WILDCARD]main.ts +type: TypeScript +dependencies: 2 unique +size: [WILDCARD] + +file:///[WILDCARD]/module_graph/main.ts ([WILDCARD]) +└─┬ http://127.0.0.1:4250/@denotest/module_graph/1.4.0/mod.ts ([WILDCARD]) + └── http://127.0.0.1:4250/@denotest/module_graph/1.4.0/other.ts ([WILDCARD]) diff --git a/tests/testdata/jsr/no_module_graph/main.out b/tests/testdata/jsr/no_module_graph/main.out new file mode 100644 index 000000000..da9b67e11 --- /dev/null +++ b/tests/testdata/jsr/no_module_graph/main.out @@ -0,0 +1,6 @@ +Download http://127.0.0.1:4250/@denotest/no_module_graph/meta.json +Download http://127.0.0.1:4250/@denotest/no_module_graph/0.1.0_meta.json +Download http://127.0.0.1:4250/@denotest/no_module_graph/0.1.0/mod.ts +Download http://127.0.0.1:4250/@denotest/no_module_graph/0.1.0/TestClass.ts +0.1.0 +TestClass {} diff --git a/tests/testdata/jsr/no_module_graph/main.ts b/tests/testdata/jsr/no_module_graph/main.ts new file mode 100644 index 000000000..6ea030c59 --- /dev/null +++ b/tests/testdata/jsr/no_module_graph/main.ts @@ -0,0 +1,4 @@ +import version, { TestClass } from "jsr:@denotest/no_module_graph@0.1.0"; + +console.log(version); +console.log(new TestClass()); diff --git a/tests/testdata/jsr/no_module_graph/main_info.out b/tests/testdata/jsr/no_module_graph/main_info.out new file mode 100644 index 000000000..0293e4120 --- /dev/null +++ b/tests/testdata/jsr/no_module_graph/main_info.out @@ -0,0 +1,12 @@ +Download http://127.0.0.1:4250/@denotest/no_module_graph/meta.json +Download http://127.0.0.1:4250/@denotest/no_module_graph/0.1.0_meta.json +Download http://127.0.0.1:4250/@denotest/no_module_graph/0.1.0/mod.ts +Download http://127.0.0.1:4250/@denotest/no_module_graph/0.1.0/TestClass.ts +local: [WILDCARD]main.ts +type: TypeScript +dependencies: 2 unique +size: [WILDCARD] + +file:///[WILDCARD]/jsr/no_module_graph/main.ts ([WILDCARD]) +└─┬ http://127.0.0.1:4250/@denotest/no_module_graph/0.1.0/mod.ts ([WILDCARD]) + └── http://127.0.0.1:4250/@denotest/no_module_graph/0.1.0/TestClass.ts ([WILDCARD]) diff --git a/tests/testdata/jsr/no_module_graph/multiple.out b/tests/testdata/jsr/no_module_graph/multiple.out new file mode 100644 index 000000000..8146276d0 --- /dev/null +++ b/tests/testdata/jsr/no_module_graph/multiple.out @@ -0,0 +1,2 @@ +0.1.0 +0.2.0 diff --git a/tests/testdata/jsr/no_module_graph/multiple.ts b/tests/testdata/jsr/no_module_graph/multiple.ts new file mode 100644 index 000000000..660ed8be6 --- /dev/null +++ b/tests/testdata/jsr/no_module_graph/multiple.ts @@ -0,0 +1,5 @@ +import version1 from "jsr:@denotest/no_module_graph@0.1.0"; +import version2 from "jsr:@denotest/no_module_graph@^0.2"; + +console.log(version1); +console.log(version2); diff --git a/tests/testdata/jsr/registry/@denotest/add/1.0.0/mod.ts b/tests/testdata/jsr/registry/@denotest/add/1.0.0/mod.ts new file mode 100644 index 000000000..8d9b8a22a --- /dev/null +++ b/tests/testdata/jsr/registry/@denotest/add/1.0.0/mod.ts @@ -0,0 +1,3 @@ +export function add(a: number, b: number): number { + return a + b; +} diff --git a/tests/testdata/jsr/registry/@denotest/add/1.0.0_meta.json b/tests/testdata/jsr/registry/@denotest/add/1.0.0_meta.json new file mode 100644 index 000000000..6eebe2198 --- /dev/null +++ b/tests/testdata/jsr/registry/@denotest/add/1.0.0_meta.json @@ -0,0 +1,8 @@ +{ + "exports": { + ".": "./mod.ts" + }, + "moduleGraph1": { + "/mod.ts": {} + } +} diff --git a/tests/testdata/jsr/registry/@denotest/add/meta.json b/tests/testdata/jsr/registry/@denotest/add/meta.json new file mode 100644 index 000000000..02601e4d0 --- /dev/null +++ b/tests/testdata/jsr/registry/@denotest/add/meta.json @@ -0,0 +1,5 @@ +{ + "versions": { + "1.0.0": {} + } +} diff --git a/tests/testdata/jsr/registry/@denotest/deps/1.0.0/mod.ts b/tests/testdata/jsr/registry/@denotest/deps/1.0.0/mod.ts new file mode 100644 index 000000000..4ba0d8aaf --- /dev/null +++ b/tests/testdata/jsr/registry/@denotest/deps/1.0.0/mod.ts @@ -0,0 +1,7 @@ +import { Other } from "jsr:@denotest/module_graph@1/other"; +import version from "jsr:@denotest/no_module_graph@^0.1"; + +export default { + version, + other: new Other(), +}; diff --git a/tests/testdata/jsr/registry/@denotest/deps/1.0.0_meta.json b/tests/testdata/jsr/registry/@denotest/deps/1.0.0_meta.json new file mode 100644 index 000000000..914e4bd73 --- /dev/null +++ b/tests/testdata/jsr/registry/@denotest/deps/1.0.0_meta.json @@ -0,0 +1,22 @@ +{ + "exports": { + ".": "./mod.ts" + }, + "moduleGraph1": { + "/mod.ts": { + "dependencies": [{ + "type": "static", + "kind": "import", + "range": [[0, 0], [0, 59]], + "specifier": "jsr:@denotest/module_graph@1/other", + "specifierRange": [[0, 22], [0, 58]] + }, { + "type": "static", + "kind": "import", + "range": [[1, 0], [1, 57]], + "specifier": "jsr:@denotest/no_module_graph@^0.1", + "specifierRange": [[1, 20], [1, 56]] + }] + } + } +} diff --git a/tests/testdata/jsr/registry/@denotest/deps/meta.json b/tests/testdata/jsr/registry/@denotest/deps/meta.json new file mode 100644 index 000000000..02601e4d0 --- /dev/null +++ b/tests/testdata/jsr/registry/@denotest/deps/meta.json @@ -0,0 +1,5 @@ +{ + "versions": { + "1.0.0": {} + } +} diff --git a/tests/testdata/jsr/registry/@denotest/module_graph/1.4.0/mod.ts b/tests/testdata/jsr/registry/@denotest/module_graph/1.4.0/mod.ts new file mode 100644 index 000000000..cb3c4a5e0 --- /dev/null +++ b/tests/testdata/jsr/registry/@denotest/module_graph/1.4.0/mod.ts @@ -0,0 +1,5 @@ +import { Other } from "./other.ts"; + +export class Test { + other = new Other(); +} diff --git a/tests/testdata/jsr/registry/@denotest/module_graph/1.4.0/other.ts b/tests/testdata/jsr/registry/@denotest/module_graph/1.4.0/other.ts new file mode 100644 index 000000000..57e436cf8 --- /dev/null +++ b/tests/testdata/jsr/registry/@denotest/module_graph/1.4.0/other.ts @@ -0,0 +1,2 @@ +export class Other { +} diff --git a/tests/testdata/jsr/registry/@denotest/module_graph/1.4.0_meta.json b/tests/testdata/jsr/registry/@denotest/module_graph/1.4.0_meta.json new file mode 100644 index 000000000..ff105b58a --- /dev/null +++ b/tests/testdata/jsr/registry/@denotest/module_graph/1.4.0_meta.json @@ -0,0 +1,18 @@ +{ + "exports": { + ".": "./mod.ts", + "./other": "./other.ts" + }, + "moduleGraph1": { + "/mod.ts": { + "dependencies": [{ + "kind": "import", + "type": "static", + "range": [[0, 0], [0, 35]], + "specifier": "./other.ts", + "specifierRange": [[0, 22], [0, 34]] + }] + }, + "/other.ts": {} + } +} diff --git a/tests/testdata/jsr/registry/@denotest/module_graph/meta.json b/tests/testdata/jsr/registry/@denotest/module_graph/meta.json new file mode 100644 index 000000000..9a450c08b --- /dev/null +++ b/tests/testdata/jsr/registry/@denotest/module_graph/meta.json @@ -0,0 +1,6 @@ +{ + "versions": { + "1.0.0": {}, + "1.4.0": {} + } +} diff --git a/tests/testdata/jsr/registry/@denotest/no_module_graph/0.1.0/TestClass.ts b/tests/testdata/jsr/registry/@denotest/no_module_graph/0.1.0/TestClass.ts new file mode 100644 index 000000000..88ac04c12 --- /dev/null +++ b/tests/testdata/jsr/registry/@denotest/no_module_graph/0.1.0/TestClass.ts @@ -0,0 +1 @@ +export default class TestClass {} diff --git a/tests/testdata/jsr/registry/@denotest/no_module_graph/0.1.0/mod.ts b/tests/testdata/jsr/registry/@denotest/no_module_graph/0.1.0/mod.ts new file mode 100644 index 000000000..57600eb4b --- /dev/null +++ b/tests/testdata/jsr/registry/@denotest/no_module_graph/0.1.0/mod.ts @@ -0,0 +1,3 @@ +export default "0.1.0"; + +export { default as TestClass } from "./TestClass.ts"; diff --git a/tests/testdata/jsr/registry/@denotest/no_module_graph/0.1.0_meta.json b/tests/testdata/jsr/registry/@denotest/no_module_graph/0.1.0_meta.json new file mode 100644 index 000000000..631a18d0e --- /dev/null +++ b/tests/testdata/jsr/registry/@denotest/no_module_graph/0.1.0_meta.json @@ -0,0 +1,5 @@ +{ + "exports": { + ".": "./mod.ts" + } +} diff --git a/tests/testdata/jsr/registry/@denotest/no_module_graph/0.1.1/TestClass.ts b/tests/testdata/jsr/registry/@denotest/no_module_graph/0.1.1/TestClass.ts new file mode 100644 index 000000000..88ac04c12 --- /dev/null +++ b/tests/testdata/jsr/registry/@denotest/no_module_graph/0.1.1/TestClass.ts @@ -0,0 +1 @@ +export default class TestClass {} diff --git a/tests/testdata/jsr/registry/@denotest/no_module_graph/0.1.1/mod.ts b/tests/testdata/jsr/registry/@denotest/no_module_graph/0.1.1/mod.ts new file mode 100644 index 000000000..5e1fd9435 --- /dev/null +++ b/tests/testdata/jsr/registry/@denotest/no_module_graph/0.1.1/mod.ts @@ -0,0 +1,3 @@ +export default "0.1.1"; + +export { default as TestClass } from "./TestClass.ts"; diff --git a/tests/testdata/jsr/registry/@denotest/no_module_graph/0.1.1_meta.json b/tests/testdata/jsr/registry/@denotest/no_module_graph/0.1.1_meta.json new file mode 100644 index 000000000..631a18d0e --- /dev/null +++ b/tests/testdata/jsr/registry/@denotest/no_module_graph/0.1.1_meta.json @@ -0,0 +1,5 @@ +{ + "exports": { + ".": "./mod.ts" + } +} diff --git a/tests/testdata/jsr/registry/@denotest/no_module_graph/0.2.0/TestClass.ts b/tests/testdata/jsr/registry/@denotest/no_module_graph/0.2.0/TestClass.ts new file mode 100644 index 000000000..88ac04c12 --- /dev/null +++ b/tests/testdata/jsr/registry/@denotest/no_module_graph/0.2.0/TestClass.ts @@ -0,0 +1 @@ +export default class TestClass {} diff --git a/tests/testdata/jsr/registry/@denotest/no_module_graph/0.2.0/mod.ts b/tests/testdata/jsr/registry/@denotest/no_module_graph/0.2.0/mod.ts new file mode 100644 index 000000000..edf9622fb --- /dev/null +++ b/tests/testdata/jsr/registry/@denotest/no_module_graph/0.2.0/mod.ts @@ -0,0 +1,3 @@ +export default "0.2.0"; + +export { default as TestClass } from "./TestClass.ts"; diff --git a/tests/testdata/jsr/registry/@denotest/no_module_graph/0.2.0_meta.json b/tests/testdata/jsr/registry/@denotest/no_module_graph/0.2.0_meta.json new file mode 100644 index 000000000..631a18d0e --- /dev/null +++ b/tests/testdata/jsr/registry/@denotest/no_module_graph/0.2.0_meta.json @@ -0,0 +1,5 @@ +{ + "exports": { + ".": "./mod.ts" + } +} diff --git a/tests/testdata/jsr/registry/@denotest/no_module_graph/meta.json b/tests/testdata/jsr/registry/@denotest/no_module_graph/meta.json new file mode 100644 index 000000000..0268b6c8a --- /dev/null +++ b/tests/testdata/jsr/registry/@denotest/no_module_graph/meta.json @@ -0,0 +1,7 @@ +{ + "versions": { + "0.1.0": {}, + "0.1.1": {}, + "0.2.0": {} + } +} diff --git a/tests/testdata/jsr/registry/@denotest/subset_type_graph/0.1.0/mod.ts b/tests/testdata/jsr/registry/@denotest/subset_type_graph/0.1.0/mod.ts new file mode 100644 index 000000000..e81b2309a --- /dev/null +++ b/tests/testdata/jsr/registry/@denotest/subset_type_graph/0.1.0/mod.ts @@ -0,0 +1,17 @@ +// add some statements that will be removed by the subset +// type graph so that we can test that the source map works +console.log(1); +console.log(2); +console.log(3); + +export class Foo { + method(): number { + return Math.random(); + } +} + +// this won't be type checked against because the subset +// type graph omit this code because it's not part of the +// public API. +const invalidTypeCheck: number = ""; +console.log(invalidTypeCheck); diff --git a/tests/testdata/jsr/registry/@denotest/subset_type_graph/0.1.0_meta.json b/tests/testdata/jsr/registry/@denotest/subset_type_graph/0.1.0_meta.json new file mode 100644 index 000000000..631a18d0e --- /dev/null +++ b/tests/testdata/jsr/registry/@denotest/subset_type_graph/0.1.0_meta.json @@ -0,0 +1,5 @@ +{ + "exports": { + ".": "./mod.ts" + } +} diff --git a/tests/testdata/jsr/registry/@denotest/subset_type_graph/meta.json b/tests/testdata/jsr/registry/@denotest/subset_type_graph/meta.json new file mode 100644 index 000000000..d10aa5c3a --- /dev/null +++ b/tests/testdata/jsr/registry/@denotest/subset_type_graph/meta.json @@ -0,0 +1,5 @@ +{ + "versions": { + "0.1.0": {} + } +} diff --git a/tests/testdata/jsr/registry/@denotest/subset_type_graph_invalid/0.1.0/mod.ts b/tests/testdata/jsr/registry/@denotest/subset_type_graph_invalid/0.1.0/mod.ts new file mode 100644 index 000000000..6a5036bf5 --- /dev/null +++ b/tests/testdata/jsr/registry/@denotest/subset_type_graph_invalid/0.1.0/mod.ts @@ -0,0 +1,12 @@ +export class Foo { + method() { + return Math.random(); + } +} + +// This will be analyzed because the method above is missing an +// explicit type which is required for the subset type graph to take +// effect. So the entire source file will be type checked against, +// causing a type error here. +const invalidTypeCheck: number = ""; +console.log(invalidTypeCheck); diff --git a/tests/testdata/jsr/registry/@denotest/subset_type_graph_invalid/0.1.0_meta.json b/tests/testdata/jsr/registry/@denotest/subset_type_graph_invalid/0.1.0_meta.json new file mode 100644 index 000000000..631a18d0e --- /dev/null +++ b/tests/testdata/jsr/registry/@denotest/subset_type_graph_invalid/0.1.0_meta.json @@ -0,0 +1,5 @@ +{ + "exports": { + ".": "./mod.ts" + } +} diff --git a/tests/testdata/jsr/registry/@denotest/subset_type_graph_invalid/meta.json b/tests/testdata/jsr/registry/@denotest/subset_type_graph_invalid/meta.json new file mode 100644 index 000000000..d10aa5c3a --- /dev/null +++ b/tests/testdata/jsr/registry/@denotest/subset_type_graph_invalid/meta.json @@ -0,0 +1,5 @@ +{ + "versions": { + "0.1.0": {} + } +} diff --git a/tests/testdata/jsr/subset_type_graph/main.check.out b/tests/testdata/jsr/subset_type_graph/main.check.out new file mode 100644 index 000000000..278884579 --- /dev/null +++ b/tests/testdata/jsr/subset_type_graph/main.check.out @@ -0,0 +1,45 @@ +Download http://127.0.0.1:4250/@denotest/subset_type_graph/meta.json +Download http://127.0.0.1:4250/@denotest/subset_type_graph_invalid/meta.json +Download http://127.0.0.1:4250/@denotest/subset_type_graph/0.1.0_meta.json +Download http://127.0.0.1:4250/@denotest/subset_type_graph_invalid/0.1.0_meta.json +[UNORDERED_START] +Download http://127.0.0.1:4250/@denotest/subset_type_graph/0.1.0/mod.ts +Download http://127.0.0.1:4250/@denotest/subset_type_graph_invalid/0.1.0/mod.ts +[UNORDERED_END] +Check file:///[WILDCARD]/subset_type_graph/main.ts +error: TS2322 [ERROR]: Type 'string' is not assignable to type 'number'. +const invalidTypeCheck: number = ""; + ~~~~~~~~~~~~~~~~ + at http://127.0.0.1:4250/@denotest/subset_type_graph_invalid/0.1.0/mod.ts:11:7 + +TS2322 [ERROR]: Type 'number' is not assignable to type 'string'. +const error1: string = new Foo1().method(); + ~~~~~~ + at file:///[WILDCARD]/subset_type_graph/main.ts:5:7 + +TS2322 [ERROR]: Type 'number' is not assignable to type 'string'. +const error2: string = new Foo2().method(); + ~~~~~~ + at file:///[WILDCARD]/subset_type_graph/main.ts:6:7 + +TS2551 [ERROR]: Property 'method2' does not exist on type 'Foo'. Did you mean 'method'? +new Foo1().method2(); + ~~~~~~~ + at file:///[WILDCARD]/subset_type_graph/main.ts:12:12 + + 'method' is declared here. + method(): number { + ~~~~~~ + at http://127.0.0.1:4250/@denotest/subset_type_graph/0.1.0/mod.ts:8:3 + +TS2551 [ERROR]: Property 'method2' does not exist on type 'Foo'. Did you mean 'method'? +new Foo2().method2(); + ~~~~~~~ + at file:///[WILDCARD]/subset_type_graph/main.ts:13:12 + + 'method' is declared here. + method() { + ~~~~~~ + at http://127.0.0.1:4250/@denotest/subset_type_graph_invalid/0.1.0/mod.ts:2:3 + +Found 5 errors. diff --git a/tests/testdata/jsr/subset_type_graph/main.ts b/tests/testdata/jsr/subset_type_graph/main.ts new file mode 100644 index 000000000..2e1614be9 --- /dev/null +++ b/tests/testdata/jsr/subset_type_graph/main.ts @@ -0,0 +1,13 @@ +import { Foo as Foo1 } from "jsr:@denotest/subset_type_graph@0.1.0"; +import { Foo as Foo2 } from "jsr:@denotest/subset_type_graph_invalid@0.1.0"; + +// these will both raise type checking errors +const error1: string = new Foo1().method(); +const error2: string = new Foo2().method(); +console.log(error1); +console.log(error2); + +// now raise some errors that will show the original code and +// these should source map to the original +new Foo1().method2(); +new Foo2().method2(); diff --git a/tests/testdata/jsr/version_not_found/main.out b/tests/testdata/jsr/version_not_found/main.out new file mode 100644 index 000000000..6a32b5d81 --- /dev/null +++ b/tests/testdata/jsr/version_not_found/main.out @@ -0,0 +1,5 @@ +Download http://127.0.0.1:4250/@denotest/deps/meta.json +Download http://127.0.0.1:4250/@denotest/deps/meta.json +error: Could not find constraint in the list of versions: @denotest/deps@0.1.4 + Specifier: jsr:@denotest/deps@0.1.4/mod.ts + at file:///[WILDCARD]/version_not_found/main.ts:1:19 diff --git a/tests/testdata/jsr/version_not_found/main.ts b/tests/testdata/jsr/version_not_found/main.ts new file mode 100644 index 000000000..a7673b744 --- /dev/null +++ b/tests/testdata/jsr/version_not_found/main.ts @@ -0,0 +1,2 @@ +import value from "jsr:@denotest/deps@0.1.4/mod.ts"; +console.log(value); diff --git a/tests/testdata/jsx/deno-jsx-error.jsonc b/tests/testdata/jsx/deno-jsx-error.jsonc new file mode 100644 index 000000000..37cb4dd91 --- /dev/null +++ b/tests/testdata/jsx/deno-jsx-error.jsonc @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "jsx": "react-jsx", + "jsxImportSource": "./nonexistent" + } +} diff --git a/tests/testdata/jsx/deno-jsx-import-map.jsonc b/tests/testdata/jsx/deno-jsx-import-map.jsonc new file mode 100644 index 000000000..5adbfa8b5 --- /dev/null +++ b/tests/testdata/jsx/deno-jsx-import-map.jsonc @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "jsx": "react-jsx", + "jsxImportSource": "jsx" + } +} diff --git a/tests/testdata/jsx/deno-jsx-precompile.jsonc b/tests/testdata/jsx/deno-jsx-precompile.jsonc new file mode 100644 index 000000000..95ae1b9f3 --- /dev/null +++ b/tests/testdata/jsx/deno-jsx-precompile.jsonc @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "jsx": "precompile", + "jsxImportSource": "jsx-precompile" + } +} diff --git a/tests/testdata/jsx/deno-jsx.json b/tests/testdata/jsx/deno-jsx.json new file mode 100644 index 000000000..311409ea3 --- /dev/null +++ b/tests/testdata/jsx/deno-jsx.json @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "jsx": "react-jsx", + "jsxImportSource": "http://localhost:4545/jsx" + } +} diff --git a/tests/testdata/jsx/deno-jsx.jsonc b/tests/testdata/jsx/deno-jsx.jsonc new file mode 100644 index 000000000..311409ea3 --- /dev/null +++ b/tests/testdata/jsx/deno-jsx.jsonc @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "jsx": "react-jsx", + "jsxImportSource": "http://localhost:4545/jsx" + } +} diff --git a/tests/testdata/jsx/deno-jsxdev-import-map.jsonc b/tests/testdata/jsx/deno-jsxdev-import-map.jsonc new file mode 100644 index 000000000..7481d5a2d --- /dev/null +++ b/tests/testdata/jsx/deno-jsxdev-import-map.jsonc @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "jsx": "react-jsxdev", + "jsxImportSource": "jsx" + } +} diff --git a/tests/testdata/jsx/deno-jsxdev.jsonc b/tests/testdata/jsx/deno-jsxdev.jsonc new file mode 100644 index 000000000..ae5bdf9f1 --- /dev/null +++ b/tests/testdata/jsx/deno-jsxdev.jsonc @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "jsx": "react-jsxdev", + "jsxImportSource": "http://localhost:4545/jsx" + } +} diff --git a/tests/testdata/jsx/deno.lock b/tests/testdata/jsx/deno.lock new file mode 100644 index 000000000..011e8fe10 --- /dev/null +++ b/tests/testdata/jsx/deno.lock @@ -0,0 +1,6 @@ +{ + "version": "2", + "remote": { + "http://localhost:4545/jsx/jsx-dev-runtime/index.ts": "183c5bf1cfb82b15fc1e8cca15593d4816035759532d851abd4476df378c8412" + } +} \ No newline at end of file diff --git a/tests/testdata/jsx/import-map-scoped.json b/tests/testdata/jsx/import-map-scoped.json new file mode 100644 index 000000000..9b2005128 --- /dev/null +++ b/tests/testdata/jsx/import-map-scoped.json @@ -0,0 +1,8 @@ +{ + "scopes": { + "../subdir/": { + "jsx/jsx-runtime": "http://localhost:4545/jsx/jsx-runtime/index.ts", + "jsx/jsx-dev-runtime": "http://localhost:4545/jsx/jsx-dev-runtime/index.ts" + } + } +} diff --git a/tests/testdata/jsx/import-map.json b/tests/testdata/jsx/import-map.json new file mode 100644 index 000000000..1bfa04e2f --- /dev/null +++ b/tests/testdata/jsx/import-map.json @@ -0,0 +1,7 @@ +{ + "imports": { + "jsx/jsx-runtime": "http://localhost:4545/jsx/jsx-runtime/index.ts", + "jsx/jsx-dev-runtime": "http://localhost:4545/jsx/jsx-dev-runtime/index.ts", + "jsx-precompile/jsx-runtime": "http://localhost:4545/jsx/jsx-precompile/index.ts" + } +} diff --git a/tests/testdata/jsx/jsx-dev-runtime/index.ts b/tests/testdata/jsx/jsx-dev-runtime/index.ts new file mode 100644 index 000000000..15e2029c8 --- /dev/null +++ b/tests/testdata/jsx/jsx-dev-runtime/index.ts @@ -0,0 +1,12 @@ +// deno-lint-ignore-file no-explicit-any +export function jsx( + _type: any, + _props: any, + _key: any, + _source: any, + _self: any, +) {} +export const jsxs = jsx; +export const jsxDEV = jsx; +export const Fragment = Symbol("Fragment"); +console.log("imported", import.meta.url); diff --git a/tests/testdata/jsx/jsx-precompile/index.ts b/tests/testdata/jsx/jsx-precompile/index.ts new file mode 100644 index 000000000..0d56095e0 --- /dev/null +++ b/tests/testdata/jsx/jsx-precompile/index.ts @@ -0,0 +1,23 @@ +// deno-lint-ignore-file no-explicit-any +export function jsx( + _type: any, + _props: any, + _key: any, + _source: any, + _self: any, +) {} +// deno-lint-ignore-file no-explicit-any +export const jsxAttr = (name: string, value: any) => `${name}="${value}"`; +// deno-lint-ignore-file no-explicit-any +export const jsxTemplate = (_template: string[], ..._exprs: any[]) => ""; +// deno-lint-ignore-file no-explicit-any +export const jsxEscape = (_value: any) => ""; +console.log("imported", import.meta.url); + +declare global { + namespace JSX { + interface IntrinsicElements { + [tagName: string]: Record; + } + } +} diff --git a/tests/testdata/jsx/jsx-runtime/index.ts b/tests/testdata/jsx/jsx-runtime/index.ts new file mode 100644 index 000000000..15e2029c8 --- /dev/null +++ b/tests/testdata/jsx/jsx-runtime/index.ts @@ -0,0 +1,12 @@ +// deno-lint-ignore-file no-explicit-any +export function jsx( + _type: any, + _props: any, + _key: any, + _source: any, + _self: any, +) {} +export const jsxs = jsx; +export const jsxDEV = jsx; +export const Fragment = Symbol("Fragment"); +console.log("imported", import.meta.url); diff --git a/tests/testdata/jupyter/install_command_not_exists.out b/tests/testdata/jupyter/install_command_not_exists.out new file mode 100644 index 000000000..1bb176e20 --- /dev/null +++ b/tests/testdata/jupyter/install_command_not_exists.out @@ -0,0 +1,5 @@ +Warning "deno jupyter" is unstable and might change in the future. +error: Failed to spawn 'jupyter' command. Is JupyterLab installed (https://jupyter.org/install) and available on the PATH? + +Caused by: +[WILDCARD] diff --git a/tests/testdata/jupyter/integration_test.ipynb b/tests/testdata/jupyter/integration_test.ipynb new file mode 100644 index 000000000..19667938c --- /dev/null +++ b/tests/testdata/jupyter/integration_test.ipynb @@ -0,0 +1,4440 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "id": "182aef1d", + "metadata": {}, + "source": [ + "# Integration Tests for Deno Jupyter\n", + "This notebook contains a number of tests to ensure that Jupyter is working as expected. You should be able to select \"Kernel -> Restart Kernel and Run All\" in Jupyter's notebook UI to run the tests." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "d7705d88", + "metadata": {}, + "source": [ + "## Passing Tests" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "669f972e", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "### Simple Tests" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "e7e8a512", + "metadata": { + "hidden": true + }, + "source": [ + "#### This test should print \"hi\".\n", + "If this doesn't work, everything else will probably fail :)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "a5d38758", + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "hi\n" + ] + } + ], + "source": [ + "console.log(\"hi\")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "bc5ce8e3", + "metadata": { + "hidden": true + }, + "source": [ + "#### Top-level await" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "f7fa885a", + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "x is \u001b[33m42\u001b[39m\n" + ] + } + ], + "source": [ + "let x = await Promise.resolve(42);\n", + "console.log(\"x is\", x);" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "c21455ae", + "metadata": { + "hidden": true + }, + "source": [ + "#### TypeScript transpiling\n", + "Credit to [typescriptlang.org](https://www.typescriptlang.org/docs/handbook/interfaces.html) for this code" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "08a17340", + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{ color: \u001b[32m\"red\"\u001b[39m, area: \u001b[33m10000\u001b[39m }" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "interface SquareConfig {\n", + " color?: string;\n", + " width?: number;\n", + "}\n", + " \n", + "function createSquare(config: SquareConfig): { color: string; area: number } {\n", + " return {\n", + " color: config.color || \"red\",\n", + " area: config.width ? config.width * config.width : 20,\n", + " };\n", + "}\n", + " \n", + "createSquare({ colour: \"red\", width: 100 });" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "eaa0ebc0", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "### Return Values" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "52876276", + "metadata": { + "hidden": true + }, + "source": [ + "#### undefined should not return a value" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "bbf2c09b", + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "undefined" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "e175c803", + "metadata": { + "hidden": true + }, + "source": [ + "#### null should return \"null\"" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "d9801d80", + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "\u001b[1mnull\u001b[22m" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "null" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "a2a716dc", + "metadata": { + "hidden": true + }, + "source": [ + "#### boolean should return the boolean" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "cfaac330", + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "\u001b[33mtrue\u001b[39m" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "true" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "8d9f1aba", + "metadata": { + "hidden": true + }, + "source": [ + "#### number should return the number" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "ec3be2da", + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "\u001b[33m42\u001b[39m" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "42" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "60965915", + "metadata": { + "hidden": true + }, + "source": [ + "#### string should return the string" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "997cf2d7", + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "\u001b[32m\"this is a test of the emergency broadcast system\"\u001b[39m" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\"this is a test of the emergency broadcast system\"" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "fe38dc27", + "metadata": { + "hidden": true + }, + "source": [ + "#### bigint should return the bigint in literal format" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "44b63807", + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "\u001b[33m31337n\u001b[39m" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "31337n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "843ccb6c", + "metadata": { + "hidden": true + }, + "source": [ + "#### symbol should return a string describing the symbol" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "e10c0d31", + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "\u001b[32mSymbol(foo)\u001b[39m" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Symbol(\"foo\")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "171b817f", + "metadata": { + "hidden": true + }, + "source": [ + "#### object should describe the object inspection" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "81c99233", + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{ foo: \u001b[32m\"bar\"\u001b[39m }" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "{foo: \"bar\"}" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "6caeb583", + "metadata": { + "hidden": true + }, + "source": [ + "#### resolve returned promise" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "43c1581b", + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Promise { \u001b[32m\"it worked!\"\u001b[39m }" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Promise.resolve(\"it worked!\")" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "9a34b725", + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Promise {\n", + " \u001b[36m\u001b[39m Error: it failed!\n", + " at :2:16\n", + "}" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Promise.reject(new Error(\"it failed!\"));" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "b5c7b819", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "ename": "Error", + "evalue": "this is a test", + "output_type": "error", + "traceback": [ + "Stack trace:", + "Error: this is a test", + " at foo (:3:9)", + " at :4:3" + ] + } + ], + "source": [ + "(function foo() {\n", + " throw new Error(\"this is a test\")\n", + "})()" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "14844fc9-536e-4121-a9bd-fc2d3f7b6395", + "metadata": {}, + "outputs": [ + { + "ename": "Unknown error", + "evalue": "a party", + "output_type": "error", + "traceback": [ + "Stack trace:", + "\"a party\"", + " at " + ] + } + ], + "source": [ + "throw \"a party\"" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "72d01fdd", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Promise { \u001b[36m\u001b[39m }" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Deno.readFile(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "28cf59d0-6908-4edc-bb10-c325beeee362", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello from Deno!\n" + ] + } + ], + "source": [ + "console.log(\"Hello from Deno!\")" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "8d5485c3-0da3-43fe-8ef5-a61e672f5e81", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[48;2;21;128;61m\u001b[37m Hello Deno \u001b[0m\n" + ] + } + ], + "source": [ + "console.log(\"%c Hello Deno \", \"background-color: #15803d; color: white;\");" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "1401d9d5-6994-4c7b-b55a-db3c16a1e2dc", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\u001b[32m\"Cool 🫡\"\u001b[39m" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\"Cool 🫡\"" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "7afdaa0a-a2a0-4f52-8c7d-b6c5f237aa0d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "┌───────┬────────┐\n", + "│ (idx) │ Values │\n", + "├───────┼────────┤\n", + "│ 0 │ 1 │\n", + "│ 1 │ 2 │\n", + "│ 2 │ 3 │\n", + "└───────┴────────┘\n" + ] + } + ], + "source": [ + "console.table([1, 2, 3])" + ] + }, + { + "cell_type": "markdown", + "id": "9f38f1eb", + "metadata": {}, + "source": [ + "## Unit Tests With `Deno.test()`" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "b33808fd", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "passing test ... \u001b[0m\u001b[32mok\u001b[0m \u001b[0m\u001b[38;5;245m(1ms)\u001b[0m\n", + "passing test with steps ...\n", + " step 1 ... \u001b[0m\u001b[32mok\u001b[0m \u001b[0m\u001b[38;5;245m(1ms)\u001b[0m\n", + " step 2 ... \u001b[0m\u001b[32mok\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + "passing test with steps ... \u001b[0m\u001b[32mok\u001b[0m \u001b[0m\u001b[38;5;245m(1ms)\u001b[0m\n", + "failing test ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(2ms)\u001b[0m\n", + "\n", + "\u001b[0m\u001b[1m\u001b[37m\u001b[41m ERRORS \u001b[0m\n", + "\n", + "failing test \u001b[0m\u001b[38;5;245m=> :7:6\u001b[0m\n", + "\u001b[0m\u001b[1m\u001b[31merror\u001b[0m: Error: some message\n", + " at \u001b[0m\u001b[36m\u001b[0m:\u001b[0m\u001b[33m8\u001b[0m:\u001b[0m\u001b[33m9\u001b[0m\n", + "\n", + "\u001b[0m\u001b[1m\u001b[37m\u001b[41m FAILURES \u001b[0m\n", + "\n", + "failing test \u001b[0m\u001b[38;5;245m=> :7:6\u001b[0m\n", + "\n", + "\u001b[0m\u001b[31mFAILED\u001b[0m | 2 passed (2 steps) | 1 failed \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n" + ] + } + ], + "source": [ + "Deno.test(\"passing test\", () => {});\n", + "\n", + "Deno.test(\"passing test with steps\", async (t) => {\n", + " await t.step(\"step 1\", () => {});\n", + " await t.step(\"step 2\", () => {});\n", + "});\n", + "\n", + "Deno.test(\"failing test\", () => {\n", + " throw new Error(\"some message\");\n", + "});\n" + ] + }, + { + "cell_type": "markdown", + "id": "8822eed9-a801-4c1b-81c0-00e4ff180f40", + "metadata": {}, + "source": [ + "## Broadcasting Display Updates" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "8e93df23-06eb-414b-98d4-51fbebb53d1f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "Complete ✅" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "await Deno.jupyter.broadcast(\"display_data\", {\n", + " data: { \"text/html\": \"Processing.\" },\n", + " metadata: {},\n", + " transient: { display_id: \"progress\" }\n", + "});\n", + "\n", + "await new Promise((resolve) => setTimeout(resolve, 500));\n", + "\n", + "await Deno.jupyter.broadcast(\"update_display_data\", {\n", + " data: { \"text/html\": \"Processing..\" },\n", + " metadata: {},\n", + " transient: { display_id: \"progress\" }\n", + "});\n", + "\n", + "await new Promise((resolve) => setTimeout(resolve, 500));\n", + "\n", + "await Deno.jupyter.broadcast(\"update_display_data\", {\n", + " data: { \"text/html\": \"Processing...\" },\n", + " metadata: {},\n", + " transient: { display_id: \"progress\" }\n", + "});\n", + "\n", + "await new Promise((resolve) => setTimeout(resolve, 500));\n", + "\n", + "await Deno.jupyter.broadcast(\"update_display_data\", {\n", + " data: { \"text/html\": \"Complete ✅\" },\n", + " metadata: {},\n", + " transient: { display_id: \"progress\" }\n", + "});" + ] + }, + { + "cell_type": "markdown", + "id": "c0eaa476-b9c8-4d00-8a97-24e6b8e861fd", + "metadata": {}, + "source": [ + "## Comms" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "6e9b530f-554d-4ef7-a5d6-69432283fd40", + "metadata": {}, + "outputs": [], + "source": [ + "// Smoke test: Send example Jupyter Widgets messages with \"extra\" context.\n", + "// No return because we don't have a front-end widget to get the message from.\n", + "await Deno.jupyter.broadcast(\n", + " \"comm_open\",\n", + " {\n", + " \"comm_id\": \"foo\",\n", + " \"target_name\": \"jupyter.widget\",\n", + " \"data\": {\n", + " \"state\": {},\n", + " },\n", + " },\n", + " {\n", + " \"metadata\": { \"version\": \"2.1.0\" },\n", + " },\n", + ");\n", + "\n", + "await Deno.jupyter.broadcast(\n", + " \"comm_msg\",\n", + " {\n", + " \"comm_id\": \"foo\",\n", + " \"data\": {\n", + " \"method\": \"update\",\n", + " \"state\": { \"answer\": null },\n", + " \"buffer_paths\": [[\"answer\"]]\n", + " },\n", + " },\n", + " {\n", + " \"buffers\": [new Uint8Array([42])],\n", + " },\n", + ");" + ] + }, + { + "cell_type": "markdown", + "id": "05d9729c-c2e7-4a4c-8d6a-59782ed9ff11", + "metadata": {}, + "source": [ + "## Rich Classes" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "f678313e-06c6-4fb8-a4ef-54a417129a82", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "class SuperColor {\n", + " constructor() {\n", + " this.color = \"#ff5398\"\n", + " }\n", + " hex() {\n", + " return this.color\n", + " }\n", + " \n", + " [Symbol.for(\"Jupyter.display\")]() {\n", + " return {\n", + " \"text/html\": `
`\n", + " }\n", + " }\n", + "}\n", + "\n", + "let sc = new SuperColor()\n", + "sc" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "c1296291-a3e8-457b-8329-6cc58a1e528a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "class SuperColorAsync {\n", + " constructor() {\n", + " this.color = \"#5398ff\"\n", + " }\n", + " hex() {\n", + " return this.color\n", + " }\n", + " \n", + " async [Symbol.for(\"Jupyter.display\")]() {\n", + " return {\n", + " \"text/html\": `
`\n", + " }\n", + " }\n", + "}\n", + "\n", + "let sc = new SuperColorAsync()\n", + "sc" + ] + }, + { + "cell_type": "markdown", + "id": "60b7d0da-53bf-4b42-a7d1-8370c7e2314d", + "metadata": {}, + "source": [ + "## Some classes will have built in support / handling via `Deno.jupyter.format` under the hood." + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "a46fb36b-bdf4-48d9-ae8c-9842d23b5456", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.dataresource+json": { + "data": [ + { + "abbrev": "Kos.", + "abbrev_len": 4, + "adm0_a3": "KOS", + "adm0_a3_is": "SRB", + "adm0_a3_un": -99, + "adm0_a3_us": "KOS", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Kosovo", + "brk_a3": "B57", + "brk_diff": 1, + "brk_group": null, + "brk_name": "Kosovo", + "continent": "Europe", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Kosovo", + "formal_fr": null, + "gdp_md_est": 5352, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Kosovo", + "gu_a3": "KOS", + "homepart": 1, + "income_grp": "4. Lower middle income", + "iso_a2": "-99", + "iso_a3": "-99", + "iso_n3": -99, + "labelrank": 6, + "lastcensus": 1981, + "level": 2, + "long_len": 6, + "mapcolor13": 11, + "mapcolor7": 2, + "mapcolor8": 2, + "mapcolor9": 3, + "name": "Kosovo", + "name_alt": null, + "name_len": 6, + "name_long": "Kosovo", + "name_sort": "Kosovo", + "note_adm0": null, + "note_brk": "Self admin.; Claimed by Serbia", + "pop_est": 1804838, + "pop_year": -99, + "postal": "KO", + "region_un": "Europe", + "region_wb": "Europe & Central Asia", + "scalerank": 1, + "sov_a3": "KOS", + "sovereignt": "Kosovo", + "su_a3": "KOS", + "su_dif": 0, + "subregion": "Southern Europe", + "subunit": "Kosovo", + "tiny": -99, + "type": "Sovereign country", + "un_a3": -99, + "wb_a2": "KV", + "wb_a3": "KSV", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Solnd.", + "abbrev_len": 6, + "adm0_a3": "SOL", + "adm0_a3_is": "SOM", + "adm0_a3_un": -99, + "adm0_a3_us": "SOM", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Somaliland", + "brk_a3": "B30", + "brk_diff": 1, + "brk_group": null, + "brk_name": "Somaliland", + "continent": "Africa", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Somaliland", + "formal_fr": null, + "gdp_md_est": 12250, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Somaliland", + "gu_a3": "SOL", + "homepart": 1, + "income_grp": "4. Lower middle income", + "iso_a2": "-99", + "iso_a3": "-99", + "iso_n3": -99, + "labelrank": 5, + "lastcensus": -99, + "level": 2, + "long_len": 10, + "mapcolor13": 2, + "mapcolor7": 3, + "mapcolor8": 6, + "mapcolor9": 5, + "name": "Somaliland", + "name_alt": null, + "name_len": 10, + "name_long": "Somaliland", + "name_sort": "Somaliland", + "note_adm0": "Self admin.", + "note_brk": "Self admin.; Claimed by Somalia", + "pop_est": 3500000, + "pop_year": -99, + "postal": "SL", + "region_un": "Africa", + "region_wb": "Sub-Saharan Africa", + "scalerank": 1, + "sov_a3": "SOL", + "sovereignt": "Somaliland", + "su_a3": "SOL", + "su_dif": 0, + "subregion": "Eastern Africa", + "subunit": "Somaliland", + "tiny": -99, + "type": "Indeterminate", + "un_a3": -99, + "wb_a2": "-99", + "wb_a3": "-99", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "N. Cy.", + "abbrev_len": 6, + "adm0_a3": "CYN", + "adm0_a3_is": "CYP", + "adm0_a3_un": -99, + "adm0_a3_us": "CYP", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Northern Cyprus", + "brk_a3": "B20", + "brk_diff": 1, + "brk_group": null, + "brk_name": "N. Cyprus", + "continent": "Asia", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Turkish Republic of Northern Cyprus", + "formal_fr": null, + "gdp_md_est": 3600, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Northern Cyprus", + "gu_a3": "CYN", + "homepart": 1, + "income_grp": "3. Upper middle income", + "iso_a2": "-99", + "iso_a3": "-99", + "iso_n3": -99, + "labelrank": 6, + "lastcensus": -99, + "level": 2, + "long_len": 15, + "mapcolor13": 8, + "mapcolor7": 3, + "mapcolor8": 1, + "mapcolor9": 4, + "name": "N. Cyprus", + "name_alt": null, + "name_len": 9, + "name_long": "Northern Cyprus", + "name_sort": "Cyprus, Northern", + "note_adm0": "Self admin.", + "note_brk": "Self admin.; Claimed by Cyprus", + "pop_est": 265100, + "pop_year": -99, + "postal": "CN", + "region_un": "Asia", + "region_wb": "Europe & Central Asia", + "scalerank": 1, + "sov_a3": "CYN", + "sovereignt": "Northern Cyprus", + "su_a3": "CYN", + "su_dif": 0, + "subregion": "Western Asia", + "subunit": "Northern Cyprus", + "tiny": -99, + "type": "Sovereign country", + "un_a3": -99, + "wb_a2": "-99", + "wb_a3": "-99", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Afg.", + "abbrev_len": 4, + "adm0_a3": "AFG", + "adm0_a3_is": "AFG", + "adm0_a3_un": -99, + "adm0_a3_us": "AFG", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Afghanistan", + "brk_a3": "AFG", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Afghanistan", + "continent": "Asia", + "economy": "7. Least developed region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Islamic State of Afghanistan", + "formal_fr": null, + "gdp_md_est": 22270, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Afghanistan", + "gu_a3": "AFG", + "homepart": 1, + "income_grp": "5. Low income", + "iso_a2": "AF", + "iso_a3": "AFG", + "iso_n3": 4, + "labelrank": 3, + "lastcensus": 1979, + "level": 2, + "long_len": 11, + "mapcolor13": 7, + "mapcolor7": 5, + "mapcolor8": 6, + "mapcolor9": 8, + "name": "Afghanistan", + "name_alt": null, + "name_len": 11, + "name_long": "Afghanistan", + "name_sort": "Afghanistan", + "note_adm0": null, + "note_brk": null, + "pop_est": 28400000, + "pop_year": -99, + "postal": "AF", + "region_un": "Asia", + "region_wb": "South Asia", + "scalerank": 1, + "sov_a3": "AFG", + "sovereignt": "Afghanistan", + "su_a3": "AFG", + "su_dif": 0, + "subregion": "Southern Asia", + "subunit": "Afghanistan", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 4, + "wb_a2": "AF", + "wb_a3": "AFG", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Ang.", + "abbrev_len": 4, + "adm0_a3": "AGO", + "adm0_a3_is": "AGO", + "adm0_a3_un": -99, + "adm0_a3_us": "AGO", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Angola", + "brk_a3": "AGO", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Angola", + "continent": "Africa", + "economy": "7. Least developed region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "People's Republic of Angola", + "formal_fr": null, + "gdp_md_est": 110300, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Angola", + "gu_a3": "AGO", + "homepart": 1, + "income_grp": "3. Upper middle income", + "iso_a2": "AO", + "iso_a3": "AGO", + "iso_n3": 24, + "labelrank": 3, + "lastcensus": 1970, + "level": 2, + "long_len": 6, + "mapcolor13": 1, + "mapcolor7": 3, + "mapcolor8": 2, + "mapcolor9": 6, + "name": "Angola", + "name_alt": null, + "name_len": 6, + "name_long": "Angola", + "name_sort": "Angola", + "note_adm0": null, + "note_brk": null, + "pop_est": 12799293, + "pop_year": -99, + "postal": "AO", + "region_un": "Africa", + "region_wb": "Sub-Saharan Africa", + "scalerank": 1, + "sov_a3": "AGO", + "sovereignt": "Angola", + "su_a3": "AGO", + "su_dif": 0, + "subregion": "Middle Africa", + "subunit": "Angola", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 24, + "wb_a2": "AO", + "wb_a3": "AGO", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Alb.", + "abbrev_len": 4, + "adm0_a3": "ALB", + "adm0_a3_is": "ALB", + "adm0_a3_un": -99, + "adm0_a3_us": "ALB", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Albania", + "brk_a3": "ALB", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Albania", + "continent": "Europe", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Albania", + "formal_fr": null, + "gdp_md_est": 21810, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Albania", + "gu_a3": "ALB", + "homepart": 1, + "income_grp": "4. Lower middle income", + "iso_a2": "AL", + "iso_a3": "ALB", + "iso_n3": 8, + "labelrank": 6, + "lastcensus": 2001, + "level": 2, + "long_len": 7, + "mapcolor13": 6, + "mapcolor7": 1, + "mapcolor8": 4, + "mapcolor9": 1, + "name": "Albania", + "name_alt": null, + "name_len": 7, + "name_long": "Albania", + "name_sort": "Albania", + "note_adm0": null, + "note_brk": null, + "pop_est": 3639453, + "pop_year": -99, + "postal": "AL", + "region_un": "Europe", + "region_wb": "Europe & Central Asia", + "scalerank": 1, + "sov_a3": "ALB", + "sovereignt": "Albania", + "su_a3": "ALB", + "su_dif": 0, + "subregion": "Southern Europe", + "subunit": "Albania", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 8, + "wb_a2": "AL", + "wb_a3": "ALB", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "U.A.E.", + "abbrev_len": 6, + "adm0_a3": "ARE", + "adm0_a3_is": "ARE", + "adm0_a3_un": -99, + "adm0_a3_us": "ARE", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "United Arab Emirates", + "brk_a3": "ARE", + "brk_diff": 0, + "brk_group": null, + "brk_name": "United Arab Emirates", + "continent": "Asia", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "United Arab Emirates", + "formal_fr": null, + "gdp_md_est": 184300, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "United Arab Emirates", + "gu_a3": "ARE", + "homepart": 1, + "income_grp": "2. High income: nonOECD", + "iso_a2": "AE", + "iso_a3": "ARE", + "iso_n3": 784, + "labelrank": 4, + "lastcensus": 2010, + "level": 2, + "long_len": 20, + "mapcolor13": 3, + "mapcolor7": 2, + "mapcolor8": 1, + "mapcolor9": 3, + "name": "United Arab Emirates", + "name_alt": null, + "name_len": 20, + "name_long": "United Arab Emirates", + "name_sort": "United Arab Emirates", + "note_adm0": null, + "note_brk": null, + "pop_est": 4798491, + "pop_year": -99, + "postal": "AE", + "region_un": "Asia", + "region_wb": "Middle East & North Africa", + "scalerank": 1, + "sov_a3": "ARE", + "sovereignt": "United Arab Emirates", + "su_a3": "ARE", + "su_dif": 0, + "subregion": "Western Asia", + "subunit": "United Arab Emirates", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 784, + "wb_a2": "AE", + "wb_a3": "ARE", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Arg.", + "abbrev_len": 4, + "adm0_a3": "ARG", + "adm0_a3_is": "ARG", + "adm0_a3_un": -99, + "adm0_a3_us": "ARG", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Argentina", + "brk_a3": "ARG", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Argentina", + "continent": "South America", + "economy": "5. Emerging region: G20", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Argentine Republic", + "formal_fr": null, + "gdp_md_est": 573900, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Argentina", + "gu_a3": "ARG", + "homepart": 1, + "income_grp": "3. Upper middle income", + "iso_a2": "AR", + "iso_a3": "ARG", + "iso_n3": 32, + "labelrank": 2, + "lastcensus": 2010, + "level": 2, + "long_len": 9, + "mapcolor13": 13, + "mapcolor7": 3, + "mapcolor8": 1, + "mapcolor9": 3, + "name": "Argentina", + "name_alt": null, + "name_len": 9, + "name_long": "Argentina", + "name_sort": "Argentina", + "note_adm0": null, + "note_brk": null, + "pop_est": 40913584, + "pop_year": -99, + "postal": "AR", + "region_un": "Americas", + "region_wb": "Latin America & Caribbean", + "scalerank": 1, + "sov_a3": "ARG", + "sovereignt": "Argentina", + "su_a3": "ARG", + "su_dif": 0, + "subregion": "South America", + "subunit": "Argentina", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 32, + "wb_a2": "AR", + "wb_a3": "ARG", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Arm.", + "abbrev_len": 4, + "adm0_a3": "ARM", + "adm0_a3_is": "ARM", + "adm0_a3_un": -99, + "adm0_a3_us": "ARM", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Armenia", + "brk_a3": "ARM", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Armenia", + "continent": "Asia", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Armenia", + "formal_fr": null, + "gdp_md_est": 18770, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Armenia", + "gu_a3": "ARM", + "homepart": 1, + "income_grp": "4. Lower middle income", + "iso_a2": "AM", + "iso_a3": "ARM", + "iso_n3": 51, + "labelrank": 6, + "lastcensus": 2001, + "level": 2, + "long_len": 7, + "mapcolor13": 10, + "mapcolor7": 3, + "mapcolor8": 1, + "mapcolor9": 2, + "name": "Armenia", + "name_alt": null, + "name_len": 7, + "name_long": "Armenia", + "name_sort": "Armenia", + "note_adm0": null, + "note_brk": null, + "pop_est": 2967004, + "pop_year": -99, + "postal": "ARM", + "region_un": "Asia", + "region_wb": "Europe & Central Asia", + "scalerank": 1, + "sov_a3": "ARM", + "sovereignt": "Armenia", + "su_a3": "ARM", + "su_dif": 0, + "subregion": "Western Asia", + "subunit": "Armenia", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 51, + "wb_a2": "AM", + "wb_a3": "ARM", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Ant.", + "abbrev_len": 4, + "adm0_a3": "ATA", + "adm0_a3_is": "ATA", + "adm0_a3_un": -99, + "adm0_a3_us": "ATA", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Antarctica", + "brk_a3": "ATA", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Antarctica", + "continent": "Antarctica", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": null, + "formal_fr": null, + "gdp_md_est": 760.4, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Antarctica", + "gu_a3": "ATA", + "homepart": 1, + "income_grp": "2. High income: nonOECD", + "iso_a2": "AQ", + "iso_a3": "ATA", + "iso_n3": 10, + "labelrank": 4, + "lastcensus": -99, + "level": 2, + "long_len": 10, + "mapcolor13": -99, + "mapcolor7": 4, + "mapcolor8": 5, + "mapcolor9": 1, + "name": "Antarctica", + "name_alt": null, + "name_len": 10, + "name_long": "Antarctica", + "name_sort": "Antarctica", + "note_adm0": null, + "note_brk": "Multiple claims held in abeyance", + "pop_est": 3802, + "pop_year": -99, + "postal": "AQ", + "region_un": "Antarctica", + "region_wb": "Antarctica", + "scalerank": 1, + "sov_a3": "ATA", + "sovereignt": "Antarctica", + "su_a3": "ATA", + "su_dif": 0, + "subregion": "Antarctica", + "subunit": "Antarctica", + "tiny": -99, + "type": "Indeterminate", + "un_a3": -99, + "wb_a2": "-99", + "wb_a3": "-99", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Fr. S.A.L.", + "abbrev_len": 10, + "adm0_a3": "ATF", + "adm0_a3_is": "ATF", + "adm0_a3_un": -99, + "adm0_a3_us": "ATF", + "adm0_a3_wb": -99, + "adm0_dif": 1, + "admin": "French Southern and Antarctic Lands", + "brk_a3": "ATF", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Fr. S. and Antarctic Lands", + "continent": "Seven seas (open ocean)", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Territory of the French Southern and Antarctic Lands", + "formal_fr": null, + "gdp_md_est": 16, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "French Southern and Antarctic Lands", + "gu_a3": "ATF", + "homepart": -99, + "income_grp": "2. High income: nonOECD", + "iso_a2": "TF", + "iso_a3": "ATF", + "iso_n3": 260, + "labelrank": 6, + "lastcensus": -99, + "level": 2, + "long_len": 35, + "mapcolor13": 11, + "mapcolor7": 7, + "mapcolor8": 5, + "mapcolor9": 9, + "name": "Fr. S. Antarctic Lands", + "name_alt": null, + "name_len": 22, + "name_long": "French Southern and Antarctic Lands", + "name_sort": "French Southern and Antarctic Lands", + "note_adm0": "Fr.", + "note_brk": null, + "pop_est": 140, + "pop_year": -99, + "postal": "TF", + "region_un": "Seven seas (open ocean)", + "region_wb": "Sub-Saharan Africa", + "scalerank": 3, + "sov_a3": "FR1", + "sovereignt": "France", + "su_a3": "ATF", + "su_dif": 0, + "subregion": "Seven seas (open ocean)", + "subunit": "French Southern and Antarctic Lands", + "tiny": 2, + "type": "Dependency", + "un_a3": -99, + "wb_a2": "-99", + "wb_a3": "-99", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Auz.", + "abbrev_len": 4, + "adm0_a3": "AUS", + "adm0_a3_is": "AUS", + "adm0_a3_un": -99, + "adm0_a3_us": "AUS", + "adm0_a3_wb": -99, + "adm0_dif": 1, + "admin": "Australia", + "brk_a3": "AUS", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Australia", + "continent": "Oceania", + "economy": "2. Developed region: nonG7", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Commonwealth of Australia", + "formal_fr": null, + "gdp_md_est": 800200, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Australia", + "gu_a3": "AUS", + "homepart": 1, + "income_grp": "1. High income: OECD", + "iso_a2": "AU", + "iso_a3": "AUS", + "iso_n3": 36, + "labelrank": 2, + "lastcensus": 2006, + "level": 2, + "long_len": 9, + "mapcolor13": 7, + "mapcolor7": 1, + "mapcolor8": 2, + "mapcolor9": 2, + "name": "Australia", + "name_alt": null, + "name_len": 9, + "name_long": "Australia", + "name_sort": "Australia", + "note_adm0": null, + "note_brk": null, + "pop_est": 21262641, + "pop_year": -99, + "postal": "AU", + "region_un": "Oceania", + "region_wb": "East Asia & Pacific", + "scalerank": 1, + "sov_a3": "AU1", + "sovereignt": "Australia", + "su_a3": "AUS", + "su_dif": 0, + "subregion": "Australia and New Zealand", + "subunit": "Australia", + "tiny": -99, + "type": "Country", + "un_a3": 36, + "wb_a2": "AU", + "wb_a3": "AUS", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Aust.", + "abbrev_len": 5, + "adm0_a3": "AUT", + "adm0_a3_is": "AUT", + "adm0_a3_un": -99, + "adm0_a3_us": "AUT", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Austria", + "brk_a3": "AUT", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Austria", + "continent": "Europe", + "economy": "2. Developed region: nonG7", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Austria", + "formal_fr": null, + "gdp_md_est": 329500, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Austria", + "gu_a3": "AUT", + "homepart": 1, + "income_grp": "1. High income: OECD", + "iso_a2": "AT", + "iso_a3": "AUT", + "iso_n3": 40, + "labelrank": 4, + "lastcensus": 2011, + "level": 2, + "long_len": 7, + "mapcolor13": 4, + "mapcolor7": 3, + "mapcolor8": 1, + "mapcolor9": 3, + "name": "Austria", + "name_alt": null, + "name_len": 7, + "name_long": "Austria", + "name_sort": "Austria", + "note_adm0": null, + "note_brk": null, + "pop_est": 8210281, + "pop_year": -99, + "postal": "A", + "region_un": "Europe", + "region_wb": "Europe & Central Asia", + "scalerank": 1, + "sov_a3": "AUT", + "sovereignt": "Austria", + "su_a3": "AUT", + "su_dif": 0, + "subregion": "Western Europe", + "subunit": "Austria", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 40, + "wb_a2": "AT", + "wb_a3": "AUT", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Aze.", + "abbrev_len": 4, + "adm0_a3": "AZE", + "adm0_a3_is": "AZE", + "adm0_a3_un": -99, + "adm0_a3_us": "AZE", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Azerbaijan", + "brk_a3": "AZE", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Azerbaijan", + "continent": "Asia", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Azerbaijan", + "formal_fr": null, + "gdp_md_est": 77610, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Azerbaijan", + "gu_a3": "AZE", + "homepart": 1, + "income_grp": "3. Upper middle income", + "iso_a2": "AZ", + "iso_a3": "AZE", + "iso_n3": 31, + "labelrank": 5, + "lastcensus": 2009, + "level": 2, + "long_len": 10, + "mapcolor13": 8, + "mapcolor7": 1, + "mapcolor8": 6, + "mapcolor9": 5, + "name": "Azerbaijan", + "name_alt": null, + "name_len": 10, + "name_long": "Azerbaijan", + "name_sort": "Azerbaijan", + "note_adm0": null, + "note_brk": null, + "pop_est": 8238672, + "pop_year": -99, + "postal": "AZ", + "region_un": "Asia", + "region_wb": "Europe & Central Asia", + "scalerank": 1, + "sov_a3": "AZE", + "sovereignt": "Azerbaijan", + "su_a3": "AZE", + "su_dif": 0, + "subregion": "Western Asia", + "subunit": "Azerbaijan", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 31, + "wb_a2": "AZ", + "wb_a3": "AZE", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Bur.", + "abbrev_len": 4, + "adm0_a3": "BDI", + "adm0_a3_is": "BDI", + "adm0_a3_un": -99, + "adm0_a3_us": "BDI", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Burundi", + "brk_a3": "BDI", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Burundi", + "continent": "Africa", + "economy": "7. Least developed region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Burundi", + "formal_fr": null, + "gdp_md_est": 3102, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Burundi", + "gu_a3": "BDI", + "homepart": 1, + "income_grp": "5. Low income", + "iso_a2": "BI", + "iso_a3": "BDI", + "iso_n3": 108, + "labelrank": 6, + "lastcensus": 2008, + "level": 2, + "long_len": 7, + "mapcolor13": 8, + "mapcolor7": 2, + "mapcolor8": 2, + "mapcolor9": 5, + "name": "Burundi", + "name_alt": null, + "name_len": 7, + "name_long": "Burundi", + "name_sort": "Burundi", + "note_adm0": null, + "note_brk": null, + "pop_est": 8988091, + "pop_year": -99, + "postal": "BI", + "region_un": "Africa", + "region_wb": "Sub-Saharan Africa", + "scalerank": 1, + "sov_a3": "BDI", + "sovereignt": "Burundi", + "su_a3": "BDI", + "su_dif": 0, + "subregion": "Eastern Africa", + "subunit": "Burundi", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 108, + "wb_a2": "BI", + "wb_a3": "BDI", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Belg.", + "abbrev_len": 5, + "adm0_a3": "BEL", + "adm0_a3_is": "BEL", + "adm0_a3_un": -99, + "adm0_a3_us": "BEL", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Belgium", + "brk_a3": "BEL", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Belgium", + "continent": "Europe", + "economy": "2. Developed region: nonG7", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Kingdom of Belgium", + "formal_fr": null, + "gdp_md_est": 389300, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Belgium", + "gu_a3": "BEL", + "homepart": 1, + "income_grp": "1. High income: OECD", + "iso_a2": "BE", + "iso_a3": "BEL", + "iso_n3": 56, + "labelrank": 2, + "lastcensus": 2011, + "level": 2, + "long_len": 7, + "mapcolor13": 8, + "mapcolor7": 3, + "mapcolor8": 2, + "mapcolor9": 1, + "name": "Belgium", + "name_alt": null, + "name_len": 7, + "name_long": "Belgium", + "name_sort": "Belgium", + "note_adm0": null, + "note_brk": null, + "pop_est": 10414336, + "pop_year": -99, + "postal": "B", + "region_un": "Europe", + "region_wb": "Europe & Central Asia", + "scalerank": 1, + "sov_a3": "BEL", + "sovereignt": "Belgium", + "su_a3": "BEL", + "su_dif": 0, + "subregion": "Western Europe", + "subunit": "Belgium", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 56, + "wb_a2": "BE", + "wb_a3": "BEL", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Benin", + "abbrev_len": 5, + "adm0_a3": "BEN", + "adm0_a3_is": "BEN", + "adm0_a3_un": -99, + "adm0_a3_us": "BEN", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Benin", + "brk_a3": "BEN", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Benin", + "continent": "Africa", + "economy": "7. Least developed region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Benin", + "formal_fr": null, + "gdp_md_est": 12830, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Benin", + "gu_a3": "BEN", + "homepart": 1, + "income_grp": "5. Low income", + "iso_a2": "BJ", + "iso_a3": "BEN", + "iso_n3": 204, + "labelrank": 5, + "lastcensus": 2002, + "level": 2, + "long_len": 5, + "mapcolor13": 12, + "mapcolor7": 1, + "mapcolor8": 2, + "mapcolor9": 2, + "name": "Benin", + "name_alt": null, + "name_len": 5, + "name_long": "Benin", + "name_sort": "Benin", + "note_adm0": null, + "note_brk": null, + "pop_est": 8791832, + "pop_year": -99, + "postal": "BJ", + "region_un": "Africa", + "region_wb": "Sub-Saharan Africa", + "scalerank": 1, + "sov_a3": "BEN", + "sovereignt": "Benin", + "su_a3": "BEN", + "su_dif": 0, + "subregion": "Western Africa", + "subunit": "Benin", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 204, + "wb_a2": "BJ", + "wb_a3": "BEN", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "B.F.", + "abbrev_len": 4, + "adm0_a3": "BFA", + "adm0_a3_is": "BFA", + "adm0_a3_un": -99, + "adm0_a3_us": "BFA", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Burkina Faso", + "brk_a3": "BFA", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Burkina Faso", + "continent": "Africa", + "economy": "7. Least developed region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Burkina Faso", + "formal_fr": null, + "gdp_md_est": 17820, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Burkina Faso", + "gu_a3": "BFA", + "homepart": 1, + "income_grp": "5. Low income", + "iso_a2": "BF", + "iso_a3": "BFA", + "iso_n3": 854, + "labelrank": 3, + "lastcensus": 2006, + "level": 2, + "long_len": 12, + "mapcolor13": 11, + "mapcolor7": 2, + "mapcolor8": 1, + "mapcolor9": 5, + "name": "Burkina Faso", + "name_alt": null, + "name_len": 12, + "name_long": "Burkina Faso", + "name_sort": "Burkina Faso", + "note_adm0": null, + "note_brk": null, + "pop_est": 15746232, + "pop_year": -99, + "postal": "BF", + "region_un": "Africa", + "region_wb": "Sub-Saharan Africa", + "scalerank": 1, + "sov_a3": "BFA", + "sovereignt": "Burkina Faso", + "su_a3": "BFA", + "su_dif": 0, + "subregion": "Western Africa", + "subunit": "Burkina Faso", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 854, + "wb_a2": "BF", + "wb_a3": "BFA", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Bang.", + "abbrev_len": 5, + "adm0_a3": "BGD", + "adm0_a3_is": "BGD", + "adm0_a3_un": -99, + "adm0_a3_us": "BGD", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Bangladesh", + "brk_a3": "BGD", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Bangladesh", + "continent": "Asia", + "economy": "7. Least developed region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "People's Republic of Bangladesh", + "formal_fr": null, + "gdp_md_est": 224000, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Bangladesh", + "gu_a3": "BGD", + "homepart": 1, + "income_grp": "5. Low income", + "iso_a2": "BD", + "iso_a3": "BGD", + "iso_n3": 50, + "labelrank": 3, + "lastcensus": 2011, + "level": 2, + "long_len": 10, + "mapcolor13": 7, + "mapcolor7": 3, + "mapcolor8": 4, + "mapcolor9": 7, + "name": "Bangladesh", + "name_alt": null, + "name_len": 10, + "name_long": "Bangladesh", + "name_sort": "Bangladesh", + "note_adm0": null, + "note_brk": null, + "pop_est": 156050883, + "pop_year": -99, + "postal": "BD", + "region_un": "Asia", + "region_wb": "South Asia", + "scalerank": 1, + "sov_a3": "BGD", + "sovereignt": "Bangladesh", + "su_a3": "BGD", + "su_dif": 0, + "subregion": "Southern Asia", + "subunit": "Bangladesh", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 50, + "wb_a2": "BD", + "wb_a3": "BGD", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Bulg.", + "abbrev_len": 5, + "adm0_a3": "BGR", + "adm0_a3_is": "BGR", + "adm0_a3_un": -99, + "adm0_a3_us": "BGR", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Bulgaria", + "brk_a3": "BGR", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Bulgaria", + "continent": "Europe", + "economy": "2. Developed region: nonG7", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Bulgaria", + "formal_fr": null, + "gdp_md_est": 93750, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Bulgaria", + "gu_a3": "BGR", + "homepart": 1, + "income_grp": "3. Upper middle income", + "iso_a2": "BG", + "iso_a3": "BGR", + "iso_n3": 100, + "labelrank": 4, + "lastcensus": 2011, + "level": 2, + "long_len": 8, + "mapcolor13": 8, + "mapcolor7": 4, + "mapcolor8": 5, + "mapcolor9": 1, + "name": "Bulgaria", + "name_alt": null, + "name_len": 8, + "name_long": "Bulgaria", + "name_sort": "Bulgaria", + "note_adm0": null, + "note_brk": null, + "pop_est": 7204687, + "pop_year": -99, + "postal": "BG", + "region_un": "Europe", + "region_wb": "Europe & Central Asia", + "scalerank": 1, + "sov_a3": "BGR", + "sovereignt": "Bulgaria", + "su_a3": "BGR", + "su_dif": 0, + "subregion": "Eastern Europe", + "subunit": "Bulgaria", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 100, + "wb_a2": "BG", + "wb_a3": "BGR", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Bhs.", + "abbrev_len": 4, + "adm0_a3": "BHS", + "adm0_a3_is": "BHS", + "adm0_a3_un": -99, + "adm0_a3_us": "BHS", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "The Bahamas", + "brk_a3": "BHS", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Bahamas", + "continent": "North America", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Commonwealth of the Bahamas", + "formal_fr": null, + "gdp_md_est": 9093, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "The Bahamas", + "gu_a3": "BHS", + "homepart": 1, + "income_grp": "2. High income: nonOECD", + "iso_a2": "BS", + "iso_a3": "BHS", + "iso_n3": 44, + "labelrank": 4, + "lastcensus": 2010, + "level": 2, + "long_len": 7, + "mapcolor13": 5, + "mapcolor7": 1, + "mapcolor8": 1, + "mapcolor9": 2, + "name": "Bahamas", + "name_alt": null, + "name_len": 7, + "name_long": "Bahamas", + "name_sort": "Bahamas, The", + "note_adm0": null, + "note_brk": null, + "pop_est": 309156, + "pop_year": -99, + "postal": "BS", + "region_un": "Americas", + "region_wb": "Latin America & Caribbean", + "scalerank": 1, + "sov_a3": "BHS", + "sovereignt": "The Bahamas", + "su_a3": "BHS", + "su_dif": 0, + "subregion": "Caribbean", + "subunit": "The Bahamas", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 44, + "wb_a2": "BS", + "wb_a3": "BHS", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "B.H.", + "abbrev_len": 4, + "adm0_a3": "BIH", + "adm0_a3_is": "BIH", + "adm0_a3_un": -99, + "adm0_a3_us": "BIH", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Bosnia and Herzegovina", + "brk_a3": "BIH", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Bosnia and Herz.", + "continent": "Europe", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Bosnia and Herzegovina", + "formal_fr": null, + "gdp_md_est": 29700, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Bosnia and Herzegovina", + "gu_a3": "BIH", + "homepart": 1, + "income_grp": "3. Upper middle income", + "iso_a2": "BA", + "iso_a3": "BIH", + "iso_n3": 70, + "labelrank": 5, + "lastcensus": 1991, + "level": 2, + "long_len": 22, + "mapcolor13": 2, + "mapcolor7": 1, + "mapcolor8": 1, + "mapcolor9": 1, + "name": "Bosnia and Herz.", + "name_alt": null, + "name_len": 16, + "name_long": "Bosnia and Herzegovina", + "name_sort": "Bosnia and Herzegovina", + "note_adm0": null, + "note_brk": null, + "pop_est": 4613414, + "pop_year": -99, + "postal": "BiH", + "region_un": "Europe", + "region_wb": "Europe & Central Asia", + "scalerank": 1, + "sov_a3": "BIH", + "sovereignt": "Bosnia and Herzegovina", + "su_a3": "BIH", + "su_dif": 0, + "subregion": "Southern Europe", + "subunit": "Bosnia and Herzegovina", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 70, + "wb_a2": "BA", + "wb_a3": "BIH", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Bela.", + "abbrev_len": 5, + "adm0_a3": "BLR", + "adm0_a3_is": "BLR", + "adm0_a3_un": -99, + "adm0_a3_us": "BLR", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Belarus", + "brk_a3": "BLR", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Belarus", + "continent": "Europe", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Belarus", + "formal_fr": null, + "gdp_md_est": 114100, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Belarus", + "gu_a3": "BLR", + "homepart": 1, + "income_grp": "3. Upper middle income", + "iso_a2": "BY", + "iso_a3": "BLR", + "iso_n3": 112, + "labelrank": 4, + "lastcensus": 2009, + "level": 2, + "long_len": 7, + "mapcolor13": 11, + "mapcolor7": 1, + "mapcolor8": 1, + "mapcolor9": 5, + "name": "Belarus", + "name_alt": null, + "name_len": 7, + "name_long": "Belarus", + "name_sort": "Belarus", + "note_adm0": null, + "note_brk": null, + "pop_est": 9648533, + "pop_year": -99, + "postal": "BY", + "region_un": "Europe", + "region_wb": "Europe & Central Asia", + "scalerank": 1, + "sov_a3": "BLR", + "sovereignt": "Belarus", + "su_a3": "BLR", + "su_dif": 0, + "subregion": "Eastern Europe", + "subunit": "Belarus", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 112, + "wb_a2": "BY", + "wb_a3": "BLR", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Belize", + "abbrev_len": 6, + "adm0_a3": "BLZ", + "adm0_a3_is": "BLZ", + "adm0_a3_un": -99, + "adm0_a3_us": "BLZ", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Belize", + "brk_a3": "BLZ", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Belize", + "continent": "North America", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Belize", + "formal_fr": null, + "gdp_md_est": 2536, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Belize", + "gu_a3": "BLZ", + "homepart": 1, + "income_grp": "4. Lower middle income", + "iso_a2": "BZ", + "iso_a3": "BLZ", + "iso_n3": 84, + "labelrank": 6, + "lastcensus": 2010, + "level": 2, + "long_len": 6, + "mapcolor13": 7, + "mapcolor7": 1, + "mapcolor8": 4, + "mapcolor9": 5, + "name": "Belize", + "name_alt": null, + "name_len": 6, + "name_long": "Belize", + "name_sort": "Belize", + "note_adm0": null, + "note_brk": null, + "pop_est": 307899, + "pop_year": -99, + "postal": "BZ", + "region_un": "Americas", + "region_wb": "Latin America & Caribbean", + "scalerank": 1, + "sov_a3": "BLZ", + "sovereignt": "Belize", + "su_a3": "BLZ", + "su_dif": 0, + "subregion": "Central America", + "subunit": "Belize", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 84, + "wb_a2": "BZ", + "wb_a3": "BLZ", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Bolivia", + "abbrev_len": 7, + "adm0_a3": "BOL", + "adm0_a3_is": "BOL", + "adm0_a3_un": -99, + "adm0_a3_us": "BOL", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Bolivia", + "brk_a3": "BOL", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Bolivia", + "continent": "South America", + "economy": "5. Emerging region: G20", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Plurinational State of Bolivia", + "formal_fr": null, + "gdp_md_est": 43270, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Bolivia", + "gu_a3": "BOL", + "homepart": 1, + "income_grp": "4. Lower middle income", + "iso_a2": "BO", + "iso_a3": "BOL", + "iso_n3": 68, + "labelrank": 3, + "lastcensus": 2001, + "level": 2, + "long_len": 7, + "mapcolor13": 3, + "mapcolor7": 1, + "mapcolor8": 5, + "mapcolor9": 2, + "name": "Bolivia", + "name_alt": null, + "name_len": 7, + "name_long": "Bolivia", + "name_sort": "Bolivia", + "note_adm0": null, + "note_brk": null, + "pop_est": 9775246, + "pop_year": -99, + "postal": "BO", + "region_un": "Americas", + "region_wb": "Latin America & Caribbean", + "scalerank": 1, + "sov_a3": "BOL", + "sovereignt": "Bolivia", + "su_a3": "BOL", + "su_dif": 0, + "subregion": "South America", + "subunit": "Bolivia", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 68, + "wb_a2": "BO", + "wb_a3": "BOL", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Brazil", + "abbrev_len": 6, + "adm0_a3": "BRA", + "adm0_a3_is": "BRA", + "adm0_a3_un": -99, + "adm0_a3_us": "BRA", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Brazil", + "brk_a3": "BRA", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Brazil", + "continent": "South America", + "economy": "3. Emerging region: BRIC", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Federative Republic of Brazil", + "formal_fr": null, + "gdp_md_est": 1993000, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Brazil", + "gu_a3": "BRA", + "homepart": 1, + "income_grp": "3. Upper middle income", + "iso_a2": "BR", + "iso_a3": "BRA", + "iso_n3": 76, + "labelrank": 2, + "lastcensus": 2010, + "level": 2, + "long_len": 6, + "mapcolor13": 7, + "mapcolor7": 5, + "mapcolor8": 6, + "mapcolor9": 5, + "name": "Brazil", + "name_alt": null, + "name_len": 6, + "name_long": "Brazil", + "name_sort": "Brazil", + "note_adm0": null, + "note_brk": null, + "pop_est": 198739269, + "pop_year": -99, + "postal": "BR", + "region_un": "Americas", + "region_wb": "Latin America & Caribbean", + "scalerank": 1, + "sov_a3": "BRA", + "sovereignt": "Brazil", + "su_a3": "BRA", + "su_dif": 0, + "subregion": "South America", + "subunit": "Brazil", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 76, + "wb_a2": "BR", + "wb_a3": "BRA", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Brunei", + "abbrev_len": 6, + "adm0_a3": "BRN", + "adm0_a3_is": "BRN", + "adm0_a3_un": -99, + "adm0_a3_us": "BRN", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Brunei", + "brk_a3": "BRN", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Brunei", + "continent": "Asia", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Negara Brunei Darussalam", + "formal_fr": null, + "gdp_md_est": 20250, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Brunei", + "gu_a3": "BRN", + "homepart": 1, + "income_grp": "2. High income: nonOECD", + "iso_a2": "BN", + "iso_a3": "BRN", + "iso_n3": 96, + "labelrank": 6, + "lastcensus": 2001, + "level": 2, + "long_len": 17, + "mapcolor13": 12, + "mapcolor7": 4, + "mapcolor8": 6, + "mapcolor9": 6, + "name": "Brunei", + "name_alt": null, + "name_len": 6, + "name_long": "Brunei Darussalam", + "name_sort": "Brunei", + "note_adm0": null, + "note_brk": null, + "pop_est": 388190, + "pop_year": -99, + "postal": "BN", + "region_un": "Asia", + "region_wb": "East Asia & Pacific", + "scalerank": 1, + "sov_a3": "BRN", + "sovereignt": "Brunei", + "su_a3": "BRN", + "su_dif": 0, + "subregion": "South-Eastern Asia", + "subunit": "Brunei", + "tiny": 2, + "type": "Sovereign country", + "un_a3": 96, + "wb_a2": "BN", + "wb_a3": "BRN", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Bhutan", + "abbrev_len": 6, + "adm0_a3": "BTN", + "adm0_a3_is": "BTN", + "adm0_a3_un": -99, + "adm0_a3_us": "BTN", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Bhutan", + "brk_a3": "BTN", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Bhutan", + "continent": "Asia", + "economy": "7. Least developed region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Kingdom of Bhutan", + "formal_fr": null, + "gdp_md_est": 3524, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Bhutan", + "gu_a3": "BTN", + "homepart": 1, + "income_grp": "4. Lower middle income", + "iso_a2": "BT", + "iso_a3": "BTN", + "iso_n3": 64, + "labelrank": 5, + "lastcensus": 2005, + "level": 2, + "long_len": 6, + "mapcolor13": 8, + "mapcolor7": 5, + "mapcolor8": 6, + "mapcolor9": 1, + "name": "Bhutan", + "name_alt": null, + "name_len": 6, + "name_long": "Bhutan", + "name_sort": "Bhutan", + "note_adm0": null, + "note_brk": null, + "pop_est": 691141, + "pop_year": -99, + "postal": "BT", + "region_un": "Asia", + "region_wb": "South Asia", + "scalerank": 1, + "sov_a3": "BTN", + "sovereignt": "Bhutan", + "su_a3": "BTN", + "su_dif": 0, + "subregion": "Southern Asia", + "subunit": "Bhutan", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 64, + "wb_a2": "BT", + "wb_a3": "BTN", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Bwa.", + "abbrev_len": 4, + "adm0_a3": "BWA", + "adm0_a3_is": "BWA", + "adm0_a3_un": -99, + "adm0_a3_us": "BWA", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Botswana", + "brk_a3": "BWA", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Botswana", + "continent": "Africa", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Botswana", + "formal_fr": null, + "gdp_md_est": 27060, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Botswana", + "gu_a3": "BWA", + "homepart": 1, + "income_grp": "3. Upper middle income", + "iso_a2": "BW", + "iso_a3": "BWA", + "iso_n3": 72, + "labelrank": 4, + "lastcensus": 2011, + "level": 2, + "long_len": 8, + "mapcolor13": 3, + "mapcolor7": 6, + "mapcolor8": 5, + "mapcolor9": 7, + "name": "Botswana", + "name_alt": null, + "name_len": 8, + "name_long": "Botswana", + "name_sort": "Botswana", + "note_adm0": null, + "note_brk": null, + "pop_est": 1990876, + "pop_year": -99, + "postal": "BW", + "region_un": "Africa", + "region_wb": "Sub-Saharan Africa", + "scalerank": 1, + "sov_a3": "BWA", + "sovereignt": "Botswana", + "su_a3": "BWA", + "su_dif": 0, + "subregion": "Southern Africa", + "subunit": "Botswana", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 72, + "wb_a2": "BW", + "wb_a3": "BWA", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "C.A.R.", + "abbrev_len": 6, + "adm0_a3": "CAF", + "adm0_a3_is": "CAF", + "adm0_a3_un": -99, + "adm0_a3_us": "CAF", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Central African Republic", + "brk_a3": "CAF", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Central African Rep.", + "continent": "Africa", + "economy": "7. Least developed region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Central African Republic", + "formal_fr": null, + "gdp_md_est": 3198, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Central African Republic", + "gu_a3": "CAF", + "homepart": 1, + "income_grp": "5. Low income", + "iso_a2": "CF", + "iso_a3": "CAF", + "iso_n3": 140, + "labelrank": 4, + "lastcensus": 2003, + "level": 2, + "long_len": 24, + "mapcolor13": 9, + "mapcolor7": 5, + "mapcolor8": 6, + "mapcolor9": 6, + "name": "Central African Rep.", + "name_alt": null, + "name_len": 20, + "name_long": "Central African Republic", + "name_sort": "Central African Republic", + "note_adm0": null, + "note_brk": null, + "pop_est": 4511488, + "pop_year": -99, + "postal": "CF", + "region_un": "Africa", + "region_wb": "Sub-Saharan Africa", + "scalerank": 1, + "sov_a3": "CAF", + "sovereignt": "Central African Republic", + "su_a3": "CAF", + "su_dif": 0, + "subregion": "Middle Africa", + "subunit": "Central African Republic", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 140, + "wb_a2": "CF", + "wb_a3": "CAF", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Can.", + "abbrev_len": 4, + "adm0_a3": "CAN", + "adm0_a3_is": "CAN", + "adm0_a3_un": -99, + "adm0_a3_us": "CAN", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Canada", + "brk_a3": "CAN", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Canada", + "continent": "North America", + "economy": "1. Developed region: G7", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Canada", + "formal_fr": null, + "gdp_md_est": 1300000, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Canada", + "gu_a3": "CAN", + "homepart": 1, + "income_grp": "1. High income: OECD", + "iso_a2": "CA", + "iso_a3": "CAN", + "iso_n3": 124, + "labelrank": 2, + "lastcensus": 2011, + "level": 2, + "long_len": 6, + "mapcolor13": 2, + "mapcolor7": 6, + "mapcolor8": 6, + "mapcolor9": 2, + "name": "Canada", + "name_alt": null, + "name_len": 6, + "name_long": "Canada", + "name_sort": "Canada", + "note_adm0": null, + "note_brk": null, + "pop_est": 33487208, + "pop_year": -99, + "postal": "CA", + "region_un": "Americas", + "region_wb": "North America", + "scalerank": 1, + "sov_a3": "CAN", + "sovereignt": "Canada", + "su_a3": "CAN", + "su_dif": 0, + "subregion": "Northern America", + "subunit": "Canada", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 124, + "wb_a2": "CA", + "wb_a3": "CAN", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Switz.", + "abbrev_len": 6, + "adm0_a3": "CHE", + "adm0_a3_is": "CHE", + "adm0_a3_un": -99, + "adm0_a3_us": "CHE", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Switzerland", + "brk_a3": "CHE", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Switzerland", + "continent": "Europe", + "economy": "2. Developed region: nonG7", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Swiss Confederation", + "formal_fr": null, + "gdp_md_est": 316700, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Switzerland", + "gu_a3": "CHE", + "homepart": 1, + "income_grp": "1. High income: OECD", + "iso_a2": "CH", + "iso_a3": "CHE", + "iso_n3": 756, + "labelrank": 4, + "lastcensus": 2010, + "level": 2, + "long_len": 11, + "mapcolor13": 3, + "mapcolor7": 5, + "mapcolor8": 2, + "mapcolor9": 7, + "name": "Switzerland", + "name_alt": null, + "name_len": 11, + "name_long": "Switzerland", + "name_sort": "Switzerland", + "note_adm0": null, + "note_brk": null, + "pop_est": 7604467, + "pop_year": -99, + "postal": "CH", + "region_un": "Europe", + "region_wb": "Europe & Central Asia", + "scalerank": 1, + "sov_a3": "CHE", + "sovereignt": "Switzerland", + "su_a3": "CHE", + "su_dif": 0, + "subregion": "Western Europe", + "subunit": "Switzerland", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 756, + "wb_a2": "CH", + "wb_a3": "CHE", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Chile", + "abbrev_len": 5, + "adm0_a3": "CHL", + "adm0_a3_is": "CHL", + "adm0_a3_un": -99, + "adm0_a3_us": "CHL", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Chile", + "brk_a3": "CHL", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Chile", + "continent": "South America", + "economy": "5. Emerging region: G20", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Chile", + "formal_fr": null, + "gdp_md_est": 244500, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Chile", + "gu_a3": "CHL", + "homepart": 1, + "income_grp": "3. Upper middle income", + "iso_a2": "CL", + "iso_a3": "CHL", + "iso_n3": 152, + "labelrank": 2, + "lastcensus": 2002, + "level": 2, + "long_len": 5, + "mapcolor13": 9, + "mapcolor7": 5, + "mapcolor8": 1, + "mapcolor9": 5, + "name": "Chile", + "name_alt": null, + "name_len": 5, + "name_long": "Chile", + "name_sort": "Chile", + "note_adm0": null, + "note_brk": null, + "pop_est": 16601707, + "pop_year": -99, + "postal": "CL", + "region_un": "Americas", + "region_wb": "Latin America & Caribbean", + "scalerank": 1, + "sov_a3": "CHL", + "sovereignt": "Chile", + "su_a3": "CHL", + "su_dif": 0, + "subregion": "South America", + "subunit": "Chile", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 152, + "wb_a2": "CL", + "wb_a3": "CHL", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "China", + "abbrev_len": 5, + "adm0_a3": "CHN", + "adm0_a3_is": "CHN", + "adm0_a3_un": -99, + "adm0_a3_us": "CHN", + "adm0_a3_wb": -99, + "adm0_dif": 1, + "admin": "China", + "brk_a3": "CHN", + "brk_diff": 0, + "brk_group": null, + "brk_name": "China", + "continent": "Asia", + "economy": "3. Emerging region: BRIC", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "People's Republic of China", + "formal_fr": null, + "gdp_md_est": 7973000, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "China", + "gu_a3": "CHN", + "homepart": 1, + "income_grp": "3. Upper middle income", + "iso_a2": "CN", + "iso_a3": "CHN", + "iso_n3": 156, + "labelrank": 2, + "lastcensus": 2010, + "level": 2, + "long_len": 5, + "mapcolor13": 3, + "mapcolor7": 4, + "mapcolor8": 4, + "mapcolor9": 4, + "name": "China", + "name_alt": null, + "name_len": 5, + "name_long": "China", + "name_sort": "China", + "note_adm0": null, + "note_brk": null, + "pop_est": 1338612970, + "pop_year": -99, + "postal": "CN", + "region_un": "Asia", + "region_wb": "East Asia & Pacific", + "scalerank": 1, + "sov_a3": "CH1", + "sovereignt": "China", + "su_a3": "CHN", + "su_dif": 0, + "subregion": "Eastern Asia", + "subunit": "China", + "tiny": -99, + "type": "Country", + "un_a3": 156, + "wb_a2": "CN", + "wb_a3": "CHN", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "I.C.", + "abbrev_len": 4, + "adm0_a3": "CIV", + "adm0_a3_is": "CIV", + "adm0_a3_un": -99, + "adm0_a3_us": "CIV", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Ivory Coast", + "brk_a3": "CIV", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Côte d'Ivoire", + "continent": "Africa", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Ivory Coast", + "formal_fr": "Republic of Cote D'Ivoire", + "gdp_md_est": 33850, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Ivory Coast", + "gu_a3": "CIV", + "homepart": 1, + "income_grp": "4. Lower middle income", + "iso_a2": "CI", + "iso_a3": "CIV", + "iso_n3": 384, + "labelrank": 3, + "lastcensus": 1998, + "level": 2, + "long_len": 13, + "mapcolor13": 3, + "mapcolor7": 4, + "mapcolor8": 6, + "mapcolor9": 3, + "name": "Côte d'Ivoire", + "name_alt": null, + "name_len": 13, + "name_long": "Côte d'Ivoire", + "name_sort": "Côte d'Ivoire", + "note_adm0": null, + "note_brk": null, + "pop_est": 20617068, + "pop_year": -99, + "postal": "CI", + "region_un": "Africa", + "region_wb": "Sub-Saharan Africa", + "scalerank": 1, + "sov_a3": "CIV", + "sovereignt": "Ivory Coast", + "su_a3": "CIV", + "su_dif": 0, + "subregion": "Western Africa", + "subunit": "Ivory Coast", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 384, + "wb_a2": "CI", + "wb_a3": "CIV", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Cam.", + "abbrev_len": 4, + "adm0_a3": "CMR", + "adm0_a3_is": "CMR", + "adm0_a3_un": -99, + "adm0_a3_us": "CMR", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Cameroon", + "brk_a3": "CMR", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Cameroon", + "continent": "Africa", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Cameroon", + "formal_fr": null, + "gdp_md_est": 42750, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Cameroon", + "gu_a3": "CMR", + "homepart": 1, + "income_grp": "4. Lower middle income", + "iso_a2": "CM", + "iso_a3": "CMR", + "iso_n3": 120, + "labelrank": 3, + "lastcensus": 2005, + "level": 2, + "long_len": 8, + "mapcolor13": 3, + "mapcolor7": 1, + "mapcolor8": 4, + "mapcolor9": 1, + "name": "Cameroon", + "name_alt": null, + "name_len": 8, + "name_long": "Cameroon", + "name_sort": "Cameroon", + "note_adm0": null, + "note_brk": null, + "pop_est": 18879301, + "pop_year": -99, + "postal": "CM", + "region_un": "Africa", + "region_wb": "Sub-Saharan Africa", + "scalerank": 1, + "sov_a3": "CMR", + "sovereignt": "Cameroon", + "su_a3": "CMR", + "su_dif": 0, + "subregion": "Middle Africa", + "subunit": "Cameroon", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 120, + "wb_a2": "CM", + "wb_a3": "CMR", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "D.R.C.", + "abbrev_len": 6, + "adm0_a3": "COD", + "adm0_a3_is": "COD", + "adm0_a3_un": -99, + "adm0_a3_us": "COD", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Democratic Republic of the Congo", + "brk_a3": "COD", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Democratic Republic of the Congo", + "continent": "Africa", + "economy": "7. Least developed region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Democratic Republic of the Congo", + "formal_fr": null, + "gdp_md_est": 20640, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Democratic Republic of the Congo", + "gu_a3": "COD", + "homepart": 1, + "income_grp": "5. Low income", + "iso_a2": "CD", + "iso_a3": "COD", + "iso_n3": 180, + "labelrank": 2, + "lastcensus": 1984, + "level": 2, + "long_len": 32, + "mapcolor13": 7, + "mapcolor7": 4, + "mapcolor8": 4, + "mapcolor9": 4, + "name": "Dem. Rep. Congo", + "name_alt": null, + "name_len": 15, + "name_long": "Democratic Republic of the Congo", + "name_sort": "Congo, Dem. Rep.", + "note_adm0": null, + "note_brk": null, + "pop_est": 68692542, + "pop_year": -99, + "postal": "DRC", + "region_un": "Africa", + "region_wb": "Sub-Saharan Africa", + "scalerank": 1, + "sov_a3": "COD", + "sovereignt": "Democratic Republic of the Congo", + "su_a3": "COD", + "su_dif": 0, + "subregion": "Middle Africa", + "subunit": "Democratic Republic of the Congo", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 180, + "wb_a2": "ZR", + "wb_a3": "ZAR", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Rep. Congo", + "abbrev_len": 10, + "adm0_a3": "COG", + "adm0_a3_is": "COG", + "adm0_a3_un": -99, + "adm0_a3_us": "COG", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Republic of Congo", + "brk_a3": "COG", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Republic of Congo", + "continent": "Africa", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Congo", + "formal_fr": null, + "gdp_md_est": 15350, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Republic of Congo", + "gu_a3": "COG", + "homepart": 1, + "income_grp": "4. Lower middle income", + "iso_a2": "CG", + "iso_a3": "COG", + "iso_n3": 178, + "labelrank": 4, + "lastcensus": 2007, + "level": 2, + "long_len": 17, + "mapcolor13": 10, + "mapcolor7": 2, + "mapcolor8": 1, + "mapcolor9": 3, + "name": "Congo", + "name_alt": null, + "name_len": 5, + "name_long": "Republic of Congo", + "name_sort": "Congo, Rep.", + "note_adm0": null, + "note_brk": null, + "pop_est": 4012809, + "pop_year": -99, + "postal": "CG", + "region_un": "Africa", + "region_wb": "Sub-Saharan Africa", + "scalerank": 1, + "sov_a3": "COG", + "sovereignt": "Republic of Congo", + "su_a3": "COG", + "su_dif": 0, + "subregion": "Middle Africa", + "subunit": "Republic of Congo", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 178, + "wb_a2": "CG", + "wb_a3": "COG", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Col.", + "abbrev_len": 4, + "adm0_a3": "COL", + "adm0_a3_is": "COL", + "adm0_a3_un": -99, + "adm0_a3_us": "COL", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Colombia", + "brk_a3": "COL", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Colombia", + "continent": "South America", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Colombia", + "formal_fr": null, + "gdp_md_est": 395400, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Colombia", + "gu_a3": "COL", + "homepart": 1, + "income_grp": "3. Upper middle income", + "iso_a2": "CO", + "iso_a3": "COL", + "iso_n3": 170, + "labelrank": 2, + "lastcensus": 2006, + "level": 2, + "long_len": 8, + "mapcolor13": 1, + "mapcolor7": 2, + "mapcolor8": 1, + "mapcolor9": 3, + "name": "Colombia", + "name_alt": null, + "name_len": 8, + "name_long": "Colombia", + "name_sort": "Colombia", + "note_adm0": null, + "note_brk": null, + "pop_est": 45644023, + "pop_year": -99, + "postal": "CO", + "region_un": "Americas", + "region_wb": "Latin America & Caribbean", + "scalerank": 1, + "sov_a3": "COL", + "sovereignt": "Colombia", + "su_a3": "COL", + "su_dif": 0, + "subregion": "South America", + "subunit": "Colombia", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 170, + "wb_a2": "CO", + "wb_a3": "COL", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "C.R.", + "abbrev_len": 4, + "adm0_a3": "CRI", + "adm0_a3_is": "CRI", + "adm0_a3_un": -99, + "adm0_a3_us": "CRI", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Costa Rica", + "brk_a3": "CRI", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Costa Rica", + "continent": "North America", + "economy": "5. Emerging region: G20", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Costa Rica", + "formal_fr": null, + "gdp_md_est": 48320, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Costa Rica", + "gu_a3": "CRI", + "homepart": 1, + "income_grp": "3. Upper middle income", + "iso_a2": "CR", + "iso_a3": "CRI", + "iso_n3": 188, + "labelrank": 5, + "lastcensus": 2011, + "level": 2, + "long_len": 10, + "mapcolor13": 2, + "mapcolor7": 3, + "mapcolor8": 2, + "mapcolor9": 4, + "name": "Costa Rica", + "name_alt": null, + "name_len": 10, + "name_long": "Costa Rica", + "name_sort": "Costa Rica", + "note_adm0": null, + "note_brk": null, + "pop_est": 4253877, + "pop_year": -99, + "postal": "CR", + "region_un": "Americas", + "region_wb": "Latin America & Caribbean", + "scalerank": 1, + "sov_a3": "CRI", + "sovereignt": "Costa Rica", + "su_a3": "CRI", + "su_dif": 0, + "subregion": "Central America", + "subunit": "Costa Rica", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 188, + "wb_a2": "CR", + "wb_a3": "CRI", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Cuba", + "abbrev_len": 4, + "adm0_a3": "CUB", + "adm0_a3_is": "CUB", + "adm0_a3_un": -99, + "adm0_a3_us": "CUB", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Cuba", + "brk_a3": "CUB", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Cuba", + "continent": "North America", + "economy": "5. Emerging region: G20", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Cuba", + "formal_fr": null, + "gdp_md_est": 108200, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Cuba", + "gu_a3": "CUB", + "homepart": 1, + "income_grp": "3. Upper middle income", + "iso_a2": "CU", + "iso_a3": "CUB", + "iso_n3": 192, + "labelrank": 3, + "lastcensus": 2002, + "level": 2, + "long_len": 4, + "mapcolor13": 4, + "mapcolor7": 3, + "mapcolor8": 5, + "mapcolor9": 3, + "name": "Cuba", + "name_alt": null, + "name_len": 4, + "name_long": "Cuba", + "name_sort": "Cuba", + "note_adm0": null, + "note_brk": null, + "pop_est": 11451652, + "pop_year": -99, + "postal": "CU", + "region_un": "Americas", + "region_wb": "Latin America & Caribbean", + "scalerank": 1, + "sov_a3": "CUB", + "sovereignt": "Cuba", + "su_a3": "CUB", + "su_dif": 0, + "subregion": "Caribbean", + "subunit": "Cuba", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 192, + "wb_a2": "CU", + "wb_a3": "CUB", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Cyp.", + "abbrev_len": 4, + "adm0_a3": "CYP", + "adm0_a3_is": "CYP", + "adm0_a3_un": -99, + "adm0_a3_us": "CYP", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Cyprus", + "brk_a3": "CYP", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Cyprus", + "continent": "Asia", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Cyprus", + "formal_fr": null, + "gdp_md_est": 22700, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Cyprus", + "gu_a3": "CYP", + "homepart": 1, + "income_grp": "2. High income: nonOECD", + "iso_a2": "CY", + "iso_a3": "CYP", + "iso_n3": 196, + "labelrank": 5, + "lastcensus": 2001, + "level": 2, + "long_len": 6, + "mapcolor13": 7, + "mapcolor7": 1, + "mapcolor8": 2, + "mapcolor9": 3, + "name": "Cyprus", + "name_alt": null, + "name_len": 6, + "name_long": "Cyprus", + "name_sort": "Cyprus", + "note_adm0": null, + "note_brk": null, + "pop_est": 531640, + "pop_year": -99, + "postal": "CY", + "region_un": "Asia", + "region_wb": "Europe & Central Asia", + "scalerank": 1, + "sov_a3": "CYP", + "sovereignt": "Cyprus", + "su_a3": "CYP", + "su_dif": 0, + "subregion": "Western Asia", + "subunit": "Cyprus", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 196, + "wb_a2": "CY", + "wb_a3": "CYP", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Cz. Rep.", + "abbrev_len": 8, + "adm0_a3": "CZE", + "adm0_a3_is": "CZE", + "adm0_a3_un": -99, + "adm0_a3_us": "CZE", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Czech Republic", + "brk_a3": "CZE", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Czech Rep.", + "continent": "Europe", + "economy": "2. Developed region: nonG7", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Czech Republic", + "formal_fr": null, + "gdp_md_est": 265200, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Czech Republic", + "gu_a3": "CZE", + "homepart": 1, + "income_grp": "1. High income: OECD", + "iso_a2": "CZ", + "iso_a3": "CZE", + "iso_n3": 203, + "labelrank": 5, + "lastcensus": 2011, + "level": 2, + "long_len": 14, + "mapcolor13": 6, + "mapcolor7": 1, + "mapcolor8": 1, + "mapcolor9": 2, + "name": "Czech Rep.", + "name_alt": null, + "name_len": 10, + "name_long": "Czech Republic", + "name_sort": "Czech Republic", + "note_adm0": null, + "note_brk": null, + "pop_est": 10211904, + "pop_year": -99, + "postal": "CZ", + "region_un": "Europe", + "region_wb": "Europe & Central Asia", + "scalerank": 1, + "sov_a3": "CZE", + "sovereignt": "Czech Republic", + "su_a3": "CZE", + "su_dif": 0, + "subregion": "Eastern Europe", + "subunit": "Czech Republic", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 203, + "wb_a2": "CZ", + "wb_a3": "CZE", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Ger.", + "abbrev_len": 4, + "adm0_a3": "DEU", + "adm0_a3_is": "DEU", + "adm0_a3_un": -99, + "adm0_a3_us": "DEU", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Germany", + "brk_a3": "DEU", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Germany", + "continent": "Europe", + "economy": "1. Developed region: G7", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Federal Republic of Germany", + "formal_fr": null, + "gdp_md_est": 2918000, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Germany", + "gu_a3": "DEU", + "homepart": 1, + "income_grp": "1. High income: OECD", + "iso_a2": "DE", + "iso_a3": "DEU", + "iso_n3": 276, + "labelrank": 2, + "lastcensus": 2011, + "level": 2, + "long_len": 7, + "mapcolor13": 1, + "mapcolor7": 2, + "mapcolor8": 5, + "mapcolor9": 5, + "name": "Germany", + "name_alt": null, + "name_len": 7, + "name_long": "Germany", + "name_sort": "Germany", + "note_adm0": null, + "note_brk": null, + "pop_est": 82329758, + "pop_year": -99, + "postal": "D", + "region_un": "Europe", + "region_wb": "Europe & Central Asia", + "scalerank": 1, + "sov_a3": "DEU", + "sovereignt": "Germany", + "su_a3": "DEU", + "su_dif": 0, + "subregion": "Western Europe", + "subunit": "Germany", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 276, + "wb_a2": "DE", + "wb_a3": "DEU", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Dji.", + "abbrev_len": 4, + "adm0_a3": "DJI", + "adm0_a3_is": "DJI", + "adm0_a3_un": -99, + "adm0_a3_us": "DJI", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Djibouti", + "brk_a3": "DJI", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Djibouti", + "continent": "Africa", + "economy": "7. Least developed region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Djibouti", + "formal_fr": null, + "gdp_md_est": 1885, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Djibouti", + "gu_a3": "DJI", + "homepart": 1, + "income_grp": "4. Lower middle income", + "iso_a2": "DJ", + "iso_a3": "DJI", + "iso_n3": 262, + "labelrank": 5, + "lastcensus": 2009, + "level": 2, + "long_len": 8, + "mapcolor13": 8, + "mapcolor7": 1, + "mapcolor8": 2, + "mapcolor9": 4, + "name": "Djibouti", + "name_alt": null, + "name_len": 8, + "name_long": "Djibouti", + "name_sort": "Djibouti", + "note_adm0": null, + "note_brk": null, + "pop_est": 516055, + "pop_year": -99, + "postal": "DJ", + "region_un": "Africa", + "region_wb": "Middle East & North Africa", + "scalerank": 1, + "sov_a3": "DJI", + "sovereignt": "Djibouti", + "su_a3": "DJI", + "su_dif": 0, + "subregion": "Eastern Africa", + "subunit": "Djibouti", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 262, + "wb_a2": "DJ", + "wb_a3": "DJI", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Den.", + "abbrev_len": 4, + "adm0_a3": "DNK", + "adm0_a3_is": "DNK", + "adm0_a3_un": -99, + "adm0_a3_us": "DNK", + "adm0_a3_wb": -99, + "adm0_dif": 1, + "admin": "Denmark", + "brk_a3": "DNK", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Denmark", + "continent": "Europe", + "economy": "2. Developed region: nonG7", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Kingdom of Denmark", + "formal_fr": null, + "gdp_md_est": 203600, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Denmark", + "gu_a3": "DNK", + "homepart": 1, + "income_grp": "1. High income: OECD", + "iso_a2": "DK", + "iso_a3": "DNK", + "iso_n3": 208, + "labelrank": 4, + "lastcensus": 2011, + "level": 2, + "long_len": 7, + "mapcolor13": 12, + "mapcolor7": 4, + "mapcolor8": 1, + "mapcolor9": 3, + "name": "Denmark", + "name_alt": null, + "name_len": 7, + "name_long": "Denmark", + "name_sort": "Denmark", + "note_adm0": null, + "note_brk": null, + "pop_est": 5500510, + "pop_year": -99, + "postal": "DK", + "region_un": "Europe", + "region_wb": "Europe & Central Asia", + "scalerank": 1, + "sov_a3": "DN1", + "sovereignt": "Denmark", + "su_a3": "DNK", + "su_dif": 0, + "subregion": "Northern Europe", + "subunit": "Denmark", + "tiny": -99, + "type": "Country", + "un_a3": 208, + "wb_a2": "DK", + "wb_a3": "DNK", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Dom. Rep.", + "abbrev_len": 9, + "adm0_a3": "DOM", + "adm0_a3_is": "DOM", + "adm0_a3_un": -99, + "adm0_a3_us": "DOM", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Dominican Republic", + "brk_a3": "DOM", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Dominican Rep.", + "continent": "North America", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Dominican Republic", + "formal_fr": null, + "gdp_md_est": 78000, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Dominican Republic", + "gu_a3": "DOM", + "homepart": 1, + "income_grp": "3. Upper middle income", + "iso_a2": "DO", + "iso_a3": "DOM", + "iso_n3": 214, + "labelrank": 5, + "lastcensus": 2010, + "level": 2, + "long_len": 18, + "mapcolor13": 7, + "mapcolor7": 5, + "mapcolor8": 2, + "mapcolor9": 5, + "name": "Dominican Rep.", + "name_alt": null, + "name_len": 14, + "name_long": "Dominican Republic", + "name_sort": "Dominican Republic", + "note_adm0": null, + "note_brk": null, + "pop_est": 9650054, + "pop_year": -99, + "postal": "DO", + "region_un": "Americas", + "region_wb": "Latin America & Caribbean", + "scalerank": 1, + "sov_a3": "DOM", + "sovereignt": "Dominican Republic", + "su_a3": "DOM", + "su_dif": 0, + "subregion": "Caribbean", + "subunit": "Dominican Republic", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 214, + "wb_a2": "DO", + "wb_a3": "DOM", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Alg.", + "abbrev_len": 4, + "adm0_a3": "DZA", + "adm0_a3_is": "DZA", + "adm0_a3_un": -99, + "adm0_a3_us": "DZA", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Algeria", + "brk_a3": "DZA", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Algeria", + "continent": "Africa", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "People's Democratic Republic of Algeria", + "formal_fr": null, + "gdp_md_est": 232900, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Algeria", + "gu_a3": "DZA", + "homepart": 1, + "income_grp": "3. Upper middle income", + "iso_a2": "DZ", + "iso_a3": "DZA", + "iso_n3": 12, + "labelrank": 3, + "lastcensus": 2008, + "level": 2, + "long_len": 7, + "mapcolor13": 3, + "mapcolor7": 5, + "mapcolor8": 1, + "mapcolor9": 6, + "name": "Algeria", + "name_alt": null, + "name_len": 7, + "name_long": "Algeria", + "name_sort": "Algeria", + "note_adm0": null, + "note_brk": null, + "pop_est": 34178188, + "pop_year": -99, + "postal": "DZ", + "region_un": "Africa", + "region_wb": "Middle East & North Africa", + "scalerank": 1, + "sov_a3": "DZA", + "sovereignt": "Algeria", + "su_a3": "DZA", + "su_dif": 0, + "subregion": "Northern Africa", + "subunit": "Algeria", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 12, + "wb_a2": "DZ", + "wb_a3": "DZA", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Ecu.", + "abbrev_len": 4, + "adm0_a3": "ECU", + "adm0_a3_is": "ECU", + "adm0_a3_un": -99, + "adm0_a3_us": "ECU", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Ecuador", + "brk_a3": "ECU", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Ecuador", + "continent": "South America", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Ecuador", + "formal_fr": null, + "gdp_md_est": 107700, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Ecuador", + "gu_a3": "ECU", + "homepart": 1, + "income_grp": "3. Upper middle income", + "iso_a2": "EC", + "iso_a3": "ECU", + "iso_n3": 218, + "labelrank": 3, + "lastcensus": 2010, + "level": 2, + "long_len": 7, + "mapcolor13": 12, + "mapcolor7": 1, + "mapcolor8": 5, + "mapcolor9": 2, + "name": "Ecuador", + "name_alt": null, + "name_len": 7, + "name_long": "Ecuador", + "name_sort": "Ecuador", + "note_adm0": null, + "note_brk": null, + "pop_est": 14573101, + "pop_year": -99, + "postal": "EC", + "region_un": "Americas", + "region_wb": "Latin America & Caribbean", + "scalerank": 1, + "sov_a3": "ECU", + "sovereignt": "Ecuador", + "su_a3": "ECU", + "su_dif": 0, + "subregion": "South America", + "subunit": "Ecuador", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 218, + "wb_a2": "EC", + "wb_a3": "ECU", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Egypt", + "abbrev_len": 5, + "adm0_a3": "EGY", + "adm0_a3_is": "EGY", + "adm0_a3_un": -99, + "adm0_a3_us": "EGY", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Egypt", + "brk_a3": "EGY", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Egypt", + "continent": "Africa", + "economy": "5. Emerging region: G20", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Arab Republic of Egypt", + "formal_fr": null, + "gdp_md_est": 443700, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Egypt", + "gu_a3": "EGY", + "homepart": 1, + "income_grp": "4. Lower middle income", + "iso_a2": "EG", + "iso_a3": "EGY", + "iso_n3": 818, + "labelrank": 2, + "lastcensus": 2006, + "level": 2, + "long_len": 5, + "mapcolor13": 2, + "mapcolor7": 4, + "mapcolor8": 6, + "mapcolor9": 7, + "name": "Egypt", + "name_alt": null, + "name_len": 5, + "name_long": "Egypt", + "name_sort": "Egypt, Arab Rep.", + "note_adm0": null, + "note_brk": null, + "pop_est": 83082869, + "pop_year": -99, + "postal": "EG", + "region_un": "Africa", + "region_wb": "Middle East & North Africa", + "scalerank": 1, + "sov_a3": "EGY", + "sovereignt": "Egypt", + "su_a3": "EGY", + "su_dif": 0, + "subregion": "Northern Africa", + "subunit": "Egypt", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 818, + "wb_a2": "EG", + "wb_a3": "EGY", + "wikipedia": -99, + "woe_id": -99 + } + ], + "schema": { + "fields": [ + { + "name": "scalerank", + "type": "integer" + }, + { + "name": "featurecla", + "type": "string" + }, + { + "name": "labelrank", + "type": "integer" + }, + { + "name": "sovereignt", + "type": "string" + }, + { + "name": "sov_a3", + "type": "string" + }, + { + "name": "adm0_dif", + "type": "integer" + }, + { + "name": "level", + "type": "integer" + }, + { + "name": "type", + "type": "string" + }, + { + "name": "admin", + "type": "string" + }, + { + "name": "adm0_a3", + "type": "string" + }, + { + "name": "geou_dif", + "type": "integer" + }, + { + "name": "geounit", + "type": "string" + }, + { + "name": "gu_a3", + "type": "string" + }, + { + "name": "su_dif", + "type": "integer" + }, + { + "name": "subunit", + "type": "string" + }, + { + "name": "su_a3", + "type": "string" + }, + { + "name": "brk_diff", + "type": "integer" + }, + { + "name": "name", + "type": "string" + }, + { + "name": "name_long", + "type": "string" + }, + { + "name": "brk_a3", + "type": "string" + }, + { + "name": "brk_name", + "type": "string" + }, + { + "name": "brk_group", + "type": "string" + }, + { + "name": "abbrev", + "type": "string" + }, + { + "name": "postal", + "type": "string" + }, + { + "name": "formal_en", + "type": "string" + }, + { + "name": "formal_fr", + "type": "string" + }, + { + "name": "note_adm0", + "type": "string" + }, + { + "name": "note_brk", + "type": "string" + }, + { + "name": "name_sort", + "type": "string" + }, + { + "name": "name_alt", + "type": "string" + }, + { + "name": "mapcolor7", + "type": "integer" + }, + { + "name": "mapcolor8", + "type": "integer" + }, + { + "name": "mapcolor9", + "type": "integer" + }, + { + "name": "mapcolor13", + "type": "integer" + }, + { + "name": "pop_est", + "type": "integer" + }, + { + "name": "gdp_md_est", + "type": "number" + }, + { + "name": "pop_year", + "type": "integer" + }, + { + "name": "lastcensus", + "type": "integer" + }, + { + "name": "gdp_year", + "type": "integer" + }, + { + "name": "economy", + "type": "string" + }, + { + "name": "income_grp", + "type": "string" + }, + { + "name": "wikipedia", + "type": "integer" + }, + { + "name": "fips_10", + "type": "string" + }, + { + "name": "iso_a2", + "type": "string" + }, + { + "name": "iso_a3", + "type": "string" + }, + { + "name": "iso_n3", + "type": "integer" + }, + { + "name": "un_a3", + "type": "integer" + }, + { + "name": "wb_a2", + "type": "string" + }, + { + "name": "wb_a3", + "type": "string" + }, + { + "name": "woe_id", + "type": "integer" + }, + { + "name": "adm0_a3_is", + "type": "string" + }, + { + "name": "adm0_a3_us", + "type": "string" + }, + { + "name": "adm0_a3_un", + "type": "integer" + }, + { + "name": "adm0_a3_wb", + "type": "integer" + }, + { + "name": "continent", + "type": "string" + }, + { + "name": "region_un", + "type": "string" + }, + { + "name": "subregion", + "type": "string" + }, + { + "name": "region_wb", + "type": "string" + }, + { + "name": "name_len", + "type": "integer" + }, + { + "name": "long_len", + "type": "integer" + }, + { + "name": "abbrev_len", + "type": "integer" + }, + { + "name": "tiny", + "type": "integer" + }, + { + "name": "homepart", + "type": "integer" + } + ] + } + }, + "text/html": [ + "
scalerankfeatureclalabelranksovereigntsov_a3adm0_difleveltypeadminadm0_a3geou_difgeounitgu_a3su_difsubunitsu_a3brk_diffnamename_longbrk_a3brk_namebrk_groupabbrevpostalformal_enformal_frnote_adm0note_brkname_sortname_altmapcolor7mapcolor8mapcolor9mapcolor13pop_estgdp_md_estpop_yearlastcensusgdp_yeareconomyincome_grpwikipediafips_10iso_a2iso_a3iso_n3un_a3wb_a2wb_a3woe_idadm0_a3_isadm0_a3_usadm0_a3_unadm0_a3_wbcontinentregion_unsubregionregion_wbname_lenlong_lenabbrev_lentinyhomepart
1Admin-0 country6KosovoKOS02Sovereign countryKosovoKOS0KosovoKOS0KosovoKOS1KosovoKosovoB57KosovonullKos.KORepublic of KosovonullnullSelf admin.; Claimed by SerbiaKosovonull2231118048385352-991981-996. Developing region4. Lower middle income-99null-99-99-99-99KVKSV-99SRBKOS-99-99EuropeEuropeSouthern EuropeEurope & Central Asia664-991
1Admin-0 country5SomalilandSOL02IndeterminateSomalilandSOL0SomalilandSOL0SomalilandSOL1SomalilandSomalilandB30SomalilandnullSolnd.SLRepublic of SomalilandnullSelf admin.Self admin.; Claimed by SomaliaSomalilandnull3652350000012250-99-99-996. Developing region4. Lower middle income-99null-99-99-99-99-99-99-99SOMSOM-99-99AfricaAfricaEastern AfricaSub-Saharan Africa10106-991
1Admin-0 country6Northern CyprusCYN02Sovereign countryNorthern CyprusCYN0Northern CyprusCYN0Northern CyprusCYN1N. CyprusNorthern CyprusB20N. CyprusnullN. Cy.CNTurkish Republic of Northern CyprusnullSelf admin.Self admin.; Claimed by CyprusCyprus, Northernnull31482651003600-99-99-996. Developing region3. Upper middle income-99null-99-99-99-99-99-99-99CYPCYP-99-99AsiaAsiaWestern AsiaEurope & Central Asia9156-991
1Admin-0 country3AfghanistanAFG02Sovereign countryAfghanistanAFG0AfghanistanAFG0AfghanistanAFG0AfghanistanAfghanistanAFGAfghanistannullAfg.AFIslamic State of AfghanistannullnullnullAfghanistannull56872840000022270-991979-997. Least developed region5. Low income-99nullAFAFG44AFAFG-99AFGAFG-99-99AsiaAsiaSouthern AsiaSouth Asia11114-991
1Admin-0 country3AngolaAGO02Sovereign countryAngolaAGO0AngolaAGO0AngolaAGO0AngolaAngolaAGOAngolanullAng.AOPeople's Republic of AngolanullnullnullAngolanull326112799293110300-991970-997. Least developed region3. Upper middle income-99nullAOAGO2424AOAGO-99AGOAGO-99-99AfricaAfricaMiddle AfricaSub-Saharan Africa664-991
1Admin-0 country6AlbaniaALB02Sovereign countryAlbaniaALB0AlbaniaALB0AlbaniaALB0AlbaniaAlbaniaALBAlbanianullAlb.ALRepublic of AlbanianullnullnullAlbanianull1416363945321810-992001-996. Developing region4. Lower middle income-99nullALALB88ALALB-99ALBALB-99-99EuropeEuropeSouthern EuropeEurope & Central Asia774-991
1Admin-0 country4United Arab EmiratesARE02Sovereign countryUnited Arab EmiratesARE0United Arab EmiratesARE0United Arab EmiratesARE0United Arab EmiratesUnited Arab EmiratesAREUnited Arab EmiratesnullU.A.E.AEUnited Arab EmiratesnullnullnullUnited Arab Emiratesnull21334798491184300-992010-996. Developing region2. High income: nonOECD-99nullAEARE784784AEARE-99AREARE-99-99AsiaAsiaWestern AsiaMiddle East & North Africa20206-991
1Admin-0 country2ArgentinaARG02Sovereign countryArgentinaARG0ArgentinaARG0ArgentinaARG0ArgentinaArgentinaARGArgentinanullArg.ARArgentine RepublicnullnullnullArgentinanull3131340913584573900-992010-995. Emerging region: G203. Upper middle income-99nullARARG3232ARARG-99ARGARG-99-99South AmericaAmericasSouth AmericaLatin America & Caribbean994-991
1Admin-0 country6ArmeniaARM02Sovereign countryArmeniaARM0ArmeniaARM0ArmeniaARM0ArmeniaArmeniaARMArmenianullArm.ARMRepublic of ArmenianullnullnullArmenianull31210296700418770-992001-996. Developing region4. Lower middle income-99nullAMARM5151AMARM-99ARMARM-99-99AsiaAsiaWestern AsiaEurope & Central Asia774-991
1Admin-0 country4AntarcticaATA02IndeterminateAntarcticaATA0AntarcticaATA0AntarcticaATA0AntarcticaAntarcticaATAAntarcticanullAnt.AQnullnullnullMultiple claims held in abeyanceAntarcticanull451-993802760.4-99-99-996. Developing region2. High income: nonOECD-99nullAQATA10-99-99-99-99ATAATA-99-99AntarcticaAntarcticaAntarcticaAntarctica10104-991
" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import pl from \"npm:nodejs-polars\";\n", + "\n", + "let response = await fetch(\n", + " \"https://cdn.jsdelivr.net/npm/world-atlas@1/world/110m.tsv\",\n", + ");\n", + "let data = await response.text();\n", + "let df = pl.readCSV(data, { sep: \"\\t\" });\n", + "\n", + "df" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Deno", + "language": "typescript", + "name": "deno" + }, + "language_info": { + "file_extension": ".ts", + "mimetype": "text/x.typescript", + "name": "typescript", + "nb_converter": "script", + "pygments_lexer": "typescript", + "version": "5.2.2" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": true + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/tests/testdata/lint/Deno.compact.format.jsonc b/tests/testdata/lint/Deno.compact.format.jsonc new file mode 100644 index 000000000..f3487501a --- /dev/null +++ b/tests/testdata/lint/Deno.compact.format.jsonc @@ -0,0 +1,11 @@ +{ + "lint": { + "include": ["with_config/"], + "exclude": ["with_config/b.ts"], + "rules": { + "tags": ["recommended"], + "include": ["ban-untagged-todo"] + }, + "report": "compact" + } +} diff --git a/tests/testdata/lint/Deno.jsonc b/tests/testdata/lint/Deno.jsonc new file mode 100644 index 000000000..e9c03cca4 --- /dev/null +++ b/tests/testdata/lint/Deno.jsonc @@ -0,0 +1,10 @@ +{ + "lint": { + "include": ["with_config/"], + "exclude": ["with_config/b.ts"], + "rules": { + "tags": ["recommended"], + "include": ["ban-untagged-todo"] + } + } +} diff --git a/tests/testdata/lint/Deno.malformed.jsonc b/tests/testdata/lint/Deno.malformed.jsonc new file mode 100644 index 000000000..fa71cd851 --- /dev/null +++ b/tests/testdata/lint/Deno.malformed.jsonc @@ -0,0 +1,11 @@ +{ + "lint": { + "include": ["with_config/"], + "exclude": ["with_config/b.ts"], + "dont_know_this_field": {}, + "rules": { + "tags": ["recommended"], + "include": ["ban-untagged-todo"] + } + } +} diff --git a/tests/testdata/lint/Deno.malformed2.jsonc b/tests/testdata/lint/Deno.malformed2.jsonc new file mode 100644 index 000000000..fa71cd851 --- /dev/null +++ b/tests/testdata/lint/Deno.malformed2.jsonc @@ -0,0 +1,11 @@ +{ + "lint": { + "include": ["with_config/"], + "exclude": ["with_config/b.ts"], + "dont_know_this_field": {}, + "rules": { + "tags": ["recommended"], + "include": ["ban-untagged-todo"] + } + } +} diff --git a/tests/testdata/lint/Deno.no_tags.jsonc b/tests/testdata/lint/Deno.no_tags.jsonc new file mode 100644 index 000000000..b63600a90 --- /dev/null +++ b/tests/testdata/lint/Deno.no_tags.jsonc @@ -0,0 +1,15 @@ +{ + "lint": { + "include": [ + "with_config/" + ], + "exclude": [ + "with_config/b.ts" + ], + "rules": { + "include": [ + "ban-untagged-todo" + ] + } + } +} diff --git a/tests/testdata/lint/deno.glob.json b/tests/testdata/lint/deno.glob.json new file mode 100644 index 000000000..f6781b0d8 --- /dev/null +++ b/tests/testdata/lint/deno.glob.json @@ -0,0 +1,11 @@ +{ + "lint": { + "include": [ + "glob/data/test1.?s", + "glob/nested/foo/*.ts", + "glob/nested/fizz/*.ts", + "glob/pages/[id].ts" + ], + "exclude": ["glob/nested/**/*bazz.ts"] + } +} diff --git a/tests/testdata/lint/expected.out b/tests/testdata/lint/expected.out new file mode 100644 index 000000000..eb8a2651a --- /dev/null +++ b/tests/testdata/lint/expected.out @@ -0,0 +1,3 @@ +[WILDCARD] +Found 3 problems +Checked 3 files diff --git a/tests/testdata/lint/expected_compact.out b/tests/testdata/lint/expected_compact.out new file mode 100644 index 000000000..d1b2b922b --- /dev/null +++ b/tests/testdata/lint/expected_compact.out @@ -0,0 +1,4 @@ +[WILDCARD]file1.js: line 1, col 1 - Ignore directive requires lint rule name(s) (ban-untagged-ignore) +[WILDCARD]file1.js: line 2, col 15 - Empty block statement (no-empty) +Found 2 problems +Checked 1 file diff --git a/tests/testdata/lint/expected_from_stdin.out b/tests/testdata/lint/expected_from_stdin.out new file mode 100644 index 000000000..59f32166f --- /dev/null +++ b/tests/testdata/lint/expected_from_stdin.out @@ -0,0 +1,12 @@ +error[no-explicit-any]: `any` type is not allowed + --> [WILDCARD]$deno$stdin.ts:1:9 + | +1 | let _a: any; + | ^^^ + = hint: Use a specific type other than `any` + + docs: https://lint.deno.land/#no-explicit-any + + +Found 1 problem +Checked 1 file diff --git a/tests/testdata/lint/expected_from_stdin_json.out b/tests/testdata/lint/expected_from_stdin_json.out new file mode 100644 index 000000000..9e1188bcd --- /dev/null +++ b/tests/testdata/lint/expected_from_stdin_json.out @@ -0,0 +1,23 @@ +{ + "diagnostics": [ + { + "filename": "[WILDCARD]$deno$stdin.ts", + "range": { + "start": { + "line": 1, + "col": 8, + "bytePos": 8 + }, + "end": { + "line": 1, + "col": 11, + "bytePos": 11 + } + }, + "message": "`any` type is not allowed", + "code": "no-explicit-any", + "hint": [WILDCARD] + } + ], + "errors": [] +} diff --git a/tests/testdata/lint/expected_glob.out b/tests/testdata/lint/expected_glob.out new file mode 100644 index 000000000..eb8a2651a --- /dev/null +++ b/tests/testdata/lint/expected_glob.out @@ -0,0 +1,3 @@ +[WILDCARD] +Found 3 problems +Checked 3 files diff --git a/tests/testdata/lint/expected_ignore.out b/tests/testdata/lint/expected_ignore.out new file mode 100644 index 000000000..b5f78ee04 --- /dev/null +++ b/tests/testdata/lint/expected_ignore.out @@ -0,0 +1,3 @@ +[WILDCARD] +Found 1 problem +Checked 2 files diff --git a/tests/testdata/lint/expected_json.out b/tests/testdata/lint/expected_json.out new file mode 100644 index 000000000..95c3d30ba --- /dev/null +++ b/tests/testdata/lint/expected_json.out @@ -0,0 +1,64 @@ +{ + "diagnostics": [ + { + "filename": "[WILDCARD]file1.js", + "range": { + "start": { + "line": 1, + "col": 0, + "bytePos": 0 + }, + "end": { + "line": 1, + "col": 19, + "bytePos": 19 + } + }, + "message": "Ignore directive requires lint rule name(s)", + "code": "ban-untagged-ignore", + "hint": [WILDCARD] + }, + { + "filename": "[WILDCARD]file1.js", + "range": { + "start": { + "line": 2, + "col": 14, + "bytePos": 34 + }, + "end": { + "line": 2, + "col": 16, + "bytePos": 36 + } + }, + "message": "Empty block statement", + "code": "no-empty", + "hint": [WILDCARD] + }, + { + "filename": "[WILDCARD]file2.ts", + "range": { + "start": { + "line": 3, + "col": 13, + "bytePos": 57 + }, + "end": { + "line": 3, + "col": 15, + "bytePos": 59 + } + }, + "message": "Empty block statement", + "code": "no-empty", + "hint": [WILDCARD] + } + ], + "errors": [ + { + "file_path": "[WILDCARD]malformed.js", + "message": "Expected '{', got 'B' at [WILDCARD]malformed.js:4:16\n\n export class A B C\n ~" + } + ] +} diff --git a/tests/testdata/lint/expected_quiet.out b/tests/testdata/lint/expected_quiet.out new file mode 100644 index 000000000..e46a94a2d --- /dev/null +++ b/tests/testdata/lint/expected_quiet.out @@ -0,0 +1,20 @@ +error[ban-untagged-ignore]: Ignore directive requires lint rule name(s) + --> [WILDCARD]file1.js:1:1 + | +1 | // deno-lint-ignore + | ^^^^^^^^^^^^^^^^^^^ + = hint: Add one or more lint rule names. E.g. // deno-lint-ignore adjacent-overload-signatures + + docs: https://lint.deno.land/#ban-untagged-ignore + + +error[no-empty]: Empty block statement + --> [WILDCARD]file1.js:2:15 + | +2 | while (false) {} + | ^^ + = hint: Add code or comment to the empty block + + docs: https://lint.deno.land/#no-empty + + diff --git a/tests/testdata/lint/expected_rules.out b/tests/testdata/lint/expected_rules.out new file mode 100644 index 000000000..4afab7b9b --- /dev/null +++ b/tests/testdata/lint/expected_rules.out @@ -0,0 +1,2 @@ +Available rules: +[WILDCARD] diff --git a/tests/testdata/lint/expected_verbose.out b/tests/testdata/lint/expected_verbose.out new file mode 100644 index 000000000..eb8a2651a --- /dev/null +++ b/tests/testdata/lint/expected_verbose.out @@ -0,0 +1,3 @@ +[WILDCARD] +Found 3 problems +Checked 3 files diff --git a/tests/testdata/lint/glob/data/tes.ts b/tests/testdata/lint/glob/data/tes.ts new file mode 100644 index 000000000..26f07fba5 --- /dev/null +++ b/tests/testdata/lint/glob/data/tes.ts @@ -0,0 +1,3 @@ +function foo() { + +} \ No newline at end of file diff --git a/tests/testdata/lint/glob/data/test1.js b/tests/testdata/lint/glob/data/test1.js new file mode 100644 index 000000000..26f07fba5 --- /dev/null +++ b/tests/testdata/lint/glob/data/test1.js @@ -0,0 +1,3 @@ +function foo() { + +} \ No newline at end of file diff --git a/tests/testdata/lint/glob/data/test1.ts b/tests/testdata/lint/glob/data/test1.ts new file mode 100644 index 000000000..26f07fba5 --- /dev/null +++ b/tests/testdata/lint/glob/data/test1.ts @@ -0,0 +1,3 @@ +function foo() { + +} \ No newline at end of file diff --git a/tests/testdata/lint/glob/data/test12.ts b/tests/testdata/lint/glob/data/test12.ts new file mode 100644 index 000000000..26f07fba5 --- /dev/null +++ b/tests/testdata/lint/glob/data/test12.ts @@ -0,0 +1,3 @@ +function foo() { + +} \ No newline at end of file diff --git a/tests/testdata/lint/glob/nested/fizz/bar.ts b/tests/testdata/lint/glob/nested/fizz/bar.ts new file mode 100644 index 000000000..26f07fba5 --- /dev/null +++ b/tests/testdata/lint/glob/nested/fizz/bar.ts @@ -0,0 +1,3 @@ +function foo() { + +} \ No newline at end of file diff --git a/tests/testdata/lint/glob/nested/fizz/bazz.ts b/tests/testdata/lint/glob/nested/fizz/bazz.ts new file mode 100644 index 000000000..26f07fba5 --- /dev/null +++ b/tests/testdata/lint/glob/nested/fizz/bazz.ts @@ -0,0 +1,3 @@ +function foo() { + +} \ No newline at end of file diff --git a/tests/testdata/lint/glob/nested/fizz/fizz.ts b/tests/testdata/lint/glob/nested/fizz/fizz.ts new file mode 100644 index 000000000..6940729e9 --- /dev/null +++ b/tests/testdata/lint/glob/nested/fizz/fizz.ts @@ -0,0 +1,2 @@ +function foo() { +} diff --git a/tests/testdata/lint/glob/nested/fizz/foo.ts b/tests/testdata/lint/glob/nested/fizz/foo.ts new file mode 100644 index 000000000..26f07fba5 --- /dev/null +++ b/tests/testdata/lint/glob/nested/fizz/foo.ts @@ -0,0 +1,3 @@ +function foo() { + +} \ No newline at end of file diff --git a/tests/testdata/lint/glob/nested/foo/bar.ts b/tests/testdata/lint/glob/nested/foo/bar.ts new file mode 100644 index 000000000..26f07fba5 --- /dev/null +++ b/tests/testdata/lint/glob/nested/foo/bar.ts @@ -0,0 +1,3 @@ +function foo() { + +} \ No newline at end of file diff --git a/tests/testdata/lint/glob/nested/foo/bazz.ts b/tests/testdata/lint/glob/nested/foo/bazz.ts new file mode 100644 index 000000000..26f07fba5 --- /dev/null +++ b/tests/testdata/lint/glob/nested/foo/bazz.ts @@ -0,0 +1,3 @@ +function foo() { + +} \ No newline at end of file diff --git a/tests/testdata/lint/glob/nested/foo/fizz.ts b/tests/testdata/lint/glob/nested/foo/fizz.ts new file mode 100644 index 000000000..26f07fba5 --- /dev/null +++ b/tests/testdata/lint/glob/nested/foo/fizz.ts @@ -0,0 +1,3 @@ +function foo() { + +} \ No newline at end of file diff --git a/tests/testdata/lint/glob/nested/foo/foo.ts b/tests/testdata/lint/glob/nested/foo/foo.ts new file mode 100644 index 000000000..26f07fba5 --- /dev/null +++ b/tests/testdata/lint/glob/nested/foo/foo.ts @@ -0,0 +1,3 @@ +function foo() { + +} \ No newline at end of file diff --git a/tests/testdata/lint/glob/pages/[id].ts b/tests/testdata/lint/glob/pages/[id].ts new file mode 100644 index 000000000..26f07fba5 --- /dev/null +++ b/tests/testdata/lint/glob/pages/[id].ts @@ -0,0 +1,3 @@ +function foo() { + +} \ No newline at end of file diff --git a/tests/testdata/lint/watch/badly_linted.js b/tests/testdata/lint/watch/badly_linted.js new file mode 100644 index 000000000..8d1c1fe79 --- /dev/null +++ b/tests/testdata/lint/watch/badly_linted.js @@ -0,0 +1 @@ +let a = 5; diff --git a/tests/testdata/lint/watch/badly_linted.js.out b/tests/testdata/lint/watch/badly_linted.js.out new file mode 100644 index 000000000..07ae031c3 --- /dev/null +++ b/tests/testdata/lint/watch/badly_linted.js.out @@ -0,0 +1,2 @@ +error[no-unused-vars]: `a` is never used +error[prefer-const]: `a` is never reassigned diff --git a/tests/testdata/lint/watch/badly_linted_fixed1.js b/tests/testdata/lint/watch/badly_linted_fixed1.js new file mode 100644 index 000000000..bfccee47d --- /dev/null +++ b/tests/testdata/lint/watch/badly_linted_fixed1.js @@ -0,0 +1 @@ +let _a = 5; diff --git a/tests/testdata/lint/watch/badly_linted_fixed1.js.out b/tests/testdata/lint/watch/badly_linted_fixed1.js.out new file mode 100644 index 000000000..67e3c9dd8 --- /dev/null +++ b/tests/testdata/lint/watch/badly_linted_fixed1.js.out @@ -0,0 +1 @@ +error[prefer-const]: `_a` is never reassigned diff --git a/tests/testdata/lint/watch/badly_linted_fixed2.js b/tests/testdata/lint/watch/badly_linted_fixed2.js new file mode 100644 index 000000000..94fe8701b --- /dev/null +++ b/tests/testdata/lint/watch/badly_linted_fixed2.js @@ -0,0 +1 @@ +const _a = 5; diff --git a/tests/testdata/lint/watch/badly_linted_fixed2.js.out b/tests/testdata/lint/watch/badly_linted_fixed2.js.out new file mode 100644 index 000000000..e69de29bb diff --git a/tests/testdata/lint/with_config.out b/tests/testdata/lint/with_config.out new file mode 100644 index 000000000..cffd6b9c7 --- /dev/null +++ b/tests/testdata/lint/with_config.out @@ -0,0 +1,22 @@ +error[ban-untagged-todo]: TODO should be tagged with (@username) or (#issue) + --> [WILDCARD]a.ts:1:1 + | +1 | // TODO: foo + | ^^^^^^^^^^^^ + = hint: Add a user tag or issue reference to the TODO comment, e.g. TODO(@djones), TODO(djones), TODO(#123) + + docs: https://lint.deno.land/#ban-untagged-todo + + +error[no-unused-vars]: `add` is never used + --> [WILDCARD]a.ts:2:10 + | +2 | function add(a: number, b: number): number { + | ^^^ + = hint: If this is intentional, prefix it with an underscore like `_add` + + docs: https://lint.deno.land/#no-unused-vars + + +Found 2 problems +Checked 1 file diff --git a/tests/testdata/lint/with_config/a.ts b/tests/testdata/lint/with_config/a.ts new file mode 100644 index 000000000..c378218a3 --- /dev/null +++ b/tests/testdata/lint/with_config/a.ts @@ -0,0 +1,4 @@ +// TODO: foo +function add(a: number, b: number): number { + return a + b; +} diff --git a/tests/testdata/lint/with_config/b.ts b/tests/testdata/lint/with_config/b.ts new file mode 100644 index 000000000..d5647067e --- /dev/null +++ b/tests/testdata/lint/with_config/b.ts @@ -0,0 +1,4 @@ +// TODO: this file should be ignored +function subtract(a: number, b: number): number { + return a - b; +} diff --git a/tests/testdata/lint/with_config_and_flags.out b/tests/testdata/lint/with_config_and_flags.out new file mode 100644 index 000000000..f3ad3cafb --- /dev/null +++ b/tests/testdata/lint/with_config_and_flags.out @@ -0,0 +1,22 @@ +error[ban-untagged-todo]: TODO should be tagged with (@username) or (#issue) + --> [WILDCARD]b.ts:1:1 + | +1 | // TODO: this file should be ignored + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = hint: Add a user tag or issue reference to the TODO comment, e.g. TODO(@djones), TODO(djones), TODO(#123) + + docs: https://lint.deno.land/#ban-untagged-todo + + +error[no-unused-vars]: `subtract` is never used + --> [WILDCARD]b.ts:2:10 + | +2 | function subtract(a: number, b: number): number { + | ^^^^^^^^ + = hint: If this is intentional, prefix it with an underscore like `_subtract` + + docs: https://lint.deno.land/#no-unused-vars + + +Found 2 problems +Checked 1 file diff --git a/tests/testdata/lint/with_config_without_tags.out b/tests/testdata/lint/with_config_without_tags.out new file mode 100644 index 000000000..cffd6b9c7 --- /dev/null +++ b/tests/testdata/lint/with_config_without_tags.out @@ -0,0 +1,22 @@ +error[ban-untagged-todo]: TODO should be tagged with (@username) or (#issue) + --> [WILDCARD]a.ts:1:1 + | +1 | // TODO: foo + | ^^^^^^^^^^^^ + = hint: Add a user tag or issue reference to the TODO comment, e.g. TODO(@djones), TODO(djones), TODO(#123) + + docs: https://lint.deno.land/#ban-untagged-todo + + +error[no-unused-vars]: `add` is never used + --> [WILDCARD]a.ts:2:10 + | +2 | function add(a: number, b: number): number { + | ^^^ + = hint: If this is intentional, prefix it with an underscore like `_add` + + docs: https://lint.deno.land/#no-unused-vars + + +Found 2 problems +Checked 1 file diff --git a/tests/testdata/lint/with_malformed_config.out b/tests/testdata/lint/with_malformed_config.out new file mode 100644 index 000000000..1c0f0fff6 --- /dev/null +++ b/tests/testdata/lint/with_malformed_config.out @@ -0,0 +1,4 @@ +error: Failed to parse "lint" configuration + +Caused by: + unknown field `dont_know_this_field`, expected one of `rules`, `include`, `exclude`, `files`, `report` diff --git a/tests/testdata/lint/with_malformed_config2.out b/tests/testdata/lint/with_malformed_config2.out new file mode 100644 index 000000000..1c0f0fff6 --- /dev/null +++ b/tests/testdata/lint/with_malformed_config2.out @@ -0,0 +1,4 @@ +error: Failed to parse "lint" configuration + +Caused by: + unknown field `dont_know_this_field`, expected one of `rules`, `include`, `exclude`, `files`, `report` diff --git a/tests/testdata/lint/with_report_config_compact.out b/tests/testdata/lint/with_report_config_compact.out new file mode 100644 index 000000000..fe1241264 --- /dev/null +++ b/tests/testdata/lint/with_report_config_compact.out @@ -0,0 +1,4 @@ +[WILDCARD]a.ts: line 1, col 1 - TODO should be tagged with (@username) or (#issue) (ban-untagged-todo) +[WILDCARD]a.ts: line 2, col 10 - `add` is never used (no-unused-vars) +Found 2 problems +Checked 1 file diff --git a/tests/testdata/lint/with_report_config_override.out b/tests/testdata/lint/with_report_config_override.out new file mode 100644 index 000000000..7ca748158 --- /dev/null +++ b/tests/testdata/lint/with_report_config_override.out @@ -0,0 +1,41 @@ +{ + "diagnostics": [ + { + "filename": "[WILDCARD]a.ts", + "range": { + "start": { + "line": 1, + "col": 0, + "bytePos": 0 + }, + "end": { + "line": 1, + "col": 12, + "bytePos": 12 + } + }, + "message": "TODO should be tagged with (@username) or (#issue)", + "code": "ban-untagged-todo", + "hint": "Add a user tag or issue reference to the TODO comment, e.g. TODO(@djones), TODO(djones), TODO(#123)" + }, + { + "filename": "[WILDCARD]a.ts", + "range": { + "start": { + "line": 2, + "col": 9, + "bytePos": 22 + }, + "end": { + "line": 2, + "col": 12, + "bytePos": 25 + } + }, + "message": "`add` is never used", + "code": "no-unused-vars", + "hint": "If this is intentional, prefix it with an underscore like `_add`" + } + ], + "errors": [] +} diff --git a/tests/testdata/lint/without_config/file1.js b/tests/testdata/lint/without_config/file1.js new file mode 100644 index 000000000..737f26818 --- /dev/null +++ b/tests/testdata/lint/without_config/file1.js @@ -0,0 +1,2 @@ +// deno-lint-ignore +while (false) {} diff --git a/tests/testdata/lint/without_config/file2.ts b/tests/testdata/lint/without_config/file2.ts new file mode 100644 index 000000000..73c612c35 --- /dev/null +++ b/tests/testdata/lint/without_config/file2.ts @@ -0,0 +1,6 @@ +try { + await Deno.open("./some/file.txt"); +} catch (_e) {} + +// deno-lint-ignore no-explicit-any +function _foo(): any {} diff --git a/tests/testdata/lint/without_config/ignored_file.ts b/tests/testdata/lint/without_config/ignored_file.ts new file mode 100644 index 000000000..97befafa3 --- /dev/null +++ b/tests/testdata/lint/without_config/ignored_file.ts @@ -0,0 +1,3 @@ +// deno-lint-ignore-file + +function foo(): any {} diff --git a/tests/testdata/lint/without_config/malformed.js b/tests/testdata/lint/without_config/malformed.js new file mode 100644 index 000000000..9b64da898 --- /dev/null +++ b/tests/testdata/lint/without_config/malformed.js @@ -0,0 +1,4 @@ +// deno-fmt-ignore-file + +// intentionally malformed file +export class A B C \ No newline at end of file diff --git a/tests/testdata/lockfile/basic/bench.nolock.out b/tests/testdata/lockfile/basic/bench.nolock.out new file mode 100644 index 000000000..83e4de242 --- /dev/null +++ b/tests/testdata/lockfile/basic/bench.nolock.out @@ -0,0 +1,6 @@ +Download http://localhost:4545/lockfile/basic/mod.ts +Check file:///[WILDCARD]/main.bench.ts +cpu: [WILDCARD] +runtime: [WILDCARD] + +[WILDCARD] diff --git a/tests/testdata/lockfile/basic/deno.json b/tests/testdata/lockfile/basic/deno.json new file mode 100644 index 000000000..d6541b78e --- /dev/null +++ b/tests/testdata/lockfile/basic/deno.json @@ -0,0 +1,5 @@ +{ + "imports": { + "mod": "http://localhost:4545/lockfile/basic/mod.ts" + } +} diff --git a/tests/testdata/lockfile/basic/deno.lock b/tests/testdata/lockfile/basic/deno.lock new file mode 100644 index 000000000..42ab94f9b --- /dev/null +++ b/tests/testdata/lockfile/basic/deno.lock @@ -0,0 +1,6 @@ +{ + "version": "2", + "remote": { + "http://localhost:4545/lockfile/basic/mod.ts": "invalid" + } +} diff --git a/tests/testdata/lockfile/basic/doc.nolock.out b/tests/testdata/lockfile/basic/doc.nolock.out new file mode 100644 index 000000000..e2d66c027 --- /dev/null +++ b/tests/testdata/lockfile/basic/doc.nolock.out @@ -0,0 +1 @@ +Download http://localhost:4545/lockfile/basic/mod.ts diff --git a/tests/testdata/lockfile/basic/fail.out b/tests/testdata/lockfile/basic/fail.out new file mode 100644 index 000000000..6a808c0a5 --- /dev/null +++ b/tests/testdata/lockfile/basic/fail.out @@ -0,0 +1,4 @@ +Download http://localhost:4545/lockfile/basic/mod.ts +error: The source code is invalid, as it does not match the expected hash in the lock file. + Specifier: [WILDCARD]mod.ts + Lock file: [WILDCARD]deno.lock diff --git a/tests/testdata/lockfile/basic/info.nolock.out b/tests/testdata/lockfile/basic/info.nolock.out new file mode 100644 index 000000000..d1ef82e49 --- /dev/null +++ b/tests/testdata/lockfile/basic/info.nolock.out @@ -0,0 +1,8 @@ +Download http://localhost:4545/lockfile/basic/mod.ts +local: [WILDCARD]main.ts +type: TypeScript +dependencies: 1 unique +size: [WILDCARD] + +file:///[WILDCARD]/main.ts ([WILDCARD]) +└── http://localhost:4545/lockfile/basic/mod.ts ([WILDCARD]) diff --git a/tests/testdata/lockfile/basic/main.bench.ts b/tests/testdata/lockfile/basic/main.bench.ts new file mode 100644 index 000000000..918adde2f --- /dev/null +++ b/tests/testdata/lockfile/basic/main.bench.ts @@ -0,0 +1,8 @@ +import { getValue } from "mod"; + +Deno.bench("bench", () => { + const testing = 1 + getValue(); + if (testing !== 6) { + throw "FAIL"; + } +}); diff --git a/tests/testdata/lockfile/basic/main.test.ts b/tests/testdata/lockfile/basic/main.test.ts new file mode 100644 index 000000000..fe45c799d --- /dev/null +++ b/tests/testdata/lockfile/basic/main.test.ts @@ -0,0 +1,8 @@ +import { getValue } from "mod"; + +Deno.test("test", () => { + const testing = 1 + getValue(); + if (testing !== 6) { + throw "FAIL"; + } +}); diff --git a/tests/testdata/lockfile/basic/main.ts b/tests/testdata/lockfile/basic/main.ts new file mode 100644 index 000000000..8d07c8153 --- /dev/null +++ b/tests/testdata/lockfile/basic/main.ts @@ -0,0 +1,3 @@ +import { getValue } from "mod"; + +console.log(getValue()); diff --git a/tests/testdata/lockfile/basic/mod.ts b/tests/testdata/lockfile/basic/mod.ts new file mode 100644 index 000000000..358b4b09e --- /dev/null +++ b/tests/testdata/lockfile/basic/mod.ts @@ -0,0 +1,3 @@ +export function getValue() { + return 5; +} diff --git a/tests/testdata/lockfile/basic/test.nolock.out b/tests/testdata/lockfile/basic/test.nolock.out new file mode 100644 index 000000000..1332dfa8f --- /dev/null +++ b/tests/testdata/lockfile/basic/test.nolock.out @@ -0,0 +1,4 @@ +Download http://localhost:4545/lockfile/basic/mod.ts +Check file:///[WILDCARD]/main.test.ts +running 1 test from [WILDCARD]/main.test.ts +[WILDCARD] diff --git a/tests/testdata/lockfile/no_dts/deno.lock.out b/tests/testdata/lockfile/no_dts/deno.lock.out new file mode 100644 index 000000000..6aa547e28 --- /dev/null +++ b/tests/testdata/lockfile/no_dts/deno.lock.out @@ -0,0 +1,6 @@ +{ + "version": "3", + "remote": { + "http://localhost:4545/lockfile/no_dts/mod.js": "3f576f37a301d298c3032eb1835240bd83f3762db26fc1d358c5d67088d6ffc8" + } +} diff --git a/tests/testdata/lockfile/no_dts/main.cache.out b/tests/testdata/lockfile/no_dts/main.cache.out new file mode 100644 index 000000000..ee8ad33ab --- /dev/null +++ b/tests/testdata/lockfile/no_dts/main.cache.out @@ -0,0 +1,2 @@ +Download http://localhost:4545/lockfile/no_dts/mod.js +Download http://localhost:4545/lockfile/no_dts/mod.d.ts diff --git a/tests/testdata/lockfile/no_dts/main.ts b/tests/testdata/lockfile/no_dts/main.ts new file mode 100644 index 000000000..7596e1e1a --- /dev/null +++ b/tests/testdata/lockfile/no_dts/main.ts @@ -0,0 +1,3 @@ +import { test } from "http://localhost:4545/lockfile/no_dts/mod.js"; + +console.log(test()); diff --git a/tests/testdata/lockfile/no_dts/mod.d.ts b/tests/testdata/lockfile/no_dts/mod.d.ts new file mode 100644 index 000000000..7d3fae61c --- /dev/null +++ b/tests/testdata/lockfile/no_dts/mod.d.ts @@ -0,0 +1 @@ +export declare function test(): number; diff --git a/tests/testdata/lockfile/no_dts/mod.js b/tests/testdata/lockfile/no_dts/mod.js new file mode 100644 index 000000000..8ac948700 --- /dev/null +++ b/tests/testdata/lockfile/no_dts/mod.js @@ -0,0 +1,4 @@ +/// +export function test() { + return 5; +} diff --git a/tests/testdata/lsp/deno.import_map.jsonc b/tests/testdata/lsp/deno.import_map.jsonc new file mode 100644 index 000000000..1682ff6b5 --- /dev/null +++ b/tests/testdata/lsp/deno.import_map.jsonc @@ -0,0 +1,3 @@ +{ + "importMap": "import-map.json" +} diff --git a/tests/testdata/lsp/deno.lint.exclude.jsonc b/tests/testdata/lsp/deno.lint.exclude.jsonc new file mode 100644 index 000000000..9d4ba52ad --- /dev/null +++ b/tests/testdata/lsp/deno.lint.exclude.jsonc @@ -0,0 +1,16 @@ +{ + "lint": { + "exclude": [ + "ignored.ts" + ], + "rules": { + "exclude": [ + "camelcase" + ], + "include": [ + "ban-untagged-todo" + ], + "tags": [] + } + } +} diff --git a/tests/testdata/lsp/diagnostics_deno_types.json b/tests/testdata/lsp/diagnostics_deno_types.json new file mode 100644 index 000000000..6ab153093 --- /dev/null +++ b/tests/testdata/lsp/diagnostics_deno_types.json @@ -0,0 +1,101 @@ +{ + "uri": "file:///a/file.ts", + "diagnostics": [ + { + "range": { + "start": { + "line": 0, + "character": 21 + }, + "end": { + "line": 0, + "character": 51 + } + }, + "severity": 1, + "code": "no-cache", + "source": "deno", + "message": "Uncached or missing remote URL: https://example.com/a/b.d.ts", + "data": { + "specifier": "https://example.com/a/b.d.ts" + } + }, + { + "range": { + "start": { + "line": 7, + "character": 19 + }, + "end": { + "line": 7, + "character": 47 + } + }, + "severity": 1, + "code": "no-cache", + "source": "deno", + "message": "Uncached or missing remote URL: https://example.com/a/e.js", + "data": { + "specifier": "https://example.com/a/e.js" + } + }, + { + "range": { + "start": { + "line": 6, + "character": 16 + }, + "end": { + "line": 6, + "character": 44 + } + }, + "severity": 1, + "code": "no-cache", + "source": "deno", + "message": "Uncached or missing remote URL: https://example.com/a/e.d.ts", + "data": { + "specifier": "https://example.com/a/e.d.ts" + } + }, + { + "range": { + "start": { + "line": 4, + "character": 19 + }, + "end": { + "line": 4, + "character": 47 + } + }, + "severity": 1, + "code": "no-cache", + "source": "deno", + "message": "Uncached or missing remote URL: https://example.com/a/d.js", + "data": { + "specifier": "https://example.com/a/d.js" + } + }, + { + "range": { + "start": { + "line": 3, + "character": 15 + }, + "end": { + "line": 3, + "character": 43 + } + }, + "severity": 1, + "code": "no-cache", + "source": "deno", + "message": "Uncached or missing remote URL: https://example.com/a/d.d.ts", + "data": { + "specifier": "https://example.com/a/d.d.ts" + } + } + ], + "version": 1 +} diff --git a/tests/testdata/lsp/import-map.json b/tests/testdata/lsp/import-map.json new file mode 100644 index 000000000..75d5d0849 --- /dev/null +++ b/tests/testdata/lsp/import-map.json @@ -0,0 +1,5 @@ +{ + "imports": { + "/~/": "./lib/" + } +} diff --git a/tests/testdata/lsp/large_file.txt b/tests/testdata/lsp/large_file.txt new file mode 100644 index 000000000..f1ca0481c --- /dev/null +++ b/tests/testdata/lsp/large_file.txt @@ -0,0 +1,676 @@ +// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. + +// @ts-check +/// +// deno-lint-ignore-file no-undef + +// This module is the entry point for "compiler" isolate, ie. the one +// that is created when Deno needs to type check TypeScript, and in some +// instances convert TypeScript to JavaScript. + +// Removes the `__proto__` for security reasons. This intentionally makes +// Deno non compliant with ECMA-262 Annex B.2.2.1 +delete Object.prototype.__proto__; + +((window) => { + /** @type {DenoCore} */ + const core = window.Deno.core; + + let logDebug = false; + let logSource = "JS"; + + function setLogDebug(debug, source) { + logDebug = debug; + if (source) { + logSource = source; + } + } + + function debug(...args) { + if (logDebug) { + const stringifiedArgs = args.map((arg) => + typeof arg === "string" ? arg : JSON.stringify(arg) + ).join(" "); + // adding a non-zero integer value to the end of the debug string causes + // the message to be printed to stderr instead of stdout, which is better + // aligned to the behaviour of debug messages + core.print(`DEBUG ${logSource} - ${stringifiedArgs}\n`, 1); + } + } + + function error(...args) { + const stringifiedArgs = args.map((arg) => + typeof arg === "string" || arg instanceof Error + ? String(arg) + : JSON.stringify(arg) + ).join(" "); + core.print(`ERROR ${logSource} = ${stringifiedArgs}\n`, 1); + } + + class AssertionError extends Error { + constructor(msg) { + super(msg); + this.name = "AssertionError"; + } + } + + function assert(cond, msg = "Assertion failed.") { + if (!cond) { + throw new AssertionError(msg); + } + } + + /** @type {Map} */ + const sourceFileCache = new Map(); + + /** @param {ts.DiagnosticRelatedInformation} diagnostic */ + function fromRelatedInformation({ + start, + length, + file, + messageText: msgText, + ...ri + }) { + let messageText; + let messageChain; + if (typeof msgText === "object") { + messageChain = msgText; + } else { + messageText = msgText; + } + if (start !== undefined && length !== undefined && file) { + const startPos = file.getLineAndCharacterOfPosition(start); + const sourceLine = file.getFullText().split("\n")[startPos.line]; + const fileName = file.fileName; + return { + start: startPos, + end: file.getLineAndCharacterOfPosition(start + length), + fileName, + messageChain, + messageText, + sourceLine, + ...ri, + }; + } else { + return { + messageChain, + messageText, + ...ri, + }; + } + } + + /** @param {ts.Diagnostic[]} diagnostics */ + function fromTypeScriptDiagnostic(diagnostics) { + return diagnostics.map(({ relatedInformation: ri, source, ...diag }) => { + /** @type {any} */ + const value = fromRelatedInformation(diag); + value.relatedInformation = ri + ? ri.map(fromRelatedInformation) + : undefined; + value.source = source; + return value; + }); + } + + // Using incremental compile APIs requires that all + // paths must be either relative or absolute. Since + // analysis in Rust operates on fully resolved URLs, + // it makes sense to use the same scheme here. + const ASSETS = "asset:///"; + const CACHE = "cache:///"; + + /** Diagnostics that are intentionally ignored when compiling TypeScript in + * Deno, as they provide misleading or incorrect information. */ + const IGNORED_DIAGNOSTICS = [ + // TS1208: All files must be modules when the '--isolatedModules' flag is + // provided. We can ignore because we guarantee that all files are + // modules. + 1208, + // TS1375: 'await' expressions are only allowed at the top level of a file + // when that file is a module, but this file has no imports or exports. + // Consider adding an empty 'export {}' to make this file a module. + 1375, + // TS1103: 'for-await-of' statement is only allowed within an async function + // or async generator. + 1103, + // TS2306: File 'file:///Users/rld/src/deno/subdir/amd_like.js' is + // not a module. + 2306, + // TS2691: An import path cannot end with a '.ts' extension. Consider + // importing 'bad-module' instead. + 2691, + // TS2792: Cannot find module. Did you mean to set the 'moduleResolution' + // option to 'node', or to add aliases to the 'paths' option? + 2792, + // TS5009: Cannot find the common subdirectory path for the input files. + 5009, + // TS5055: Cannot write file + // 'http://localhost:4545/subdir/mt_application_x_javascript.j4.js' + // because it would overwrite input file. + 5055, + // TypeScript is overly opinionated that only CommonJS modules kinds can + // support JSON imports. Allegedly this was fixed in + // Microsoft/TypeScript#26825 but that doesn't seem to be working here, + // so we will ignore complaints about this compiler setting. + 5070, + // TS7016: Could not find a declaration file for module '...'. '...' + // implicitly has an 'any' type. This is due to `allowJs` being off by + // default but importing of a JavaScript module. + 7016, + ]; + + const SNAPSHOT_COMPILE_OPTIONS = { + esModuleInterop: true, + jsx: ts.JsxEmit.React, + module: ts.ModuleKind.ESNext, + noEmit: true, + strict: true, + target: ts.ScriptTarget.ESNext, + }; + + class ScriptSnapshot { + /** @type {string} */ + specifier; + /** @type {string} */ + version; + /** + * @param {string} specifier + * @param {string} version + */ + constructor(specifier, version) { + this.specifier = specifier; + this.version = version; + } + /** + * @param {number} start + * @param {number} end + * @returns {string} + */ + getText(start, end) { + const { specifier, version } = this; + debug( + `snapshot.getText(${start}, ${end}) specifier: ${specifier} version: ${version}`, + ); + return core.jsonOpSync("op_get_text", { specifier, version, start, end }); + } + /** + * @returns {number} + */ + getLength() { + const { specifier, version } = this; + debug(`snapshot.getLength() specifier: ${specifier} version: ${version}`); + return core.jsonOpSync("op_get_length", { specifier, version }); + } + /** + * @param {ScriptSnapshot} oldSnapshot + * @returns {ts.TextChangeRange | undefined} + */ + getChangeRange(oldSnapshot) { + const { specifier, version } = this; + const { version: oldVersion } = oldSnapshot; + const oldLength = oldSnapshot.getLength(); + debug( + `snapshot.getLength() specifier: ${specifier} oldVersion: ${oldVersion} version: ${version}`, + ); + return core.jsonOpSync( + "op_get_change_range", + { specifier, oldLength, oldVersion, version }, + ); + } + dispose() { + const { specifier, version } = this; + debug(`snapshot.dispose() specifier: ${specifier} version: ${version}`); + core.jsonOpSync("op_dispose", { specifier, version }); + } + } + + /** @type {ts.CompilerOptions} */ + let compilationSettings = {}; + + /** @type {ts.LanguageService} */ + let languageService; + + /** An object literal of the incremental compiler host, which provides the + * specific "bindings" to the Deno environment that tsc needs to work. + * + * @type {ts.CompilerHost & ts.LanguageServiceHost} */ + const host = { + fileExists(fileName) { + debug(`host.fileExists("${fileName}")`); + return false; + }, + readFile(specifier) { + debug(`host.readFile("${specifier}")`); + return core.jsonOpSync("op_load", { specifier }).data; + }, + getSourceFile( + specifier, + languageVersion, + _onError, + _shouldCreateNewSourceFile, + ) { + debug( + `host.getSourceFile("${specifier}", ${ + ts.ScriptTarget[languageVersion] + })`, + ); + let sourceFile = sourceFileCache.get(specifier); + if (sourceFile) { + return sourceFile; + } + + /** @type {{ data: string; hash?: string; scriptKind: ts.ScriptKind }} */ + const { data, hash, scriptKind } = core.jsonOpSync( + "op_load", + { specifier }, + ); + assert( + data != null, + `"data" is unexpectedly null for "${specifier}".`, + ); + sourceFile = ts.createSourceFile( + specifier, + data, + languageVersion, + false, + scriptKind, + ); + sourceFile.moduleName = specifier; + sourceFile.version = hash; + sourceFileCache.set(specifier, sourceFile); + return sourceFile; + }, + getDefaultLibFileName() { + return `${ASSETS}/lib.esnext.d.ts`; + }, + getDefaultLibLocation() { + return ASSETS; + }, + writeFile(fileName, data, _writeByteOrderMark, _onError, sourceFiles) { + debug(`host.writeFile("${fileName}")`); + let maybeSpecifiers; + if (sourceFiles) { + maybeSpecifiers = sourceFiles.map((sf) => sf.moduleName); + } + return core.jsonOpSync( + "op_emit", + { maybeSpecifiers, fileName, data }, + ); + }, + getCurrentDirectory() { + return CACHE; + }, + getCanonicalFileName(fileName) { + return fileName; + }, + useCaseSensitiveFileNames() { + return true; + }, + getNewLine() { + return "\n"; + }, + resolveModuleNames(specifiers, base) { + debug(`host.resolveModuleNames()`); + debug(` base: ${base}`); + debug(` specifiers: ${specifiers.join(", ")}`); + /** @type {Array<[string, ts.Extension] | undefined>} */ + const resolved = core.jsonOpSync("op_resolve", { + specifiers, + base, + }); + if (resolved) { + const result = resolved.map((item) => { + if (item) { + const [resolvedFileName, extension] = item; + return { + resolvedFileName, + extension, + isExternalLibraryImport: false, + }; + } + return undefined; + }); + result.length = specifiers.length; + return result; + } else { + return new Array(specifiers.length); + } + }, + createHash(data) { + return core.jsonOpSync("op_create_hash", { data }).hash; + }, + + // LanguageServiceHost + getCompilationSettings() { + debug("host.getCompilationSettings()"); + return compilationSettings; + }, + getScriptFileNames() { + debug("host.getScriptFileNames()"); + return core.jsonOpSync("op_script_names", undefined); + }, + getScriptVersion(specifier) { + debug(`host.getScriptVersion("${specifier}")`); + const sourceFile = sourceFileCache.get(specifier); + if (sourceFile) { + return sourceFile.version ?? "1"; + } + return core.jsonOpSync("op_script_version", { specifier }); + }, + getScriptSnapshot(specifier) { + debug(`host.getScriptSnapshot("${specifier}")`); + const sourceFile = sourceFileCache.get(specifier); + if (sourceFile) { + return { + getText(start, end) { + return sourceFile.text.substring(start, end); + }, + getLength() { + return sourceFile.text.length; + }, + getChangeRange() { + return undefined; + }, + }; + } + /** @type {string | undefined} */ + const version = core.jsonOpSync("op_script_version", { specifier }); + if (version != null) { + return new ScriptSnapshot(specifier, version); + } + return undefined; + }, + }; + + /** @type {Array<[string, number]>} */ + const stats = []; + let statsStart = 0; + + function performanceStart() { + stats.length = 0; + statsStart = Date.now(); + ts.performance.enable(); + } + + /** + * @param {{ program: ts.Program | ts.EmitAndSemanticDiagnosticsBuilderProgram, fileCount?: number }} options + */ + function performanceProgram({ program, fileCount }) { + if (program) { + if ("getProgram" in program) { + program = program.getProgram(); + } + stats.push(["Files", program.getSourceFiles().length]); + stats.push(["Nodes", program.getNodeCount()]); + stats.push(["Identifiers", program.getIdentifierCount()]); + stats.push(["Symbols", program.getSymbolCount()]); + stats.push(["Types", program.getTypeCount()]); + stats.push(["Instantiations", program.getInstantiationCount()]); + } else if (fileCount != null) { + stats.push(["Files", fileCount]); + } + const programTime = ts.performance.getDuration("Program"); + const bindTime = ts.performance.getDuration("Bind"); + const checkTime = ts.performance.getDuration("Check"); + const emitTime = ts.performance.getDuration("Emit"); + stats.push(["Parse time", programTime]); + stats.push(["Bind time", bindTime]); + stats.push(["Check time", checkTime]); + stats.push(["Emit time", emitTime]); + stats.push( + ["Total TS time", programTime + bindTime + checkTime + emitTime], + ); + } + + function performanceEnd() { + const duration = Date.now() - statsStart; + stats.push(["Compile time", duration]); + return stats; + } + + /** + * @typedef {object} Request + * @property {Record} config + * @property {boolean} debug + * @property {string[]} rootNames + */ + + /** The API that is called by Rust when executing a request. + * @param {Request} request + */ + function exec({ config, debug: debugFlag, rootNames }) { + setLogDebug(debugFlag, "TS"); + performanceStart(); + debug(">>> exec start", { rootNames }); + debug(config); + + const { options, errors: configFileParsingDiagnostics } = ts + .convertCompilerOptionsFromJson(config, ""); + // The `allowNonTsExtensions` is a "hidden" compiler option used in VSCode + // which is not allowed to be passed in JSON, we need it to allow special + // URLs which Deno supports. So we need to either ignore the diagnostic, or + // inject it ourselves. + Object.assign(options, { allowNonTsExtensions: true }); + const program = ts.createIncrementalProgram({ + rootNames, + options, + host, + configFileParsingDiagnostics, + }); + + const { diagnostics: emitDiagnostics } = program.emit(); + + const diagnostics = [ + ...program.getConfigFileParsingDiagnostics(), + ...program.getSyntacticDiagnostics(), + ...program.getOptionsDiagnostics(), + ...program.getGlobalDiagnostics(), + ...program.getSemanticDiagnostics(), + ...emitDiagnostics, + ].filter(({ code }) => !IGNORED_DIAGNOSTICS.includes(code)); + performanceProgram({ program }); + + core.jsonOpSync("op_respond", { + diagnostics: fromTypeScriptDiagnostic(diagnostics), + stats: performanceEnd(), + }); + debug("<<< exec stop"); + } + + /** + * @param {number} id + * @param {any} data + */ + function respond(id, data = null) { + core.jsonOpSync("op_respond", { id, data }); + } + + /** + * @param {LanguageServerRequest} request + */ + function serverRequest({ id, ...request }) { + debug(`serverRequest()`, { id, ...request }); + switch (request.method) { + case "configure": { + const { options, errors } = ts + .convertCompilerOptionsFromJson(request.compilerOptions, ""); + Object.assign(options, { allowNonTsExtensions: true }); + if (errors.length) { + debug(ts.formatDiagnostics(errors, host)); + } + compilationSettings = options; + return respond(id, true); + } + case "getAsset": { + const sourceFile = host.getSourceFile( + request.specifier, + ts.ScriptTarget.ESNext, + ); + return respond(id, sourceFile && sourceFile.text); + } + case "getDiagnostics": { + try { + /** @type {Record} */ + const diagnosticMap = {}; + for (const specifier of request.specifiers) { + diagnosticMap[specifier] = fromTypeScriptDiagnostic([ + ...languageService.getSemanticDiagnostics(specifier), + ...languageService.getSuggestionDiagnostics(specifier), + ...languageService.getSyntacticDiagnostics(specifier), + ].filter(({ code }) => !IGNORED_DIAGNOSTICS.includes(code))); + } + return respond(id, diagnosticMap); + } catch (e) { + if ("stack" in e) { + error(e.stack); + } else { + error(e); + } + return respond(id, {}); + } + } + case "getQuickInfo": { + return respond( + id, + languageService.getQuickInfoAtPosition( + request.specifier, + request.position, + ), + ); + } + case "getCompletions": { + return respond( + id, + languageService.getCompletionsAtPosition( + request.specifier, + request.position, + request.preferences, + ), + ); + } + case "getDocumentHighlights": { + return respond( + id, + languageService.getDocumentHighlights( + request.specifier, + request.position, + request.filesToSearch, + ), + ); + } + case "getReferences": { + return respond( + id, + languageService.getReferencesAtPosition( + request.specifier, + request.position, + ), + ); + } + case "getDefinition": { + return respond( + id, + languageService.getDefinitionAndBoundSpan( + request.specifier, + request.position, + ), + ); + } + case "getImplementation": { + return respond( + id, + languageService.getImplementationAtPosition( + request.specifier, + request.position, + ), + ); + } + case "findRenameLocations": { + return respond( + id, + languageService.findRenameLocations( + request.specifier, + request.position, + request.findInStrings, + request.findInComments, + request.providePrefixAndSuffixTextForRename, + ), + ); + } + default: + throw new TypeError( + // @ts-ignore exhausted case statement sets type to never + `Invalid request method for request: "${request.method}" (${id})`, + ); + } + } + + /** @param {{ debug: boolean; }} init */ + function serverInit({ debug: debugFlag }) { + if (hasStarted) { + throw new Error("The language server has already been initialized."); + } + hasStarted = true; + languageService = ts.createLanguageService(host); + core.ops(); + setLogDebug(debugFlag, "TSLS"); + debug("serverInit()"); + } + + let hasStarted = false; + + /** Startup the runtime environment, setting various flags. + * @param {{ debugFlag?: boolean; legacyFlag?: boolean; }} msg + */ + function startup({ debugFlag = false }) { + if (hasStarted) { + throw new Error("The compiler runtime already started."); + } + hasStarted = true; + core.ops(); + setLogDebug(!!debugFlag, "TS"); + } + + // Setup the compiler runtime during the build process. + core.ops(); + core.registerErrorClass("Error", Error); + + // A build time only op that provides some setup information that is used to + // ensure the snapshot is setup properly. + /** @type {{ buildSpecifier: string; libs: string[] }} */ + const { buildSpecifier, libs } = core.jsonOpSync("op_build_info", {}); + for (const lib of libs) { + const specifier = `lib.${lib}.d.ts`; + // we are using internal APIs here to "inject" our custom libraries into + // tsc, so things like `"lib": [ "deno.ns" ]` are supported. + if (!ts.libs.includes(lib)) { + ts.libs.push(lib); + ts.libMap.set(lib, `lib.${lib}.d.ts`); + } + // we are caching in memory common type libraries that will be re-used by + // tsc on when the snapshot is restored + assert( + host.getSourceFile(`${ASSETS}${specifier}`, ts.ScriptTarget.ESNext), + ); + } + // this helps ensure as much as possible is in memory that is re-usable + // before the snapshotting is done, which helps unsure fast "startup" for + // subsequent uses of tsc in Deno. + const TS_SNAPSHOT_PROGRAM = ts.createProgram({ + rootNames: [buildSpecifier], + options: SNAPSHOT_COMPILE_OPTIONS, + host, + }); + ts.getPreEmitDiagnostics(TS_SNAPSHOT_PROGRAM); + + // exposes the two functions that are called by `tsc::exec()` when type + // checking TypeScript. + globalThis.startup = startup; + globalThis.exec = exec; + + // exposes the functions that are called when the compiler is used as a + // language service. + globalThis.serverInit = serverInit; + globalThis.serverRequest = serverRequest; +})(this); diff --git a/tests/testdata/lsp/registries/a_latest_.json b/tests/testdata/lsp/registries/a_latest_.json new file mode 100644 index 000000000..f9f9d111e --- /dev/null +++ b/tests/testdata/lsp/registries/a_latest_.json @@ -0,0 +1,4 @@ +[ + "b/c.ts", + "d/e.js" +] diff --git a/tests/testdata/lsp/registries/a_v1.0.0_.json b/tests/testdata/lsp/registries/a_v1.0.0_.json new file mode 100644 index 000000000..f9f9d111e --- /dev/null +++ b/tests/testdata/lsp/registries/a_v1.0.0_.json @@ -0,0 +1,4 @@ +[ + "b/c.ts", + "d/e.js" +] diff --git a/tests/testdata/lsp/registries/a_v1.0.0_b.json b/tests/testdata/lsp/registries/a_v1.0.0_b.json new file mode 100644 index 000000000..20ec4ad90 --- /dev/null +++ b/tests/testdata/lsp/registries/a_v1.0.0_b.json @@ -0,0 +1,3 @@ +[ + "b/c.ts" +] diff --git a/tests/testdata/lsp/registries/a_v1.0.1_.json b/tests/testdata/lsp/registries/a_v1.0.1_.json new file mode 100644 index 000000000..f9f9d111e --- /dev/null +++ b/tests/testdata/lsp/registries/a_v1.0.1_.json @@ -0,0 +1,4 @@ +[ + "b/c.ts", + "d/e.js" +] diff --git a/tests/testdata/lsp/registries/a_v2.0.0_.json b/tests/testdata/lsp/registries/a_v2.0.0_.json new file mode 100644 index 000000000..f9f9d111e --- /dev/null +++ b/tests/testdata/lsp/registries/a_v2.0.0_.json @@ -0,0 +1,4 @@ +[ + "b/c.ts", + "d/e.js" +] diff --git a/tests/testdata/lsp/registries/a_versions_.json b/tests/testdata/lsp/registries/a_versions_.json new file mode 100644 index 000000000..930e38323 --- /dev/null +++ b/tests/testdata/lsp/registries/a_versions_.json @@ -0,0 +1,5 @@ +[ + "v1.0.0", + "v1.0.1", + "v2.0.0" +] diff --git a/tests/testdata/lsp/registries/a_versions_v1..json b/tests/testdata/lsp/registries/a_versions_v1..json new file mode 100644 index 000000000..1d8a865c1 --- /dev/null +++ b/tests/testdata/lsp/registries/a_versions_v1..json @@ -0,0 +1,4 @@ +[ + "v1.0.0", + "v1.0.1" +] diff --git a/tests/testdata/lsp/registries/b_latest_.json b/tests/testdata/lsp/registries/b_latest_.json new file mode 100644 index 000000000..f9f9d111e --- /dev/null +++ b/tests/testdata/lsp/registries/b_latest_.json @@ -0,0 +1,4 @@ +[ + "b/c.ts", + "d/e.js" +] diff --git a/tests/testdata/lsp/registries/b_v0.0.1_.json b/tests/testdata/lsp/registries/b_v0.0.1_.json new file mode 100644 index 000000000..f9f9d111e --- /dev/null +++ b/tests/testdata/lsp/registries/b_v0.0.1_.json @@ -0,0 +1,4 @@ +[ + "b/c.ts", + "d/e.js" +] diff --git a/tests/testdata/lsp/registries/b_v0.0.2_.json b/tests/testdata/lsp/registries/b_v0.0.2_.json new file mode 100644 index 000000000..f9f9d111e --- /dev/null +++ b/tests/testdata/lsp/registries/b_v0.0.2_.json @@ -0,0 +1,4 @@ +[ + "b/c.ts", + "d/e.js" +] diff --git a/tests/testdata/lsp/registries/b_v0.0.3_.json b/tests/testdata/lsp/registries/b_v0.0.3_.json new file mode 100644 index 000000000..f9f9d111e --- /dev/null +++ b/tests/testdata/lsp/registries/b_v0.0.3_.json @@ -0,0 +1,4 @@ +[ + "b/c.ts", + "d/e.js" +] diff --git a/tests/testdata/lsp/registries/b_versions_.json b/tests/testdata/lsp/registries/b_versions_.json new file mode 100644 index 000000000..9532fbb85 --- /dev/null +++ b/tests/testdata/lsp/registries/b_versions_.json @@ -0,0 +1,5 @@ +[ + "v0.0.1", + "v0.0.2", + "v0.0.3" +] diff --git a/tests/testdata/lsp/registries/cde_tags.json b/tests/testdata/lsp/registries/cde_tags.json new file mode 100644 index 000000000..24aeba56a --- /dev/null +++ b/tests/testdata/lsp/registries/cde_tags.json @@ -0,0 +1,4 @@ +[ + "1.0.0", + "1.0.1" +] diff --git a/tests/testdata/lsp/registries/cdef_tags.json b/tests/testdata/lsp/registries/cdef_tags.json new file mode 100644 index 000000000..a69cb1c55 --- /dev/null +++ b/tests/testdata/lsp/registries/cdef_tags.json @@ -0,0 +1,4 @@ +[ + "2.0.0", + "2.0.1" +] diff --git a/tests/testdata/lsp/registries/complex.json b/tests/testdata/lsp/registries/complex.json new file mode 100644 index 000000000..b6e28649a --- /dev/null +++ b/tests/testdata/lsp/registries/complex.json @@ -0,0 +1,5 @@ +[ + "efg", + "efgh", + "fg" +] diff --git a/tests/testdata/lsp/registries/complex_efg.json b/tests/testdata/lsp/registries/complex_efg.json new file mode 100644 index 000000000..cd170d1d8 --- /dev/null +++ b/tests/testdata/lsp/registries/complex_efg.json @@ -0,0 +1,6 @@ +[ + "0.2.2", + "0.2.1", + "0.2.0", + "0.1.0" +] diff --git a/tests/testdata/lsp/registries/complex_efg_0.2.0.json b/tests/testdata/lsp/registries/complex_efg_0.2.0.json new file mode 100644 index 000000000..d333b9e28 --- /dev/null +++ b/tests/testdata/lsp/registries/complex_efg_0.2.0.json @@ -0,0 +1,6 @@ +[ + "mod.ts", + "example/mod.ts", + "CHANGELOG.md", + "deps.ts" +] diff --git a/tests/testdata/lsp/registries/def_tags.json b/tests/testdata/lsp/registries/def_tags.json new file mode 100644 index 000000000..5a33204f2 --- /dev/null +++ b/tests/testdata/lsp/registries/def_tags.json @@ -0,0 +1,3 @@ +[ + "3.0.0" +] diff --git a/tests/testdata/lsp/registries/deno-import-intellisense-complex.json b/tests/testdata/lsp/registries/deno-import-intellisense-complex.json new file mode 100644 index 000000000..98e913bdb --- /dev/null +++ b/tests/testdata/lsp/registries/deno-import-intellisense-complex.json @@ -0,0 +1,22 @@ +{ + "version": 1, + "registries": [ + { + "schema": "/:module([a-zA-Z0-9_]*)@:version/:path*", + "variables": [ + { + "key": "module", + "url": "http://localhost:4545/lsp/registries/complex.json" + }, + { + "key": "version", + "url": "http://localhost:4545/lsp/registries/complex_${module}.json" + }, + { + "key": "path", + "url": "http://localhost:4545/lsp/registries/complex_${module}_${version}.json" + } + ] + } + ] +} diff --git a/tests/testdata/lsp/registries/deno-import-intellisense-key-first.json b/tests/testdata/lsp/registries/deno-import-intellisense-key-first.json new file mode 100644 index 000000000..9aa33ecd3 --- /dev/null +++ b/tests/testdata/lsp/registries/deno-import-intellisense-key-first.json @@ -0,0 +1,18 @@ +{ + "version": 1, + "registries": [ + { + "schema": "/:module([a-zA-Z0-9-_]+)@:tag([a-zA-Z0-9-_\\.]+)", + "variables": [ + { + "key": "module", + "url": "http://localhost:4545/lsp/registries/key_first.json" + }, + { + "key": "tag", + "url": "http://localhost:4545/lsp/registries/${module}_tags.json" + } + ] + } + ] +} diff --git a/tests/testdata/lsp/registries/deno-import-intellisense.json b/tests/testdata/lsp/registries/deno-import-intellisense.json new file mode 100644 index 000000000..5fd87085e --- /dev/null +++ b/tests/testdata/lsp/registries/deno-import-intellisense.json @@ -0,0 +1,62 @@ +{ + "version": 2, + "registries": [ + { + "schema": "/x/:module([a-z0-9_]*)@:version?/:path*", + "variables": [ + { + "key": "module", + "documentation": "/lsp/registries/doc_${module}.json", + "url": "/lsp/registries/modules_${module}.json" + }, + { + "key": "version", + "documentation": "/lsp/registries/doc_${module}_${{version}}.json", + "url": "/lsp/registries/${module}_versions_${{version}}.json" + }, + { + "key": "path", + "documentation": "/lsp/registries/doc_${module}_${{version}}_${path}.json", + "url": "/lsp/registries/${module}_${{version}}_${path}.json" + } + ] + }, + { + "schema": "/x/:module([a-z0-9_]*)/:path*", + "variables": [ + { + "key": "module", + "documentation": "/lsp/registries/doc_${module}.json", + "url": "/lsp/registries/modules_${module}.json" + }, + { + "key": "path", + "documentation": "/lsp/registries/doc_${module}_latest_${path}.json", + "url": "/lsp/registries/${module}_latest_${path}.json" + } + ] + }, + { + "schema": "/std@:version?/:path*", + "variables": [ + { + "key": "version", + "url": "/lsp/registries/std_${{version}}.json" + }, + { + "key": "path", + "url": "/lsp/registries/std_${{version}}_${path}.json" + } + ] + }, + { + "schema": "/std/:path*", + "variables": [ + { + "key": "path", + "url": "/lsp/registries/std_latest_${path}.json" + } + ] + } + ] +} diff --git a/tests/testdata/lsp/registries/doc_a.json b/tests/testdata/lsp/registries/doc_a.json new file mode 100644 index 000000000..ecddb9144 --- /dev/null +++ b/tests/testdata/lsp/registries/doc_a.json @@ -0,0 +1,4 @@ +{ + "kind": "markdown", + "value": "**a**" +} diff --git a/tests/testdata/lsp/registries/doc_a_latest_mod.ts.json b/tests/testdata/lsp/registries/doc_a_latest_mod.ts.json new file mode 100644 index 000000000..522f5b271 --- /dev/null +++ b/tests/testdata/lsp/registries/doc_a_latest_mod.ts.json @@ -0,0 +1,4 @@ +{ + "kind": "markdown", + "value": "**a**\n\nmod.ts" +} diff --git a/tests/testdata/lsp/registries/key_first.json b/tests/testdata/lsp/registries/key_first.json new file mode 100644 index 000000000..c95261b25 --- /dev/null +++ b/tests/testdata/lsp/registries/key_first.json @@ -0,0 +1,5 @@ +[ + "cde", + "cdef", + "def" +] diff --git a/tests/testdata/lsp/registries/modules_.json b/tests/testdata/lsp/registries/modules_.json new file mode 100644 index 000000000..fae3b40a3 --- /dev/null +++ b/tests/testdata/lsp/registries/modules_.json @@ -0,0 +1,8 @@ +{ + "items": [ + "a", + "b" + ], + "isIncomplete": true, + "preselect": "a" +} diff --git a/tests/testdata/lsp/registries/modules_a.json b/tests/testdata/lsp/registries/modules_a.json new file mode 100644 index 000000000..0163f18a4 --- /dev/null +++ b/tests/testdata/lsp/registries/modules_a.json @@ -0,0 +1,10 @@ +{ + "items": [ + "a", + "aa", + "ab", + "aba" + ], + "isIncomplete": false, + "preselect": "a" +} diff --git a/tests/testdata/lsp/types.tsconfig.json b/tests/testdata/lsp/types.tsconfig.json new file mode 100644 index 000000000..50de6939c --- /dev/null +++ b/tests/testdata/lsp/types.tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "types": [ + "./a.d.ts" + ] + }, + "lint": { + "rules": { + "tags": [] + } + } +} diff --git a/tests/testdata/lsp/x_deno_warning_redirect.js b/tests/testdata/lsp/x_deno_warning_redirect.js new file mode 100644 index 000000000..34b950566 --- /dev/null +++ b/tests/testdata/lsp/x_deno_warning_redirect.js @@ -0,0 +1 @@ +console.log("testing x-deno-warning header"); diff --git a/tests/testdata/malformed_config/deno.json b/tests/testdata/malformed_config/deno.json new file mode 100644 index 000000000..60df56527 --- /dev/null +++ b/tests/testdata/malformed_config/deno.json @@ -0,0 +1 @@ +not a json file diff --git a/tests/testdata/module_graph/file_tests-a.mjs b/tests/testdata/module_graph/file_tests-a.mjs new file mode 100644 index 000000000..72b3a67bc --- /dev/null +++ b/tests/testdata/module_graph/file_tests-a.mjs @@ -0,0 +1,3 @@ +import * as b from "./b.ts"; + +console.log(b); diff --git a/tests/testdata/module_graph/file_tests-b-mod.js b/tests/testdata/module_graph/file_tests-b-mod.js new file mode 100644 index 000000000..59d168993 --- /dev/null +++ b/tests/testdata/module_graph/file_tests-b-mod.js @@ -0,0 +1 @@ +export const b = "b"; diff --git a/tests/testdata/module_graph/file_tests-b.ts b/tests/testdata/module_graph/file_tests-b.ts new file mode 100644 index 000000000..59d168993 --- /dev/null +++ b/tests/testdata/module_graph/file_tests-b.ts @@ -0,0 +1 @@ +export const b = "b"; diff --git a/tests/testdata/module_graph/file_tests-c-mod.ts b/tests/testdata/module_graph/file_tests-c-mod.ts new file mode 100644 index 000000000..7f2cfac77 --- /dev/null +++ b/tests/testdata/module_graph/file_tests-c-mod.ts @@ -0,0 +1 @@ +export const c = "c"; diff --git a/tests/testdata/module_graph/file_tests-checkwithconfig.ts b/tests/testdata/module_graph/file_tests-checkwithconfig.ts new file mode 100644 index 000000000..e7af5fa19 --- /dev/null +++ b/tests/testdata/module_graph/file_tests-checkwithconfig.ts @@ -0,0 +1,5 @@ +import { ServerRequest } from "https://deno.land/std/http/server.ts"; + +export default (req: ServerRequest) => { + req.respond({ body: `Hello, from Deno v${Deno.version.deno}!` }); +}; diff --git a/tests/testdata/module_graph/file_tests-diag.ts b/tests/testdata/module_graph/file_tests-diag.ts new file mode 100644 index 000000000..ba365234a --- /dev/null +++ b/tests/testdata/module_graph/file_tests-diag.ts @@ -0,0 +1,4 @@ +import * as c from "./c/mod.ts"; + +// deno-lint-ignore no-undef +consol.log(c); diff --git a/tests/testdata/module_graph/file_tests-dynamicimport.ts b/tests/testdata/module_graph/file_tests-dynamicimport.ts new file mode 100644 index 000000000..b5c9f080f --- /dev/null +++ b/tests/testdata/module_graph/file_tests-dynamicimport.ts @@ -0,0 +1,5 @@ +try { + await import("bare_module_specifier"); +} catch (err) { + console.log(err); +} diff --git a/tests/testdata/module_graph/file_tests-importjson.ts b/tests/testdata/module_graph/file_tests-importjson.ts new file mode 100644 index 000000000..c2bc2bca7 --- /dev/null +++ b/tests/testdata/module_graph/file_tests-importjson.ts @@ -0,0 +1,3 @@ +import * as config from "./some.json"; + +console.log(config); diff --git a/tests/testdata/module_graph/file_tests-importremap.ts b/tests/testdata/module_graph/file_tests-importremap.ts new file mode 100644 index 000000000..17f012673 --- /dev/null +++ b/tests/testdata/module_graph/file_tests-importremap.ts @@ -0,0 +1,3 @@ +import * as a from "https://deno.land/x/a/mod.ts"; + +console.log(a); diff --git a/tests/testdata/module_graph/file_tests-main.ts b/tests/testdata/module_graph/file_tests-main.ts new file mode 100644 index 000000000..aa8eef1b8 --- /dev/null +++ b/tests/testdata/module_graph/file_tests-main.ts @@ -0,0 +1,4 @@ +// @deno-types="https://deno.land/x/lib/mod.d.ts" +import * as lib from "https://deno.land/x/lib/mod.js"; + +console.log(lib); diff --git a/tests/testdata/module_graph/file_tests-some.json b/tests/testdata/module_graph/file_tests-some.json new file mode 100644 index 000000000..567c4ba21 --- /dev/null +++ b/tests/testdata/module_graph/file_tests-some.json @@ -0,0 +1,5 @@ +{ + "config": { + "debug": true + } +} diff --git a/tests/testdata/module_graph/file_typesref.d.ts b/tests/testdata/module_graph/file_typesref.d.ts new file mode 100644 index 000000000..8ae31dde3 --- /dev/null +++ b/tests/testdata/module_graph/file_typesref.d.ts @@ -0,0 +1 @@ +export const a: "a"; diff --git a/tests/testdata/module_graph/file_typesref.js b/tests/testdata/module_graph/file_typesref.js new file mode 100644 index 000000000..79da24cae --- /dev/null +++ b/tests/testdata/module_graph/file_typesref.js @@ -0,0 +1,3 @@ +/// + +export const a = "a"; diff --git a/tests/testdata/module_graph/https_deno.land-std-http-server.ts b/tests/testdata/module_graph/https_deno.land-std-http-server.ts new file mode 100644 index 000000000..0b3c995ec --- /dev/null +++ b/tests/testdata/module_graph/https_deno.land-std-http-server.ts @@ -0,0 +1,5 @@ +export class ServerRequest { + respond(value: { body: string }) { + console.log(value); + } +} diff --git a/tests/testdata/module_graph/https_deno.land-x-a-mod.ts b/tests/testdata/module_graph/https_deno.land-x-a-mod.ts new file mode 100644 index 000000000..1e334d399 --- /dev/null +++ b/tests/testdata/module_graph/https_deno.land-x-a-mod.ts @@ -0,0 +1 @@ +export * as b from "../b/mod.js"; diff --git a/tests/testdata/module_graph/https_deno.land-x-a.ts b/tests/testdata/module_graph/https_deno.land-x-a.ts new file mode 100644 index 000000000..a6e3cea80 --- /dev/null +++ b/tests/testdata/module_graph/https_deno.land-x-a.ts @@ -0,0 +1 @@ +export const a = "hello"; diff --git a/tests/testdata/module_graph/https_deno.land-x-import_map.ts b/tests/testdata/module_graph/https_deno.land-x-import_map.ts new file mode 100644 index 000000000..e285d863a --- /dev/null +++ b/tests/testdata/module_graph/https_deno.land-x-import_map.ts @@ -0,0 +1,4 @@ +import * as $ from "jquery"; +import * as _ from "lodash"; + +console.log($, _); diff --git a/tests/testdata/module_graph/https_deno.land-x-jquery.js b/tests/testdata/module_graph/https_deno.land-x-jquery.js new file mode 100644 index 000000000..71896157a --- /dev/null +++ b/tests/testdata/module_graph/https_deno.land-x-jquery.js @@ -0,0 +1,3 @@ +const $ = {}; + +export default $; diff --git a/tests/testdata/module_graph/https_deno.land-x-lib-a.ts b/tests/testdata/module_graph/https_deno.land-x-lib-a.ts new file mode 100644 index 000000000..a0a6f8e94 --- /dev/null +++ b/tests/testdata/module_graph/https_deno.land-x-lib-a.ts @@ -0,0 +1 @@ +export const a: string[] = []; diff --git a/tests/testdata/module_graph/https_deno.land-x-lib-b.js b/tests/testdata/module_graph/https_deno.land-x-lib-b.js new file mode 100644 index 000000000..13cacdd8b --- /dev/null +++ b/tests/testdata/module_graph/https_deno.land-x-lib-b.js @@ -0,0 +1 @@ +export const b = []; diff --git a/tests/testdata/module_graph/https_deno.land-x-lib-c.d.ts b/tests/testdata/module_graph/https_deno.land-x-lib-c.d.ts new file mode 100644 index 000000000..fac988e49 --- /dev/null +++ b/tests/testdata/module_graph/https_deno.land-x-lib-c.d.ts @@ -0,0 +1 @@ +export const c: string[]; diff --git a/tests/testdata/module_graph/https_deno.land-x-lib-c.js b/tests/testdata/module_graph/https_deno.land-x-lib-c.js new file mode 100644 index 000000000..620ca0b66 --- /dev/null +++ b/tests/testdata/module_graph/https_deno.land-x-lib-c.js @@ -0,0 +1,3 @@ +/// + +export const c = []; diff --git a/tests/testdata/module_graph/https_deno.land-x-lib-mod.d.ts b/tests/testdata/module_graph/https_deno.land-x-lib-mod.d.ts new file mode 100644 index 000000000..76ed81df0 --- /dev/null +++ b/tests/testdata/module_graph/https_deno.land-x-lib-mod.d.ts @@ -0,0 +1,9 @@ +export * as a from "./a.ts"; +export * as b from "./b.js"; +export * as c from "./c.js"; + +export interface A { + a: string; +} + +export const mod: A[]; diff --git a/tests/testdata/module_graph/https_deno.land-x-lib-mod.js b/tests/testdata/module_graph/https_deno.land-x-lib-mod.js new file mode 100644 index 000000000..505162094 --- /dev/null +++ b/tests/testdata/module_graph/https_deno.land-x-lib-mod.js @@ -0,0 +1,5 @@ +export * as a from "./a.ts"; +export * as b from "./b.js"; +export * as c from "./c.js"; + +export const mod = []; diff --git a/tests/testdata/module_graph/https_deno.land-x-mod.ts b/tests/testdata/module_graph/https_deno.land-x-mod.ts new file mode 100644 index 000000000..35d76ef75 --- /dev/null +++ b/tests/testdata/module_graph/https_deno.land-x-mod.ts @@ -0,0 +1,3 @@ +import * as a from "./a.ts"; + +console.log(a); diff --git a/tests/testdata/module_graph/https_deno.land-x-transpile.tsx b/tests/testdata/module_graph/https_deno.land-x-transpile.tsx new file mode 100644 index 000000000..02955bad8 --- /dev/null +++ b/tests/testdata/module_graph/https_deno.land-x-transpile.tsx @@ -0,0 +1,5 @@ +export default class A { + render() { + return
Hello world!
; + } +} diff --git a/tests/testdata/module_graph/https_unpkg.com-lodash-index.js b/tests/testdata/module_graph/https_unpkg.com-lodash-index.js new file mode 100644 index 000000000..d16c126a6 --- /dev/null +++ b/tests/testdata/module_graph/https_unpkg.com-lodash-index.js @@ -0,0 +1,3 @@ +const _ = {}; + +export default _; diff --git a/tests/testdata/module_graph/lockfile.json b/tests/testdata/module_graph/lockfile.json new file mode 100644 index 000000000..03cfe1185 --- /dev/null +++ b/tests/testdata/module_graph/lockfile.json @@ -0,0 +1,8 @@ +{ + "https://deno.land/x/lib/a.ts": "4437fee72a750d9540a9575ea6426761d0aa1beedfa308fb1bc38701d97011b8", + "https://deno.land/x/lib/b.js": "093cc4164ca7a9adb11597ad291e021634f0b2d8c048137f7e9fb0d709499028", + "https://deno.land/x/lib/c.d.ts": "a95647377477cc663559f5e857bf318c584622ed1295a8ccb0c091d06bee0456", + "https://deno.land/x/lib/c.js": "4ff934f4b3b06f320c3130326376d9f2435e2ecedd582940ca90938137d004e1", + "https://deno.land/x/lib/mod.d.ts": "e54b994fbf63cb7f01076ea54f2ed67b185f2a48e8ff71d74bd9c8180a338eb7", + "https://deno.land/x/lib/mod.js": "3f6fcb8ef83ed6c66e71774d5079d14d22a6948dc6e5358ac30e0ab55e1a6404" +} diff --git a/tests/testdata/module_graph/lockfile_fail.json b/tests/testdata/module_graph/lockfile_fail.json new file mode 100644 index 000000000..c0019fba4 --- /dev/null +++ b/tests/testdata/module_graph/lockfile_fail.json @@ -0,0 +1,8 @@ +{ + "https://deno.land/x/lib/a.ts": "4437fee72a750d9540a9575ea6426761d0aa1beedfa308fb1bc38701d97011b8", + "https://deno.land/x/lib/b.js": "093cc4164ca7a9adb11597ad291e021634f0b2d8c048137f7e9fb0d709499028", + "https://deno.land/x/lib/c.d.ts": "a95647377477cc663559f5e857bf318c584622ed1295a8ccb0c091d06bee0456", + "https://deno.land/x/lib/c.js": "4ff934f4b3b06f320c3130326376d9f2435e2ecedd582940ca90938137d004e1", + "https://deno.land/x/lib/mod.d.ts": "e54b994fbf63cb7f01076ea54f2ed67b185f2a48e8ff71d74bd9c8180a338eb7", + "https://deno.land/x/lib/mod.js": "3f6fcb8ef83fd6c66e71774d5079d14d22a6948dc6e5358ac30e0ab55e1a6404" +} diff --git a/tests/testdata/module_graph/tsconfig.json b/tests/testdata/module_graph/tsconfig.json new file mode 100644 index 000000000..a4c5f4f33 --- /dev/null +++ b/tests/testdata/module_graph/tsconfig.json @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "target": "ES5", + "jsx": "preserve" + } +} diff --git a/tests/testdata/module_graph/tsconfig_01.json b/tests/testdata/module_graph/tsconfig_01.json new file mode 100644 index 000000000..f7496d475 --- /dev/null +++ b/tests/testdata/module_graph/tsconfig_01.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "strict": false, + "noImplicitAny": false, + "noImplicitThis": false, + "alwaysStrict": false, + "strictNullChecks": false, + "strictFunctionTypes": true, + "strictPropertyInitialization": false, + "experimentalDecorators": true, + "emitDecoratorMetadata": true + } +} diff --git a/tests/testdata/navigator_language.ts b/tests/testdata/navigator_language.ts new file mode 100644 index 000000000..1cdbc2fe6 --- /dev/null +++ b/tests/testdata/navigator_language.ts @@ -0,0 +1 @@ +console.log(navigator.language); diff --git a/tests/testdata/navigator_languages.ts b/tests/testdata/navigator_languages.ts new file mode 100644 index 000000000..41dece950 --- /dev/null +++ b/tests/testdata/navigator_languages.ts @@ -0,0 +1 @@ +console.log(navigator.languages); diff --git a/tests/testdata/node/rejection_handled_web_process.ts b/tests/testdata/node/rejection_handled_web_process.ts new file mode 100644 index 000000000..e331f8998 --- /dev/null +++ b/tests/testdata/node/rejection_handled_web_process.ts @@ -0,0 +1,26 @@ +import chalk from "npm:chalk"; +import process from "node:process"; + +console.log(chalk.red("Hello world!")); + +globalThis.addEventListener("unhandledrejection", (e) => { + console.log('globalThis.addEventListener("unhandledrejection");'); + e.preventDefault(); +}); + +globalThis.addEventListener("rejectionhandled", (_) => { + console.log("Web rejectionhandled"); +}); + +process.on("rejectionHandled", (_) => { + console.log("Node rejectionHandled"); +}); + +const a = Promise.reject(1); +setTimeout(() => { + a.catch(() => console.log("Added catch handler to the promise")); +}, 100); + +setTimeout(() => { + console.log("Success"); +}, 500); diff --git a/tests/testdata/node/rejection_handled_web_process.ts.out b/tests/testdata/node/rejection_handled_web_process.ts.out new file mode 100644 index 000000000..e6fefede2 --- /dev/null +++ b/tests/testdata/node/rejection_handled_web_process.ts.out @@ -0,0 +1,6 @@ +Hello world! +globalThis.addEventListener("unhandledrejection"); +Added catch handler to the promise +Web rejectionhandled +Node rejectionHandled +Success diff --git a/tests/testdata/node/require_esm_error/esm.js b/tests/testdata/node/require_esm_error/esm.js new file mode 100644 index 000000000..0613f1911 --- /dev/null +++ b/tests/testdata/node/require_esm_error/esm.js @@ -0,0 +1 @@ +export class Test {} diff --git a/tests/testdata/node/require_esm_error/main.out b/tests/testdata/node/require_esm_error/main.out new file mode 100644 index 000000000..3db23ff24 --- /dev/null +++ b/tests/testdata/node/require_esm_error/main.out @@ -0,0 +1,3 @@ +error: Uncaught (in promise) Error: require() of ES Module [WILDCARD]esm.js from [WILDCARD]main.ts not supported. Instead change the require to a dynamic import() which is available in all CommonJS modules. + at [WILDCARD] + at file:///[WILDCARD]/require_esm_error/main.ts:5:1 diff --git a/tests/testdata/node/require_esm_error/main.ts b/tests/testdata/node/require_esm_error/main.ts new file mode 100644 index 000000000..612e91714 --- /dev/null +++ b/tests/testdata/node/require_esm_error/main.ts @@ -0,0 +1,5 @@ +import { createRequire } from "node:module"; + +const require = createRequire(import.meta.url); + +require("./esm.js"); diff --git a/tests/testdata/node/test.js b/tests/testdata/node/test.js new file mode 100644 index 000000000..0f0f9b6b6 --- /dev/null +++ b/tests/testdata/node/test.js @@ -0,0 +1,390 @@ +// Copyright Joyent, Inc. and other Node contributors. + +// Ported from https://github.com/nodejs/node/blob/d396a041f71cc055ad60b0abc63ad81c0ee6a574/test/fixtures/test-runner/output/output.js + +// deno-lint-ignore-file + +import assert from "node:assert"; +import test from "node:test"; +import util from "node:util"; +import { setImmediate } from "node:timers"; + +test("sync pass todo", (t) => { + t.todo(); +}); + +test("sync pass todo with message", (t) => { + t.todo("this is a passing todo"); +}); + +test("sync fail todo", (t) => { + t.todo(); + throw new Error("thrown from sync fail todo"); +}); + +test("sync fail todo with message", (t) => { + t.todo("this is a failing todo"); + throw new Error("thrown from sync fail todo with message"); +}); + +test("sync skip pass", (t) => { + t.skip(); +}); + +test("sync skip pass with message", (t) => { + t.skip("this is skipped"); +}); + +test("sync pass", (t) => { + t.diagnostic("this test should pass"); +}); + +test("sync throw fail", () => { + throw new Error("thrown from sync throw fail"); +}); + +test("async skip pass", async (t) => { + t.skip(); +}); + +test("async pass", async () => { +}); + +test("async throw fail", async () => { + throw new Error("thrown from async throw fail"); +}); + +test("nested test", async (t) => { + await t.test("nested 1", async (t) => { + await t.test("nested 2", () => { + }); + }); +}); + +test("async skip fail", async (t) => { + t.skip(); + throw new Error("thrown from async throw fail"); +}); + +test("async assertion fail", async () => { + // Make sure the assert module is handled. + assert.strictEqual(true, false); +}); + +test("resolve pass", () => { + return Promise.resolve(); +}); + +test("reject fail", () => { + return Promise.reject(new Error("rejected from reject fail")); +}); + +test("unhandled rejection - passes but warns", () => { + Promise.reject(new Error("rejected from unhandled rejection fail")); +}); + +test("async unhandled rejection - passes but warns", async () => { + Promise.reject(new Error("rejected from async unhandled rejection fail")); +}); + +test("immediate throw - passes but warns", () => { + setImmediate(() => { + throw new Error("thrown from immediate throw fail"); + }); +}); + +test("immediate reject - passes but warns", () => { + setImmediate(() => { + Promise.reject(new Error("rejected from immediate reject fail")); + }); +}); + +test("immediate resolve pass", () => { + return new Promise((resolve) => { + setImmediate(() => { + resolve(); + }); + }); +}); + +test("subtest sync throw fail", async (t) => { + await t.test("+sync throw fail", (t) => { + t.diagnostic("this subtest should make its parent test fail"); + throw new Error("thrown from subtest sync throw fail"); + }); +}); + +test("sync throw non-error fail", async (t) => { + throw Symbol("thrown symbol from sync throw non-error fail"); +}); + +test("level 0a", { concurrency: 4 }, async (t) => { + t.test("level 1a", async (t) => { + const p1a = new Promise((resolve) => { + setTimeout(() => { + resolve(); + }, 100); + }); + + return p1a; + }); + + test("level 1b", async (t) => { + const p1b = new Promise((resolve) => { + resolve(); + }); + + return p1b; + }); + + t.test("level 1c", async (t) => { + const p1c = new Promise((resolve) => { + setTimeout(() => { + resolve(); + }, 200); + }); + + return p1c; + }); + + t.test("level 1d", async (t) => { + const p1c = new Promise((resolve) => { + setTimeout(() => { + resolve(); + }, 150); + }); + + return p1c; + }); + + const p0a = new Promise((resolve) => { + setTimeout(() => { + resolve(); + }, 300); + }); + + return p0a; +}); + +test("top level", { concurrency: 2 }, async (t) => { + t.test("+long running", async (t) => { + return new Promise((resolve, reject) => { + setTimeout(resolve, 300).unref(); + }); + }); + + t.test("+short running", async (t) => { + t.test("++short running", async (t) => {}); + }); +}); + +test("invalid subtest - pass but subtest fails", (t) => { + setImmediate(() => { + t.test("invalid subtest fail", () => { + throw new Error("this should not be thrown"); + }); + }); +}); + +test("sync skip option", { skip: true }, (t) => { + throw new Error("this should not be executed"); +}); + +test("sync skip option with message", { skip: "this is skipped" }, (t) => { + throw new Error("this should not be executed"); +}); + +test("sync skip option is false fail", { skip: false }, (t) => { + throw new Error("this should be executed"); +}); + +// A test with no arguments provided. +test(); + +// A test with only a named function provided. +test(function functionOnly() {}); + +// A test with only an anonymous function provided. +test(() => {}); + +// A test with only a name provided. +test("test with only a name provided"); + +// A test with an empty string name. +test(""); + +// A test with only options provided. +test({ skip: true }); + +// A test with only a name and options provided. +test("test with a name and options provided", { skip: true }); + +// A test with only options and a function provided. +test({ skip: true }, function functionAndOptions() {}); + +// A test whose description needs to be escaped. +// test("escaped description \\ # \\#\\ \n \t \f \v \b \r"); + +// A test whose skip message needs to be escaped. +test("escaped skip message", { skip: "#skip" }); + +// A test whose todo message needs to be escaped. +test("escaped todo message", { todo: "#todo" }); + +// A test with a diagnostic message that needs to be escaped. +test("escaped diagnostic", (t) => { + t.diagnostic("#diagnostic"); +}); + +test("callback pass", (t, done) => { + setImmediate(done); +}); + +test("callback fail", (t, done) => { + setImmediate(() => { + done(new Error("callback failure")); + }); +}); + +test("sync t is this in test", function (t) { + assert.strictEqual(this, t); +}); + +test("async t is this in test", async function (t) { + assert.strictEqual(this, t); +}); + +test("callback t is this in test", function (t, done) { + assert.strictEqual(this, t); + done(); +}); + +test("callback also returns a Promise", async (t, done) => { + throw new Error("thrown from callback also returns a Promise"); +}); + +test("callback throw", (t, done) => { + throw new Error("thrown from callback throw"); +}); + +test("callback called twice", (t, done) => { + done(); + done(); +}); + +test("callback called twice in different ticks", (t, done) => { + setImmediate(done); + done(); +}); + +test("callback called twice in future tick", (t, done) => { + setImmediate(() => { + done(); + done(); + }); +}); + +test("callback async throw", (t, done) => { + setImmediate(() => { + throw new Error("thrown from callback async throw"); + }); +}); + +test("callback async throw after done", (t, done) => { + setImmediate(() => { + throw new Error("thrown from callback async throw after done"); + }); + + done(); +}); + +test("custom inspect symbol fail", () => { + const obj = { + [util.inspect.custom]() { + return "customized"; + }, + foo: 1, + }; + + throw obj; +}); + +test("custom inspect symbol that throws fail", () => { + const obj = { + [util.inspect.custom]() { + throw new Error("bad-inspect"); + }, + foo: 1, + }; + + throw obj; +}); + +test("subtest sync throw fails", async (t) => { + await t.test("sync throw fails at first", (t) => { + throw new Error("thrown from subtest sync throw fails at first"); + }); + await t.test("sync throw fails at second", (t) => { + throw new Error("thrown from subtest sync throw fails at second"); + }); +}); + +test("timed out async test", { timeout: 5 }, async (t) => { + return new Promise((resolve) => { + setTimeout(resolve, 100); + }); +}); + +test("timed out callback test", { timeout: 5 }, (t, done) => { + setTimeout(done, 100); +}); + +test("large timeout async test is ok", { timeout: 30_000_000 }, async (t) => { + return new Promise((resolve) => { + setTimeout(resolve, 10); + }); +}); + +test( + "large timeout callback test is ok", + { timeout: 30_000_000 }, + (t, done) => { + setTimeout(done, 10); + }, +); + +test("successful thenable", () => { + let thenCalled = false; + return { + get then() { + if (thenCalled) throw new Error(); + thenCalled = true; + return (successHandler) => successHandler(); + }, + }; +}); + +test("rejected thenable", () => { + let thenCalled = false; + return { + get then() { + if (thenCalled) throw new Error(); + thenCalled = true; + return (_, errorHandler) => errorHandler("custom error"); + }, + }; +}); + +test("unfinished test with uncaughtException", async () => { + await new Promise(() => { + setTimeout(() => { + throw new Error("foo"); + }); + }); +}); + +test("unfinished test with unhandledRejection", async () => { + await new Promise(() => { + setTimeout(() => Promise.reject(new Error("bar"))); + }); +}); diff --git a/tests/testdata/node/test.out b/tests/testdata/node/test.out new file mode 100644 index 000000000..2579f605d --- /dev/null +++ b/tests/testdata/node/test.out @@ -0,0 +1,175 @@ +[WILDCARD] +running 63 tests from ./node/test.js +sync pass todo ... +------- output ------- +Warning: Not implemented: test.TestContext.todo +----- output end ----- +sync pass todo ... ok [WILDCARD] +sync pass todo with message ... +------- output ------- +Warning: Not implemented: test.TestContext.todo +----- output end ----- +sync pass todo with message ... ok [WILDCARD] +sync fail todo ... +------- output ------- +Warning: Not implemented: test.TestContext.todo +----- output end ----- +sync fail todo ... FAILED [WILDCARD] +sync fail todo with message ... +------- output ------- +Warning: Not implemented: test.TestContext.todo +----- output end ----- +sync fail todo with message ... FAILED [WILDCARD] +sync skip pass ... +------- output ------- +Warning: Not implemented: test.TestContext.skip +----- output end ----- +sync skip pass ... ok [WILDCARD] +sync skip pass with message ... +------- output ------- +Warning: Not implemented: test.TestContext.skip +----- output end ----- +sync skip pass with message ... ok [WILDCARD] +sync pass ... +------- output ------- +DIAGNOSTIC: this test should pass +----- output end ----- +sync pass ... ok [WILDCARD] +sync throw fail ... FAILED [WILDCARD] +async skip pass ... +------- output ------- +Warning: Not implemented: test.TestContext.skip +----- output end ----- +async skip pass ... ok [WILDCARD] +async pass ... ok [WILDCARD] +async throw fail ... FAILED [WILDCARD] +nested test ... + nested 1 ... + nested 2 ... ok [WILDCARD] + nested 1 ... ok [WILDCARD] +nested test ... ok [WILDCARD] +async skip fail ... +------- output ------- +Warning: Not implemented: test.TestContext.skip +----- output end ----- +async skip fail ... FAILED [WILDCARD] +async assertion fail ... FAILED [WILDCARD] +resolve pass ... ok [WILDCARD] +reject fail ... FAILED [WILDCARD] +unhandled rejection - passes but warns ... +Uncaught error from ./node/test.js FAILED +unhandled rejection - passes but warns ... cancelled ([WILDCARD]) +async unhandled rejection - passes but warns ... cancelled ([WILDCARD]) +immediate throw - passes but warns ... cancelled ([WILDCARD]) +immediate reject - passes but warns ... cancelled ([WILDCARD]) +immediate resolve pass ... cancelled ([WILDCARD]) +subtest sync throw fail ... cancelled ([WILDCARD]) +sync throw non-error fail ... cancelled ([WILDCARD]) +level 0a ... cancelled ([WILDCARD]) +top level ... cancelled ([WILDCARD]) +invalid subtest - pass but subtest fails ... cancelled ([WILDCARD]) +sync skip option ... ignored ([WILDCARD]) +sync skip option with message ... cancelled ([WILDCARD]) +sync skip option is false fail ... cancelled ([WILDCARD]) +noop ... cancelled ([WILDCARD]) +functionOnly ... cancelled ([WILDCARD]) + ... cancelled ([WILDCARD]) +test with only a name provided ... cancelled ([WILDCARD]) +noop ... cancelled ([WILDCARD]) +noop ... ignored ([WILDCARD]) +test with a name and options provided ... ignored ([WILDCARD]) +functionAndOptions ... ignored ([WILDCARD]) +escaped skip message ... cancelled ([WILDCARD]) +escaped todo message ... cancelled ([WILDCARD]) +escaped diagnostic ... cancelled ([WILDCARD]) +callback pass ... cancelled ([WILDCARD]) +callback fail ... cancelled ([WILDCARD]) +sync t is this in test ... cancelled ([WILDCARD]) +async t is this in test ... cancelled ([WILDCARD]) +callback t is this in test ... cancelled ([WILDCARD]) +callback also returns a Promise ... cancelled ([WILDCARD]) +callback throw ... cancelled ([WILDCARD]) +callback called twice ... cancelled ([WILDCARD]) +callback called twice in different ticks ... cancelled ([WILDCARD]) +callback called twice in future tick ... cancelled ([WILDCARD]) +callback async throw ... cancelled ([WILDCARD]) +callback async throw after done ... cancelled ([WILDCARD]) +custom inspect symbol fail ... cancelled ([WILDCARD]) +custom inspect symbol that throws fail ... cancelled ([WILDCARD]) +subtest sync throw fails ... cancelled ([WILDCARD]) +timed out async test ... cancelled ([WILDCARD]) +timed out callback test ... cancelled ([WILDCARD]) +large timeout async test is ok ... cancelled ([WILDCARD]) +large timeout callback test is ok ... cancelled ([WILDCARD]) +successful thenable ... cancelled ([WILDCARD]) +rejected thenable ... cancelled ([WILDCARD]) +unfinished test with uncaughtException ... cancelled ([WILDCARD]) +unfinished test with unhandledRejection ... cancelled ([WILDCARD]) + + ERRORS + +sync fail todo => ./node/test.js:20:1 +error: Error: thrown from sync fail todo + throw new Error("thrown from sync fail todo"); +[WILDCARD] + +sync fail todo with message => ./node/test.js:25:1 +error: Error: thrown from sync fail todo with message + throw new Error("thrown from sync fail todo with message"); +[WILDCARD] + +sync throw fail => ./node/test.js:42:1 +error: Error: thrown from sync throw fail + throw new Error("thrown from sync throw fail"); +[WILDCARD] + +async throw fail => ./node/test.js:53:1 +error: Error: thrown from async throw fail + throw new Error("thrown from async throw fail"); +[WILDCARD] + +async skip fail => ./node/test.js:64:1 +error: Error: thrown from async throw fail + throw new Error("thrown from async throw fail"); +[WILDCARD] + +async assertion fail => ./node/test.js:69:1 +error: AssertionError: Values are not strictly equal: + + + [Diff] Actual / Expected + + +- true ++ false + + at [WILDCARD] + +reject fail => ./node/test.js:78:1 +error: Error: rejected from reject fail + return Promise.reject(new Error("rejected from reject fail")); + ^ + at [WILDCARD] + +./node/test.js (uncaught error) +error: (in promise) Error: rejected from unhandled rejection fail + Promise.reject(new Error("rejected from unhandled rejection fail")); + ^ + at [WILDCARD] +This error was not caught from a test and caused the test runner to fail on the referenced module. +It most likely originated from a dangling promise, event/timeout handler or top-level code. + + FAILURES + +sync fail todo => ./node/test.js:20:1 +sync fail todo with message => ./node/test.js:25:1 +sync throw fail => ./node/test.js:42:1 +async throw fail => ./node/test.js:53:1 +async skip fail => ./node/test.js:64:1 +async assertion fail => ./node/test.js:69:1 +reject fail => ./node/test.js:78:1 +./node/test.js (uncaught error) + +FAILED | 9 passed (2 steps) | 51 failed | 4 ignored [WILDCARD] + +error: Test failed diff --git a/tests/testdata/node/unhandled_rejection_web.ts b/tests/testdata/node/unhandled_rejection_web.ts new file mode 100644 index 000000000..396c58c2a --- /dev/null +++ b/tests/testdata/node/unhandled_rejection_web.ts @@ -0,0 +1,17 @@ +import chalk from "npm:chalk"; + +console.log(chalk.red("Hello world!")); + +globalThis.addEventListener("unhandledrejection", (e) => { + console.log("Handled the promise rejection"); + e.preventDefault(); +}); + +// deno-lint-ignore require-await +(async () => { + throw new Error("boom!"); +})(); + +setTimeout(() => { + console.log("Success"); +}, 1000); diff --git a/tests/testdata/node/unhandled_rejection_web.ts.out b/tests/testdata/node/unhandled_rejection_web.ts.out new file mode 100644 index 000000000..19db7f90e --- /dev/null +++ b/tests/testdata/node/unhandled_rejection_web.ts.out @@ -0,0 +1,4 @@ +[WILDCARD] +Hello world! +Handled the promise rejection +Success diff --git a/tests/testdata/node/unhandled_rejection_web_process.ts b/tests/testdata/node/unhandled_rejection_web_process.ts new file mode 100644 index 000000000..2aaacfbff --- /dev/null +++ b/tests/testdata/node/unhandled_rejection_web_process.ts @@ -0,0 +1,21 @@ +import chalk from "npm:chalk"; +import process from "node:process"; + +console.log(chalk.red("Hello world!")); + +process.on("unhandledRejection", (_e) => { + console.log('process.on("unhandledRejection");'); +}); + +globalThis.addEventListener("unhandledrejection", (_e) => { + console.log('globalThis.addEventListener("unhandledrejection");'); +}); + +// deno-lint-ignore require-await +(async () => { + throw new Error("boom!"); +})(); + +setTimeout(() => { + console.log("Success"); +}, 1000); diff --git a/tests/testdata/node/unhandled_rejection_web_process.ts.out b/tests/testdata/node/unhandled_rejection_web_process.ts.out new file mode 100644 index 000000000..ea307474a --- /dev/null +++ b/tests/testdata/node/unhandled_rejection_web_process.ts.out @@ -0,0 +1,5 @@ +[WILDCARD] +Hello world! +globalThis.addEventListener("unhandledrejection"); +process.on("unhandledRejection"); +Success diff --git a/tests/testdata/npm/README.md b/tests/testdata/npm/README.md new file mode 100644 index 000000000..ba3f5f771 --- /dev/null +++ b/tests/testdata/npm/README.md @@ -0,0 +1,18 @@ +# npm test data + +This folder contains test data for npm specifiers. + +## Registry + +The registry is served by the test server (server in test_util) at +http://localhost:4545/npm/registry/ via the `./registry` folder. + +### Updating with real npm packages + +1. Set the `DENO_TEST_UTIL_UPDATE_NPM=1` environment variable +2. Run the test and it should download the packages. + +### Using a custom npm package + +1. Add the custom package to `./registry/@denotest` +2. Reference `npm:@denotest/` in the tests. diff --git a/tests/testdata/npm/binary_package/main.js b/tests/testdata/npm/binary_package/main.js new file mode 100644 index 000000000..8823c5a5b --- /dev/null +++ b/tests/testdata/npm/binary_package/main.js @@ -0,0 +1 @@ +import "npm:@denotest/binary-package"; diff --git a/tests/testdata/npm/builtin_module_module/main.js b/tests/testdata/npm/builtin_module_module/main.js new file mode 100644 index 000000000..9a036791b --- /dev/null +++ b/tests/testdata/npm/builtin_module_module/main.js @@ -0,0 +1 @@ +import "npm:@denotest/builtin-module-module"; diff --git a/tests/testdata/npm/builtin_module_module/main.out b/tests/testdata/npm/builtin_module_module/main.out new file mode 100644 index 000000000..160ba6503 --- /dev/null +++ b/tests/testdata/npm/builtin_module_module/main.out @@ -0,0 +1,4 @@ +function +function +function +true diff --git a/tests/testdata/npm/cached_only/main.out b/tests/testdata/npm/cached_only/main.out new file mode 100644 index 000000000..d03420fee --- /dev/null +++ b/tests/testdata/npm/cached_only/main.out @@ -0,0 +1,2 @@ +error: Error getting response at http://localhost:4545/npm/registry/chalk for package "chalk": An npm specifier not found in cache: "chalk", --cached-only is specified. + at file:///[WILDCARD]/testdata/npm/cached_only/main.ts:1:19 diff --git a/tests/testdata/npm/cached_only/main.ts b/tests/testdata/npm/cached_only/main.ts new file mode 100644 index 000000000..1ccc441a1 --- /dev/null +++ b/tests/testdata/npm/cached_only/main.ts @@ -0,0 +1,3 @@ +import chalk from "npm:chalk@5"; + +console.log(chalk); diff --git a/tests/testdata/npm/cached_only_after_first_run/main1.ts b/tests/testdata/npm/cached_only_after_first_run/main1.ts new file mode 100644 index 000000000..1ccc441a1 --- /dev/null +++ b/tests/testdata/npm/cached_only_after_first_run/main1.ts @@ -0,0 +1,3 @@ +import chalk from "npm:chalk@5"; + +console.log(chalk); diff --git a/tests/testdata/npm/cached_only_after_first_run/main2.ts b/tests/testdata/npm/cached_only_after_first_run/main2.ts new file mode 100644 index 000000000..1aba1bc2c --- /dev/null +++ b/tests/testdata/npm/cached_only_after_first_run/main2.ts @@ -0,0 +1,3 @@ +import chalk from "npm:chalk@4"; + +console.log(chalk); diff --git a/tests/testdata/npm/check_errors/main.ts b/tests/testdata/npm/check_errors/main.ts new file mode 100644 index 000000000..4b8684195 --- /dev/null +++ b/tests/testdata/npm/check_errors/main.ts @@ -0,0 +1,3 @@ +import * as test from "npm:@denotest/check-error"; + +console.log(test.Asdf); // should error diff --git a/tests/testdata/npm/check_errors/main_all.out b/tests/testdata/npm/check_errors/main_all.out new file mode 100644 index 000000000..96f16d0b9 --- /dev/null +++ b/tests/testdata/npm/check_errors/main_all.out @@ -0,0 +1,19 @@ +Download http://localhost:4545/npm/registry/@denotest/check-error +Download http://localhost:4545/npm/registry/@denotest/check-error/1.0.0.tgz +Check file:///[WILDCARD]/check_errors/main.ts +error: TS2506 [ERROR]: 'Class1' is referenced directly or indirectly in its own base expression. +export class Class1 extends Class2 { + ~~~~~~ + at file:///[WILDCARD]/check-error/1.0.0/index.d.ts:2:14 + +TS2506 [ERROR]: 'Class2' is referenced directly or indirectly in its own base expression. +export class Class2 extends Class1 { + ~~~~~~ + at file:///[WILDCARD]/check-error/1.0.0/index.d.ts:5:14 + +TS2339 [ERROR]: Property 'Asdf' does not exist on type 'typeof import("file:///[WILDCARD]/@denotest/check-error/1.0.0/index.d.ts")'. +console.log(test.Asdf); // should error + ~~~~ + at file:///[WILDCARD]/check_errors/main.ts:3:18 + +Found 3 errors. diff --git a/tests/testdata/npm/check_errors/main_local.out b/tests/testdata/npm/check_errors/main_local.out new file mode 100644 index 000000000..1624b98bc --- /dev/null +++ b/tests/testdata/npm/check_errors/main_local.out @@ -0,0 +1,7 @@ +Download http://localhost:4545/npm/registry/@denotest/check-error +Download http://localhost:4545/npm/registry/@denotest/check-error/1.0.0.tgz +Check file:///[WILDCARD]/check_errors/main.ts +error: TS2339 [ERROR]: Property 'Asdf' does not exist on type 'typeof import("file:///[WILDCARD]/@denotest/check-error/1.0.0/index.d.ts")'. +console.log(test.Asdf); // should error + ~~~~ + at file:///[WILDCARD]/npm/check_errors/main.ts:3:18 diff --git a/tests/testdata/npm/child_process_fork_test/main.out b/tests/testdata/npm/child_process_fork_test/main.out new file mode 100644 index 000000000..d5bc57741 --- /dev/null +++ b/tests/testdata/npm/child_process_fork_test/main.out @@ -0,0 +1,2 @@ +function +Done. diff --git a/tests/testdata/npm/child_process_fork_test/main.ts b/tests/testdata/npm/child_process_fork_test/main.ts new file mode 100644 index 000000000..e560edb7e --- /dev/null +++ b/tests/testdata/npm/child_process_fork_test/main.ts @@ -0,0 +1,4 @@ +import "npm:chalk@4"; +import { run } from "npm:@denotest/child-process-fork"; + +run(); diff --git a/tests/testdata/npm/cjs-invalid-name-exports/main.out b/tests/testdata/npm/cjs-invalid-name-exports/main.out new file mode 100644 index 000000000..45ec15d0e --- /dev/null +++ b/tests/testdata/npm/cjs-invalid-name-exports/main.out @@ -0,0 +1,13 @@ +[Module: null prototype] { + "a \\ b": "a \\ b", + "another 'case'": "example", + default: { + 'wow "double quotes"': "double quotes", + "another 'case'": "example", + "a \\ b": "a \\ b", + "name variable": "a", + "foo - bar": "foo - bar" + }, + "foo - bar": "foo - bar", + 'wow "double quotes"': "double quotes" +} diff --git a/tests/testdata/npm/cjs-invalid-name-exports/main.ts b/tests/testdata/npm/cjs-invalid-name-exports/main.ts new file mode 100644 index 000000000..9bdf0e43b --- /dev/null +++ b/tests/testdata/npm/cjs-invalid-name-exports/main.ts @@ -0,0 +1,3 @@ +import * as foo from "npm:@denotest/cjs-invalid-name-exports"; + +console.log(foo); diff --git a/tests/testdata/npm/cjs_local_global_decls/main.out b/tests/testdata/npm/cjs_local_global_decls/main.out new file mode 100644 index 000000000..f9331e2e5 --- /dev/null +++ b/tests/testdata/npm/cjs_local_global_decls/main.out @@ -0,0 +1,3 @@ +Download http://localhost:4545/npm/registry/@denotest/cjs-local-global-decls +Download http://localhost:4545/npm/registry/@denotest/cjs-local-global-decls/1.0.0.tgz +Loaded. diff --git a/tests/testdata/npm/cjs_local_global_decls/main.ts b/tests/testdata/npm/cjs_local_global_decls/main.ts new file mode 100644 index 000000000..04074057b --- /dev/null +++ b/tests/testdata/npm/cjs_local_global_decls/main.ts @@ -0,0 +1 @@ +import "npm:@denotest/cjs-local-global-decls@1.0.0"; diff --git a/tests/testdata/npm/cjs_module_export_assignment/main.out b/tests/testdata/npm/cjs_module_export_assignment/main.out new file mode 100644 index 000000000..dea185e38 --- /dev/null +++ b/tests/testdata/npm/cjs_module_export_assignment/main.out @@ -0,0 +1,6 @@ +{ func: [Function: func] } +[Module: null prototype] { + default: { func: [Function: func] }, + func: [Function: func] +} +5 diff --git a/tests/testdata/npm/cjs_module_export_assignment/main.ts b/tests/testdata/npm/cjs_module_export_assignment/main.ts new file mode 100644 index 000000000..93d3db1c3 --- /dev/null +++ b/tests/testdata/npm/cjs_module_export_assignment/main.ts @@ -0,0 +1,6 @@ +import defaultImport, * as namespaceImport from "npm:@denotest/cjs-module-export-assignment"; +import { func } from "npm:@denotest/cjs-module-export-assignment"; + +console.log(defaultImport); +console.log(namespaceImport); +console.log(func()); diff --git a/tests/testdata/npm/cjs_module_export_assignment_number/main.out b/tests/testdata/npm/cjs_module_export_assignment_number/main.out new file mode 100644 index 000000000..e559775cf --- /dev/null +++ b/tests/testdata/npm/cjs_module_export_assignment_number/main.out @@ -0,0 +1,3 @@ +5 +5 +[Module: null prototype] { default: 5 } diff --git a/tests/testdata/npm/cjs_module_export_assignment_number/main.ts b/tests/testdata/npm/cjs_module_export_assignment_number/main.ts new file mode 100644 index 000000000..aee24bf19 --- /dev/null +++ b/tests/testdata/npm/cjs_module_export_assignment_number/main.ts @@ -0,0 +1,7 @@ +import defaultImport, * as namespaceImport from "npm:@denotest/cjs-module-export-assignment-number"; + +const testDefault: 5 = defaultImport; +console.log(testDefault); +const testNamespace: 5 = namespaceImport.default; +console.log(testNamespace); +console.log(namespaceImport); diff --git a/tests/testdata/npm/cjs_reexport_collision/main.out b/tests/testdata/npm/cjs_reexport_collision/main.out new file mode 100644 index 000000000..ed3193f8d --- /dev/null +++ b/tests/testdata/npm/cjs_reexport_collision/main.out @@ -0,0 +1 @@ +Hi. diff --git a/tests/testdata/npm/cjs_reexport_collision/main.ts b/tests/testdata/npm/cjs_reexport_collision/main.ts new file mode 100644 index 000000000..4bfcd89b1 --- /dev/null +++ b/tests/testdata/npm/cjs_reexport_collision/main.ts @@ -0,0 +1,2 @@ +import ReExportCollision from "npm:@denotest/cjs-reexport-collision"; +ReExportCollision.default.sayHello(); diff --git a/tests/testdata/npm/cjs_require_esm_error/main.out b/tests/testdata/npm/cjs_require_esm_error/main.out new file mode 100644 index 000000000..b6ade6904 --- /dev/null +++ b/tests/testdata/npm/cjs_require_esm_error/main.out @@ -0,0 +1,2 @@ +error: Uncaught (in promise) Error: require() of ES Module [WILDCARD]my_es_module.js from [WILDCARD]index.js not supported. Instead change the require to a dynamic import() which is available in all CommonJS modules. + [WILDCARD] diff --git a/tests/testdata/npm/cjs_require_esm_error/main.ts b/tests/testdata/npm/cjs_require_esm_error/main.ts new file mode 100644 index 000000000..3fbb1215a --- /dev/null +++ b/tests/testdata/npm/cjs_require_esm_error/main.ts @@ -0,0 +1 @@ +import "npm:@denotest/cjs-require-esm-error"; diff --git a/tests/testdata/npm/cjs_require_esm_mjs_error/main.out b/tests/testdata/npm/cjs_require_esm_mjs_error/main.out new file mode 100644 index 000000000..e779cfaf8 --- /dev/null +++ b/tests/testdata/npm/cjs_require_esm_mjs_error/main.out @@ -0,0 +1,2 @@ +error: Uncaught (in promise) Error: require() of ES Module [WILDCARD]esm_mjs.mjs from [WILDCARD]require_mjs.js not supported. Instead change the require to a dynamic import() which is available in all CommonJS modules. + [WILDCARD] diff --git a/tests/testdata/npm/cjs_require_esm_mjs_error/main.ts b/tests/testdata/npm/cjs_require_esm_mjs_error/main.ts new file mode 100644 index 000000000..2121f1dbb --- /dev/null +++ b/tests/testdata/npm/cjs_require_esm_mjs_error/main.ts @@ -0,0 +1 @@ +import "npm:@denotest/cjs-require-esm-error/require_mjs.js"; diff --git a/tests/testdata/npm/cjs_sub_path/main.js b/tests/testdata/npm/cjs_sub_path/main.js new file mode 100644 index 000000000..b71360959 --- /dev/null +++ b/tests/testdata/npm/cjs_sub_path/main.js @@ -0,0 +1,21 @@ +// this package will require a subpath like "ajv/dist/compile/codegen" +// and also get the parent directory index.js file using require("..") +import Ajv from "npm:ajv@~8.11"; +import addFormats from "npm:ajv-formats@2.1.1"; +import { expect } from "npm:chai@4.3"; + +const ajv = new Ajv(); +addFormats(ajv); + +const schema = { + type: "string", + format: "date", + formatMinimum: "2016-02-06", + formatExclusiveMaximum: "2016-12-27", +}; +const validate = ajv.compile(schema); + +expect(validate("2016-02-06")).to.be.true; +expect(validate("2016-02-05")).to.be.false; + +console.log("Fini"); diff --git a/tests/testdata/npm/cjs_sub_path/main.out b/tests/testdata/npm/cjs_sub_path/main.out new file mode 100644 index 000000000..34ec9d63f --- /dev/null +++ b/tests/testdata/npm/cjs_sub_path/main.out @@ -0,0 +1,35 @@ +[UNORDERED_START] +Download http://localhost:4545/npm/registry/ajv +Download http://localhost:4545/npm/registry/ajv-formats +Download http://localhost:4545/npm/registry/chai +Download http://localhost:4545/npm/registry/fast-deep-equal +Download http://localhost:4545/npm/registry/json-schema-traverse +Download http://localhost:4545/npm/registry/require-from-string +Download http://localhost:4545/npm/registry/uri-js +Download http://localhost:4545/npm/registry/assertion-error +Download http://localhost:4545/npm/registry/check-error +Download http://localhost:4545/npm/registry/deep-eql +Download http://localhost:4545/npm/registry/get-func-name +Download http://localhost:4545/npm/registry/loupe +Download http://localhost:4545/npm/registry/pathval +Download http://localhost:4545/npm/registry/type-detect +Download http://localhost:4545/npm/registry/punycode +[UNORDERED_END] +[UNORDERED_START] +Download http://localhost:4545/npm/registry/ajv/ajv-8.11.0.tgz +Download http://localhost:4545/npm/registry/ajv-formats/ajv-formats-2.1.1.tgz +Download http://localhost:4545/npm/registry/assertion-error/assertion-error-1.1.0.tgz +Download http://localhost:4545/npm/registry/chai/chai-4.3.6.tgz +Download http://localhost:4545/npm/registry/check-error/check-error-1.0.2.tgz +Download http://localhost:4545/npm/registry/deep-eql/deep-eql-3.0.1.tgz +Download http://localhost:4545/npm/registry/fast-deep-equal/fast-deep-equal-3.1.3.tgz +Download http://localhost:4545/npm/registry/get-func-name/get-func-name-2.0.0.tgz +Download http://localhost:4545/npm/registry/json-schema-traverse/json-schema-traverse-1.0.0.tgz +Download http://localhost:4545/npm/registry/loupe/loupe-2.3.4.tgz +Download http://localhost:4545/npm/registry/pathval/pathval-1.1.1.tgz +Download http://localhost:4545/npm/registry/punycode/punycode-2.1.1.tgz +Download http://localhost:4545/npm/registry/require-from-string/require-from-string-2.0.2.tgz +Download http://localhost:4545/npm/registry/type-detect/type-detect-4.0.8.tgz +Download http://localhost:4545/npm/registry/uri-js/uri-js-4.4.1.tgz +[UNORDERED_END] +Fini diff --git a/tests/testdata/npm/cjs_this_in_exports/main.js b/tests/testdata/npm/cjs_this_in_exports/main.js new file mode 100644 index 000000000..03aaabe05 --- /dev/null +++ b/tests/testdata/npm/cjs_this_in_exports/main.js @@ -0,0 +1,11 @@ +import defaultImport, { getValue } from "npm:@denotest/cjs-this-in-exports"; +import * as namespaceImport from "npm:@denotest/cjs-this-in-exports"; + +console.log(defaultImport.getValue()); +// In Node this actually fails, but it seems to work in Deno +// so I guess there's no harm in that. +console.log(namespaceImport.getValue()); + +// This will throw because it's lost its context. +// (same thing occurs with Node's cjs -> esm translation) +getValue(); diff --git a/tests/testdata/npm/cjs_this_in_exports/main.out b/tests/testdata/npm/cjs_this_in_exports/main.out new file mode 100644 index 000000000..ba436bddc --- /dev/null +++ b/tests/testdata/npm/cjs_this_in_exports/main.out @@ -0,0 +1,5 @@ +1 +1 +error: Uncaught (in promise) TypeError: this.otherMethod is not a function + at getValue (file://[WILDCARD]/@denotest/cjs-this-in-exports/1.0.0/index.js:3:17) + at file://[WILDCARD]/testdata/npm/cjs_this_in_exports/main.js:11:1 diff --git a/tests/testdata/npm/cjs_with_deps/main.js b/tests/testdata/npm/cjs_with_deps/main.js new file mode 100644 index 000000000..568726874 --- /dev/null +++ b/tests/testdata/npm/cjs_with_deps/main.js @@ -0,0 +1,12 @@ +import chalk from "npm:chalk@4"; +import { expect } from "npm:chai@4.3"; + +console.log(chalk.green("chalk cjs loads")); + +const timeout = setTimeout(() => {}, 0); +expect(timeout).to.be.a("number"); +clearTimeout(timeout); + +const interval = setInterval(() => {}, 100); +expect(interval).to.be.a("number"); +clearInterval(interval); diff --git a/tests/testdata/npm/cjs_with_deps/main.out b/tests/testdata/npm/cjs_with_deps/main.out new file mode 100644 index 000000000..aac21abba --- /dev/null +++ b/tests/testdata/npm/cjs_with_deps/main.out @@ -0,0 +1,33 @@ +[UNORDERED_START] +Download http://localhost:4545/npm/registry/chalk +Download http://localhost:4545/npm/registry/chai +Download http://localhost:4545/npm/registry/ansi-styles +Download http://localhost:4545/npm/registry/supports-color +Download http://localhost:4545/npm/registry/assertion-error +Download http://localhost:4545/npm/registry/check-error +Download http://localhost:4545/npm/registry/deep-eql +Download http://localhost:4545/npm/registry/get-func-name +Download http://localhost:4545/npm/registry/loupe +Download http://localhost:4545/npm/registry/pathval +Download http://localhost:4545/npm/registry/type-detect +Download http://localhost:4545/npm/registry/color-convert +Download http://localhost:4545/npm/registry/has-flag +Download http://localhost:4545/npm/registry/color-name +[UNORDERED_END] +[UNORDERED_START] +Download http://localhost:4545/npm/registry/ansi-styles/ansi-styles-4.3.0.tgz +Download http://localhost:4545/npm/registry/assertion-error/assertion-error-1.1.0.tgz +Download http://localhost:4545/npm/registry/chai/chai-4.3.6.tgz +Download http://localhost:4545/npm/registry/chalk/chalk-4.1.2.tgz +Download http://localhost:4545/npm/registry/check-error/check-error-1.0.2.tgz +Download http://localhost:4545/npm/registry/color-convert/color-convert-2.0.1.tgz +Download http://localhost:4545/npm/registry/color-name/color-name-1.1.4.tgz +Download http://localhost:4545/npm/registry/deep-eql/deep-eql-3.0.1.tgz +Download http://localhost:4545/npm/registry/get-func-name/get-func-name-2.0.0.tgz +Download http://localhost:4545/npm/registry/has-flag/has-flag-4.0.0.tgz +Download http://localhost:4545/npm/registry/loupe/loupe-2.3.4.tgz +Download http://localhost:4545/npm/registry/pathval/pathval-1.1.1.tgz +Download http://localhost:4545/npm/registry/supports-color/supports-color-7.2.0.tgz +Download http://localhost:4545/npm/registry/type-detect/type-detect-4.0.8.tgz +[UNORDERED_END] +chalk cjs loads diff --git a/tests/testdata/npm/cjs_with_deps/main_info.out b/tests/testdata/npm/cjs_with_deps/main_info.out new file mode 100644 index 000000000..bcaaf1eec --- /dev/null +++ b/tests/testdata/npm/cjs_with_deps/main_info.out @@ -0,0 +1,22 @@ +local: [WILDCARD]main.js +type: JavaScript +dependencies: 14 unique +size: [WILDCARD] + +file:///[WILDCARD]/npm/cjs_with_deps/main.js ([WILDCARD]) +├─┬ npm:/chalk@4.1.2 ([WILDCARD]) +│ ├─┬ npm:/ansi-styles@4.3.0 ([WILDCARD]) +│ │ └─┬ npm:/color-convert@2.0.1 ([WILDCARD]) +│ │ └── npm:/color-name@1.1.4 ([WILDCARD]) +│ └─┬ npm:/supports-color@7.2.0 ([WILDCARD]) +│ └── npm:/has-flag@4.0.0 ([WILDCARD]) +└─┬ npm:/chai@4.3.6 ([WILDCARD]) + ├── npm:/assertion-error@1.1.0 ([WILDCARD]) + ├── npm:/check-error@1.0.2 ([WILDCARD]) + ├─┬ npm:/deep-eql@3.0.1 ([WILDCARD]) + │ └── npm:/type-detect@4.0.8 ([WILDCARD]) + ├── npm:/get-func-name@2.0.0 ([WILDCARD]) + ├─┬ npm:/loupe@2.3.4 ([WILDCARD]) + │ └── npm:/get-func-name@2.0.0 ([WILDCARD]) + ├── npm:/pathval@1.1.1 ([WILDCARD]) + └── npm:/type-detect@4.0.8 ([WILDCARD]) diff --git a/tests/testdata/npm/cjs_with_deps/main_info_json.out b/tests/testdata/npm/cjs_with_deps/main_info_json.out new file mode 100644 index 000000000..fd850b8a1 --- /dev/null +++ b/tests/testdata/npm/cjs_with_deps/main_info_json.out @@ -0,0 +1,149 @@ +{ + "roots": [ + "file://[WILDCARD]/main.js" + ], + "modules": [ + { + "kind": "esm", + "dependencies": [ + { + "specifier": "npm:chalk@4", + "code": { + "specifier": "npm:chalk@4", + "span": { + "start": { + "line": 0, + "character": 18 + }, + "end": { + "line": 0, + "character": 31 + } + } + }, + "npmPackage": "chalk@4.1.2" + }, + { + "specifier": "npm:chai@4.3", + "code": { + "specifier": "npm:chai@4.3", + "span": { + "start": { + "line": 1, + "character": 23 + }, + "end": { + "line": 1, + "character": 37 + } + } + }, + "npmPackage": "chai@4.3.6" + } + ], + "local": "[WILDCARD]main.js", + "emit": null, + "map": null, + "size": 325, + "mediaType": "JavaScript", + "specifier": "[WILDCARD]/main.js" + } + ], + "redirects": { + "npm:chai@4.3": "npm:/chai@4.3.6", + "npm:chalk@4": "npm:/chalk@4.1.2" + }, + "npmPackages": { + "ansi-styles@4.3.0": { + "name": "ansi-styles", + "version": "4.3.0", + "dependencies": [ + "color-convert@2.0.1" + ] + }, + "assertion-error@1.1.0": { + "name": "assertion-error", + "version": "1.1.0", + "dependencies": [] + }, + "chai@4.3.6": { + "name": "chai", + "version": "4.3.6", + "dependencies": [ + "assertion-error@1.1.0", + "check-error@1.0.2", + "deep-eql@3.0.1", + "get-func-name@2.0.0", + "loupe@2.3.4", + "pathval@1.1.1", + "type-detect@4.0.8" + ] + }, + "chalk@4.1.2": { + "name": "chalk", + "version": "4.1.2", + "dependencies": [ + "ansi-styles@4.3.0", + "supports-color@7.2.0" + ] + }, + "check-error@1.0.2": { + "name": "check-error", + "version": "1.0.2", + "dependencies": [] + }, + "color-convert@2.0.1": { + "name": "color-convert", + "version": "2.0.1", + "dependencies": [ + "color-name@1.1.4" + ] + }, + "color-name@1.1.4": { + "name": "color-name", + "version": "1.1.4", + "dependencies": [] + }, + "deep-eql@3.0.1": { + "name": "deep-eql", + "version": "3.0.1", + "dependencies": [ + "type-detect@4.0.8" + ] + }, + "get-func-name@2.0.0": { + "name": "get-func-name", + "version": "2.0.0", + "dependencies": [] + }, + "has-flag@4.0.0": { + "name": "has-flag", + "version": "4.0.0", + "dependencies": [] + }, + "loupe@2.3.4": { + "name": "loupe", + "version": "2.3.4", + "dependencies": [ + "get-func-name@2.0.0" + ] + }, + "pathval@1.1.1": { + "name": "pathval", + "version": "1.1.1", + "dependencies": [] + }, + "supports-color@7.2.0": { + "name": "supports-color", + "version": "7.2.0", + "dependencies": [ + "has-flag@4.0.0" + ] + }, + "type-detect@4.0.8": { + "name": "type-detect", + "version": "4.0.8", + "dependencies": [] + } + } +} diff --git a/tests/testdata/npm/cjs_with_deps/main_node_modules.out b/tests/testdata/npm/cjs_with_deps/main_node_modules.out new file mode 100644 index 000000000..548f567f1 --- /dev/null +++ b/tests/testdata/npm/cjs_with_deps/main_node_modules.out @@ -0,0 +1,47 @@ +[UNORDERED_START] +Download http://localhost:4545/npm/registry/chalk +Download http://localhost:4545/npm/registry/chai +Download http://localhost:4545/npm/registry/ansi-styles +Download http://localhost:4545/npm/registry/supports-color +Download http://localhost:4545/npm/registry/assertion-error +Download http://localhost:4545/npm/registry/check-error +Download http://localhost:4545/npm/registry/deep-eql +Download http://localhost:4545/npm/registry/get-func-name +Download http://localhost:4545/npm/registry/loupe +Download http://localhost:4545/npm/registry/pathval +Download http://localhost:4545/npm/registry/type-detect +Download http://localhost:4545/npm/registry/color-convert +Download http://localhost:4545/npm/registry/has-flag +Download http://localhost:4545/npm/registry/color-name +[UNORDERED_END] +[UNORDERED_START] +Download http://localhost:4545/npm/registry/ansi-styles/ansi-styles-4.3.0.tgz +Initialize ansi-styles@4.3.0 +Download http://localhost:4545/npm/registry/assertion-error/assertion-error-1.1.0.tgz +Initialize assertion-error@1.1.0 +Download http://localhost:4545/npm/registry/chai/chai-4.3.6.tgz +Initialize chai@4.3.6 +Download http://localhost:4545/npm/registry/chalk/chalk-4.1.2.tgz +Initialize chalk@4.1.2 +Download http://localhost:4545/npm/registry/check-error/check-error-1.0.2.tgz +Initialize check-error@1.0.2 +Download http://localhost:4545/npm/registry/color-convert/color-convert-2.0.1.tgz +Initialize color-convert@2.0.1 +Download http://localhost:4545/npm/registry/color-name/color-name-1.1.4.tgz +Initialize color-name@1.1.4 +Download http://localhost:4545/npm/registry/deep-eql/deep-eql-3.0.1.tgz +Initialize deep-eql@3.0.1 +Download http://localhost:4545/npm/registry/get-func-name/get-func-name-2.0.0.tgz +Initialize get-func-name@2.0.0 +Download http://localhost:4545/npm/registry/has-flag/has-flag-4.0.0.tgz +Initialize has-flag@4.0.0 +Download http://localhost:4545/npm/registry/loupe/loupe-2.3.4.tgz +Initialize loupe@2.3.4 +Download http://localhost:4545/npm/registry/pathval/pathval-1.1.1.tgz +Initialize pathval@1.1.1 +Download http://localhost:4545/npm/registry/supports-color/supports-color-7.2.0.tgz +Initialize supports-color@7.2.0 +Download http://localhost:4545/npm/registry/type-detect/type-detect-4.0.8.tgz +Initialize type-detect@4.0.8 +[UNORDERED_END] +chalk cjs loads diff --git a/tests/testdata/npm/cjs_yargs/main.js b/tests/testdata/npm/cjs_yargs/main.js new file mode 100644 index 000000000..832fd053c --- /dev/null +++ b/tests/testdata/npm/cjs_yargs/main.js @@ -0,0 +1,20 @@ +import yargs from "npm:yargs@15.4.1"; + +const args = yargs(["serve", "8000"]) + .command("serve [port]", "start the server", (yargs) => { + return yargs + .positional("port", { + describe: "port to bind on", + default: 5000, + }); + }, (argv) => { + console.info(`start server on :${argv.port}`); + }) + .option("verbose", { + alias: "v", + type: "boolean", + description: "Run with verbose logging", + }) + .argv; + +console.log(args); diff --git a/tests/testdata/npm/cjs_yargs/main.out b/tests/testdata/npm/cjs_yargs/main.out new file mode 100644 index 000000000..422cbb134 --- /dev/null +++ b/tests/testdata/npm/cjs_yargs/main.out @@ -0,0 +1,84 @@ +[UNORDERED_START] +Download http://localhost:4545/npm/registry/yargs +Download http://localhost:4545/npm/registry/cliui +Download http://localhost:4545/npm/registry/decamelize +Download http://localhost:4545/npm/registry/find-up +Download http://localhost:4545/npm/registry/get-caller-file +Download http://localhost:4545/npm/registry/require-directory +Download http://localhost:4545/npm/registry/require-main-filename +Download http://localhost:4545/npm/registry/set-blocking +Download http://localhost:4545/npm/registry/string-width +Download http://localhost:4545/npm/registry/which-module +Download http://localhost:4545/npm/registry/y18n +Download http://localhost:4545/npm/registry/yargs-parser +Download http://localhost:4545/npm/registry/strip-ansi +Download http://localhost:4545/npm/registry/wrap-ansi +Download http://localhost:4545/npm/registry/locate-path +Download http://localhost:4545/npm/registry/path-exists +Download http://localhost:4545/npm/registry/emoji-regex +Download http://localhost:4545/npm/registry/is-fullwidth-code-point +Download http://localhost:4545/npm/registry/camelcase +Download http://localhost:4545/npm/registry/ansi-regex +Download http://localhost:4545/npm/registry/ansi-styles +Download http://localhost:4545/npm/registry/p-locate +Download http://localhost:4545/npm/registry/color-convert +Download http://localhost:4545/npm/registry/p-limit +Download http://localhost:4545/npm/registry/color-name +Download http://localhost:4545/npm/registry/p-try +[UNORDERED_END] +[UNORDERED_START] +Download http://localhost:4545/npm/registry/ansi-regex/ansi-regex-5.0.1.tgz +Initialize ansi-regex@5.0.1 +Download http://localhost:4545/npm/registry/ansi-styles/ansi-styles-4.3.0.tgz +Initialize ansi-styles@4.3.0 +Download http://localhost:4545/npm/registry/camelcase/camelcase-5.3.1.tgz +Initialize camelcase@5.3.1 +Download http://localhost:4545/npm/registry/cliui/cliui-6.0.0.tgz +Initialize cliui@6.0.0 +Download http://localhost:4545/npm/registry/color-convert/color-convert-2.0.1.tgz +Initialize color-convert@2.0.1 +Download http://localhost:4545/npm/registry/color-name/color-name-1.1.4.tgz +Initialize color-name@1.1.4 +Download http://localhost:4545/npm/registry/decamelize/decamelize-1.2.0.tgz +Initialize decamelize@1.2.0 +Download http://localhost:4545/npm/registry/emoji-regex/emoji-regex-8.0.0.tgz +Initialize emoji-regex@8.0.0 +Download http://localhost:4545/npm/registry/find-up/find-up-4.1.0.tgz +Initialize find-up@4.1.0 +Download http://localhost:4545/npm/registry/get-caller-file/get-caller-file-2.0.5.tgz +Initialize get-caller-file@2.0.5 +Download http://localhost:4545/npm/registry/is-fullwidth-code-point/is-fullwidth-code-point-3.0.0.tgz +Initialize is-fullwidth-code-point@3.0.0 +Download http://localhost:4545/npm/registry/locate-path/locate-path-5.0.0.tgz +Initialize locate-path@5.0.0 +Download http://localhost:4545/npm/registry/p-limit/p-limit-2.3.0.tgz +Initialize p-limit@2.3.0 +Download http://localhost:4545/npm/registry/p-locate/p-locate-4.1.0.tgz +Initialize p-locate@4.1.0 +Download http://localhost:4545/npm/registry/p-try/p-try-2.2.0.tgz +Initialize p-try@2.2.0 +Download http://localhost:4545/npm/registry/path-exists/path-exists-4.0.0.tgz +Initialize path-exists@4.0.0 +Download http://localhost:4545/npm/registry/require-directory/require-directory-2.1.1.tgz +Initialize require-directory@2.1.1 +Download http://localhost:4545/npm/registry/require-main-filename/require-main-filename-2.0.0.tgz +Initialize require-main-filename@2.0.0 +Download http://localhost:4545/npm/registry/set-blocking/set-blocking-2.0.0.tgz +Initialize set-blocking@2.0.0 +Download http://localhost:4545/npm/registry/string-width/string-width-4.2.3.tgz +Initialize string-width@4.2.3 +Download http://localhost:4545/npm/registry/strip-ansi/strip-ansi-6.0.1.tgz +Initialize strip-ansi@6.0.1 +Download http://localhost:4545/npm/registry/which-module/which-module-2.0.0.tgz +Initialize which-module@2.0.0 +Download http://localhost:4545/npm/registry/wrap-ansi/wrap-ansi-6.2.0.tgz +Initialize wrap-ansi@6.2.0 +Download http://localhost:4545/npm/registry/y18n/y18n-4.0.3.tgz +Initialize y18n@4.0.3 +Download http://localhost:4545/npm/registry/yargs/yargs-15.4.1.tgz +Initialize yargs@15.4.1 +Download http://localhost:4545/npm/registry/yargs-parser/yargs-parser-18.1.3.tgz +Initialize yargs-parser@18.1.3 +[UNORDERED_END] +start server on :8000 +[WILDCARD] diff --git a/tests/testdata/npm/compare_globals/main.out b/tests/testdata/npm/compare_globals/main.out new file mode 100644 index 000000000..0e366fae7 --- /dev/null +++ b/tests/testdata/npm/compare_globals/main.out @@ -0,0 +1,28 @@ +[UNORDERED_START] +Download http://localhost:4545/npm/registry/@types/node +Download http://localhost:4545/npm/registry/@denotest/globals +[UNORDERED_END] +[UNORDERED_START] +Download http://localhost:4545/npm/registry/@denotest/globals/1.0.0.tgz +Download http://localhost:4545/npm/registry/@types/node/node-18.8.2.tgz +[UNORDERED_END] +Check file:///[WILDCARD]/npm/compare_globals/main.ts +true +true +[] +false +function +function +function +undefined +false +false +true +true +true +true +false +false +bar +bar +true diff --git a/tests/testdata/npm/compare_globals/main.ts b/tests/testdata/npm/compare_globals/main.ts new file mode 100644 index 000000000..6f7b9ef8e --- /dev/null +++ b/tests/testdata/npm/compare_globals/main.ts @@ -0,0 +1,52 @@ +/// + +import * as globals from "npm:@denotest/globals"; +console.log(globals.global === globals.globalThis); +// @ts-expect-error even though these are the same object, they have different types +console.log(globals.globalThis === globalThis); +console.log(globals.process.execArgv); + +type AssertTrue = never; +type _TestNoProcessGlobal = AssertTrue< + typeof globalThis extends { process: any } ? false : true +>; +type _TestHasNodeJsGlobal = NodeJS.Architecture; + +const controller = new AbortController(); +controller.abort("reason"); // in the NodeJS declaration it doesn't have a reason + +// Some globals are not the same between Node and Deno. +// @ts-expect-error incompatible types between Node and Deno +console.log(globalThis.setTimeout === globals.getSetTimeout()); + +// Super edge case where some Node code deletes a global where the +// Node code has its own global and the Deno code has the same global, +// but it's different. Basically if some Node code deletes +// one of these globals then we don't want it to suddenly inherit +// the Deno global (or touch the Deno global at all). +console.log(typeof globalThis.setTimeout); +console.log(typeof globals.getSetTimeout()); +globals.deleteSetTimeout(); +console.log(typeof globalThis.setTimeout); +console.log(typeof globals.getSetTimeout()); + +// In Deno, the process global is not defined, but in Node it is. +console.log("process" in globalThis); +console.log( + Object.getOwnPropertyDescriptor(globalThis, "process") !== undefined, +); +globals.checkProcessGlobal(); + +// In Deno, the window global is defined, but in Node it is not. +console.log("window" in globalThis); +console.log( + Object.getOwnPropertyDescriptor(globalThis, "window") !== undefined, +); +globals.checkWindowGlobal(); + +// "Non-managed" globals are shared between Node and Deno. +(globalThis as any).foo = "bar"; +console.log((globalThis as any).foo); +console.log(globals.getFoo()); + +console.log(Reflect.ownKeys(globalThis).includes("console")); // non-enumerable keys are included diff --git a/tests/testdata/npm/conditional_exports/main.js b/tests/testdata/npm/conditional_exports/main.js new file mode 100644 index 000000000..52b78bc22 --- /dev/null +++ b/tests/testdata/npm/conditional_exports/main.js @@ -0,0 +1,15 @@ +import mod from "npm:@denotest/conditional-exports"; +import foo from "npm:@denotest/conditional-exports/foo.js"; +import client from "npm:@denotest/conditional-exports/client"; +import clientFoo from "npm:@denotest/conditional-exports/client/foo"; +import clientBar from "npm:@denotest/conditional-exports/client/bar"; +import clientM from "npm:@denotest/conditional-exports/client/m"; +import supportsESM from "npm:supports-esm"; + +console.log(mod); +console.log(foo); +console.log(client); +console.log(clientFoo); +console.log(clientBar); +console.log(clientM); +console.log(supportsESM); diff --git a/tests/testdata/npm/conditional_exports/main.out b/tests/testdata/npm/conditional_exports/main.out new file mode 100644 index 000000000..dbd1b87fe --- /dev/null +++ b/tests/testdata/npm/conditional_exports/main.out @@ -0,0 +1,19 @@ +[UNORDERED_START] +Download http://localhost:4545/npm/registry/@denotest/conditional-exports +Download http://localhost:4545/npm/registry/supports-esm +Download http://localhost:4545/npm/registry/has-package-exports +Download http://localhost:4545/npm/registry/@ljharb/has-package-exports-patterns +[UNORDERED_END] +[UNORDERED_START] +Download http://localhost:4545/npm/registry/@denotest/conditional-exports/1.0.0.tgz +Download http://localhost:4545/npm/registry/@ljharb/has-package-exports-patterns/has-package-exports-patterns-0.0.2.tgz +Download http://localhost:4545/npm/registry/has-package-exports/has-package-exports-1.3.0.tgz +Download http://localhost:4545/npm/registry/supports-esm/supports-esm-1.0.0.tgz +[UNORDERED_END] +{ hello: "from esm" } +{ hello: "from foo" } +{ hello: "from esm client" } +{ hello: "from esm client foo" } +{ hello: "from esm client bar" } +{ hello: "from esm client m" } +true diff --git a/tests/testdata/npm/conditional_exports/main_node_modules.out b/tests/testdata/npm/conditional_exports/main_node_modules.out new file mode 100644 index 000000000..460aec0f1 --- /dev/null +++ b/tests/testdata/npm/conditional_exports/main_node_modules.out @@ -0,0 +1,23 @@ +[UNORDERED_START] +Download http://localhost:4545/npm/registry/@denotest/conditional-exports +Download http://localhost:4545/npm/registry/supports-esm +Download http://localhost:4545/npm/registry/has-package-exports +Download http://localhost:4545/npm/registry/@ljharb/has-package-exports-patterns +[UNORDERED_END] +[UNORDERED_START] +Download http://localhost:4545/npm/registry/@denotest/conditional-exports/1.0.0.tgz +Initialize @denotest/conditional-exports@1.0.0 +Download http://localhost:4545/npm/registry/@ljharb/has-package-exports-patterns/has-package-exports-patterns-0.0.2.tgz +Initialize @ljharb/has-package-exports-patterns@0.0.2 +Download http://localhost:4545/npm/registry/has-package-exports/has-package-exports-1.3.0.tgz +Initialize has-package-exports@1.3.0 +Download http://localhost:4545/npm/registry/supports-esm/supports-esm-1.0.0.tgz +Initialize supports-esm@1.0.0 +[UNORDERED_END] +{ hello: "from esm" } +{ hello: "from foo" } +{ hello: "from esm client" } +{ hello: "from esm client foo" } +{ hello: "from esm client bar" } +{ hello: "from esm client m" } +true diff --git a/tests/testdata/npm/create_require/main.out b/tests/testdata/npm/create_require/main.out new file mode 100644 index 000000000..70b0415b3 --- /dev/null +++ b/tests/testdata/npm/create_require/main.out @@ -0,0 +1,12 @@ +[WILDCARD] +function +function +function +function +function +function +The argument 'filename' must be a file URL object, file URL string, or absolute path string. Received https://example.com/ +The argument 'filename' must be a file URL object, file URL string, or absolute path string. Received https://example.com/ +The argument 'filename' must be a file URL object, file URL string, or absolute path string. Received 1 +The argument 'filename' must be a file URL object, file URL string, or absolute path string. Received foo +The argument 'filename' must be a file URL object, file URL string, or absolute path string. Received ./foo diff --git a/tests/testdata/npm/create_require/main.ts b/tests/testdata/npm/create_require/main.ts new file mode 100644 index 000000000..625c734aa --- /dev/null +++ b/tests/testdata/npm/create_require/main.ts @@ -0,0 +1 @@ +import "npm:@denotest/create-require@1.0.0"; diff --git a/tests/testdata/npm/d_ext/main.out b/tests/testdata/npm/d_ext/main.out new file mode 100644 index 000000000..e96c6e392 --- /dev/null +++ b/tests/testdata/npm/d_ext/main.out @@ -0,0 +1,3 @@ +Download http://localhost:4545/npm/registry/@denotest/d-ext +Download http://localhost:4545/npm/registry/@denotest/d-ext/1.0.0.tgz +Check file:///[WILDCARD]/npm/d_ext/main.ts diff --git a/tests/testdata/npm/d_ext/main.ts b/tests/testdata/npm/d_ext/main.ts new file mode 100644 index 000000000..c92dbe065 --- /dev/null +++ b/tests/testdata/npm/d_ext/main.ts @@ -0,0 +1,3 @@ +import { test } from "npm:@denotest/d-ext"; + +console.log(test); diff --git a/tests/testdata/npm/deno_cache.out b/tests/testdata/npm/deno_cache.out new file mode 100644 index 000000000..e2e68b7bb --- /dev/null +++ b/tests/testdata/npm/deno_cache.out @@ -0,0 +1,8 @@ +[UNORDERED_START] +Download http://localhost:4545/npm/registry/chalk +Download http://localhost:4545/npm/registry/mkdirp +[UNORDERED_END] +[UNORDERED_START] +Download http://localhost:4545/npm/registry/chalk/chalk-5.0.1.tgz +Download http://localhost:4545/npm/registry/mkdirp/mkdirp-1.0.4.tgz +[UNORDERED_END] diff --git a/tests/testdata/npm/deno_run_cjs.out b/tests/testdata/npm/deno_run_cjs.out new file mode 100644 index 000000000..ffe7cbd89 --- /dev/null +++ b/tests/testdata/npm/deno_run_cjs.out @@ -0,0 +1,4 @@ +this +is +a +test diff --git a/tests/testdata/npm/deno_run_cowsay.out b/tests/testdata/npm/deno_run_cowsay.out new file mode 100644 index 000000000..46de82730 --- /dev/null +++ b/tests/testdata/npm/deno_run_cowsay.out @@ -0,0 +1,8 @@ + _______ +< Hello > + ------- + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || diff --git a/tests/testdata/npm/deno_run_cowsay_no_permissions.out b/tests/testdata/npm/deno_run_cowsay_no_permissions.out new file mode 100644 index 000000000..206ef1484 --- /dev/null +++ b/tests/testdata/npm/deno_run_cowsay_no_permissions.out @@ -0,0 +1,2 @@ +error: Uncaught PermissionDenied: Requires read access to , run again with the --allow-read flag +[WILDCARD] diff --git a/tests/testdata/npm/deno_run_cowthink.out b/tests/testdata/npm/deno_run_cowthink.out new file mode 100644 index 000000000..8dd990ed6 --- /dev/null +++ b/tests/testdata/npm/deno_run_cowthink.out @@ -0,0 +1,8 @@ + _______ +( Hello ) + ------- + o ^__^ + o (oo)\_______ + (__)\ )\/\ + ||----w | + || || diff --git a/tests/testdata/npm/deno_run_esm.out b/tests/testdata/npm/deno_run_esm.out new file mode 100644 index 000000000..ffe7cbd89 --- /dev/null +++ b/tests/testdata/npm/deno_run_esm.out @@ -0,0 +1,4 @@ +this +is +a +test diff --git a/tests/testdata/npm/deno_run_no_bin_entrypoint.out b/tests/testdata/npm/deno_run_no_bin_entrypoint.out new file mode 100644 index 000000000..73bddfecf --- /dev/null +++ b/tests/testdata/npm/deno_run_no_bin_entrypoint.out @@ -0,0 +1 @@ +error: '[WILDCARD]@denotest[WILDCARD]esm-basic[WILDCARD]package.json' did not have a bin property diff --git a/tests/testdata/npm/deno_run_no_bin_entrypoint_non_existent_subpath.out b/tests/testdata/npm/deno_run_no_bin_entrypoint_non_existent_subpath.out new file mode 100644 index 000000000..ea5ee3d35 --- /dev/null +++ b/tests/testdata/npm/deno_run_no_bin_entrypoint_non_existent_subpath.out @@ -0,0 +1,3 @@ +error: '[WILDCARD]@denotest[WILDCARD]esm-basic[WILDCARD]package.json' did not have a bin property + +Fallback failed: Cannot find module 'file:///[WILDCARD]/non-existent.js' diff --git a/tests/testdata/npm/deno_run_no_ext.out b/tests/testdata/npm/deno_run_no_ext.out new file mode 100644 index 000000000..ffe7cbd89 --- /dev/null +++ b/tests/testdata/npm/deno_run_no_ext.out @@ -0,0 +1,4 @@ +this +is +a +test diff --git a/tests/testdata/npm/deno_run_non_existent.out b/tests/testdata/npm/deno_run_non_existent.out new file mode 100644 index 000000000..47021e00c --- /dev/null +++ b/tests/testdata/npm/deno_run_non_existent.out @@ -0,0 +1,3 @@ +Download http://localhost:4545/npm/registry/mkdirp +Download http://localhost:4545/npm/registry/mkdirp +error: Could not find npm package 'mkdirp' matching '0.5.125'. diff --git a/tests/testdata/npm/deno_run_special_chars_in_bin_name.out b/tests/testdata/npm/deno_run_special_chars_in_bin_name.out new file mode 100644 index 000000000..ffe7cbd89 --- /dev/null +++ b/tests/testdata/npm/deno_run_special_chars_in_bin_name.out @@ -0,0 +1,4 @@ +this +is +a +test diff --git a/tests/testdata/npm/different_nested_dep/main.js b/tests/testdata/npm/different_nested_dep/main.js new file mode 100644 index 000000000..5677eb094 --- /dev/null +++ b/tests/testdata/npm/different_nested_dep/main.js @@ -0,0 +1,5 @@ +import dep from "@denotest/different-nested-dep"; +import childDep from "@denotest/different-nested-dep-child"; + +console.log(dep); +console.log(childDep); diff --git a/tests/testdata/npm/different_nested_dep/main.out b/tests/testdata/npm/different_nested_dep/main.out new file mode 100644 index 000000000..1191247b6 --- /dev/null +++ b/tests/testdata/npm/different_nested_dep/main.out @@ -0,0 +1,2 @@ +1 +2 diff --git a/tests/testdata/npm/different_nested_dep/package.json b/tests/testdata/npm/different_nested_dep/package.json new file mode 100644 index 000000000..c20425851 --- /dev/null +++ b/tests/testdata/npm/different_nested_dep/package.json @@ -0,0 +1,6 @@ +{ + "dependencies": { + "@denotest/different-nested-dep": "1.0.0", + "@denotest/different-nested-dep-child": "2.0.0" + } +} diff --git a/tests/testdata/npm/directory_import/folder_index_js.out b/tests/testdata/npm/directory_import/folder_index_js.out new file mode 100644 index 000000000..72f285fc0 --- /dev/null +++ b/tests/testdata/npm/directory_import/folder_index_js.out @@ -0,0 +1,7 @@ +Download http://localhost:4545/npm/registry/@denotest/sub-folders +Download http://localhost:4545/npm/registry/@denotest/sub-folders/1.0.0.tgz +error: Directory import [WILDCARD]folder_index_js is not supported resolving import from file:///[WILDCARD]/directory_import/folder_index_js.ts +Did you mean to import index.js within the directory? + +Caused by: + [WILDCARD] diff --git a/tests/testdata/npm/directory_import/folder_index_js.ts b/tests/testdata/npm/directory_import/folder_index_js.ts new file mode 100644 index 000000000..b0d51fcd9 --- /dev/null +++ b/tests/testdata/npm/directory_import/folder_index_js.ts @@ -0,0 +1,2 @@ +import test from "npm:@denotest/sub-folders/folder_index_js"; +console.log(test); diff --git a/tests/testdata/npm/directory_import/folder_no_index.out b/tests/testdata/npm/directory_import/folder_no_index.out new file mode 100644 index 000000000..86ac88207 --- /dev/null +++ b/tests/testdata/npm/directory_import/folder_no_index.out @@ -0,0 +1,6 @@ +Download http://localhost:4545/npm/registry/@denotest/sub-folders +Download http://localhost:4545/npm/registry/@denotest/sub-folders/1.0.0.tgz +error: Directory import [WILDCARD]folder_no_index is not supported resolving import from file:///[WILDCARD]/folder_no_index.ts + +Caused by: + [WILDCARD] diff --git a/tests/testdata/npm/directory_import/folder_no_index.ts b/tests/testdata/npm/directory_import/folder_no_index.ts new file mode 100644 index 000000000..4c5fb7ec0 --- /dev/null +++ b/tests/testdata/npm/directory_import/folder_no_index.ts @@ -0,0 +1,2 @@ +import test from "npm:@denotest/sub-folders/folder_no_index"; +console.log(test); diff --git a/tests/testdata/npm/dual_cjs_esm/main.out b/tests/testdata/npm/dual_cjs_esm/main.out new file mode 100644 index 000000000..32e232f11 --- /dev/null +++ b/tests/testdata/npm/dual_cjs_esm/main.out @@ -0,0 +1,3 @@ +esm +cjs +cjs diff --git a/tests/testdata/npm/dual_cjs_esm/main.ts b/tests/testdata/npm/dual_cjs_esm/main.ts new file mode 100644 index 000000000..4f3b79667 --- /dev/null +++ b/tests/testdata/npm/dual_cjs_esm/main.ts @@ -0,0 +1,6 @@ +import { getKind } from "npm:@denotest/dual-cjs-esm@latest"; // test out @latest dist tag +import * as cjs from "npm:@denotest/dual-cjs-esm@latest/cjs/main.cjs"; + +console.log(getKind()); +console.log(cjs.getKind()); +console.log(cjs.getSubPathKind()); diff --git a/tests/testdata/npm/dynamic_import/main.out b/tests/testdata/npm/dynamic_import/main.out new file mode 100644 index 000000000..cefb3ad44 --- /dev/null +++ b/tests/testdata/npm/dynamic_import/main.out @@ -0,0 +1,6 @@ +A +Download http://localhost:4545/npm/registry/chalk +Download http://localhost:4545/npm/registry/chalk/chalk-5.0.1.tgz +B +C +devDependency import failed: TypeError: Relative import path "xo"[WILDCARD] \ No newline at end of file diff --git a/tests/testdata/npm/dynamic_import/main.ts b/tests/testdata/npm/dynamic_import/main.ts new file mode 100644 index 000000000..8b850a8ee --- /dev/null +++ b/tests/testdata/npm/dynamic_import/main.ts @@ -0,0 +1,3 @@ +const importName = "./other.ts"; +console.log("A"); +await import(importName); diff --git a/tests/testdata/npm/dynamic_import/other.ts b/tests/testdata/npm/dynamic_import/other.ts new file mode 100644 index 000000000..008f8833e --- /dev/null +++ b/tests/testdata/npm/dynamic_import/other.ts @@ -0,0 +1,11 @@ +console.log("B"); +const chalk = (await import("npm:chalk@5")).default; + +console.log(chalk.green("C")); + +try { + // Trying to import a devDependency should result in an error + await import("xo"); +} catch (e) { + console.error("devDependency import failed:", e); +} diff --git a/tests/testdata/npm/dynamic_import_deno_ts_from_npm/add.ts b/tests/testdata/npm/dynamic_import_deno_ts_from_npm/add.ts new file mode 100644 index 000000000..3b399665d --- /dev/null +++ b/tests/testdata/npm/dynamic_import_deno_ts_from_npm/add.ts @@ -0,0 +1,3 @@ +export function add(a: number, b: number) { + return a + b; +} diff --git a/tests/testdata/npm/dynamic_import_deno_ts_from_npm/main.out b/tests/testdata/npm/dynamic_import_deno_ts_from_npm/main.out new file mode 100644 index 000000000..81d7aba8a --- /dev/null +++ b/tests/testdata/npm/dynamic_import_deno_ts_from_npm/main.out @@ -0,0 +1,2 @@ +3 +-1 diff --git a/tests/testdata/npm/dynamic_import_deno_ts_from_npm/main.ts b/tests/testdata/npm/dynamic_import_deno_ts_from_npm/main.ts new file mode 100644 index 000000000..4d5deec48 --- /dev/null +++ b/tests/testdata/npm/dynamic_import_deno_ts_from_npm/main.ts @@ -0,0 +1,8 @@ +import { dynamicImport } from "npm:@denotest/dynamic-import"; + +const { add } = await dynamicImport(new URL("./add.ts", import.meta.url)); +console.log(add(1, 2)); +const { subtract } = await dynamicImport( + new URL("./subtract.mts", import.meta.url), +); +console.log(subtract(1, 2)); diff --git a/tests/testdata/npm/dynamic_import_deno_ts_from_npm/subtract.mts b/tests/testdata/npm/dynamic_import_deno_ts_from_npm/subtract.mts new file mode 100644 index 000000000..4bf634170 --- /dev/null +++ b/tests/testdata/npm/dynamic_import_deno_ts_from_npm/subtract.mts @@ -0,0 +1,3 @@ +export function subtract(a: number, b: number) { + return a - b; +} diff --git a/tests/testdata/npm/dynamic_import_invalid_package_name/main.out b/tests/testdata/npm/dynamic_import_invalid_package_name/main.out new file mode 100644 index 000000000..0e9de5f25 --- /dev/null +++ b/tests/testdata/npm/dynamic_import_invalid_package_name/main.out @@ -0,0 +1,6 @@ +Download http://localhost:4545/npm/registry/ws%3A +FAILED +TypeError: npm package 'ws:' does not exist. + at async file:///[WILDCARD]/dynamic_import_invalid_package_name/main.ts:2:3 { + code: "ERR_MODULE_NOT_FOUND" +} diff --git a/tests/testdata/npm/dynamic_import_invalid_package_name/main.ts b/tests/testdata/npm/dynamic_import_invalid_package_name/main.ts new file mode 100644 index 000000000..368ccc282 --- /dev/null +++ b/tests/testdata/npm/dynamic_import_invalid_package_name/main.ts @@ -0,0 +1,6 @@ +try { + await import(`npm:${"ws:"}`); +} catch (err) { + console.log("FAILED"); + console.log(err); +} diff --git a/tests/testdata/npm/dynamic_import_json/main.js b/tests/testdata/npm/dynamic_import_json/main.js new file mode 100644 index 000000000..6d8abfc9e --- /dev/null +++ b/tests/testdata/npm/dynamic_import_json/main.js @@ -0,0 +1,4 @@ +const info = await import("npm:@denotest/binary-package@1/package.json", { + assert: { type: "json" }, +}); +console.log(json); diff --git a/tests/testdata/npm/dynamic_import_json/main.out b/tests/testdata/npm/dynamic_import_json/main.out new file mode 100644 index 000000000..07f48e8a5 --- /dev/null +++ b/tests/testdata/npm/dynamic_import_json/main.out @@ -0,0 +1,14 @@ +[Module: null prototype] { + default: { + { + name: "@denotest/binary-package", + version: "1.0.0", + main: "index.js", + optionalDependencies: { + "@denotest/binary-package-linux": "1.0.0", + "@denotest/binary-package-mac": "1.0.0", + "@denotest/binary-package-windows": "1.0.0" + } + } + } +} \ No newline at end of file diff --git a/tests/testdata/npm/dynamic_import_reload_same_package/main.out b/tests/testdata/npm/dynamic_import_reload_same_package/main.out new file mode 100644 index 000000000..918e7f5e8 --- /dev/null +++ b/tests/testdata/npm/dynamic_import_reload_same_package/main.out @@ -0,0 +1,5 @@ +Download http://localhost:4545/npm/registry/chalk +Download http://localhost:4545/npm/registry/chalk/chalk-5.0.1.tgz +Starting... +Ran other. +Finished... diff --git a/tests/testdata/npm/dynamic_import_reload_same_package/main.ts b/tests/testdata/npm/dynamic_import_reload_same_package/main.ts new file mode 100644 index 000000000..7c7ee7d55 --- /dev/null +++ b/tests/testdata/npm/dynamic_import_reload_same_package/main.ts @@ -0,0 +1,7 @@ +import chalk from "npm:chalk@5"; + +console.log(chalk.green("Starting...")); +// non-analyzable +const importName = "./other.ts"; +await import(importName); +console.log(chalk.green("Finished...")); diff --git a/tests/testdata/npm/dynamic_import_reload_same_package/other.ts b/tests/testdata/npm/dynamic_import_reload_same_package/other.ts new file mode 100644 index 000000000..28e3da14f --- /dev/null +++ b/tests/testdata/npm/dynamic_import_reload_same_package/other.ts @@ -0,0 +1,3 @@ +import chalk from "npm:chalk@5"; + +console.log(chalk.green("Ran other.")); diff --git a/tests/testdata/npm/env_var_re_export/main.js b/tests/testdata/npm/env_var_re_export/main.js new file mode 100644 index 000000000..ed91487a0 --- /dev/null +++ b/tests/testdata/npm/env_var_re_export/main.js @@ -0,0 +1,3 @@ +import { getEnv } from "npm:@denotest/env-var-re-export"; + +console.log(getEnv()); diff --git a/tests/testdata/npm/error_version_after_subpath/main.js b/tests/testdata/npm/error_version_after_subpath/main.js new file mode 100644 index 000000000..77c7a017c --- /dev/null +++ b/tests/testdata/npm/error_version_after_subpath/main.js @@ -0,0 +1 @@ +import "npm:react-dom/server@18.2.0"; diff --git a/tests/testdata/npm/error_version_after_subpath/main.out b/tests/testdata/npm/error_version_after_subpath/main.out new file mode 100644 index 000000000..0cdd1b6da --- /dev/null +++ b/tests/testdata/npm/error_version_after_subpath/main.out @@ -0,0 +1,2 @@ +error: Invalid package specifier 'npm:react-dom/server@18.2.0'. Did you mean to write 'npm:react-dom@18.2.0/server'? + at [WILDCARD]/npm/error_version_after_subpath/main.js:1:8 diff --git a/tests/testdata/npm/esm/main.js b/tests/testdata/npm/esm/main.js new file mode 100644 index 000000000..0f1fa2590 --- /dev/null +++ b/tests/testdata/npm/esm/main.js @@ -0,0 +1,9 @@ +import chalk from "npm:chalk@5"; + +if (import.meta.main) { + console.log(chalk.green("chalk esm loads")); +} + +export function test(value) { + return chalk.red(value); +} diff --git a/tests/testdata/npm/esm/main.out b/tests/testdata/npm/esm/main.out new file mode 100644 index 000000000..2010a5b73 --- /dev/null +++ b/tests/testdata/npm/esm/main.out @@ -0,0 +1,3 @@ +Download http://localhost:4545/npm/registry/chalk +Download http://localhost:4545/npm/registry/chalk/chalk-5.0.1.tgz +chalk esm loads diff --git a/tests/testdata/npm/esm/test.js b/tests/testdata/npm/esm/test.js new file mode 100644 index 000000000..b9c91c715 --- /dev/null +++ b/tests/testdata/npm/esm/test.js @@ -0,0 +1,5 @@ +import { test } from "./main.js"; + +Deno.test("test", () => { + console.log(test("test")); +}); diff --git a/tests/testdata/npm/esm/test.out b/tests/testdata/npm/esm/test.out new file mode 100644 index 000000000..a87924424 --- /dev/null +++ b/tests/testdata/npm/esm/test.out @@ -0,0 +1,11 @@ +Download http://localhost:4545/npm/registry/chalk +Download http://localhost:4545/npm/registry/chalk/chalk-5.0.1.tgz +running 1 test from ./npm/esm/test.js +test ... +------- output ------- +test +----- output end ----- +test ... ok ([WILDCARD]s) + +ok | 1 passed | 0 failed ([WILDCARD]s) + diff --git a/tests/testdata/npm/esm_import_cjs_default/main.out b/tests/testdata/npm/esm_import_cjs_default/main.out new file mode 100644 index 000000000..0f6a61e34 --- /dev/null +++ b/tests/testdata/npm/esm_import_cjs_default/main.out @@ -0,0 +1,51 @@ +Node esm importing node cjs +=========================== +{ + default: [Function (anonymous)], + named: [Function (anonymous)], + MyClass: [class MyClass] +} +{ default: [Function (anonymous)], named: [Function (anonymous)] } +[Module: null prototype] { + MyClass: [class MyClass], + __esModule: true, + default: { + default: [Function (anonymous)], + named: [Function (anonymous)], + MyClass: [class MyClass] + }, + named: [Function (anonymous)] +} +[Module: null prototype] { + __esModule: true, + default: { default: [Function (anonymous)], named: [Function (anonymous)] }, + named: [Function (anonymous)] +} +=========================== +static method +Deno esm importing node cjs +=========================== +{ + default: [Function (anonymous)], + named: [Function (anonymous)], + MyClass: [class MyClass] +} +[Module: null prototype] { + MyClass: [class MyClass], + __esModule: true, + default: { + default: [Function (anonymous)], + named: [Function (anonymous)], + MyClass: [class MyClass] + }, + named: [Function (anonymous)] +} +=========================== +Deno esm importing node esm +=========================== +[Function: default] +[Module: null prototype] { default: [Function: default] } +=========================== +1 +5 +static method diff --git a/tests/testdata/npm/esm_import_cjs_default/main.ts b/tests/testdata/npm/esm_import_cjs_default/main.ts new file mode 100644 index 000000000..f9c3280e5 --- /dev/null +++ b/tests/testdata/npm/esm_import_cjs_default/main.ts @@ -0,0 +1,23 @@ +// @ts-check +import cjsDefault, { + MyClass as MyCjsClass, +} from "npm:@denotest/cjs-default-export"; +import * as cjsNamespace from "npm:@denotest/cjs-default-export"; +import esmDefault from "npm:@denotest/esm-import-cjs-default"; +import * as esmNamespace from "npm:@denotest/esm-import-cjs-default"; + +console.log("Deno esm importing node cjs"); +console.log("==========================="); +console.log(cjsDefault); +console.log(cjsNamespace); +console.log("==========================="); + +console.log("Deno esm importing node esm"); +console.log("==========================="); +console.log(esmDefault); +console.log(esmNamespace); +console.log("==========================="); + +console.log(cjsDefault.default()); +console.log(esmDefault()); +console.log(MyCjsClass.someStaticMethod()); diff --git a/tests/testdata/npm/file_dts_dmts_dcts/main.out b/tests/testdata/npm/file_dts_dmts_dcts/main.out new file mode 100644 index 000000000..c92043f8b --- /dev/null +++ b/tests/testdata/npm/file_dts_dmts_dcts/main.out @@ -0,0 +1,24 @@ +Download http://localhost:4545/npm/registry/@denotest/file-dts-dmts-dcts +Download http://localhost:4545/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0.tgz +Check file:///[WILDCARD]/main.ts +error: TS2322 [ERROR]: Type '5' is not assignable to type '"dts"'. +const value1: Dts1 = 5; + ~~~~~~ + at file:///[WILDCARD] + +TS2322 [ERROR]: Type '5' is not assignable to type '"mts"'. +const value2: Mts1 = 5; + ~~~~~~ + at file:///[WILDCARD] + +TS2322 [ERROR]: Type '5' is not assignable to type '"mts"'. +const value3: Mts2 = 5; + ~~~~~~ + at file:///[WILDCARD] + +TS2322 [ERROR]: Type '5' is not assignable to type '"cts"'. +const value4: Cts1 = 5; + ~~~~~~ + at file:///[WILDCARD] + +Found 4 errors. diff --git a/tests/testdata/npm/file_dts_dmts_dcts/main.ts b/tests/testdata/npm/file_dts_dmts_dcts/main.ts new file mode 100644 index 000000000..63686e2d3 --- /dev/null +++ b/tests/testdata/npm/file_dts_dmts_dcts/main.ts @@ -0,0 +1,9 @@ +import { Value as Dts1 } from "npm:@denotest/file-dts-dmts-dcts/js"; +import { Value as Mts1 } from "npm:@denotest/file-dts-dmts-dcts"; +import { Value as Mts2 } from "npm:@denotest/file-dts-dmts-dcts/mjs"; +import { Value as Cts1 } from "npm:@denotest/file-dts-dmts-dcts/cjs"; + +const value1: Dts1 = 5; +const value2: Mts1 = 5; +const value3: Mts2 = 5; +const value4: Cts1 = 5; diff --git a/tests/testdata/npm/import_json/main.js b/tests/testdata/npm/import_json/main.js new file mode 100644 index 000000000..b752bdef8 --- /dev/null +++ b/tests/testdata/npm/import_json/main.js @@ -0,0 +1,4 @@ +import json from "npm:@denotest/binary-package@1/package.json" assert { + type: "json", +}; +console.log(json); diff --git a/tests/testdata/npm/import_json/main.out b/tests/testdata/npm/import_json/main.out new file mode 100644 index 000000000..7db7ec4ea --- /dev/null +++ b/tests/testdata/npm/import_json/main.out @@ -0,0 +1,10 @@ +{ + name: "@denotest/binary-package", + version: "1.0.0", + main: "index.js", + optionalDependencies: { + "@denotest/binary-package-linux": "1.0.0", + "@denotest/binary-package-mac": "1.0.0", + "@denotest/binary-package-windows": "1.0.0" + } +} diff --git a/tests/testdata/npm/import_map/import_map.json b/tests/testdata/npm/import_map/import_map.json new file mode 100644 index 000000000..1c3baacd1 --- /dev/null +++ b/tests/testdata/npm/import_map/import_map.json @@ -0,0 +1,6 @@ +{ + "imports": { + "chalk": "npm:chalk@5", + "@denotest/": "npm:/@denotest/dual-cjs-esm/" + } +} diff --git a/tests/testdata/npm/import_map/main.js b/tests/testdata/npm/import_map/main.js new file mode 100644 index 000000000..e354b7e92 --- /dev/null +++ b/tests/testdata/npm/import_map/main.js @@ -0,0 +1,10 @@ +import chalk from "chalk"; +import { getSubPathKind } from "@denotest/subpath/main.mjs"; + +console.log(chalk.green("chalk import map loads")); + +export function test(value) { + return chalk.red(value); +} + +console.log(getSubPathKind()); diff --git a/tests/testdata/npm/import_map/main.out b/tests/testdata/npm/import_map/main.out new file mode 100644 index 000000000..a3d1d9f3a --- /dev/null +++ b/tests/testdata/npm/import_map/main.out @@ -0,0 +1,10 @@ +[UNORDERED_START] +Download http://localhost:4545/npm/registry/chalk +Download http://localhost:4545/npm/registry/@denotest/dual-cjs-esm +[UNORDERED_END] +[UNORDERED_START] +Download http://localhost:4545/npm/registry/@denotest/dual-cjs-esm/1.0.0.tgz +Download http://localhost:4545/npm/registry/chalk/chalk-5.0.1.tgz +[UNORDERED_END] +chalk import map loads +esm diff --git a/tests/testdata/npm/imports_package_json/import_not_defined.js b/tests/testdata/npm/imports_package_json/import_not_defined.js new file mode 100644 index 000000000..dc4d2df16 --- /dev/null +++ b/tests/testdata/npm/imports_package_json/import_not_defined.js @@ -0,0 +1,3 @@ +import data from "@denotest/imports-package-json/import-not-defined"; + +console.log(data); diff --git a/tests/testdata/npm/imports_package_json/import_not_defined.out b/tests/testdata/npm/imports_package_json/import_not_defined.out new file mode 100644 index 000000000..3580d9007 --- /dev/null +++ b/tests/testdata/npm/imports_package_json/import_not_defined.out @@ -0,0 +1,6 @@ +Download http://localhost:4545/npm/registry/@denotest/imports-package-json +Download http://localhost:4545/npm/registry/@denotest/imports-package-json/1.0.0.tgz +error: Could not resolve '#not-defined' from 'file:///[WILDCARD]/@denotest/imports-package-json/1.0.0/import_not_defined.js'. + +Caused by: + [ERR_PACKAGE_IMPORT_NOT_DEFINED] Package import specifier "#not-defined" is not defined in package [WILDCARD]package.json imported from [WILDCARD]import_not_defined.js diff --git a/tests/testdata/npm/imports_package_json/main.js b/tests/testdata/npm/imports_package_json/main.js new file mode 100644 index 000000000..53090dd94 --- /dev/null +++ b/tests/testdata/npm/imports_package_json/main.js @@ -0,0 +1,7 @@ +import data from "@denotest/imports-package-json"; + +console.log(data.hi); +console.log(data.bye); +console.log(typeof data.fs.readFile); +console.log(typeof data.path.join); +console.log(typeof data.fs2.writeFile); diff --git a/tests/testdata/npm/imports_package_json/main.out b/tests/testdata/npm/imports_package_json/main.out new file mode 100644 index 000000000..9f702b96b --- /dev/null +++ b/tests/testdata/npm/imports_package_json/main.out @@ -0,0 +1,7 @@ +Download http://localhost:4545/npm/registry/@denotest/imports-package-json +Download http://localhost:4545/npm/registry/@denotest/imports-package-json/1.0.0.tgz +hi +bye +function +function +function diff --git a/tests/testdata/npm/imports_package_json/package.json b/tests/testdata/npm/imports_package_json/package.json new file mode 100644 index 000000000..cb6a08d1a --- /dev/null +++ b/tests/testdata/npm/imports_package_json/package.json @@ -0,0 +1,6 @@ +{ + "name": "my-test", + "dependencies": { + "@denotest/imports-package-json": "1.0.0" + } +} diff --git a/tests/testdata/npm/imports_package_json/sub_path_import_not_defined.js b/tests/testdata/npm/imports_package_json/sub_path_import_not_defined.js new file mode 100644 index 000000000..f1097aa06 --- /dev/null +++ b/tests/testdata/npm/imports_package_json/sub_path_import_not_defined.js @@ -0,0 +1,3 @@ +import data from "@denotest/imports-package-json/sub-path-import-not-defined"; + +console.log(data); diff --git a/tests/testdata/npm/imports_package_json/sub_path_import_not_defined.out b/tests/testdata/npm/imports_package_json/sub_path_import_not_defined.out new file mode 100644 index 000000000..04a21c99e --- /dev/null +++ b/tests/testdata/npm/imports_package_json/sub_path_import_not_defined.out @@ -0,0 +1,6 @@ +Download http://localhost:4545/npm/registry/@denotest/imports-package-json +Download http://localhost:4545/npm/registry/@denotest/imports-package-json/1.0.0.tgz +error: Could not resolve '#hi' from 'file:///[WILDCARD]/@denotest/imports-package-json/1.0.0/sub_path/import_not_defined.js'. + +Caused by: + [ERR_PACKAGE_IMPORT_NOT_DEFINED] Package import specifier "#hi" is not defined in package [WILDCARD]sub_path[WILDCARD]package.json imported from [WILDCARD]import_not_defined.js diff --git a/tests/testdata/npm/info/chalk.out b/tests/testdata/npm/info/chalk.out new file mode 100644 index 000000000..63fa20da5 --- /dev/null +++ b/tests/testdata/npm/info/chalk.out @@ -0,0 +1,9 @@ +dependencies: 5 unique +size: [WILDCARD] + +npm:/chalk@4.1.2 ([WILDCARD]) +├─┬ npm:/ansi-styles@4.3.0 ([WILDCARD]) +│ └─┬ npm:/color-convert@2.0.1 ([WILDCARD]) +│ └── npm:/color-name@1.1.4 ([WILDCARD]) +└─┬ npm:/supports-color@7.2.0 ([WILDCARD]) + └── npm:/has-flag@4.0.0 ([WILDCARD]) diff --git a/tests/testdata/npm/info/chalk_json.out b/tests/testdata/npm/info/chalk_json.out new file mode 100644 index 000000000..bffed4ad4 --- /dev/null +++ b/tests/testdata/npm/info/chalk_json.out @@ -0,0 +1,56 @@ +{ + "roots": [ + "npm:chalk@4" + ], + "modules": [ + { + "kind": "npm", + "specifier": "npm:/chalk@4.1.2", + "npmPackage": "chalk@4.1.2" + } + ], + "redirects": { + "npm:chalk@4": "npm:/chalk@4.1.2" + }, + "npmPackages": { + "ansi-styles@4.3.0": { + "name": "ansi-styles", + "version": "4.3.0", + "dependencies": [ + "color-convert@2.0.1" + ] + }, + "chalk@4.1.2": { + "name": "chalk", + "version": "4.1.2", + "dependencies": [ + "ansi-styles@4.3.0", + "supports-color@7.2.0" + ] + }, + "color-convert@2.0.1": { + "name": "color-convert", + "version": "2.0.1", + "dependencies": [ + "color-name@1.1.4" + ] + }, + "color-name@1.1.4": { + "name": "color-name", + "version": "1.1.4", + "dependencies": [] + }, + "has-flag@4.0.0": { + "name": "has-flag", + "version": "4.0.0", + "dependencies": [] + }, + "supports-color@7.2.0": { + "name": "supports-color", + "version": "7.2.0", + "dependencies": [ + "has-flag@4.0.0" + ] + } + } +} diff --git a/tests/testdata/npm/invalid_package_name/main.js b/tests/testdata/npm/invalid_package_name/main.js new file mode 100644 index 000000000..1e3783054 --- /dev/null +++ b/tests/testdata/npm/invalid_package_name/main.js @@ -0,0 +1 @@ +import * as foo from "npm:@foo"; diff --git a/tests/testdata/npm/invalid_package_name/main.out b/tests/testdata/npm/invalid_package_name/main.out new file mode 100644 index 000000000..b4a421bd7 --- /dev/null +++ b/tests/testdata/npm/invalid_package_name/main.out @@ -0,0 +1,2 @@ +error: Invalid package specifier 'npm:@foo'. Did not contain a valid package name. + at [WILDCARD]/invalid_package_name/main.js:1:22 diff --git a/tests/testdata/npm/local_dir_resolves_symlinks/index.js b/tests/testdata/npm/local_dir_resolves_symlinks/index.js new file mode 100644 index 000000000..72d8913f5 --- /dev/null +++ b/tests/testdata/npm/local_dir_resolves_symlinks/index.js @@ -0,0 +1,3 @@ +import * as d from "define-properties"; + +console.log(typeof d.default === "function", "it works"); diff --git a/tests/testdata/npm/local_dir_resolves_symlinks/index.out b/tests/testdata/npm/local_dir_resolves_symlinks/index.out new file mode 100644 index 000000000..25d44c6b8 --- /dev/null +++ b/tests/testdata/npm/local_dir_resolves_symlinks/index.out @@ -0,0 +1,2 @@ +Download [WILDCARD] +true it works diff --git a/tests/testdata/npm/local_dir_resolves_symlinks/package.json b/tests/testdata/npm/local_dir_resolves_symlinks/package.json new file mode 100644 index 000000000..4c974022e --- /dev/null +++ b/tests/testdata/npm/local_dir_resolves_symlinks/package.json @@ -0,0 +1,7 @@ +{ + "name": "foo", + "type": "module", + "dependencies": { + "define-properties": "^1.2.0" + } +} diff --git a/tests/testdata/npm/lock_file/lock.json b/tests/testdata/npm/lock_file/lock.json new file mode 100644 index 000000000..57253314e --- /dev/null +++ b/tests/testdata/npm/lock_file/lock.json @@ -0,0 +1,164 @@ +{ + "version": "2", + "remote": {}, + "npm": { + "specifiers": { "fs-extra@10.1.0": "fs-extra@10.1.0", "vue": "vue@3.2.38" }, + "packages": { + "@babel/parser@7.19.0": { + "integrity": "sha512-foobar!", + "dependencies": {} + }, + "@vue/compiler-core@3.2.38": { + "integrity": "sha512-/FsvnSu7Z+lkd/8KXMa4yYNUiqQrI22135gfsQYVGuh5tqEgOB0XqrUdb/KnCLa5+TmQLPwvyUnKMyCpu+SX3Q==", + "dependencies": { + "@babel/parser": "@babel/parser@7.19.0", + "@vue/shared": "@vue/shared@3.2.38", + "estree-walker": "estree-walker@2.0.2", + "source-map": "source-map@0.6.1" + } + }, + "@vue/compiler-dom@3.2.38": { + "integrity": "sha512-zqX4FgUbw56kzHlgYuEEJR8mefFiiyR3u96498+zWPsLeh1WKvgIReoNE+U7gG8bCUdvsrJ0JRmev0Ky6n2O0g==", + "dependencies": { + "@vue/compiler-core": "@vue/compiler-core@3.2.38", + "@vue/shared": "@vue/shared@3.2.38" + } + }, + "@vue/compiler-sfc@3.2.38": { + "integrity": "sha512-KZjrW32KloMYtTcHAFuw3CqsyWc5X6seb8KbkANSWt3Cz9p2qA8c1GJpSkksFP9ABb6an0FLCFl46ZFXx3kKpg==", + "dependencies": { + "@babel/parser": "@babel/parser@7.19.0", + "@vue/compiler-core": "@vue/compiler-core@3.2.38", + "@vue/compiler-dom": "@vue/compiler-dom@3.2.38", + "@vue/compiler-ssr": "@vue/compiler-ssr@3.2.38", + "@vue/reactivity-transform": "@vue/reactivity-transform@3.2.38", + "@vue/shared": "@vue/shared@3.2.38", + "estree-walker": "estree-walker@2.0.2", + "magic-string": "magic-string@0.25.9", + "postcss": "postcss@8.4.16", + "source-map": "source-map@0.6.1" + } + }, + "@vue/compiler-ssr@3.2.38": { + "integrity": "sha512-bm9jOeyv1H3UskNm4S6IfueKjUNFmi2kRweFIGnqaGkkRePjwEcfCVqyS3roe7HvF4ugsEkhf4+kIvDhip6XzQ==", + "dependencies": { + "@vue/compiler-dom": "@vue/compiler-dom@3.2.38", + "@vue/shared": "@vue/shared@3.2.38" + } + }, + "@vue/reactivity-transform@3.2.38": { + "integrity": "sha512-3SD3Jmi1yXrDwiNJqQ6fs1x61WsDLqVk4NyKVz78mkaIRh6d3IqtRnptgRfXn+Fzf+m6B1KxBYWq1APj6h4qeA==", + "dependencies": { + "@babel/parser": "@babel/parser@7.19.0", + "@vue/compiler-core": "@vue/compiler-core@3.2.38", + "@vue/shared": "@vue/shared@3.2.38", + "estree-walker": "estree-walker@2.0.2", + "magic-string": "magic-string@0.25.9" + } + }, + "@vue/reactivity@3.2.38": { + "integrity": "sha512-6L4myYcH9HG2M25co7/BSo0skKFHpAN8PhkNPM4xRVkyGl1K5M3Jx4rp5bsYhvYze2K4+l+pioN4e6ZwFLUVtw==", + "dependencies": { "@vue/shared": "@vue/shared@3.2.38" } + }, + "@vue/runtime-core@3.2.38": { + "integrity": "sha512-kk0qiSiXUU/IKxZw31824rxmFzrLr3TL6ZcbrxWTKivadoKupdlzbQM4SlGo4MU6Zzrqv4fzyUasTU1jDoEnzg==", + "dependencies": { + "@vue/reactivity": "@vue/reactivity@3.2.38", + "@vue/shared": "@vue/shared@3.2.38" + } + }, + "@vue/runtime-dom@3.2.38": { + "integrity": "sha512-4PKAb/ck2TjxdMSzMsnHViOrrwpudk4/A56uZjhzvusoEU9xqa5dygksbzYepdZeB5NqtRw5fRhWIiQlRVK45A==", + "dependencies": { + "@vue/runtime-core": "@vue/runtime-core@3.2.38", + "@vue/shared": "@vue/shared@3.2.38", + "csstype": "csstype@2.6.20" + } + }, + "@vue/server-renderer@3.2.38": { + "integrity": "sha512-pg+JanpbOZ5kEfOZzO2bt02YHd+ELhYP8zPeLU1H0e7lg079NtuuSB8fjLdn58c4Ou8UQ6C1/P+528nXnLPAhA==", + "dependencies": { + "@vue/compiler-ssr": "@vue/compiler-ssr@3.2.38", + "@vue/shared": "@vue/shared@3.2.38" + } + }, + "@vue/shared@3.2.38": { + "integrity": "sha512-dTyhTIRmGXBjxJE+skC8tTWCGLCVc4wQgRRLt8+O9p5ewBAjoBwtCAkLPrtToSr1xltoe3st21Pv953aOZ7alg==", + "dependencies": {} + }, + "csstype@2.6.20": { + "integrity": "sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA==", + "dependencies": {} + }, + "estree-walker@2.0.2": { + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dependencies": {} + }, + "fs-extra@10.1.0": { + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dependencies": { + "graceful-fs": "graceful-fs@4.2.10", + "jsonfile": "jsonfile@6.1.0", + "universalify": "universalify@2.0.0" + } + }, + "graceful-fs@4.2.10": { + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dependencies": {} + }, + "jsonfile@6.1.0": { + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "graceful-fs": "graceful-fs@4.2.10", + "universalify": "universalify@2.0.0" + } + }, + "magic-string@0.25.9": { + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "dependencies": { "sourcemap-codec": "sourcemap-codec@1.4.8" } + }, + "nanoid@3.3.4": { + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "dependencies": {} + }, + "picocolors@1.0.0": { + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dependencies": {} + }, + "postcss@8.4.16": { + "integrity": "sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==", + "dependencies": { + "nanoid": "nanoid@3.3.4", + "picocolors": "picocolors@1.0.0", + "source-map-js": "source-map-js@1.0.2" + } + }, + "source-map-js@1.0.2": { + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dependencies": {} + }, + "source-map@0.6.1": { + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dependencies": {} + }, + "sourcemap-codec@1.4.8": { + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "dependencies": {} + }, + "universalify@2.0.0": { + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dependencies": {} + }, + "vue@3.2.38": { + "integrity": "sha512-hHrScEFSmDAWL0cwO4B6WO7D3sALZPbfuThDsGBebthrNlDxdJZpGR3WB87VbjpPh96mep1+KzukYEhpHDFa8Q==", + "dependencies": { + "@vue/compiler-dom": "@vue/compiler-dom@3.2.38", + "@vue/compiler-sfc": "@vue/compiler-sfc@3.2.38", + "@vue/runtime-dom": "@vue/runtime-dom@3.2.38", + "@vue/server-renderer": "@vue/server-renderer@3.2.38", + "@vue/shared": "@vue/shared@3.2.38" + } + } + } + } +} diff --git a/tests/testdata/npm/lock_file/main.js b/tests/testdata/npm/lock_file/main.js new file mode 100644 index 000000000..a7b5960ca --- /dev/null +++ b/tests/testdata/npm/lock_file/main.js @@ -0,0 +1,5 @@ +import fsx from "npm:fs-extra@10.1.0"; +import { createApp } from "npm:vue"; + +console.log(fsx.access); +console.log(createApp); diff --git a/tests/testdata/npm/lock_file/main.out b/tests/testdata/npm/lock_file/main.out new file mode 100644 index 000000000..65e881be6 --- /dev/null +++ b/tests/testdata/npm/lock_file/main.out @@ -0,0 +1,12 @@ +Download [WILDCARD] +error: Integrity check failed for npm package: "@babel/parser@7.19.0". Unable to verify that the package +is the same as when the lockfile was generated. + +Actual: sha512-74bEXKX2h+8rrfQUfsBfuZZHzsEs6Eql4pqy/T4Nn6Y9wNPggQOqD6z6pn5Bl8ZfysKouFZT/UXEH94ummEeQw== +Expected: sha512-foobar! + +This could be caused by: + * the lock file may be corrupt + * the source itself may be corrupt + +Use "--lock-write" flag to regenerate the lockfile at "[WILDCARD]lock.json". diff --git a/tests/testdata/npm/mixed_case_package_name/global.out b/tests/testdata/npm/mixed_case_package_name/global.out new file mode 100644 index 000000000..33d09890b --- /dev/null +++ b/tests/testdata/npm/mixed_case_package_name/global.out @@ -0,0 +1,9 @@ +[UNORDERED_START] +Download http://localhost:4545/npm/registry/@denotest/MixedCase +Download http://localhost:4545/npm/registry/@denotest/CAPITALS +[UNORDERED_END] +[UNORDERED_START] +Download http://localhost:4545/npm/registry/@denotest/CAPITALS/1.0.0.tgz +Download http://localhost:4545/npm/registry/@denotest/MixedCase/1.0.0.tgz +[UNORDERED_END] +5 diff --git a/tests/testdata/npm/mixed_case_package_name/global.ts b/tests/testdata/npm/mixed_case_package_name/global.ts new file mode 100644 index 000000000..a721b3d78 --- /dev/null +++ b/tests/testdata/npm/mixed_case_package_name/global.ts @@ -0,0 +1,2 @@ +import value from "npm:@denotest/MixedCase"; +console.log(value); diff --git a/tests/testdata/npm/mixed_case_package_name/local.out b/tests/testdata/npm/mixed_case_package_name/local.out new file mode 100644 index 000000000..782107eb1 --- /dev/null +++ b/tests/testdata/npm/mixed_case_package_name/local.out @@ -0,0 +1,13 @@ +[UNORDERED_START] +Download http://localhost:4545/npm/registry/@denotest/MixedCase +Download http://localhost:4545/npm/registry/@denotest/CAPITALS +[UNORDERED_END] +[UNORDERED_START] +Download http://localhost:4545/npm/registry/@denotest/CAPITALS/1.0.0.tgz +Initialize @denotest/CAPITALS@1.0.0 +Download http://localhost:4545/npm/registry/@denotest/MixedCase/1.0.0.tgz +Initialize @denotest/MixedCase@1.0.0 +[UNORDERED_END] +5 +true +true diff --git a/tests/testdata/npm/mixed_case_package_name/local.ts b/tests/testdata/npm/mixed_case_package_name/local.ts new file mode 100644 index 000000000..6ca6cb581 --- /dev/null +++ b/tests/testdata/npm/mixed_case_package_name/local.ts @@ -0,0 +1,18 @@ +import value from "npm:@denotest/MixedCase"; +console.log(value); +console.log(pathExists("./node_modules/.deno")); +console.log( + pathExists("./node_modules/.deno/_ibsgk3tporsxg5bpinavaskuifgfg@1.0.0"), +); + +function pathExists(filePath: string) { + try { + Deno.lstatSync(filePath); + return true; + } catch (error) { + if (error instanceof Deno.errors.NotFound) { + return false; + } + throw error; + } +} diff --git a/tests/testdata/npm/no_npm_after_first_run/main1.ts b/tests/testdata/npm/no_npm_after_first_run/main1.ts new file mode 100644 index 000000000..1ccc441a1 --- /dev/null +++ b/tests/testdata/npm/no_npm_after_first_run/main1.ts @@ -0,0 +1,3 @@ +import chalk from "npm:chalk@5"; + +console.log(chalk); diff --git a/tests/testdata/npm/no_types_cjs/main.ts b/tests/testdata/npm/no_types_cjs/main.ts new file mode 100644 index 000000000..32458e839 --- /dev/null +++ b/tests/testdata/npm/no_types_cjs/main.ts @@ -0,0 +1,7 @@ +import mod from "npm:@denotest/no-types-cjs"; + +// it actually returns a `number` and has that in its +// jsdocs, but the jsdocs should not have been resolved so +// this should type check just fine +const value: string = mod(); +console.log(value); diff --git a/tests/testdata/npm/no_types_in_conditional_exports/main.out b/tests/testdata/npm/no_types_in_conditional_exports/main.out new file mode 100644 index 000000000..3c856ac09 --- /dev/null +++ b/tests/testdata/npm/no_types_in_conditional_exports/main.out @@ -0,0 +1,4 @@ +Download http://localhost:4545/npm/registry/@denotest/no-types-in-conditional-exports +Download http://localhost:4545/npm/registry/@denotest/no-types-in-conditional-exports/1.0.0.tgz +Check [WILDCARD]npm/no_types_in_conditional_exports/main.ts +{ foo: "bar" } diff --git a/tests/testdata/npm/no_types_in_conditional_exports/main.ts b/tests/testdata/npm/no_types_in_conditional_exports/main.ts new file mode 100644 index 000000000..7ec2f18fd --- /dev/null +++ b/tests/testdata/npm/no_types_in_conditional_exports/main.ts @@ -0,0 +1,2 @@ +import foo from "npm:@denotest/no-types-in-conditional-exports@1.0.0"; +console.log(foo); diff --git a/tests/testdata/npm/node_modules_deno_node_modules/main.out b/tests/testdata/npm/node_modules_deno_node_modules/main.out new file mode 100644 index 000000000..1ebdb2dd5 --- /dev/null +++ b/tests/testdata/npm/node_modules_deno_node_modules/main.out @@ -0,0 +1,2 @@ +esm +esm diff --git a/tests/testdata/npm/node_modules_deno_node_modules/main.ts b/tests/testdata/npm/node_modules_deno_node_modules/main.ts new file mode 100644 index 000000000..6e4a32d8e --- /dev/null +++ b/tests/testdata/npm/node_modules_deno_node_modules/main.ts @@ -0,0 +1,7 @@ +import { getKind as getKind1 } from "npm:@denotest/dual-cjs-esm-dep"; +// this should still be able to be resolved even though it's missing the +// "@denotest/dual-cjs-esm" package because the above import will resolve it +import { getKind as getKind2 } from "npm:@denotest/dual-cjs-esm-dep-missing"; + +console.log(getKind1()); +console.log(getKind2()); diff --git a/tests/testdata/npm/node_modules_import/main.out b/tests/testdata/npm/node_modules_import/main.out new file mode 100644 index 000000000..083edaac2 --- /dev/null +++ b/tests/testdata/npm/node_modules_import/main.out @@ -0,0 +1,3 @@ +2 +2 +2 diff --git a/tests/testdata/npm/node_modules_import/main.ts b/tests/testdata/npm/node_modules_import/main.ts new file mode 100644 index 000000000..848ca0f81 --- /dev/null +++ b/tests/testdata/npm/node_modules_import/main.ts @@ -0,0 +1,16 @@ +import * as myImport1 from "@denotest/esm-basic"; +import * as myImport2 from "./node_modules/@denotest/esm-basic/main.mjs"; +import * as myImport3 from "@denotest/esm-basic/main.mjs"; + +myImport1.setValue(5); +myImport2.setValue(2); + +// these should all give type errors +const value1: string = myImport1.getValue(); +const value2: string = myImport2.getValue(); +const value3: string = myImport3.getValue(); + +// these should all be equal because it should be mutating the same module +console.log(value1); +console.log(value2); +console.log(value3); diff --git a/tests/testdata/npm/node_modules_import/main_check.out b/tests/testdata/npm/node_modules_import/main_check.out new file mode 100644 index 000000000..cf7cc110d --- /dev/null +++ b/tests/testdata/npm/node_modules_import/main_check.out @@ -0,0 +1,16 @@ +error: TS2322 [ERROR]: Type 'number' is not assignable to type 'string'. +const value1: string = myImport1.getValue(); + ~~~~~~ + at file:///[WILDCARD]/npm/node_modules_import/main.ts:9:7 + +TS2322 [ERROR]: Type 'number' is not assignable to type 'string'. +const value2: string = myImport2.getValue(); + ~~~~~~ + at file:///[WILDCARD]/npm/node_modules_import/main.ts:10:7 + +TS2322 [ERROR]: Type 'number' is not assignable to type 'string'. +const value3: string = myImport3.getValue(); + ~~~~~~ + at file:///[WILDCARD]/npm/node_modules_import/main.ts:11:7 + +Found 3 errors. diff --git a/tests/testdata/npm/node_modules_import/package.json b/tests/testdata/npm/node_modules_import/package.json new file mode 100644 index 000000000..ed77298e0 --- /dev/null +++ b/tests/testdata/npm/node_modules_import/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "@denotest/esm-basic": "^1" + } +} diff --git a/tests/testdata/npm/nonexistent_file/main.js b/tests/testdata/npm/nonexistent_file/main.js new file mode 100644 index 000000000..c480b0548 --- /dev/null +++ b/tests/testdata/npm/nonexistent_file/main.js @@ -0,0 +1,2 @@ +import hmacSHA512 from "npm:crypto-js/non-existent"; +console.log(hmacSHA512); diff --git a/tests/testdata/npm/nonexistent_file/main.out b/tests/testdata/npm/nonexistent_file/main.out new file mode 100644 index 000000000..baa79b1ce --- /dev/null +++ b/tests/testdata/npm/nonexistent_file/main.out @@ -0,0 +1,4 @@ +error: Unable to load [WILDCARD]non-existent imported from [WILDCARD]main.js + +Caused by: +[WILDCARD] diff --git a/tests/testdata/npm/peer_deps_with_copied_folders/main.out b/tests/testdata/npm/peer_deps_with_copied_folders/main.out new file mode 100644 index 000000000..32fa3b76f --- /dev/null +++ b/tests/testdata/npm/peer_deps_with_copied_folders/main.out @@ -0,0 +1,14 @@ +[UNORDERED_START] +Download http://localhost:4545/npm/registry/@denotest/peer-dep-test-child +Download http://localhost:4545/npm/registry/@denotest/peer-dep-test-grandchild +Download http://localhost:4545/npm/registry/@denotest/peer-dep-test-peer +[UNORDERED_END] +[UNORDERED_START] +Download http://localhost:4545/npm/registry/@denotest/peer-dep-test-child/1.0.0.tgz +Download http://localhost:4545/npm/registry/@denotest/peer-dep-test-child/2.0.0.tgz +Download http://localhost:4545/npm/registry/@denotest/peer-dep-test-grandchild/1.0.0.tgz +Download http://localhost:4545/npm/registry/@denotest/peer-dep-test-peer/1.0.0.tgz +Download http://localhost:4545/npm/registry/@denotest/peer-dep-test-peer/2.0.0.tgz +[UNORDERED_END] +1 +2 diff --git a/tests/testdata/npm/peer_deps_with_copied_folders/main.ts b/tests/testdata/npm/peer_deps_with_copied_folders/main.ts new file mode 100644 index 000000000..a8ea8104a --- /dev/null +++ b/tests/testdata/npm/peer_deps_with_copied_folders/main.ts @@ -0,0 +1,5 @@ +import version1 from "npm:@denotest/peer-dep-test-child@1"; +import version2 from "npm:@denotest/peer-dep-test-child@2"; + +console.error(version1); +console.error(version2); diff --git a/tests/testdata/npm/peer_deps_with_copied_folders/main_info.out b/tests/testdata/npm/peer_deps_with_copied_folders/main_info.out new file mode 100644 index 000000000..638f9328d --- /dev/null +++ b/tests/testdata/npm/peer_deps_with_copied_folders/main_info.out @@ -0,0 +1,14 @@ +local: [WILDCARD]main.ts +type: TypeScript +dependencies: 6 unique +size: [WILDCARD] + +file:///[WILDCARD]/testdata/npm/peer_deps_with_copied_folders/main.ts (171B) +├─┬ npm:/@denotest/peer-dep-test-child@1.0.0 ([WILDCARD]) +│ ├─┬ npm:/@denotest/peer-dep-test-grandchild@1.0.0_@denotest+peer-dep-test-peer@1.0.0 ([WILDCARD]) +│ │ └── npm:/@denotest/peer-dep-test-peer@1.0.0 ([WILDCARD]) +│ └── npm:/@denotest/peer-dep-test-peer@1.0.0 ([WILDCARD]) +└─┬ npm:/@denotest/peer-dep-test-child@2.0.0 ([WILDCARD]) + ├─┬ npm:/@denotest/peer-dep-test-grandchild@1.0.0_@denotest+peer-dep-test-peer@2.0.0 ([WILDCARD]) + │ └── npm:/@denotest/peer-dep-test-peer@2.0.0 ([WILDCARD]) + └── npm:/@denotest/peer-dep-test-peer@2.0.0 ([WILDCARD]) diff --git a/tests/testdata/npm/peer_deps_with_copied_folders/main_info_json.out b/tests/testdata/npm/peer_deps_with_copied_folders/main_info_json.out new file mode 100644 index 000000000..a4306a6d5 --- /dev/null +++ b/tests/testdata/npm/peer_deps_with_copied_folders/main_info_json.out @@ -0,0 +1,98 @@ +{ + "roots": [ + "[WILDCARD]/npm/peer_deps_with_copied_folders/main.ts" + ], + "modules": [ + { + "kind": "esm", + "dependencies": [ + { + "specifier": "npm:@denotest/peer-dep-test-child@1", + "code": { + "specifier": "npm:@denotest/peer-dep-test-child@1", + "span": { + "start": { + "line": 0, + "character": 21 + }, + "end": { + "line": 0, + "character": 58 + } + } + }, + "npmPackage": "@denotest/peer-dep-test-child@1.0.0_@denotest+peer-dep-test-peer@1.0.0" + }, + { + "specifier": "npm:@denotest/peer-dep-test-child@2", + "code": { + "specifier": "npm:@denotest/peer-dep-test-child@2", + "span": { + "start": { + "line": 1, + "character": 21 + }, + "end": { + "line": 1, + "character": 58 + } + } + }, + "npmPackage": "@denotest/peer-dep-test-child@2.0.0_@denotest+peer-dep-test-peer@2.0.0" + } + ], + "local": "[WILDCARD]main.ts", + "emit": null, + "map": null, + "size": 171, + "mediaType": "TypeScript", + "specifier": "file://[WILDCARD]/main.ts" + } + ], + "redirects": { + "npm:@denotest/peer-dep-test-child@1": "npm:/@denotest/peer-dep-test-child@1.0.0", + "npm:@denotest/peer-dep-test-child@2": "npm:/@denotest/peer-dep-test-child@2.0.0" + }, + "npmPackages": { + "@denotest/peer-dep-test-child@1.0.0_@denotest+peer-dep-test-peer@1.0.0": { + "name": "@denotest/peer-dep-test-child", + "version": "1.0.0", + "dependencies": [ + "@denotest/peer-dep-test-grandchild@1.0.0_@denotest+peer-dep-test-peer@1.0.0", + "@denotest/peer-dep-test-peer@1.0.0" + ] + }, + "@denotest/peer-dep-test-child@2.0.0_@denotest+peer-dep-test-peer@2.0.0": { + "name": "@denotest/peer-dep-test-child", + "version": "2.0.0", + "dependencies": [ + "@denotest/peer-dep-test-grandchild@1.0.0_@denotest+peer-dep-test-peer@2.0.0", + "@denotest/peer-dep-test-peer@2.0.0" + ] + }, + "@denotest/peer-dep-test-grandchild@1.0.0_@denotest+peer-dep-test-peer@1.0.0": { + "name": "@denotest/peer-dep-test-grandchild", + "version": "1.0.0", + "dependencies": [ + "@denotest/peer-dep-test-peer@1.0.0" + ] + }, + "@denotest/peer-dep-test-grandchild@1.0.0_@denotest+peer-dep-test-peer@2.0.0": { + "name": "@denotest/peer-dep-test-grandchild", + "version": "1.0.0", + "dependencies": [ + "@denotest/peer-dep-test-peer@2.0.0" + ] + }, + "@denotest/peer-dep-test-peer@1.0.0": { + "name": "@denotest/peer-dep-test-peer", + "version": "1.0.0", + "dependencies": [] + }, + "@denotest/peer-dep-test-peer@2.0.0": { + "name": "@denotest/peer-dep-test-peer", + "version": "2.0.0", + "dependencies": [] + } + } +} diff --git a/tests/testdata/npm/peer_deps_with_copied_folders/main_node_modules.out b/tests/testdata/npm/peer_deps_with_copied_folders/main_node_modules.out new file mode 100644 index 000000000..02b5cbafd --- /dev/null +++ b/tests/testdata/npm/peer_deps_with_copied_folders/main_node_modules.out @@ -0,0 +1,9 @@ +[UNORDERED_START] +Initialize @denotest/peer-dep-test-child@1.0.0 +Initialize @denotest/peer-dep-test-child@2.0.0 +Initialize @denotest/peer-dep-test-grandchild@1.0.0 +Initialize @denotest/peer-dep-test-peer@1.0.0 +Initialize @denotest/peer-dep-test-peer@2.0.0 +[UNORDERED_END] +1 +2 diff --git a/tests/testdata/npm/peer_deps_with_copied_folders/main_node_modules_reload.out b/tests/testdata/npm/peer_deps_with_copied_folders/main_node_modules_reload.out new file mode 100644 index 000000000..ed73c6cc2 --- /dev/null +++ b/tests/testdata/npm/peer_deps_with_copied_folders/main_node_modules_reload.out @@ -0,0 +1,19 @@ +[UNORDERED_START] +Download http://localhost:4545/npm/registry/@denotest/peer-dep-test-child +Download http://localhost:4545/npm/registry/@denotest/peer-dep-test-grandchild +Download http://localhost:4545/npm/registry/@denotest/peer-dep-test-peer +[UNORDERED_END] +[UNORDERED_START] +Download http://localhost:4545/npm/registry/@denotest/peer-dep-test-child/1.0.0.tgz +Initialize @denotest/peer-dep-test-child@1.0.0 +Download http://localhost:4545/npm/registry/@denotest/peer-dep-test-child/2.0.0.tgz +Initialize @denotest/peer-dep-test-child@2.0.0 +Download http://localhost:4545/npm/registry/@denotest/peer-dep-test-grandchild/1.0.0.tgz +Initialize @denotest/peer-dep-test-grandchild@1.0.0 +Download http://localhost:4545/npm/registry/@denotest/peer-dep-test-peer/1.0.0.tgz +Initialize @denotest/peer-dep-test-peer@1.0.0 +Download http://localhost:4545/npm/registry/@denotest/peer-dep-test-peer/2.0.0.tgz +Initialize @denotest/peer-dep-test-peer@2.0.0 +[UNORDERED_END] +1 +2 diff --git a/tests/testdata/npm/permissions_outside_package/foo/config.js b/tests/testdata/npm/permissions_outside_package/foo/config.js new file mode 100644 index 000000000..e667790d2 --- /dev/null +++ b/tests/testdata/npm/permissions_outside_package/foo/config.js @@ -0,0 +1,4 @@ +module.exports = { + "name": "foobar", + "version": "0.0.1", +}; diff --git a/tests/testdata/npm/permissions_outside_package/foo/package.json b/tests/testdata/npm/permissions_outside_package/foo/package.json new file mode 100644 index 000000000..cc049e6ce --- /dev/null +++ b/tests/testdata/npm/permissions_outside_package/foo/package.json @@ -0,0 +1,4 @@ +{ + "name": "foobar", + "version": "0.0.1" +} diff --git a/tests/testdata/npm/permissions_outside_package/main.out b/tests/testdata/npm/permissions_outside_package/main.out new file mode 100644 index 000000000..4edf66ae9 --- /dev/null +++ b/tests/testdata/npm/permissions_outside_package/main.out @@ -0,0 +1,3 @@ +Download http://localhost:4545/npm/registry/@denotest/permissions-outside-package +Download http://localhost:4545/npm/registry/@denotest/permissions-outside-package/1.0.0.tgz +{ name: "foobar", version: "0.0.1" } diff --git a/tests/testdata/npm/permissions_outside_package/main.ts b/tests/testdata/npm/permissions_outside_package/main.ts new file mode 100644 index 000000000..b0b82b626 --- /dev/null +++ b/tests/testdata/npm/permissions_outside_package/main.ts @@ -0,0 +1,5 @@ +import { loadConfigFile } from "npm:@denotest/permissions-outside-package"; + +const fileName = `${Deno.cwd()}/npm/permissions_outside_package/foo/config.js`; +const config = loadConfigFile(fileName); +console.log(config); diff --git a/tests/testdata/npm/registry/@babel/parser/parser-7.19.0.tgz b/tests/testdata/npm/registry/@babel/parser/parser-7.19.0.tgz new file mode 100644 index 000000000..37a6a69e1 Binary files /dev/null and b/tests/testdata/npm/registry/@babel/parser/parser-7.19.0.tgz differ diff --git a/tests/testdata/npm/registry/@babel/parser/registry.json b/tests/testdata/npm/registry/@babel/parser/registry.json new file mode 100644 index 000000000..804d6af3c --- /dev/null +++ b/tests/testdata/npm/registry/@babel/parser/registry.json @@ -0,0 +1 @@ +{"_id":"@babel/parser","_rev":"159-f1c1f8af37b518a2f385d23fe5247b93","name":"@babel/parser","dist-tags":{"latest":"7.19.0"},"versions":{"7.0.0-beta.48":{"name":"@babel/parser","version":"7.0.0-beta.48","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","files":["bin","lib"],"engines":{"node":">=6.0.0"},"devDependencies":{"@babel/helper-fixtures":"7.0.0-beta.48","charcodes":"0.1.0","unicode-10.0.0":"^0.7.4"},"bin":{"parser":"./bin/babel-parser.js"},"publishConfig":{"tag":"next"},"contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"_id":"@babel/parser@7.0.0-beta.48","_npmVersion":"5.6.0","_nodeVersion":"8.10.0","_npmUser":{"name":"hzoo","email":"hi@henryzoo.com"},"dist":{"integrity":"sha512-X3pKxvy7vL79zc/6XS6cCObyuRMnsRGRu7d3zVSPZGCdxkK0/wTeFRwseRjcvhReV/6LW2D8H8qHVFFL0c+5+w==","shasum":"f93895cbacee703c0ec98e5af3901c77edd9f1d7","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.0.0-beta.48.tgz","fileCount":6,"unpackedSize":380503,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbBxCGCRA9TVsSAnZWagAALkIQAI8MHP43v0t5yW+5eb8a\nFvCKyfUV5pYIAgLwyT6QlxWhW37Yy2x1jqzQPVFDz3TEvXHSetOroranW1v6\nH3RrGgFfV6ouyrKnYgk8JpTXHWlHKXWB0m0BqkOrMQwDdQVVVeIxdpQr1yrb\noyt5AjRZ272dKN0Q4iQTeLqC6uxUXYlarbBRUgWXx5BuLh//rVjIJGQ5Fj2m\nZcFFGRjbyw9Hdb0/wo7x0lV6VEi4Oh2wRNZuskIFBRNAiHdrCLf1IZEDsQRE\nGRXuKXc6Xj8LeHvoS2V5Vvs7dbuUq5lq5oiRiTEkPt032MSftU8tsl4UysVn\n1krvHCQYqNCg5WgKJlqXZCae+AxUWj9UacC98aq4vAeZl3DVzoJ5n5ENcHcI\na9Wrs0qumfODoxaDOSs+DNXAYnSc91zoguH187OOCLfas2Gw1MyRIXnJwvnH\nVnwnQyFBuRDDigxBGrRVVFkY6cf+vzoSaVIs5VL8wI85FDtKK/JmTtGwWLtk\nE1xG2tQVl622gWNZqPvoKbS5U1glbq9oPq7ECkPwWA9DSzdBidXfdezyMxJe\n1weMKBjz4+cOvzDS5ybdDPjQE1HlfQ3ffWz8nMm1agoLMXBz5e9pqYo098sL\n+FbijDCbi2Db3fD3UT1DBFMp3+GHuhe4/Aiow2TgL6l9rPlijvXVtAZdnRPV\ng+id\r\n=kdOk\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDAA6v59EOxXdvlxd1qBARkqQnKBlFXKh6jsUWh3QjH5AiAU2vwRBMq7QoDx0p8aFo8KwEKPV1ZVfucF9oSPqrPbnw=="}]},"maintainers":[{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"xtuc","email":"contact@xtuc.fr"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.0.0-beta.48_1527189637129_0.00583250000069091"},"_hasShrinkwrap":false},"7.0.0-beta.49":{"name":"@babel/parser","version":"7.0.0-beta.49","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","files":["bin","lib"],"engines":{"node":">=6.0.0"},"devDependencies":{"@babel/helper-fixtures":"7.0.0-beta.49","charcodes":"0.1.0","unicode-10.0.0":"^0.7.4"},"bin":{"parser":"./bin/babel-parser.js"},"publishConfig":{"tag":"next"},"contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"readme":"

\n \"@babel/parser\"\n

\n\n

\n The Babel parser (previously Babylon) is a JavaScript parser used in Babel.\n

\n\n - The latest ECMAScript version enabled by default (ES2017).\n - Comment attachment.\n - Support for JSX, Flow, Typescript.\n - Support for experimental language proposals (accepting PRs for anything at least [stage-0](https://github.com/tc39/proposals/blob/master/stage-0-proposals.md)).\n\n## Credits\n\nHeavily based on [acorn](https://github.com/marijnh/acorn) and [acorn-jsx](https://github.com/RReverser/acorn-jsx),\nthanks to the awesome work of [@RReverser](https://github.com/RReverser) and [@marijnh](https://github.com/marijnh).\n\n## API\n\n### `babelParser.parse(code, [options])`\n\n### `babelParser.parseExpression(code, [options])`\n\n`parse()` parses the provided `code` as an entire ECMAScript program, while\n`parseExpression()` tries to parse a single Expression with performance in\nmind. When in doubt, use `.parse()`.\n\n### Options\n\n- **allowImportExportEverywhere**: By default, `import` and `export`\n declarations can only appear at a program's top level. Setting this\n option to `true` allows them anywhere where a statement is allowed.\n\n- **allowAwaitOutsideFunction**: By default, `await` use is not allowed\n outside of an async function. Set this to `true` to accept such\n code.\n\n- **allowReturnOutsideFunction**: By default, a return statement at\n the top level raises an error. Set this to `true` to accept such\n code.\n\n- **allowSuperOutsideMethod**: TODO\n\n- **sourceType**: Indicate the mode the code should be parsed in. Can be\n one of `\"script\"`, `\"module\"`, or `\"unambiguous\"`. Defaults to `\"script\"`. `\"unambiguous\"` will make @babel/parser attempt to _guess_, based on the presence of ES6 `import` or `export` statements. Files with ES6 `import`s and `export`s are considered `\"module\"` and are otherwise `\"script\"`.\n\n- **sourceFilename**: Correlate output AST nodes with their source filename. Useful when generating code and source maps from the ASTs of multiple input files.\n\n- **startLine**: By default, the first line of code parsed is treated as line 1. You can provide a line number to alternatively start with. Useful for integration with other source tools.\n\n- **plugins**: Array containing the plugins that you want to enable.\n\n- **strictMode**: TODO\n\n- **ranges**: Adds a `ranges` property to each node: `[node.start, node.end]`\n\n- **tokens**: Adds all parsed tokens to a `tokens` property on the `File` node\n\n### Output\n\nThe Babel parser generates AST according to [Babel AST format][].\nIt is based on [ESTree spec][] with the following deviations:\n\n> There is now an `estree` plugin which reverts these deviations\n\n- [Literal][] token is replaced with [StringLiteral][], [NumericLiteral][], [BooleanLiteral][], [NullLiteral][], [RegExpLiteral][]\n- [Property][] token is replaced with [ObjectProperty][] and [ObjectMethod][]\n- [MethodDefinition][] is replaced with [ClassMethod][]\n- [Program][] and [BlockStatement][] contain additional `directives` field with [Directive][] and [DirectiveLiteral][]\n- [ClassMethod][], [ObjectProperty][], and [ObjectMethod][] value property's properties in [FunctionExpression][] is coerced/brought into the main method node.\n\nAST for JSX code is based on [Facebook JSX AST][].\n\n[Babel AST format]: https://github.com/babel/babel/tree/master/packages/babel-parser/ast/spec.md\n[ESTree spec]: https://github.com/estree/estree\n\n[Literal]: https://github.com/estree/estree/blob/master/es5.md#literal\n[Property]: https://github.com/estree/estree/blob/master/es5.md#property\n[MethodDefinition]: https://github.com/estree/estree/blob/master/es2015.md#methoddefinition\n\n[StringLiteral]: https://github.com/babel/babel/tree/master/packages/babel-parser/ast/spec.md#stringliteral\n[NumericLiteral]: https://github.com/babel/babel/tree/master/packages/babel-parser/ast/spec.md#numericliteral\n[BooleanLiteral]: https://github.com/babel/babel/tree/master/packages/babel-parser/ast/spec.md#booleanliteral\n[NullLiteral]: https://github.com/babel/babel/tree/master/packages/babel-parser/ast/spec.md#nullliteral\n[RegExpLiteral]: https://github.com/babel/babel/tree/master/packages/babel-parser/ast/spec.md#regexpliteral\n[ObjectProperty]: https://github.com/babel/babel/tree/master/packages/babel-parser/ast/spec.md#objectproperty\n[ObjectMethod]: https://github.com/babel/babel/tree/master/packages/babel-parser/ast/spec.md#objectmethod\n[ClassMethod]: https://github.com/babel/babel/tree/master/packages/babel-parser/ast/spec.md#classmethod\n[Program]: https://github.com/babel/babel/tree/master/packages/babel-parser/ast/spec.md#programs\n[BlockStatement]: https://github.com/babel/babel/tree/master/packages/babel-parser/ast/spec.md#blockstatement\n[Directive]: https://github.com/babel/babel/tree/master/packages/babel-parser/ast/spec.md#directive\n[DirectiveLiteral]: https://github.com/babel/babel/tree/master/packages/babel-parser/ast/spec.md#directiveliteral\n[FunctionExpression]: https://github.com/babel/babel/tree/master/packages/babel-parser/ast/spec.md#functionexpression\n\n[Facebook JSX AST]: https://github.com/facebook/jsx/blob/master/AST.md\n\n### Semver\n\nThe Babel Parser follows semver in most situations. The only thing to note is that some spec-compliancy bug fixes may be released under patch versions.\n\nFor example: We push a fix to early error on something like [#107](https://github.com/babel/babylon/pull/107) - multiple default exports per file. That would be considered a bug fix even though it would cause a build to fail.\n\n### Example\n\n```javascript\nrequire(\"@babel/parser\").parse(\"code\", {\n // parse in strict mode and allow module declarations\n sourceType: \"module\",\n\n plugins: [\n // enable jsx and flow syntax\n \"jsx\",\n \"flow\"\n ]\n});\n```\n\n### Plugins\n\n| Name | Code Example |\n|------|--------------|\n| `estree` ([repo](https://github.com/estree/estree)) | n/a |\n| `jsx` ([repo](https://facebook.github.io/jsx/)) | `{s}` |\n| `flow` ([repo](https://github.com/facebook/flow)) | `var a: string = \"\";` |\n| `flowComments` ([docs](https://flow.org/en/docs/types/comments/)) | `/*:: type Foo = {...}; */` |\n| `typescript` ([repo](https://github.com/Microsoft/TypeScript)) | `var a: string = \"\";` |\n| `doExpressions` | `var a = do { if (true) { 'hi'; } };` |\n| `objectRestSpread` ([proposal](https://github.com/tc39/proposal-object-rest-spread)) | `var a = { b, ...c };` |\n| `decorators` (Stage 2 [proposal](https://github.com/tc39/proposal-decorators)) and `decorators-legacy` (Stage 1) | `@a class A {}` |\n| `classProperties` ([proposal](https://github.com/tc39/proposal-class-public-fields)) | `class A { b = 1; }` |\n| `classPrivateProperties` ([proposal](https://github.com/tc39/proposal-private-fields)) | `class A { #b = 1; }` |\n| `classPrivateMethods` ([proposal](https://github.com/tc39/proposal-private-methods)) | `class A { #c() {} }` |\n| `exportDefaultFrom` ([proposal](https://github.com/leebyron/ecmascript-export-default-from)) | `export v from \"mod\"` |\n| `exportNamespaceFrom` ([proposal](https://github.com/leebyron/ecmascript-export-ns-from)) | `export * as ns from \"mod\"` |\n| `asyncGenerators` ([proposal](https://github.com/tc39/proposal-async-iteration)) | `async function*() {}`, `for await (let a of b) {}` |\n| `functionBind` ([proposal](https://github.com/zenparsing/es-function-bind)) | `a::b`, `::console.log` |\n| `functionSent` | `function.sent` |\n| `dynamicImport` ([proposal](https://github.com/tc39/proposal-dynamic-import)) | `import('./guy').then(a)` |\n| `numericSeparator` ([proposal](https://github.com/samuelgoto/proposal-numeric-separator)) | `1_000_000` |\n| `optionalChaining` ([proposal](https://github.com/tc39/proposal-optional-chaining)) | `a?.b` |\n| `importMeta` ([proposal](https://github.com/tc39/proposal-import-meta)) | `import.meta.url` |\n| `bigInt` ([proposal](https://github.com/tc39/proposal-bigint)) | `100n` |\n| `optionalCatchBinding` ([proposal](https://github.com/babel/proposals/issues/7)) | `try {throw 0;} catch{do();}` |\n| `throwExpressions` ([proposal](https://github.com/babel/proposals/issues/23)) | `() => throw new Error(\"\")` |\n| `pipelineOperator` ([proposal](https://github.com/babel/proposals/issues/29)) | `a \\|> b` |\n| `nullishCoalescingOperator` ([proposal](https://github.com/babel/proposals/issues/14)) | `a ?? b` |\n\n\n#### Plugins options\n\n> NOTE: When a plugin is specified multiple times, only the first options are considered.\n\n- `decorators`:\n - `decoratorsBeforeExport` (`boolean`)\n ```js\n // decoratorsBeforeExport: true\n @dec\n export class C {}\n\n // decoratorsBeforeExport: false\n export @dec class C {}\n ```\n- `flow`:\n - `all` (`boolean`)\n \n\n### FAQ\n\n#### Will the Babel parser support a plugin system?\n\nPrevious issues: [#1351](https://github.com/babel/babel/issues/1351), [#6694](https://github.com/babel/babel/issues/6694).\n\nWe currently aren't willing to commit to supporting the API for plugins or the resulting ecosystem (there is already enough work maintaining Babel's own plugin system). It's not clear how to make that API effective, and it would limit our ability to refactor and optimize the codebase.\n\nOur current recommendation for those that want to create their own custom syntax is for users to fork the parser.\n\nTo consume your custom parser, you can add to your `.babelrc` via its npm package name or require it if using JavaScript,\n\n```json\n{\n \"parserOpts\": {\n \"parser\": \"custom-fork-of-babel-parser-on-npm-here\"\n }\n}\n```\n","readmeFilename":"README.md","_id":"@babel/parser@7.0.0-beta.49","scripts":{},"_shasum":"944d0c5ba2812bb159edbd226743afd265179bdc","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.12.3","_npmUser":{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},"dist":{"shasum":"944d0c5ba2812bb159edbd226743afd265179bdc","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.0.0-beta.49.tgz","fileCount":6,"unpackedSize":380539,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbCDMMCRA9TVsSAnZWagAAHWoP/2ySWeX6rqdKww6gCeJG\nojr30jIga9mFPRGncr2r7rdoZTuuk1qZDmBq7p8BurcMusosKwCrlBFuxaVW\nQNn0lX/YsDXr7txzAIWBrZDGc9ZVUyPNaiNU8ycgSeo+++2xBhn4Wb9aOtsm\npy8lcvT7TY6znjVE/oFinjBFNA9Q218mzTtAuxaBbL3HqcMw2O75EGX9nHbf\ndLHxqixFjGkpf1USXU7hxs8MBZ9JY7vD/AcneJnhRc/TbXAhZ7Y4JUXung6+\nC0lz0ph6qpPJvzRASw1OrQsmgJ39Ioa1QfRT7IVtEPBb5rsWdOO5OHpCmmc+\nR2RqkULbunAJx80To0LSCLbDR6Wy4qoFXwdaFgkukNSPQ4l1G0a9RFkdf6tm\nmxl8X3S3J/9/pWQUTGa7A9fKQf1aoTtowZA7scFYfWgWInysn8caTSZ6nCIt\nfV1XP0ytKq6gSyhiPRwC0odisASmowPTwGy/IJdelT/YHjKVYwBJLDeZjymV\nPM+6OhLVzO1LyoxZG0YHEzesjZqxGZfVQYht6TTS9gvT19u938SiSyHhboON\ndrGz8cvcniV1otT379FUwjG46zauuTcv8TgGDGOnoNax8KfVb5qd55pHHsd+\nq4snfd89jwlCqTeEss1xVGxTw+c6gZvHmtjs3dWDzcUEJ5vJaPnIT9vCK/OK\nj4cP\r\n=VaoJ\r\n-----END PGP SIGNATURE-----\r\n","integrity":"sha512-rFcOXcsUXcfmQJY8mN/1zfgRYq4A02e9GiJRT3ai3TM81F2iPcnUV4wG/DUrZITL69RVHR2FM9iYM5AK8E7fcw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIH4Vj+evhB8vvQIAZmVrLVGkQEXmr/0qrR5FwOJ+jkB6AiAiMzCD5uKyk6HkzOdJH94NhpIm6wCekkBlOCA2oI7zEg=="}]},"maintainers":[{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"xtuc","email":"contact@xtuc.fr"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.0.0-beta.49_1527264012017_0.5407240697297271"},"_hasShrinkwrap":false},"7.0.0-beta.50":{"name":"@babel/parser","version":"7.0.0-beta.50","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","files":["bin","lib"],"engines":{"node":">=6.0.0"},"devDependencies":{"@babel/helper-fixtures":"7.0.0-beta.50","charcodes":"0.1.0","unicode-11.0.0":"^0.7.7"},"bin":{"parser":"./bin/babel-parser.js"},"publishConfig":{"tag":"next"},"contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"licenseText":"Copyright (C) 2012-2014 by various contributors (see AUTHORS)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@babel/parser@7.0.0-beta.50","dist":{"shasum":"9ffc59e4ca51df0a6cc8b5d1f22d7e534bb3fa5d","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.0.0-beta.50.tgz","fileCount":9,"unpackedSize":372331,"integrity":"sha512-H7zivdk3e61mMaDtmK4XMknROoHlAirhD5rG2gnyMo0VbunMzTWKSD4aGLY6so2FPsi26VtT8tylwjlRz3dNcw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIH5tJRAHHAxkMdE97o4a59bzCBjJXBEPzB0ZnuL3gO39AiEAjqAhPqTgXqK0IKNjODRG2MJAa5BEpKUje0JbN5S5pQg="}]},"maintainers":[{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"xtuc","email":"contact@xtuc.fr"}],"_npmUser":{"name":"hzoo","email":"hi@henryzoo.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.0.0-beta.50_1528832802669_0.9988240036319185"},"_hasShrinkwrap":false},"7.0.0-beta.51":{"name":"@babel/parser","version":"7.0.0-beta.51","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","files":["bin","lib"],"engines":{"node":">=6.0.0"},"devDependencies":{"@babel/helper-fixtures":"7.0.0-beta.51","charcodes":"0.1.0","unicode-11.0.0":"^0.7.7"},"bin":{"parser":"./bin/babel-parser.js"},"publishConfig":{"tag":"next"},"contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"licenseText":"Copyright (C) 2012-2014 by various contributors (see AUTHORS)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@babel/parser@7.0.0-beta.51","dist":{"shasum":"27cec2df409df60af58270ed8f6aa55409ea86f6","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.0.0-beta.51.tgz","fileCount":9,"unpackedSize":372331,"integrity":"sha512-y62bVWBe50ulqJxTiF6siQRmO5sXCmEZDAvUZiu867U10UUwQFI7QjiI/MgfWXkX966ap9rMims1rfEk05r0AA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC1vNQM3V8u+m+XN+qdNDepdYicVTcp8MLIJy4Pe/hpGgIhAPuwY9OaV/OeRjxKueiLL+2GJlBkT/MHOV8ms/Hs3+lz"}]},"maintainers":[{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"xtuc","email":"contact@xtuc.fr"}],"_npmUser":{"name":"hzoo","email":"hi@henryzoo.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.0.0-beta.51_1528838349835_0.3115893685536284"},"_hasShrinkwrap":false},"7.0.0-beta.52":{"name":"@babel/parser","version":"7.0.0-beta.52","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","files":["bin","lib"],"engines":{"node":">=6.0.0"},"devDependencies":{"@babel/helper-fixtures":"7.0.0-beta.52","charcodes":"0.1.0","unicode-11.0.0":"^0.7.7"},"bin":{"parser":"./bin/babel-parser.js"},"publishConfig":{"tag":"next"},"contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"licenseText":"Copyright (C) 2012-2014 by various contributors (see AUTHORS)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@babel/parser@7.0.0-beta.52","dist":{"shasum":"4e935b62cd9bf872bd37bcf1f63d82fe7b0237a2","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.0.0-beta.52.tgz","fileCount":9,"unpackedSize":372329,"integrity":"sha512-1yK/5GCWjDaZkcRaeym8TsklEf5UiWGFT5U7v7srAmg8H/covDVCYLkUNIKkMxFx/ufEaSQ15+dnuA7BkQO+XA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICpzXBU+xTDYlbA4CZ08XFv2ew6y6e1fGIf+G/b8vac0AiAdF4uaFM9zVyW01sS0L95RTkm0JOnt0wBWfFmLu6l4FQ=="}]},"maintainers":[{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"xtuc","email":"contact@xtuc.fr"}],"_npmUser":{"name":"hzoo","email":"hi@henryzoo.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.0.0-beta.52_1530838747547_0.3496276227335484"},"_hasShrinkwrap":false},"7.0.0-beta.53":{"name":"@babel/parser","version":"7.0.0-beta.53","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","files":["bin","lib"],"engines":{"node":">=6.0.0"},"devDependencies":{"@babel/helper-fixtures":"7.0.0-beta.53","charcodes":"0.1.0","unicode-11.0.0":"^0.7.7"},"bin":{"parser":"./bin/babel-parser.js"},"publishConfig":{"tag":"next"},"contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"licenseText":"Copyright (C) 2012-2014 by various contributors (see AUTHORS)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@babel/parser@7.0.0-beta.53","dist":{"shasum":"1f45eb617bf9463d482b2c04d349d9e4edbf4892","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.0.0-beta.53.tgz","fileCount":9,"unpackedSize":373881,"integrity":"sha512-SYoyLjcE+D28Ly2kkPXP6eIVy4YwViRSffri5WHi8PRxy8ngnx6mTXFzGAsSSPzUN3DK+sf8qBsdDGeQz1SJEw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAxzuKibJYdHZIEAWmZHeEClwpPUi7gFYkTvMXdkGwg4AiEAma9A4kAEwpxTxCIafilkzD2i2TgKPUmF708xL58EZ14="}]},"maintainers":[{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"xtuc","email":"contact@xtuc.fr"}],"_npmUser":{"name":"hzoo","email":"hi@henryzoo.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.0.0-beta.53_1531316396567_0.45536197193121386"},"_hasShrinkwrap":false},"7.0.0-beta.54":{"name":"@babel/parser","version":"7.0.0-beta.54","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","files":["bin","lib"],"engines":{"node":">=6.0.0"},"devDependencies":{"@babel/helper-fixtures":"7.0.0-beta.54","charcodes":"0.1.0","unicode-11.0.0":"^0.7.7"},"bin":{"parser":"./bin/babel-parser.js"},"publishConfig":{"tag":"next"},"contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"licenseText":"Copyright (C) 2012-2014 by various contributors (see AUTHORS)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@babel/parser@7.0.0-beta.54","dist":{"shasum":"c01aa63b57c9c8dce8744796c81d9df121f20db4","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.0.0-beta.54.tgz","fileCount":9,"unpackedSize":373881,"integrity":"sha512-2jT3u3JB83zwYO5fk/QD2TwMRg6B5BmgF6bFM/1uVFxPYdrJzLrNjip1AtqghSNWYJFDR5fNwKYYtupHCkeCzA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDr59P1G1TJOOyADvgn6FJrL0REiwcN4rhTEJhNWWvOsAIgePlEcpf1xx4jC5dcSnTT2XLJikCve4VCbPnwEqV4kmk="}]},"maintainers":[{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"xtuc","email":"contact@xtuc.fr"}],"_npmUser":{"name":"hzoo","email":"hi@henryzoo.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.0.0-beta.54_1531763987398_0.9262821370822878"},"_hasShrinkwrap":false},"7.0.0-beta.55":{"name":"@babel/parser","version":"7.0.0-beta.55","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","files":["bin","lib"],"engines":{"node":">=6.0.0"},"devDependencies":{"@babel/helper-fixtures":"7.0.0-beta.55","charcodes":"0.1.0","unicode-11.0.0":"^0.7.7"},"bin":{"parser":"./bin/babel-parser.js"},"publishConfig":{"tag":"next"},"contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"licenseText":"Copyright (C) 2012-2014 by various contributors (see AUTHORS)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@babel/parser@7.0.0-beta.55","dist":{"shasum":"0a527efc148c6c8cd85d5ffddacad817a2daeeb2","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.0.0-beta.55.tgz","fileCount":9,"unpackedSize":374307,"integrity":"sha512-rMSWwnceZ/MGbP42VKcThkY6YVWq9AoX/Um9Jxfl4ZOnsMnZeOnL03jgNZ4YhB7yOkQNpF9A42UiYz81NDPvmg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDSLZMiEC5BwdJonoPGscPNXYj1BTuxJbI2kCCEixdQPwIgCRFFCvc11VYkCEsorv5XQD+kn+Mjj1uiBNkdzbdW9IA="}]},"maintainers":[{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"xtuc","email":"contact@xtuc.fr"}],"_npmUser":{"name":"hzoo","email":"hi@henryzoo.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.0.0-beta.55_1532815605751_0.17174101313315915"},"_hasShrinkwrap":false},"7.0.0-beta.56":{"name":"@babel/parser","version":"7.0.0-beta.56","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","files":["bin","lib"],"engines":{"node":">=6.0.0"},"devDependencies":{"@babel/helper-fixtures":"7.0.0-beta.56","charcodes":"0.1.0","unicode-11.0.0":"^0.7.7"},"bin":{"parser":"./bin/babel-parser.js"},"publishConfig":{"tag":"next"},"contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"licenseText":"Copyright (C) 2012-2014 by various contributors (see AUTHORS)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@babel/parser@7.0.0-beta.56","dist":{"shasum":"8638aa02e0130cd10b2ba4128e2b804112073ed3","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.0.0-beta.56.tgz","integrity":"sha512-JM0ughhbo+sPXw2Z+SUyowfYrAOhjanzjMshcLswBdXVelJCOeEKe/FqMqPWGVPQr7wByongXIn+MKdCpY7DBw==","fileCount":9,"unpackedSize":374721,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbZPtACRA9TVsSAnZWagAAum8P/3eerRrcWmTn4sEr6c7t\nbRt5N3fnCTEarYWICQq5U8ZQmJrjgAJeK9rYVeFWE8o2oQ96gLSLKUz/luOJ\nNOPRkUjUrfyt2GX+FQAWi0dL+/0GMibNOf9cb/DEk2UTXHrNBJvY1G/Lx9zZ\n9nkmor1V91KIG2U+GN85WIGgpsG+vOEbsUn9+dVivAke3AsgwgaIexaOwb+l\neOUV2mYLhEvpZztud30dV/HSupOtD7xGNK7X2yYtnVdPl9J8bIMtnLzHHnKn\ncPZdZE4kaud7X0DU9O0okbnAxla91lVfYxbES4JlPUgiPTuGbY5Ab44OOANK\n09pOeyHQAf5uOGkywXClEo3NtIVz+mIY2+WGPBPvLeTviABHgtBpph8vSmID\nqBOU7ShTckAj5RZ1JjbF7TBTCunpdYZZsUjuErc2f/I+rlg2rHxQUHnF6jLO\nhIwLCxDZCStkWOWnWoeXYR3Kb1ebj1Z8KpM8FceEM5XcXH7BYnCCGn2D2NIw\n8vWcolI4ZGok4A2KToKKrZafAHqxvIrDPzjriBjWPRPcroh2XPfCUb8iWnjs\ndtz08yOtw/dOk6RfsfSlo+hKT/SIt9MdpINqkCDx2IxBvsgOkJqFWZYaBQg3\nLVhzlL0UAKZ/HMRG+bFcj8u07vcmDrmlW3NWdqvOZV5pMUuiNupCZ0XLIX6F\nJ3w8\r\n=sYe7\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCYPrzPXHTAtnF2erp3Rbv3hRXgTh08dkQbPUKNrriILAIgLO5KEJYz9alRrQNa/8s2pwAUFx1T5Yr1Ks+BNQQTDJ4="}]},"maintainers":[{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"xtuc","email":"contact@xtuc.fr"}],"_npmUser":{"name":"hzoo","email":"hi@henryzoo.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.0.0-beta.56_1533344575668_0.9890174787264132"},"_hasShrinkwrap":false},"7.0.0-rc.0":{"name":"@babel/parser","version":"7.0.0-rc.0","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","files":["bin","lib"],"engines":{"node":">=6.0.0"},"devDependencies":{"@babel/helper-fixtures":"7.0.0-rc.0","charcodes":"0.1.0","unicode-11.0.0":"^0.7.7"},"bin":{"parser":"./bin/babel-parser.js"},"publishConfig":{"tag":"next"},"contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"licenseText":"Copyright (C) 2012-2014 by various contributors (see AUTHORS)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@babel/parser@7.0.0-rc.0","dist":{"shasum":"6ad941b6425e7f5feee909e3bc3e6e8712397541","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.0.0-rc.0.tgz","integrity":"sha512-G/NZNnuzemO7mzvpKdTonhsisgKTcXw5sV2lBumD/FlWLxAvmmITfHym0upWMN9xAMBRlq3WAdWXYju42NOSIg==","fileCount":9,"unpackedSize":374715,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbbGQdCRA9TVsSAnZWagAAKHUP/08wduLSFYGKkg5WX2le\nd8aBiiwfiC+hur2QL5K7moIk5xlbd/H1YDkiUnctpn0bV3MEjrAX92/ef2Pu\nKPNBskK5t04N+muAj0Qoa/DDLBeuH7GLuYzLdbKTiWB8d7fo+skcM6NXpRQI\nxRKlPOJ/A6garSmrFgqAdJwlqr14YSk5XPNc9/C+uYmDUxIS357gyhNZfvL7\nUSrFBn6PzgvNEwNq4IG+xLdqSPZdc+tUrakL427X+0zS+lATgI4t13o1zekD\nHxK7bEMAjcWmyewzC4wQkTWrE5WXc9WOAxhVPguuKicNyuQG8K4wxlSTq8/r\nl/DRKq64pYVFfzp9h1hIPfFtvattYSCBFn/TfbLZ+YQeAxSf819aFTH94kR5\nMNZ5pf8DaOao/rP3vzxGpmcmyg/KpVY9LG/J0JKhr1m+9T++DhPGVRcOExzc\n7yKnDWlSn8jJKcYlw9VUCJZo7gROAPUOROzlcOTx1WoHeli/y5dG9bfieYel\n5mT9Z1UN2SanGOBBGAYnUypHIvr5YT90DX9/tFcI6U7N8lQFHDoymLhEvFBg\nFbq3U2IlK8irls5sSCR9DpvPMgpdLDWKF52SynGTlZPBvv4hu94D8zHKu8hk\nUcnpbGYkT/PfNFn0cVXkNW3lMORCtM18oDkuZ3ovEFLprJlfkV6ja8IUwtMc\nxNNm\r\n=AeMq\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD9WS96V7qepNF9jkkFqj3fJ/pZKg5RU0XPDyibeyR3tAIhAINIWLUTJcQTV8raXrJ3NQ/kotFYVdSANFwiYuy7OBkS"}]},"maintainers":[{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"xtuc","email":"contact@xtuc.fr"}],"_npmUser":{"name":"hzoo","email":"hi@henryzoo.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.0.0-rc.0_1533830172687_0.43335646761234914"},"_hasShrinkwrap":false},"7.0.0-rc.1":{"name":"@babel/parser","version":"7.0.0-rc.1","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","files":["bin","lib"],"engines":{"node":">=6.0.0"},"devDependencies":{"@babel/helper-fixtures":"7.0.0-rc.1","charcodes":"0.1.0","unicode-11.0.0":"^0.7.7"},"bin":{"parser":"./bin/babel-parser.js"},"publishConfig":{"tag":"next"},"contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"licenseText":"Copyright (C) 2012-2014 by various contributors (see AUTHORS)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@babel/parser@7.0.0-rc.1","dist":{"shasum":"d009a9bba8175d7b971e30cd03535b278c44082d","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.0.0-rc.1.tgz","integrity":"sha512-rC+bIz2eZnJlacERmJO25UAbXVZttcSxh0Px0gRGinOTzug5tL7+L9urfIdSWlv1ZzP03+f2xkOFLOxZqSsVmQ==","fileCount":9,"unpackedSize":374715,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbbJ64CRA9TVsSAnZWagAAtCkP/38Rg+xEPHh5TgTkLZ1H\nHOHnWNazcTVQz5dKzn+gjLLCF9fQoWbygfra+4oeRXWIxKa7OUBjtoeFsp2b\nn9G7p8GiELdYOUYZC/Rm/wZSWrvlOxltBbS5rgtYZuXJA+YU/ujpXWATK/Zg\nKxME1ihN7sS9+z3hlb4jUfkN0Kb8k364b8hDOp/YAKaDKcB27dvufi8fVX+d\ni4+kGK7EvV+ccSPlBTIMQ+gpEsmW6zvIV2OrwR9aUPBPnVtFF+SSxeeYQ7J0\nAQWt8DH+ttaOVW7iKgjdOQm7p8aR5A0dJqIAi59N8Zgw73vlYq5AsbFQzUvC\nw5HOwi+xgDMaMYVClC5PuqoanZtHmvpm6s03monDxIobPQo560ULxdBngvWS\n8N5A78blW0gSX5CxmAumML0I/qFAKJIFqfZEqSTmsJjlf4jk3IZVE5iPmtGE\nYbZ/KI58j7GJt4//oO4Rg/FsT/Kn7SVEPStIy2lSgsWkfDyQiMnPeupxY9GM\n9EAaD1yuMX+eW72EXRg5JECzWVWcYX5hRwYpLge6rAFcxgUjvdeSQGqndu0u\nzZv2b3/zUhNzAf10W4/APJdGBk8ZxeM0vuiHqBnnIxQo4iOiIgFtOsGDZAlI\n4HP9ovf2UgPP71slAd+z7GCJh0hKl/exlIBD4yYXTx50KpJsm9ex4eX3DQ+1\nOz7m\r\n=8caI\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEGPyqVTUQFqbFxLghQyGGroBVQdRQ+VBv7QX/Dy0wTfAiBiZ2RkPJsZXngGI2TZMwPZ5FA++GyWIn0TussDuMXlHA=="}]},"maintainers":[{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"xtuc","email":"contact@xtuc.fr"}],"_npmUser":{"name":"hzoo","email":"hi@henryzoo.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.0.0-rc.1_1533845176004_0.7074827547463136"},"_hasShrinkwrap":false},"7.0.0-rc.2":{"name":"@babel/parser","version":"7.0.0-rc.2","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","files":["bin","lib"],"engines":{"node":">=6.0.0"},"devDependencies":{"@babel/helper-fixtures":"7.0.0-rc.2","charcodes":"0.1.0","unicode-11.0.0":"^0.7.7"},"bin":{"parser":"./bin/babel-parser.js"},"publishConfig":{"tag":"next"},"contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"licenseText":"Copyright (C) 2012-2014 by various contributors (see AUTHORS)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@babel/parser@7.0.0-rc.2","dist":{"shasum":"a98c01af5834e71d48a5108e3aeeee333cdf26c4","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.0.0-rc.2.tgz","integrity":"sha512-zDB1QPgQWYwuJty3Ymbx1hq7zbBEbZjTprHOhforvzyQFV86LNh6FS0InjnOUXM6p6QUyONz8KTt/v+MRMd0Hg==","fileCount":9,"unpackedSize":375454,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbfGZoCRA9TVsSAnZWagAAvfsP/iJ7wBW9beNsUSB6VUtU\nCRGzDdPoR0H0nKYwOjId+b0kXyaYhSu27HQ96se4YpKZ4P6U65imdohkUs2g\n6NWJUsvkKAanRBYM1lk6bx5FZS9Uz7uq8ekjAVdzKiFfjAABmo+xpoy0JM4W\ndiTxc/ydvAjGJzOvH1J3TlR7nBhO3eDVw5QQ/iAG6qMdpV3cZG8HiyKZ1EWB\na25PaTZtRZgQMUPHCJmIyOX6fg34UQgahy+dWFNVfuWjVXJ753avHdxQSELg\n3kp7s3K1mlYBfSeCS7dmSOuJgVO1eTLw7i1bwzbunGBc+Ssgrbrk/X5cHPEw\nb0too2qomo0/nf354Us1yFAfUrHNiqILuAPoer4iO1s547r2trBY5cyjNLUA\naZMtb8/DZIqJVmfcWLldIIskJ5hbnmswyTRu/3bLWC0WkzK+R2ZueZrcH0eW\nxf+qSI/dDESNCog4y7mh2NVfCyEh1KgNHvxyJ2NedWe5PTrQrQShC9JY8UQo\n1l71BTFDlf81qblEiwZ0RhRxrGgcB9Uk2K0QEfTuvh8gr96ZXpoKXPa2A+q/\nW4sCmABqwV/FBZDu27u+tSsD7OHdRRxeyTF8N7NxyNz6qqAXx/0d1b/6Adyy\nqA7pcjZayKHrWP7NQc4IAcm5VNLiKgVYQ3S0qTVcUOV4uPYM1+4sJjtJMFZl\nJ4rz\r\n=N3Px\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCnvfJY1viGmAnalMIe4eNPVnmgOc3hyikPXheFU/Q0zAIhAKPUV9buDxNE5KzfrTJVJW22tinRhE8F/wucdeXUaYxA"}]},"maintainers":[{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"xtuc","email":"contact@xtuc.fr"}],"_npmUser":{"name":"hzoo","email":"hi@henryzoo.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.0.0-rc.2_1534879336456_0.6255402074759919"},"_hasShrinkwrap":false},"7.0.0-rc.3":{"name":"@babel/parser","version":"7.0.0-rc.3","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","files":["bin","lib"],"engines":{"node":">=6.0.0"},"devDependencies":{"@babel/helper-fixtures":"7.0.0-rc.3","charcodes":"0.1.0","unicode-11.0.0":"^0.7.7"},"bin":{"parser":"./bin/babel-parser.js"},"publishConfig":{"tag":"next"},"contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"licenseText":"Copyright (C) 2012-2014 by various contributors (see AUTHORS)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@babel/parser@7.0.0-rc.3","dist":{"shasum":"859d7b60ef6b939aab5f6d4f4bffbb7bafdc418b","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.0.0-rc.3.tgz","integrity":"sha512-oNVEL3NpMaC8q1hQwWrmgj34dAT3KIAK5zhVN4V6YTzotJOSK0ul7SaRm42YDdP56aOkzvGAZylCVtvu6jREhg==","fileCount":9,"unpackedSize":375454,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbgEkUCRA9TVsSAnZWagAA6nwP/1m8EMWQPcWfv2qC6jgf\nl/5HxuEwwrznJcBHqYQaIrl/OeoW8VQsTZ24xpHzUU4/E0WhqxpWGE02ufNH\nZ6lFYaRSIA0vyyR7o3lJqDdHgq2N18EMkl4O8ej/CuviN2eRE8owLOKX1GrL\n2ullKv+ZrprQjHmGr3aGauuApYAS4VqoLUapvAtkuyfUsrzbidlZ7/XzzyWt\nEQEAq8PeZ60qcNnYrhlpeQWhkiAdXtW2zV+fbk9bZZKXSEQt+XML6AbtSu8c\nSwI2tLIYihN0Kxz89R+FgbqtCRO8CEOITUGgEpdff96D/8+Dz3bDXLAX1mht\nPm6gY2dKyrP6y/xQ+eXOxJYBF5Kh/Jk0sYT6R3WcnKwaEzt5/2pqj7YJbQKC\ntRT3mc+Kn/RkANDqUlsOg9HxCVA42TCH6+mCMw1w2VexrDAViY+EsAgiDmEX\n/8b+P7hJwhnZq/raUxDOMUDkWpSOL30pR5Yfwz7rVJO7DcQW3c2qOo2pbgdJ\npYXCYBDdbuF7rsiBHHQ0XSJ/fGU1WolSmqPN2/kOwq6Fk0NdgFuntEZEudhq\n7Mj8cD1PuTawgQEtjgmln77yYTq44fQkpte+oVuDwCtpCkcI8pZp29n3bRMo\nyT5cy4hs9rC8CO3CpbpeVuvMBcilQAlvkIufrYFgkEAXKUN+FGbBo6/jquWD\nd3Fw\r\n=tMuU\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDbh9ROKbuHUCDif9pKde/Ho4RHeAtzSkbq0797EaSYvwIhAMyqA30cjHphEVX0Q06qZPRe+V0i/cMV+5ieOVOt7NH3"}]},"maintainers":[{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"xtuc","email":"contact@xtuc.fr"}],"_npmUser":{"name":"hzoo","email":"hi@henryzoo.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.0.0-rc.3_1535133971784_0.6078029812665302"},"_hasShrinkwrap":false},"7.0.0-rc.4":{"name":"@babel/parser","version":"7.0.0-rc.4","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","files":["bin","lib"],"engines":{"node":">=6.0.0"},"devDependencies":{"@babel/helper-fixtures":"^7.0.0-rc.4","charcodes":"0.1.0","unicode-11.0.0":"^0.7.7"},"bin":{"parser":"./bin/babel-parser.js"},"publishConfig":{"tag":"next"},"contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"licenseText":"Copyright (C) 2012-2014 by various contributors (see AUTHORS)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@babel/parser@7.0.0-rc.4","dist":{"shasum":"c5c773df2554d76c9fc0a3711c18109fce3f54f5","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.0.0-rc.4.tgz","integrity":"sha512-X4BqD6IwlJleaAV2iDBe4pTOVhhJ/neQqHH8gFQXiAIeTSmwGMdXAUky2Hhdc/2Wpss0zW6CXtxQ5C6NBJmxxg==","fileCount":9,"unpackedSize":374970,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbhCnsCRA9TVsSAnZWagAAfikP/2Gwm09fYB8Fm6pAbXWP\nIq0s3FiSpzZi7OSJ/5xT4G4qpF3O2tuA67EHtC6cS1noIkRuwy6R6Png7rS0\nz4vvn2SQhMw4WBulOqDXmMZyH/NwRx2H6hzVG1yRSIYlpT7Xkvai/+7BBP/H\nACz4p5ntPcrydlVXx+Wz0JCngRYa7VlGf0me6/gIq2/xW4d/GSp8OT4Kgg7u\ni7S+6FZZudSH0b8hi7/Ly2+6iSQ3y/GKsio5ZWpfIHa4fH12HmV502lsQtol\ndlFqDJoe0d78/335wUPSRTakHkdPCepRsdSR74RdIOaNma2CFtk8XjeZhpwQ\nnhVakT7qM2j2lsoMi1D0crQ+YiwsK+8FaudzYFlUMhfiN0e6R+sr3IhOtkGO\ncoU2vVvuX0xHkyPJ8kmmD8+x8ewYbafQlQKqxLSSIv5GWt0SNLlF37fOM6EI\nsB/k1uYXS7+dAWriZT7kLTRWb0W9blrm+JEJAdyakMmebyycKi8j/qdRp9eo\nfAbT8mRviRTSGo0Mx331BsDOv9e9eYogy3H//xqaMjY8T5xT3aEoh8tGG3uN\nny+MueyJs1ALr4+YDBoLV1eQ/i19hvRJaxPn0Ggz7gsOcAVjJC6j5VGNmbVa\noFyF7/V8KmjhRj35LJpr3dDPff6n3CogKHQVUZhI96PoNmMFXfkEoROWzwOE\nzXLw\r\n=BVXE\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIECSKsAdXk4S17ZU/NdzVhMkUirlJECaP8OdlCanbnstAiEA8yco7V8eyp+83qzyRTCMrGHZZSH6LlRoAeJM55DnBXs="}]},"maintainers":[{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"xtuc","email":"contact@xtuc.fr"}],"_npmUser":{"name":"hzoo","email":"hi@henryzoo.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.0.0-rc.4_1535388140015_0.2949932735959726"},"_hasShrinkwrap":false},"7.0.0":{"name":"@babel/parser","version":"7.0.0","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","files":["bin","lib"],"engines":{"node":">=6.0.0"},"devDependencies":{"@babel/helper-fixtures":"^7.0.0","charcodes":"0.1.0","unicode-11.0.0":"^0.7.7"},"bin":{"parser":"./bin/babel-parser.js"},"publishConfig":{"tag":"next"},"contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"readmeFilename":"README.md","readme":"# @babel/parser\n\n> A JavaScript parser\n\nSee our website [@babel/parser](https://babeljs.io/docs/en/next/babel-parser.html) for more information or the [issues](https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A%20babylon%22+is%3Aopen) associated with this package.\n\n## Install\n\nUsing npm:\n\n```sh\nnpm install --save-dev @babel/parser\n```\n\nor using yarn:\n\n```sh\nyarn add @babel/parser --dev\n```\n","licenseText":"Copyright (C) 2012-2014 by various contributors (see AUTHORS)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@babel/parser@7.0.0","dist":{"shasum":"697655183394facffb063437ddf52c0277698775","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.0.0.tgz","integrity":"sha512-RgJhNdRinpO8zibnoHbzTTexNs4c8ROkXFBanNDZTLHjwbdLk8J5cJSKulx/bycWTLYmKVNCkxRtVCoJnqPk+g==","fileCount":9,"unpackedSize":374960,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbhHAPCRA9TVsSAnZWagAArKsP/0y/HRpjG4RSrq9HckUF\nAPi3UhsII+oKnCFUrX1WVbgACP8DIcgexWNrsT95vXsxaeAaLbYRJ54VYWa5\nZlFPOmPLu04EAX72n1Wx/0CXbOJF6mmCwpNNCJ/xYwBiPCthLs7W0Ls8uNcv\nsCWRyC65E66YsbsBd2lYbyu694wExK85Ykp8tydkAh1pc8c7f8k5kX+G52dL\nrgHIRyk886sTTNGo46mfAJVR0J8b1pd4gBoofzbQQ8zyrbIMqwtFOKySN6SF\nIKNYFfiHRTuutk32LzXPT7V3J3JdCqjgiIN2uf9DKZ867ib1ast3HEDpwaGR\nMpuNFvkVQe4N5qGWoJjFwYsakwEXInt9HVuNenonukuFTzF/rtXYzV0ZwxRc\nKL4jzQn90iG87cOCZAN2LMn0bHGDVFKGtfNXCTIJQN1lEUUlVUE+YRuHc0zZ\noikaulQMQ5WezmN25z7uM+Owq+/IoHVo1aF+BzD50k/9VQnyV4iar4M5p+5Q\nqI10Efu5n1+bXWSh0LGieQSUAVnc8K3Auo2dTN6WqulSJfgidgUE9HZ58pGK\n5Qa2q47SkQxO9TAwxaYwjQ+FcjBQvJgfwC2PO2bfWwuegdWDKU6l66/gqwf3\nLLztH8+pGGTv902PKmeZmHUg/YTikR02OOH9aoo1+2ND6NcrJdPybWm6C4SG\nFh9q\r\n=VrI1\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDTOLFougSDgp1eOIsw7WkRcKIQjluu2fSa9RKqeRJkYAiEA7hH2MbCQwrZ3sttG9rnpO1h64jE4Iad2tsyexJBFnUs="}]},"maintainers":[{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"xtuc","email":"contact@xtuc.fr"}],"_npmUser":{"name":"hzoo","email":"hi@henryzoo.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.0.0_1535406094393_0.9691964480234936"},"_hasShrinkwrap":false},"7.1.0":{"name":"@babel/parser","version":"7.1.0","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"tag":"next"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/helper-fixtures":"^7.0.0","charcodes":"0.1.0","unicode-11.0.0":"^0.7.7"},"bin":{"parser":"./bin/babel-parser.js"},"contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"licenseText":"Copyright (C) 2012-2014 by various contributors (see AUTHORS)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@babel/parser@7.1.0","dist":{"shasum":"a7cd42cb3c12aec52e24375189a47b39759b783e","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.1.0.tgz","integrity":"sha512-SmjnXCuPAlai75AFtzv+KCBcJ3sDDWbIn+WytKw1k+wAtEy6phqI2RqKh/zAnw53i1NR8su3Ep/UoqaKcimuLg==","fileCount":11,"unpackedSize":379058,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJboADGCRA9TVsSAnZWagAAY+AP/RYrLwR0GmLVGHDrHF4r\nE2wG4Eb0yf0ZqC2mwLgpTdnuDYFbJ4PZ07nRcHWp/OLNJA0HDvVexSvpWnZ+\nRI/Jy99OgplpILirKsw6eQQRp7UY7jDNEgqKcPXdTfYne/nlued1lhkexQ38\nlsFfhkqA22cNtBmAtpHXSBwEu3w283HSEKn5aTTTbT+Ag+lxE/Pq4/vWtlFr\n/eGFK1FNE9JPEuik0PMM6k7pODn52O7NTTiiv0CEtFepaFCdFve2p5f/YW3S\nFkHMxsLIBTkw9q0Aizkna+tMzf3WgYvysKVZafzxqWTE+bJhEhmv75mEZM1s\nN2B085El/TPuv2/jlv4/B1iuwvKuAtYzVsQ11L+0WG7o6XhM9F6BgKLEWgfN\ngXOJHTDjfKCKhwVIrpyCy7H9kJ4ORxQKD9KlOa03ahD/WQM6qoEnZWp7IikF\nVaNxaOITFcONs7Hm0eWLSTYxN8vEWQnciIxaou1nBLLApBJbOCy+sAAHivmI\nFVptP11N3qgEfq1haL6HurNutnMyIad5mrNsLpQNbRa+bDc/8sMzbdJ4qqu9\niENs6oEZUgbM1WnDv4Wzx5El2LXlxyQ9Sw8DzwA1S396Ob2OtQ6wVpgPancL\n1EYwd9hsJ0VSenEirIfmcN/wgHTWdnBK+tOcus88R3XztyQmcLQZxHGipbPk\nY9d/\r\n=EWLz\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIA+2nMsFarriw6VHTrSlYH9of1gO7WBBG5jhfhFT/XX1AiA9JuSkY9gz+SlOuSMBVW6El01Fnq9oSeX+eZcw7FghRg=="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"}],"_npmUser":{"name":"hzoo","email":"hi@henryzoo.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.1.0_1537212613281_0.2420030098564825"},"_hasShrinkwrap":false},"7.1.1":{"name":"@babel/parser","version":"7.1.1","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"tag":"next"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/helper-fixtures":"^7.0.0","charcodes":"0.1.0","unicode-11.0.0":"^0.7.7"},"bin":{"parser":"./bin/babel-parser.js"},"contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"licenseText":"Copyright (C) 2012-2014 by various contributors (see AUTHORS)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@babel/parser@7.1.1","dist":{"shasum":"c23e1f3539047b898e471ecfbe7752082384c572","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.1.1.tgz","integrity":"sha512-PIP7vcQK6XPA2cpJy3LqAmFO/fWMehuCa/NNC8NVdqcXblDfV950g2QeMpR4FcU4zfVpJ32WbkvhaTbShiaWNA==","fileCount":11,"unpackedSize":379112,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbrojmCRA9TVsSAnZWagAATN8P/22f6Nm5w3asrL/y28aZ\ny2ij+/PsRHHY1snmVgAUIuHVd8KFQOaZVXckXek+7zlmJQz/EyEVhh67L61m\npEMoXJPM72rFhB5zjJX31ezfv9FFJ1AjwoIoD0cpIYle7X8DXRbBG2nE0wzp\niIftO3a5j9aDgsVCnNgrpsRpY5aZPr0QslrgWDj/q7ZY5rfJIqLalvHpAs0d\nQiTb4oiP0R85TeUGCjZXbq7PytQDB6qp3sak7RUiA1dsJG3OIINB6n5GLVM2\nYPy8tf7bOY2E52EE926VHn3CiFzem5Tz3mVU8NMyCF3hTXgnwEjb+F/J0GDW\n9HR/ydSHdWuYGLgXNhR/z//Uky/Fl9vb88N0YP3zEw7lTI6+kxhXpG8Grfvd\ngvF1qM0hb69973fBttsSHXze6iUgmG3G5A69CHTs0CQyUf36X6otnbhlQYLI\nIsMW1Y1+T0YQIdVhkWQhdUoBrG76fK8N8kCBgzkUXnk/QsO78UU6DLvGd9fb\nObXicoF72U2Za6EE9NmfYNxBfRdVJ0ZnT1XJWUmgXxBunP/AZP4bIPdtcUJe\naDtISP9ibH9p/h90j1/cz1Sl4J7DgKgPmVGUkhsIsouuJT10W7BTn9gGjPCn\n03E8693fC5meRHzsCeA972SPvDFKJhQcytIX8jIa9id16nWzO8QS88jYINvn\nlBHE\r\n=yPDg\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHTTn0ia4GqoA38ZdaI6Xm5QUyQ60khqsTlrF6APJLjeAiA14YbgLotHYOEOPaeseBrA4+4q+LVkR5pucgiXDu8DTg=="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"}],"_npmUser":{"name":"hzoo","email":"hi@henryzoo.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.1.1_1538164965997_0.9740085057982457"},"_hasShrinkwrap":false},"7.1.2":{"name":"@babel/parser","version":"7.1.2","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"tag":"next"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/helper-fixtures":"^7.0.0","charcodes":"0.1.0","unicode-11.0.0":"^0.7.7"},"bin":{"parser":"./bin/babel-parser.js"},"contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"licenseText":"Copyright (C) 2012-2014 by various contributors (see AUTHORS)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@babel/parser@7.1.2","dist":{"shasum":"85c5c47af6d244fab77bce6b9bd830e38c978409","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.1.2.tgz","integrity":"sha512-x5HFsW+E/nQalGMw7hu+fvPqnBeBaIr0lWJ2SG0PPL2j+Pm9lYvCrsZJGIgauPIENx0v10INIyFjmSNUD/gSqQ==","fileCount":11,"unpackedSize":379112,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbrqj9CRA9TVsSAnZWagAAYrIQAJ44wVqn4Mlheq/a7EWd\nX/2LWf1GCU1g0oFmFzNqQGss7JehaUAx5e6GxDGTPQNP0DkV+hxKSFN9lV1k\n7HXXXPzqEV7NUlK6FJ51335ZW0TIy4ptXqxIPaTGPDrvjZFWsxRYAq+g76az\npJ8udjMp0zFgZAxtdP95Xhzz3j2EDlunOI/MD2QQXouCWHItS11n/gGT/DJ0\nZySf7gQ3djHLnGzXLXWLMReIbPnVSR6Uo/5oTdGGO9myphnJlCq0lz5jP0cW\nk+t2qz0ZfeFNp9MlhtKKpHp4LBoSNEjo8FqCttPriXb/uWR1KFPsDMoJmRNr\nA5UTzrobs0eF0dL/PzrwQO1tgYAGriuNE+iKgrKAuoAICGGEvWPRgiUX8icw\n8DMkrKWaVisloSQ9kK0aENXfg6uPfRKxfRPGnA00BO7HMDpiOws+nckNFExs\nZsqBdZPDa+J9X6S0WTiJh51rSzlTa4ofx68YgGaxlU/OQyb5TRQThwdQ/Wk7\npd4N6rOAYZWIf3E45HeK6JwaNFtgjf1tK1EwVRR2E2uZZikY8tBKoB0eu7hh\nmHBr7wDc1sFrC6phHoehgRSzyDU0QsjDjKw6RSxForLLMtTmByiwKA++Unub\nuMLsQKkI3WLSpDu6q/zdB/a7fqHMxwqgCDB6YM480smyG3HY8szn/AGIS4Qw\n3IBm\r\n=d+wQ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAJiorKD2GN8VRt4h0D+AwX6ENzat91ONRcF06bxcd+tAiA/jYxvlR53/JMor1+bHf42Esk3y9Uuf6kPsNPoXqStDw=="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"}],"_npmUser":{"name":"hzoo","email":"hi@henryzoo.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.1.2_1538173181144_0.6119566779112873"},"_hasShrinkwrap":false},"7.1.3":{"name":"@babel/parser","version":"7.1.3","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"tag":"next"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/helper-fixtures":"^7.0.0","charcodes":"0.1.0","unicode-11.0.0":"^0.7.7"},"bin":{"parser":"./bin/babel-parser.js"},"contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"licenseText":"Copyright (C) 2012-2014 by various contributors (see AUTHORS)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@babel/parser@7.1.3","dist":{"shasum":"2c92469bac2b7fbff810b67fca07bd138b48af77","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.1.3.tgz","integrity":"sha512-gqmspPZOMW3MIRb9HlrnbZHXI1/KHTOroBwN1NcLL6pWxzqzEKGvRTq0W/PxS45OtQGbaFikSQpkS5zbnsQm2w==","fileCount":11,"unpackedSize":380749,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbv3G7CRA9TVsSAnZWagAA3agP/Rm7qWl6AbXD0/osPKD3\nyk22fFUndD96FsCZQE/JLRIOm38yptRqs+uaqu8Nz+RTy2xKZHay+eNRqFde\nVKKbEG25Kc9GdtT+aSsSWL63ybOC6/porWjvjpgSpL+/4AY/XQu9lMzEKgY+\noRqWP/ztBJzchpbmASoQgHxwVXMcAIrR6SPN7LOHpoX+wMo/08sIJBjPReNy\nzxoFx9zJ6nvwRAUafrWNdhX7PSwBkfOZaaXRRuW26qvsRM85SWuqLseYkbZG\nqgvlp/ljfcDeeRkr+Gb1dTpMPu0BJsmjLJ5HQu3/RyedeFMDeG1Y/JXXJU7x\nEMUPN7JR6vN64ZuKqNQIj2Cn8AkUwBs+Wjy+cSbPyYdbmMYceEgAWxsJChLR\n6KqkE1noe2b8az17Ki3lXdMM2IAvN6/WSB49dJkEkGcM/aIU6ZFgYkLmb+eF\nx1K+Fqp06qiC38vtcPZJ/jR/KY3M7Lcth6RUgNLJWdoeiN6TVMpFqEEsyAAn\nB2p7Xm+CqWepaXfZYpO0Q1hex6nTVXvh9YrssYBFZDTQHiPEgOjGWkomyqHl\nC+rey8bJoHbdp709x41yScrICKnZ9FR8PoJbreynpnB8igKk33Ek6QyjGr9q\n9LwNaJUE5rWKkWEiUsYcNWhbRDE8LIsLiOTm4vWRTPTGVuL82B4pF+VlD1et\nhlvw\r\n=F6Gx\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFeTUFBduhM6UtmQm6yAVPcwJ+/RczCPKjSAJovGTlIRAiEAseb55OUvRrgZkobFWKdl4frk03/odyX1NdZ0WfzEt4k="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"}],"_npmUser":{"name":"hzoo","email":"hi@henryzoo.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.1.3_1539273146670_0.24542036832549252"},"_hasShrinkwrap":false},"7.1.5":{"name":"@babel/parser","version":"7.1.5","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"tag":"next"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/helper-fixtures":"^7.0.0","charcodes":"0.1.0","unicode-11.0.0":"^0.7.7"},"bin":{"parser":"./bin/babel-parser.js"},"contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"licenseText":"Copyright (C) 2012-2014 by various contributors (see AUTHORS)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@babel/parser@7.1.5","dist":{"shasum":"20b7d5e7e1811ba996f8a868962ea7dd2bfcd2fc","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.1.5.tgz","integrity":"sha512-WXKf5K5HT6X0kKiCOezJZFljsfxKV1FpU8Tf1A7ZpGvyd/Q4hlrJm2EwoH2onaUq3O4tLDp+4gk0hHPsMyxmOg==","fileCount":11,"unpackedSize":384944,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJb4hPmCRA9TVsSAnZWagAAvzMP/j2jK6vrlbCf6+j1ZmpR\nJyUUlamJetRpCdUtZVRsNKow2h8n9qCpqnlqeR/uIod+L9XcTOCfUV8jM3O7\n9Gv3AasZa1Wc12Qyve7FgAKTPcgRiToigLQ0al9JAr+WdnfX0aqkNvA4RGNJ\nnyN0OByi4Pj2xdJalyPhFatSGL4kCyqEDaNuDzOWEzOaMeMO5hvi+ysNecja\n2TSXoVNTMmRx9csdvbe064yV/PqZZ5fdObFH0ppKcNmlQQoG+xovU/2YIVCb\nVz5LHHaqMZU1BLkDHxP+WC6ZBUYeRnx3ZI5VGJJOJAGNi2LSXqMS37bOfIFp\nG1jFzIZ7qtMpsvZF4RALaNFaHvbohKOQHG0kFLIG36Ua8hER9Lc+4KmslZrJ\n/SeuvH8eUpy9ciuCMwumM5TOcFVK4ZcDtWmz101rtb7XbROc4ocOurMNMht7\neBFaB/sdQvvXLScy3WcbFdeUZ9BOQdOXH5N/y/0Ff9jakpcxXswQ16/qtGcK\nOTLNr307O1ZNQ1Zo1NaFs+vsudKMszSwhnVei3IhEx9pZarJUiB3dbdng5Pj\nhuz7jblpZ+XHAl9Ode3R8THJK075598yun7qDsfJfalt0NHgvL6FOGUzbU4F\nhoTklSk96m8Q920OWB9lrCe7C5FYDMzn2Ptok1ghcGTpFjQCBAeHr4Z5ZScA\nTot8\r\n=x7dd\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEZN9Pb7lrB3EhCW8OIwd/Ry6ecjwQczaGND2lb7rHkQAiABrJumDC7ZRTAJICedhWCyl6/aGazf59FL4HzzSBQcMA=="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"}],"_npmUser":{"name":"hzoo","email":"hi@henryzoo.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.1.5_1541542885277_0.8922366356437124"},"_hasShrinkwrap":false},"7.1.6":{"name":"@babel/parser","version":"7.1.6","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"tag":"next"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/helper-fixtures":"^7.0.0","charcodes":"0.1.0","unicode-11.0.0":"^0.7.7"},"bin":{"parser":"./bin/babel-parser.js"},"contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"licenseText":"Copyright (C) 2012-2014 by various contributors (see AUTHORS)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@babel/parser@7.1.6","dist":{"shasum":"16e97aca1ec1062324a01c5a6a7d0df8dd189854","integrity":"sha512-dWP6LJm9nKT6ALaa+bnL247GHHMWir3vSlZ2+IHgHgktZQx0L3Uvq2uAWcuzIe+fujRsYWBW2q622C5UvGK9iQ==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.1.6.tgz","fileCount":11,"unpackedSize":386240,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJb6z3FCRA9TVsSAnZWagAAdxEP/1PGQJDnXRIC3AYvU3MC\ntvonX2hmeNyeEK9dKhrjo+9ewakAUvDbomrZ9SNbP2b4FPJfS+1mFpGYfVCq\nFJ9P/Pae5gqUR1qvZBzlo6gPS3IHtLiy8ZLBlihfOq9q71rWaUzed7e3sPw8\ngridQdjei9YnS2rGuMUQTzAPGAhC8BMxM9bLk2/JY1Zldxo95VJgWHk+Yu9+\nf8qdlYsRncA0Kmc1f5Zq5t4nT9v1jnjklTScnOoURLviGyh7K0aFLKczR2rs\ndFvlUoCZlJHolASzgu68n7NrmfhTESzwVhB05yFJOxmL9+IOE+jhF4WA9HQE\nt1O8CLyX9Lrsy1jdww2bhFEGlbyxstWKQzN/nygehupWLWrj/bmuFikjv3s4\nS9palvy7Zr4ZVKXQAGuuvtIjMLeKT3fL9idJgGtudhfVwNAokLZc/Uib7Vi+\nvm5NxqjhQd+MaWMPquboIH0UEbyEMGeg8llsBI5bD4cX4D4jPv0Anglp88cc\nb+J4xgUEfKVd0foJyNgZTd84EPoZoO/RZHFSNiatus7igL033JuU3zfWI1L0\n9HRMlNeG40T33gAjYrBKtsyDMZ297PrD8W2HVjsXx2siVfcE4PH296X21L8Q\n1Sp1Bwq7WwzyxSblXgejAaPRK52XQB7UhC93BtGzcrswiqbRM8VFqmq36NkD\ncySP\r\n=28qE\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEjZxZLv50WB7IG11Ua581aMRt1RoHhL/23BLZ17GOUZAiAFCToPp1B2O73CtHLn7XVQdNH74Ah7iiEcL23EPcCFWw=="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.1.6_1542143428615_0.4931549257100467"},"_hasShrinkwrap":false},"7.2.0":{"name":"@babel/parser","version":"7.2.0","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"tag":"next"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/helper-fixtures":"^7.2.0","charcodes":"0.1.0","unicode-11.0.0":"^0.7.7"},"bin":{"parser":"./bin/babel-parser.js"},"contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"licenseText":"Copyright (C) 2012-2014 by various contributors (see AUTHORS)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@babel/parser@7.2.0","dist":{"shasum":"02d01dbc330b6cbf36b76ac93c50752c69027065","integrity":"sha512-M74+GvK4hn1eejD9lZ7967qAwvqTZayQa3g10ag4s9uewgR7TKjeaT0YMyoq+gVfKYABiWZ4MQD701/t5e1Jhg==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.2.0.tgz","fileCount":11,"unpackedSize":395009,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcBXySCRA9TVsSAnZWagAAVWgP/1NvvymRa5yKYV4EG8ek\ncj59ojfvUfTfMh6dt1VAWkk5Gj03R/O7C7rPsXNM4mHiCBW+ruoiro2xq3NM\niH/R/gpug8cwoC1yAmU16Og2tnVgKXtDdI83UxcAaTRKiRPSnDEFZ4HigC2N\nML1HTo9qH+4U7b/KesjA6xbRz6vcuD9jAFo8A2y1wHPHyH+/xxn697jGwrpi\nNBgL59mwRxfoTovjOLPuYyGNQZXcyuFxcz1YK0hxRK0vby7z0aVfeflz3Y4y\nFFmg0wwmk3BxpmS7SMoL1OIlnYB+Vdq7nrSKhWYKHViBXKDICRLa6OEkIl4I\nc7BIE5c6YnG/gZEiNaJxS+c+dg9WAHL7Xi0B6r/g8RxG/ViJ8eBt9sm/vD5n\nP/5pNYKS8JJHrjyqzTDyTW0RCBQ/ZA5WzJaOFxtWfb9Yh+4i8TT0Dm3J7BPR\nc3jNzEXMFFP45RQyweeB4tXG2JM7G3D14BBpDMjkjQQ2AmfesD7I3joqtNqW\nvN2sO3XE3TFOg1OTfHRPZhm+ejiJuVbXB2X/jfXp9sfkSLXcWNKQpSuSpGWj\nufY2FJ5Fa8C97nYMemB8euWKoa77J0TQKdPfMT7MZjLSsP0Siybo/AsXCrbS\nssVjjLzcAMN3REqoC3U49MMcsPpY1LjfD0WbujiRbl1eCeUwwLD2ZEhhQbYM\niUoU\r\n=E2wm\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDqrlOa8EAaPXXXAheXfxHtxUwKgWJHoofmroCqjZtCAwIhAI5VoCuB4eE5g+5lKc8jnlUbrry3kqb4I0aQz2epqbR7"}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.2.0_1543863441301_0.2567904879865688"},"_hasShrinkwrap":false},"7.2.2":{"name":"@babel/parser","version":"7.2.2","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"tag":"next"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/helper-fixtures":"^7.2.0","charcodes":"0.1.0","unicode-11.0.0":"^0.7.7"},"bin":{"parser":"./bin/babel-parser.js"},"contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"licenseText":"Copyright (C) 2012-2014 by various contributors (see AUTHORS)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@babel/parser@7.2.2","dist":{"shasum":"37ebdbc88a2e1ebc6c8dd3d35ea9436e3e39e477","integrity":"sha512-UNTmQ5cSLDeBGBl+s7JeowkqIHgmFAGBnLDdIzFmUNSuS5JF0XBcN59jsh/vJO/YjfsBqMxhMjoFGmNExmf0FA==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.2.2.tgz","fileCount":11,"unpackedSize":396067,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcFNHcCRA9TVsSAnZWagAA0PsP/A9NJu/qSOlwNwNFRLH+\nLkC71kyGJkmsh7hcPwkbMP/NQLT0pAxGgCbYUNwQ5qKmCYHZCIr1M7p73g9p\nOIScv2s6SmIjdp/O0ausG2QL+yTlCTyuL9j1XSpeJF44MNRXOyrvPAfA7JVN\nlZ5UOe9pS7eDXdRUc9KyWbgxhbXLDbjc3hC9Xuj27gMUyyFGykoayQ/2xpMm\n446cr8UWJLfNPovWKby1KDHxtp3XAWeTOCjje+yO+u+NIe0HOzCNVUuK4bZX\ngVrzPMw4jhqlE5KnSzNFA8OM3GtvjrU+AaJ5QvTHxRzFU0fUkUA24TV+oKa5\nRlXsCiZ2w9yJAaA6uyAgxpd3Ns/nStBGAkx2MxcgYSXwlA3sZ5I6CToS61Ku\nSbREfyVRB2ImU/zLE4rX+1qeA7fxCJj3pW1dDrYPnDrIO81ZyKTHYxoXyHM4\nEzb3oDM1JO1+y7gaGJGzI9P0aBNux1QFtVBcGMBcKVFstZ7EI1WqLGPtZbPF\nhk+yxPix4AMuHzJxpHTZVRvjUtjg054a19X9Z/A0LN2ZFVDjkXWD3UJATwcT\nMkV7aGpr42V27LkCL8Sd4EkNmTZioqdO7/p+LO/IQoNY/1f/VZrotu9gq9Cz\nbfaiqwFVUcV16g/EkzfEPoYtvND0jkSG+Pship4cGmarji/rP4BvrwQvcsLy\nHYk5\r\n=gwX7\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDAfpeeWHzQ6OiXlz62fwcfI7QIbSD8dwKMrzJH8J/itAIgRjPEq41iMCHO96bcEu59kD98k7Kq366cI+TBzJ1OyG8="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.2.2_1544868316380_0.5221032562533485"},"_hasShrinkwrap":false},"7.2.3":{"name":"@babel/parser","version":"7.2.3","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"tag":"next"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/helper-fixtures":"^7.2.0","charcodes":"0.1.0","unicode-11.0.0":"^0.7.7"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"d35f2ad92b322c3bb9c6792e2683807afae0b105","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"licenseText":"Copyright (C) 2012-2014 by various contributors (see AUTHORS)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@babel/parser@7.2.3","dist":{"shasum":"32f5df65744b70888d17872ec106b02434ba1489","integrity":"sha512-0LyEcVlfCoFmci8mXx8A5oIkpkOgyo8dRHtxBnK9RRBwxO2+JZPNsqtVEZQ7mJFPxnXF9lfmU24mHOPI0qnlkA==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.2.3.tgz","fileCount":7,"unpackedSize":396327,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcG3kzCRA9TVsSAnZWagAAbVQP/0XMyixB24NJdh+ewZzA\n0g1kq4mDBymMcEwjVfRRrqgnNFL5/X84HT1ZDuNeCxCUJVHYgu/Srx4i7KOx\n/IOHcEDuEbHQKVYEWxuqKVf3y8ZzDxTQHQQaZuWqIMaLNewjY/ayvxglX+QK\nU8eIptEetyxJ1feXC2gaSGHF0QiYdF9PoIX6WwdoUO7H9jaxknJc8ImxrjQ2\n9bzWkl7WCaezBAeUsIc8NFwKa716rp3HORHJU35gc+xCr5dAG5G4cRu2KLja\nEb0RjiC4RauJw4OHMRE//nIvirc8VphxsKtE+SriUwq4kkn43fN0aX50YCii\n+FDdI0j7JJzu0jWuiZQmXltoVTWFtt6NToG4QbQRBH7vhNQ7FAzC0SgXc23p\nyHFvH2ejACI/BH2EyjxA95aBJZHxRjUGm0MCMf1BB11yg6WOy57OQLZbAj+s\nSPKe23+Nfd/2rztlEBD0BlpTgJLURfW22w44lvrgilyV6ze+0VhLSK97TDbd\nRGvqbq+oOwpUHeu3NaU0peMpVraXJp4mjy1M682mCbyeBeS+YbPxDP2iU6qe\nrsxHePruVrfR9XqjVrGiA+as9lleGRcIscCv4JvWpcT9ehgm/82T9oSYC+sB\n3NyQO2GyrNnPjA3IPV0PMfclYS5g8Xg0Tr0OZ76eIZweXDUJXCgo67OuDbFd\nwn0Q\r\n=iqx6\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDSoCmmd0vlH2YsI9k9esj2w7ehQCRf5n1Ae0280nHvHAIhAPHX/iJ2rzr5dfhDAUGy8n6CYMav8d5xjt1mFEHHBku8"}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.2.3_1545304370884_0.12121109533385921"},"_hasShrinkwrap":false},"7.3.0":{"name":"@babel/parser","version":"7.3.0","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"tag":"next"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/helper-fixtures":"^7.2.0","charcodes":"0.1.0","unicode-11.0.0":"^0.7.8"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"f6ee26c3da4c903818fd61fd9e5e8e1970185f77","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"licenseText":"Copyright (C) 2012-2014 by various contributors (see AUTHORS)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@babel/parser@7.3.0","dist":{"shasum":"930251fe6714df47ce540a919ccdf6dcfb652b61","integrity":"sha512-8M30TzMpLHGmuthHZStm4F+az5wxyYeh8U+LWK7+b2qnlQ0anXBmOQ1I8DCMV1K981wPY3C3kWZ4SA1lR3Y3xQ==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.3.0.tgz","fileCount":7,"unpackedSize":357807,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcRjn3CRA9TVsSAnZWagAApG4QAJNJ12isGYqvsHFTjspU\n1Yf2FMiMjRce6H6z8cdTH+C1gLhOGSWIrEpEc+A+Z+IR5NuM3xWOdtYxwc72\n8R9lrtPynLVYeMq9HCLZ5gVd4dPzkmxI6YW0LVjV8UL0Z5EpZyXQDoloKtSg\nwJ5tp/eYE3xFxgtRLdrW9cYWg9i9rvt3LlH6aSDUR0TBfAIaV/3F309Iz0Gq\njhW1CTNSPngn6wEvytb5GKMmJMHKvYMWajhnXemDTbY2fz0zvsHcnt+zAqe5\niDO7ivDmkWCWy+C5j5f9RQ/JhahBSIYDLqKY99hnoURLTJ882I87KvdW+WD1\nCxrYV1qCsPPqkoloAqVJ6CwaPIsXd9DCv5gFVABojHEp/ysNFjZMxAuELa4Q\n52pCFAVmWbmB40ckW6lpIvdSqEnw0xU14qMEytR79W3Sz+MSlNdrinb2fe0W\nG7nBinijQGG8UUdwzucxKyYyne7YlQ0s16lgs/HbLNX9B0CJjxrZ9dmpdm96\n8biK5pIAcRLcImroayOzPF7i5lQZBAvuCBI2Ck6Kb8tnhzeTbxWUmqelYM7M\nrnuooXafO29fGbvMwyTIJQxsC5YYtyTDX3XDzYryjrAPBwgZeITVeYssarI8\n0QjCmJba6I8jWXRfTZvhWtZ00I6jkWT08UoKFcn1gRoaCFZYR7DRNp2Kwi1U\nS4WF\r\n=wiCy\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDqYWmmMb4aEWH+0ZISZnSh4hKbW0YHWjck8hyUlutN/wIgRFDyls1sxsQs/v+kKN9+6x8wnNBVInFmC6eLVI1W7So="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.3.0_1548106231351_0.617800459301878"},"_hasShrinkwrap":false},"7.3.1":{"name":"@babel/parser","version":"7.3.1","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"tag":"next"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/helper-fixtures":"^7.2.0","charcodes":"0.1.0","unicode-11.0.0":"^0.7.8"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"f2af6c1170ebbea22bd29a2bae01efaec800dfe9","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"licenseText":"Copyright (C) 2012-2014 by various contributors (see AUTHORS)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@babel/parser@7.3.1","dist":{"shasum":"8f4ffd45f779e6132780835ffa7a215fa0b2d181","integrity":"sha512-ATz6yX/L8LEnC3dtLQnIx4ydcPxhLcoy9Vl6re00zb2w5lG6itY6Vhnr1KFRPq/FHNsgl/gh2mjNN20f9iJTTA==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.3.1.tgz","fileCount":7,"unpackedSize":357845,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcRsKqCRA9TVsSAnZWagAAV8kQAJgvZrJ3ZBeQQP9Ivowo\nzo/H0SJsc5E6rPUBZgLfT6z6gcrBizu5qzQ+kNezOB9u2eBLXHoZXWvxArl4\nSCHSSvZ5LjJCUvLPBiWCIiSip3ceKusxxmXO26PLAjUt4vx8GfE2vThRiTzi\np94CXOa0s8w/t4QU98SaMTCzGnGPyg8iNYOeA2J7npfXGnvOkfO4wzFcEonG\ndYvzwGSM/DjV0EqEP4J30pScPVCJY2tCs6pS9yp91LxEumVFQKMP1Q75G1sO\nMcFM9rwme1uQapZNrQxlNDdn+o1WDXWCiELaxW4nRnYBOauEycAUFYFwfAvL\ndE/hQceqH1+RYmfCH3jVSKkEUAmBwlMsowG1hSzIYfMfwclvRI2rmiqb1kRL\n37VQmCaxnWJIHPzX9ebVxeqD0LNHUqX3g/hplOlOcOh0huH188qXpi+KdXl8\nQW+20EC/+fVxDrtSGgLR0ni/jgiIVrIptEB23rkaSbEofSGInF1AKZLJU8wW\no34vTXLL/RniSXnznGG8hWmWh3KambygpzmNt8IlqX7JlhqBggipzk/GbnyT\n3jxOo20mslKr6gB8aKS48TmcyP5OZNpIA3BOfyI+yowwaw1mmn3EyZKJqTNH\nzuBVZnzlA4ddtHXE7LAvZcmSk71VV8g6L9jsN+YefF/Je0eP2KrJjxSYHa+4\nssqv\r\n=+ETn\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIC82jK8ZtUBWquVwBWgnVdhMznhPhbplSNOB7qSY1dxYAiEAkTaZ4L4nYhbXtXG8JOMBUt/qKahzoZ3pbq807XtcrQk="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.3.1_1548141225815_0.9489986812025404"},"_hasShrinkwrap":false},"7.3.2":{"name":"@babel/parser","version":"7.3.2","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"tag":"next"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/helper-fixtures":"^7.2.0","charcodes":"0.1.0","unicode-11.0.0":"^0.7.8"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"d896ce2b53f64742feeea27dd33ee45934cd041a","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"licenseText":"Copyright (C) 2012-2014 by various contributors (see AUTHORS)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@babel/parser@7.3.2","dist":{"shasum":"95cdeddfc3992a6ca2a1315191c1679ca32c55cd","integrity":"sha512-QzNUC2RO1gadg+fs21fi0Uu0OuGNzRKEmgCxoLNzbCdoprLwjfmZwzUrpUNfJPaVRwBpDY47A17yYEGWyRelnQ==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.3.2.tgz","fileCount":7,"unpackedSize":360201,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcWLtCCRA9TVsSAnZWagAAswoQAIP9DZNgxQeAH70hrw91\nX8OPE1M49iSJJY/ZREbbTs4kaEIAVRdrmga9r5PK3lOo+jtj+UOxxin6SCJT\ngdYL18VysgVE3GJ7B82cG9kDZTVJM8cHQAkHaCljZpvPL1i7WVGLaoMEaIDd\n8RTfHm1IiS7HcFt9oBIFtV0zkppaRou9j4x8dlF69V070jMjuhzpbwKoK3Zi\nv9M1sko/XW/zxPqDC8OhIVbWBA+xIL14fFZhcJzwOuCEoqJZKca3PtuE1sMk\nIEQDE0NlUB7H3uHvqmru8BPAFd7WjUuPntj10nAZq6Xo6iAqWYq9y3bFtrX3\nIVEgdIPypf8/KyFCkTc9af1XX5kMX+rWpTsZYuIqZkKHjxkOcI3pL+PhIgi1\nZVBsBjL5GnuaxHIVNovVIj0wLqz1VZh9krgBysrwmFE/RveS2LLKs4xNB8cR\njvGNTpPgAuERcLG4z0QxzWo+CTcFaTwe9RUZ6bd97F7/QOS5MeuSrr0YehCU\n2SbndJHk61+PUimR3VatbVgr6nFrz+7teqSQBeaUMyXdPSAMQi3wxYbCLQYz\nbSEwt/MvMSRvJTpO2e/NWVR2HkreKZIeecMzEXDur1fbLeOZGHtgQ9FgLs5N\nykOc5cLGQr833uE9/67m7KpjRWFoWv9APzHYTxSerbbkKc9zOoXFkTqQT6j7\nVXM/\r\n=M4M5\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCRLh0YKaax+2nQqWvhdB6Zoup9S0aERpPrvvpd6jWK1wIhAJ8TcqeKndXIVprWm1PSASOkZ+OxtkIDArkwsyIZhdbB"}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.3.2_1549318978031_0.7363055325268009"},"_hasShrinkwrap":false},"7.3.3":{"name":"@babel/parser","version":"7.3.3","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"tag":"next"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.0.0","@babel/helper-fixtures":"^7.2.0","charcodes":"0.1.0","unicode-11.0.0":"^0.7.8"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"d1fe2d05f4c468640facf40565e30f7110757f2d","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"licenseText":"Copyright (C) 2012-2014 by various contributors (see AUTHORS)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@babel/parser@7.3.3","dist":{"shasum":"092d450db02bdb6ccb1ca8ffd47d8774a91aef87","integrity":"sha512-xsH1CJoln2r74hR+y7cg2B5JCPaTh+Hd+EbBRk9nWGSNspuo6krjhX0Om6RnRQuIvFq8wVXCLKH3kwKDYhanSg==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.3.3.tgz","fileCount":7,"unpackedSize":360878,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcZyu0CRA9TVsSAnZWagAAYoQP/RVs85ESCIT9u+RukdaP\nI/GScCm98fAMypPiVPJ9pcEOh5bC0U+XB09fX0ArhjopWIASKg9XB0/+oYHD\n0qYWu1Kw6MSyqy0Ad6UJmWBMdmvRSm1ZlGOaX46ByGsAPBfzPOLwo7gMD1Jt\nJH/bF36zL+v+q9Y097e2ky5GffMn3plMi2TMyxgsdzQXFpRTk6w8U8klUdUM\nlH9V5i4u3dL/jlt7h6bDUXP+0tGUdIv2CRyWXjTFlUrhyQGi8ql8cByqRHGL\nisePzb0PJyHLcDpu+Yc8XWReeKbJ4nHaggJTLF5ZsYxyucqqjnXMCwHXG0h9\n36sZ1qx8qGNochEa3XVOk2KKTzZUJregunSKVNO+6D8ozvCZuA4r63RlDHmg\nadUASFrlOPDju0TR3fEHeyUggagQGaJu1+gCbK4TDtCXWj70OTL1OjwAd2ki\n8F2gTpP/uWmJdcK+DLNhvrEmE/RsJvnxiTX+Rz5r1R8GcUO+hB1mpIH6aIAo\n5E/WB3xoFBnd00ZNYCoavQJibvRBzVo76g60P0jnW+W/TII8cEKHL0QkH5SF\n36o06NGCDioVGeUJLTmepQ/o8Gp9YradzZpf71JjcvF9mWqPGUjrKL668l1Z\nJAaWLwqjpfK2o0qCi6fZsSujBdFHV3NZVVHQFvfyMGfBEfaRv2vCSyX6pxgC\nueWn\r\n=mHMV\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC0xlJvkUBjfLBeYqbxaNCJ8ZQBTm0VYm+v9Id8JkJPtQIgAL2/X+OIXY8YHH/cDoMRVALhn5YqzgeMVL4Nspxv9BY="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.3.3_1550265267374_0.7591597341672258"},"_hasShrinkwrap":false},"7.3.4":{"name":"@babel/parser","version":"7.3.4","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"tag":"next"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.0.0","@babel/helper-fixtures":"^7.2.0","charcodes":"0.1.0","unicode-11.0.0":"^0.7.8"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"1f6454cc90fe33e0a32260871212e2f719f35741","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"licenseText":"Copyright (C) 2012-2014 by various contributors (see AUTHORS)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@babel/parser@7.3.4","dist":{"shasum":"a43357e4bbf4b92a437fb9e465c192848287f27c","integrity":"sha512-tXZCqWtlOOP4wgCp6RjRvLmfuhnqTLy9VHwRochJBCP2nDm27JnnuFEnXFASVyQNHk36jD1tAammsCEEqgscIQ==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.3.4.tgz","fileCount":7,"unpackedSize":360997,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcdDVmCRA9TVsSAnZWagAACfMP/2pdeZlIPGxeY8MZQTb2\njpWGUGE43p5/V5OYEVsuh5NqlJHlOPS4mTymPerGQpmiSv4CtP/HGUFLO91/\nFZii42NIPsOpzM/Qb2jXmpEEZCnVc29Z7ddQ454WK7BDJoOyNWwmI+mKNvVt\ninv+OFllEO9fxYOcBBteDeLHGYD25ARtXZt2d3H7S8bFLoOKbhHA73grcz3c\n8DnC9g8/iFRyzAQ4oqHRnDnJ0eyxKboR1g9omtB0GSybYwx6LpnHqZkr8bz7\nkYdEWa38ey9lK04VGgG7ZHSDdXJN8Hp5/PvAS3nzAj3SvdRGeOdsIib4DdZ0\nSxtSSVIgSca19Kiy3vG4AoGZyIFSe4anX4DugeQSGaztRW02tGID7qlbIobD\nA1GdrMqcs+CaD0b8F4bGn4HnUV7C4SPtBQRvnbzwBsWGvmUi89dRAPd5J+vE\n4bnv4o1LXO3QoxWY3mDd5+7CQxamz9wdVH2AgTFqsASl8XvsuHcfsULCtjSU\nBEP4kSnIemNMu1IU5nJelHnMgu5atBEUwF6Ft5bhJY32xAQtW8ENUydtTAjx\naux76Zb+tWwBMeQlOCs7eSR94Jy/wlR2ehyfbhNyOaVwTYVqxwB4AKWtdcXV\nHXOqmE4kuMJaBz6MUzeBt/ie3O8cDWCLwU5ZY5iQ8AvMQanRCxadEbJyqv5H\nWYtE\r\n=K4JH\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCwQgzEyUqBNnJOwGkpAcCpc72uJVq7MqYquztvWGlNoQIhAMGp7U2IEwHjysxND6zdSkDGWYWWSopv3W2LKqeYb+aI"}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.3.4_1551119717485_0.050403403311564565"},"_hasShrinkwrap":false},"7.4.0":{"name":"@babel/parser","version":"7.4.0","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"tag":"next"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.0.0","@babel/helper-fixtures":"^7.2.0","charcodes":"^0.2.0","unicode-12.0.0":"^0.7.9"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"f1328fb913b5a93d54dfc6e3728b1f56c8f4a804","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"licenseText":"Copyright (C) 2012-2014 by various contributors (see AUTHORS)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@babel/parser@7.4.0","dist":{"shasum":"6de669e73ac3a32c754280d0fef8fca6aad2c416","integrity":"sha512-ZmMhJfU/+SXXvy9ALjDZopa3T3EixQtQai89JRC48eM9OUwrxJjYjuM/0wmdl2AekytlzMVhPY8cYdLb13kpKQ==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.4.0.tgz","fileCount":7,"unpackedSize":375478,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJckVShCRA9TVsSAnZWagAAuwgP+QDB47GhNNK+lftZTbwO\nGSAikiLvfWoShQmjyRqjYWSrtZjJZjCDSYWnJ5YdcdFS+bZYucMKpISXBJJM\nadz2D990PfBt3yUw4u8vIds68fsi8vpUyMrICw10eeMMAjotQoEZTaIn6CEK\nu7colJjKSWOQ0z36NYX+CriSsK37pXILOpd9bMFxarS/8K9d6+AsW0g1uyic\n673Gyx4wvIsbaCyUCdCujbyfQkuQ2PAZ2+l7eaedzCmWYVsyE6U6BEd0Hpq3\niDgUgvuEvzF+vjiaPbExKyTW/93cePH8XhgGS6M2qzhRIXHycIWiM0Whg8S4\nKxSQ0ymXxm+RhDPBkq2DH8NDMuCQSQQLguylljzdsVPBF76SCBjPxDgr4g34\n/jLbdF7iHRgQUNuioHGNf+a6kQlVdArezraISHB5RIRdql5B1XEsWgkFulK2\nO4dxsnbwRXnlIxsOndvxTyOPM+QdoSLiQLo9KTS63jlVRSBuYfJDmifYLMRj\nzyzIPyukUvedcyTg7dOw97KDnhQD31lDkJdfBBcc2IcBzFDZq4gtyGmzQ70I\niYqTemrfCuxHM9m5FljykMJSFBREqR3xL5uGZKT6n/pQFK0vbv5X9y1ufZSX\n8czpcpwG4lNkmoxHJwGsXvGAVnKNSUGx83uC+yYT4KNY3dvWM6BJ4nqA9uCN\n/L3a\r\n=Xtpi\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHlkW+h68R5p0Jtp9M9fq1uaXuK4iH9y0wQ9zKL+U9SkAiBjKSJTrM+xMtwT1L8ruUoJPKnRg2Su0Xni3sWVdOs/TQ=="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.4.0_1553028256570_0.9301618665578377"},"_hasShrinkwrap":false},"7.4.2":{"name":"@babel/parser","version":"7.4.2","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"tag":"next"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.0.0","@babel/helper-fixtures":"^7.2.0","charcodes":"^0.2.0","unicode-12.0.0":"^0.7.9"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"7dea0f23de51af336a2fab0286a73af30cddf3be","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"licenseText":"Copyright (C) 2012-2014 by various contributors (see AUTHORS)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@babel/parser@7.4.2","dist":{"shasum":"b4521a400cb5a871eab3890787b4bc1326d38d91","integrity":"sha512-9fJTDipQFvlfSVdD/JBtkiY0br9BtfvW2R8wo6CX/Ej2eMuV0gWPk1M67Mt3eggQvBqYW1FCEk8BN7WvGm/g5g==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.4.2.tgz","fileCount":7,"unpackedSize":375634,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJck2S1CRA9TVsSAnZWagAA6tMP/iU+eTGQKmia+5r5KwPR\nbjqZKLpSp81nz+VaKlu3yN/T2WMmJcJutmI887wtBPzlGfUYOfMgdtGOh2bB\nN4mC/RUBNtF9RDr2oFTyx4gXQhGJcy3lXO2w9bEZovxdvNUKp6ENpTYNrBnv\nJ2UHiGelLm2WGFdAHhwVg32QRATCH1beJ7QKOcyWn4f0yx32ATjZfKbHQ/8i\nA7oDx+HCUln4WgD3/nVqjaAb0RrMwx7yjEAnrcCQbAXFvv043X7eYwTNQiZV\nlqAscYE63mO2xr63Ja0KWcvlNZlmf4AnfI7vqpiqlnD7y+px7aySj+8o2HnY\nZTngprOMD39mR6H1Arc4zOgpyaFL8g8hQ2iKBdEag/HLNYf9f11UfQKrJwCN\nN1pO3hN5y3dqBi144ieRIYUzHbbzoe5YLd9RRYQseW1kZtQNrNVOf7vinzMr\nTugoxHKzsKNRrlHPBlVXiCGNt4RJyUlpWCEwIEqYMIkLIYCiho2Yq+eezc8F\nXh0mFxk1fCvJI9/SIFY9/ZNI6RmIGj5kJu93eZQgTeeTCxS5nHiDtOMUdAC4\n8XrAJTM6aMjMR11xmsOUtYcBMxSVnUljY2UR1zms4Fb/WwHpsqR/sadY8fGp\nvBzPBLyha56HpT/pke3aJeVM9MIwWqB7TFLvSu4vTgKSnM3h67lDyshg08Cg\nb5dL\r\n=mpV+\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDjCYwWsGAQ7THuvWvh6RFqhGDycAiY9RPufkxYitDu7QIhALo7TJqs+vbUzXt/bPI7lL29t1WG52sAScxF2THB1qUF"}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.4.2_1553163444598_0.027618229964785357"},"_hasShrinkwrap":false},"7.4.3":{"name":"@babel/parser","version":"7.4.3","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"tag":"next"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.0.0","@babel/helper-fixtures":"^7.4.3","charcodes":"^0.2.0","unicode-12.0.0":"^0.7.9"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"508fde4009f31883f318b9e6546459ac1b086a91","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"licenseText":"Copyright (C) 2012-2014 by various contributors (see AUTHORS)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@babel/parser@7.4.3","dist":{"shasum":"eb3ac80f64aa101c907d4ce5406360fe75b7895b","integrity":"sha512-gxpEUhTS1sGA63EGQGuA+WESPR/6tz6ng7tSHFCmaTJK/cGK8y37cBTspX+U2xCAue2IQVvF6Z0oigmjwD8YGQ==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.4.3.tgz","fileCount":7,"unpackedSize":375823,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJco749CRA9TVsSAnZWagAALJQP/33wpsZYUkYJVNNm5NTh\nm08MgT69tABFAZ/s9H19P3O8yXxxQgnr479QvehrN36JwLy+R4vG3HEUD9b6\n3YIu9/QqJnl+VI5oBHqAQim2JnhOK79cL2YFCuKhSkBD6FfhBE+LIuLUEE6x\ndcFGI2y+3XtPjiljcLUjVLu04WeFo4zURS2a0aT5hJdlWS8HFQHGIVl5z9V4\n3SyUoTcx00bFd7nEUma5/nQe9EfcwqmFQ4n1PNyrSlzHouImCbrKCRO+tgPY\nrK8nHa9If4ScDXWcR8BNjKSK+IPzeB8KswpEQ2C3nlXruFPYppY8i/z9v4hf\nLd993mf3LM9u1vEKNH+LCmcA2zW16Sqym09ArzlaytjZr3GP6bJpLzJ2IWO8\nQMilL2wyWTvVLOoWthCRxr09ariEsFbBj4eY4NVAycMXuvv0SYJez7/xYqdb\nGhNG+jzy0HYXE2WrdrC4u7IaPkjGEb52osiMhZD35R9H6DraMJfzbcLq1v8X\nnc2US5cX47S4G/CBeP81IZqVHKCMm/uoOwP6XNx8/Ml7l7saVRj9wazem5SR\nfolhbXTbAQ4d+qpuOlxjWzZ3c+/3+ygrMLAp2Qid2j746S0TBIp9EP+5YkZs\nA883NltM1QtuM1TAWimISCF/hmVkBFS147xJNAiSNtC7srq8QkLKrY0+XUuZ\nowM7\r\n=bBSx\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCwtT388CR3Pp+SQlWkR/2D1Br0fIBYtevZsIWzmQ8eiAIgEAWm9mnFTjUI6w+JMCpx5BWcbT93K4gBk25L9eTsht0="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.4.3_1554234940957_0.35272537733176534"},"_hasShrinkwrap":false},"7.4.4":{"name":"@babel/parser","version":"7.4.4","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"tag":"next"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.0.0","@babel/helper-fixtures":"^7.4.4","charcodes":"^0.2.0","unicode-12.0.0":"^0.7.9"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"2c88694388831b1e5b88e4bbed6781eb2be1edba","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"licenseText":"Copyright (C) 2012-2014 by various contributors (see AUTHORS)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@babel/parser@7.4.4","dist":{"shasum":"5977129431b8fe33471730d255ce8654ae1250b6","integrity":"sha512-5pCS4mOsL+ANsFZGdvNLybx4wtqAZJ0MJjMHxvzI3bvIsz6sQvzW8XX92EYIkiPtIvcfG3Aj+Ir5VNyjnZhP7w==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.4.4.tgz","fileCount":7,"unpackedSize":379555,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcw3IuCRA9TVsSAnZWagAAll8P/0CRtLLRwDa5tt8qGqBy\nZsW029gD6trEofLGXXtDfU5nsDukUGulcqUK23BgbtAVPpSVHZ8+Y/g3tnyT\nCq2AfliZT9LBfDK/dCBCgbNBIbBsZPk8d5Exwr9sXui9dRpUVU858dJ8uMlU\nOzoxPo65y++ifc+j4O4Rgf/+M0+9+KIiQGpUvxj9d1ws4Kedzh9OuqwUKZsn\nsZ6Gs4vyVxTM8OrdcLMD2ljGMe2TMTrBaiW/ih6r36nBdwF+On8eR3oY4QDN\nVf1SokhuyKsthXjys7UYbczdgz1fgPQdEHrXiPw14DbW8w3stdOOjTGlV3do\nADVnAFUpNBPmPbDh/tzLpbGJbodgllmlAmzty3ym6KuMc6u5zC1pcdmXvIhs\n6PHTfseCOb2oBG6f8YhOUelPzsZfYknDguGxDAT9Ys9W+QEQrwk44ua3Zvgn\nMbGU9i82nmqTdPtFSO4Va/pINOyPFA8z02zJIwipCggY29Zo8RwBYqhbclRp\ndLVejJO2KDJouDnWneSAb3fL41b0yyGONEyMIUIBNvdOwE7/rJMaXkfhgIO7\nSQQbX8UtL/qo2ZjlY2uoVNecXOG2oSvjlp2Ld8rqQ0PvgilInCXcs95i6ZHS\nL9TP62/BMZKGj6Pjnikb1OxGGCbywk7SMYXYMJMz2jqYgwHGuwfQosfbTym6\nlS3p\r\n=pzWh\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFlDr/6gATmsIpcO0QGXxUb2wl5XlxvjhkFxUzqQ17TuAiEA6T1U+FucPVknNvnP/F1dlsfoXgHkWPQny27ClcjxcSA="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.4.4_1556312621496_0.28265716580501454"},"_hasShrinkwrap":false},"7.4.5":{"name":"@babel/parser","version":"7.4.5","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"tag":"next"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.0.0","@babel/helper-fixtures":"^7.4.4","charcodes":"^0.2.0","unicode-12.0.0":"^0.7.9"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"33ab4f166117e2380de3955a0842985f578b01b8","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"licenseText":"Copyright (C) 2012-2014 by various contributors (see AUTHORS)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@babel/parser@7.4.5","dist":{"shasum":"04af8d5d5a2b044a2a1bffacc1e5e6673544e872","integrity":"sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.4.5.tgz","fileCount":7,"unpackedSize":380255,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJc5DlBCRA9TVsSAnZWagAAVGoP/j8+GyjrybpUcRw9akKO\nwUxQElwFee/BZQxEGCo6L8HeAMM34QGltF0lLkU5a387vj/1jf8vkEZJj3dl\nbTyAxX/7+eS3lzeUD6LirNmNneVU0nUACgGzTpfGp/vPt+WMWKutsog6/WFA\nY1lh8lynwWwabOGfWUFgGUy2gIj5kpcmMW2bWRko2xlZqNy3wb1EdbwZRrEl\nWwFIO7drAZ9l75AD9lVDoKuLxduRZJmNPcma5UMhYojOjcXdikOVM3GSisGo\nVWZKKelmXxDnLH8sO8qdXrM7nEuYYLkLpR8iAKY3e6VTC71UJS0mh8NMN3gx\n2XkdxpGY1GHd8ZnSoaa8NoTzR7R03PKInl2We27XCQuPb/6i3Lvl6nY1RGxG\nN8AtkhWgqGW7B/uhm6X5V5nx8IWcOqk+t33VS63+Xajsavis3N51wjnR/dsv\nrHedpy0mDlO3EZ5Y2IceOU4BeNkUlnFctwihnVkigmTVlXHDdoJYBuU9sKZy\nwMY+iIUmSHJQuAPVOQnkXylRUczrunfr2xJndYHXOKW7/zYJWJgblO0vvKM5\nLcD8fO2YWHdXeHq4INwBv0Yq2ZqKSXWvyzY2QxV/S+lh2xoQIpIBRLNeYOf9\nE5vwbEZ2wDJgy7FJZfp+XY+OU/BASa64WsoOeS+nzT9XscXIGLHZup0N2pUV\nIU9z\r\n=kVVq\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIACwjfzb9aBCVbUP3U6GyJlmxpfbGOYYI5JyOF6b2LBdAiB6Wtw90rm/aqRTI6bZUEGdepgGXsNFz26NOVCoGsP1Ug=="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.4.5_1558460736488_0.4078919765603206"},"_hasShrinkwrap":false},"7.5.0":{"name":"@babel/parser","version":"7.5.0","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"tag":"next"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.0.0","@babel/helper-fixtures":"^7.4.4","charcodes":"^0.2.0","unicode-12.0.0":"^0.7.9"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"49da9a07c81156e997e60146eb001ea77b7044c4","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"_id":"@babel/parser@7.5.0","_nodeVersion":"12.6.0","_npmVersion":"lerna/3.14.0/node@v12.6.0+x64 (linux)","dist":{"integrity":"sha512-I5nW8AhGpOXGCCNYGc+p7ExQIBxRFnS2fd/d862bNOKvmoEPjYPcfIjsfdy0ujagYOIYPczKgD9l3FsgTkAzKA==","shasum":"3e0713dff89ad6ae37faec3b29dcfc5c979770b7","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.5.0.tgz","fileCount":7,"unpackedSize":381965,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdHffWCRA9TVsSAnZWagAA9jQP/06OdoTB2pMqBTLZ8zvg\nBq+6vDCqkG+GbleZGmKdPAE//ViAVISi6NKc9X2BG791pMsOmN/S7NhzmHlg\nfSOFqGZ/3LS/eDvsuLvdTnvGls8bC+hsaldlrN/dNB9I9z4A2hrW8R2Snqzr\nPePG7tfjH8FoEnoBWnj985LG7KmhlCNnIztJJdGlMwCS9hVMm1dTNMdrqZdJ\ny6MLhDWhIZHcSbbVgdwYhkPDSBgpsFWastKuChVOp7sMdVH7Fu6yGo7D80vT\npn1FtYc1m7g8h45sgnzDTJlMEucsSRS8YwTHdBTQVT9pZtzXoNCuHudOAcVO\nUowBrrxV5AKqTMXTHgTODjacheEHbln+zUsa8wdlfnEAlhrvqz3oAnF171Nm\nRcdqHdpZY0vJYvHRrVitepI86jpprbzO5AU1goGU0UVUSxU6cQ6vGEdQxWtS\n9J0hkfObIyShJf5mxbT5K/B3jvzYQc1pjohiNriCX4F5Mmr/ykpsev0nsRaz\n+83C1fip3+XQgMqsqPh+BmpU8rkRFrX9gM0TWxpAZMhTsQweilP5h/B7g3Oj\ny1CdUIIWgliycoz0IbLqR4LSlKrv+EBkSUlkBLO0nuGgjm+Kp2xeNLm2Q3bB\nvtpqnZBXVGvgAtv85HaV1MH24oWDfbrDfc1q1bfyoCFcnBrB24jybDLD/HFk\nIvdR\r\n=3QHN\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDwn7aLI2rxIIA0DKFu1grc3HE+0RSHXLW4wz1iJcGjaAiBRn8Qq/fYR4PXQ6B9zDTUt5gHuNFdR9qtD8XD0FvhwXg=="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.5.0_1562245077638_0.7584086349713239"},"_hasShrinkwrap":false},"7.5.5":{"name":"@babel/parser","version":"7.5.5","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"tag":"next"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.5.5","@babel/helper-fixtures":"^7.5.5","charcodes":"^0.2.0","unicode-12.0.0":"^0.7.9"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"0407f034f09381b95e9cabefbf6b176c76485a43","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"_id":"@babel/parser@7.5.5","_nodeVersion":"11.14.0","_npmVersion":"lerna/3.15.0/node@v11.14.0+x64 (linux)","dist":{"integrity":"sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g==","shasum":"02f077ac8817d3df4a832ef59de67565e71cca4b","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.5.5.tgz","fileCount":7,"unpackedSize":381965,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdL5FXCRA9TVsSAnZWagAAvF0P/1z5k4yexJtyJMWGULou\nmVC4HBAsjD4Az4v8B/EgpV9pE+3Oa0x3cklS2+wV0OKFK1Sad+GA1zhJCGAk\nkULfyA/MmPJEitBMjUg/rjxL+qJtohD3+xgmxDQemPecenKI0fM4v95W2ASg\nrbbu16FB8IIcEwtERoPytfPJeAPuvQg1GQJ599EE17R+SK1TJWYwlCZsJLU1\nzz8eL0RilPZvPT7NU1mrn+W1nfUBeZHRo70PZupTaCHLGijfg0/CZAv5Lp1Q\nTUtGV/MJMA9k+3mjXBukPgi1sg1y7p7jVTqX71+QnQAdCnGrS35wQKzHFqrX\nUL/4+MMqz09bhkiBwqkQja9j8psoHdpRIgzXASvr0W1uOa4gtlfEgQFkjDti\nMQTdH8V790ou8UKKK3OzyekStdICtqVu60QQAfW2OZX4pCJksEtKRamGLSpM\n2JxymjLxHgFBujCbURoyXMIaqC258bjZOgZ+MsHJS9RXPeu3j9SyM8SctrX/\n7u7CIBI+ImI8V2Y5qxBLm0uegrr3T6MlDwxVXrvLDzLAsX5lJDvUaloqAs8z\ncUQbw2mMqoRnRHZ5s2T1NByLwCCkVHdoqDpNlfLOiyVamGtcN1p2M4oOB3ll\nSFVS8c2poac9NiOdGnITa7zKMxpiC/N6Pt+VuYAxuNxjFcFGnl4xYPyZK5/7\n0NU4\r\n=4w4P\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGveRlEsQ9b/MTb1sTSEjB3dGocOi5w0ZfQIqkgXxkNtAiEA6tcnSxmtLQtBz45Xv3dOUMqxqugTA1+0jkqpWqPJvuU="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.5.5_1563398487324_0.9360975806380283"},"_hasShrinkwrap":false},"7.6.0":{"name":"@babel/parser","version":"7.6.0","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"tag":"next"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.5.5","@babel/helper-fixtures":"^7.6.0","charcodes":"^0.2.0","unicode-12.0.0":"^0.7.9"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"cbd5a26e57758e3f748174ff84aa570e8780e85d","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"_id":"@babel/parser@7.6.0","_nodeVersion":"11.14.0","_npmVersion":"lerna/3.16.4/node@v11.14.0+x64 (linux)","dist":{"integrity":"sha512-+o2q111WEx4srBs7L9eJmcwi655eD8sXniLqMB93TBK9GrNzGrxDWSjiqz2hLU0Ha8MTXFIP0yd9fNdP+m43ZQ==","shasum":"3e05d0647432a8326cb28d0de03895ae5a57f39b","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.6.0.tgz","fileCount":7,"unpackedSize":384395,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdcph5CRA9TVsSAnZWagAATBsP/2gAMDrvojmv3pidLFGA\n/D7Q9jVU5UD+N8vwR2OJyqT7Ojnha6fhRZQ1NS/UGBMH5DpQH/7cppWA3SUd\nPY32sZQAhyd54Pt+rVO4MBblnmtA0Jk+dYKEAYktdkYaB3e13Iy/Vr3IagfQ\nuqH8MkGWbXg5Gf+pmR0ZtSlqFu2zAbJgWYrg4nX0fQr7jW424RSfgOgnYeDL\nb7gC4hMweOuOqDmLn0em3tj1R/9yVNkCrOSIgo9nfOsNzRB9UHadsht4kVcD\nDxvJgdUar21w0M4qXnmwFcPI1YMb3O2sOByC/KdpuqITLDa9PFG5DoDTLSjD\nnT8c3LXvmEkkFyaJOdfhNrz7eXsdIXzCfBUnsR3rI0ZYIo45OIW31dhp83RO\nWCveTbwjioOr7HOcBOvlXA0sF68/I2X/05rSx6+KxeBVDyg/SblmHz8fDhzq\nWXpila1Q1IA7BGyFjicrX+qT9Gh9AIPwlOAQ0jty8BoDVBoYlJOIyww+Ed/w\nndMjQ/3afce8wYaGf0qoNWKSw08/ydSFiP7+8nb2/O/6yg4niRGW881ZOfws\nRCNTPomZyGDRm6NFlBVi3MQQH/A1eqzav/N6EqA5+0WAq4MxJoZrA+T5/rPo\nMHBQu/4E0s2SdQufXFzA3D0NJO2uBXTBisWRe+HmhzGxwZbsLqjl/f3RmAr6\nzJkQ\r\n=RiQl\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBjFEdnicZ7H/SF0WxJ8/HuFnGH6upwe0nzZU3a/Ae5CAiATT0vPGiKbUabu15OlbTJWAy7MjujBxnE/6olKfR5Zag=="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.6.0_1567791224435_0.8197941062561318"},"_hasShrinkwrap":false},"7.6.2":{"name":"@babel/parser","version":"7.6.2","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"tag":"next"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.5.5","@babel/helper-fixtures":"^7.6.2","charcodes":"^0.2.0","unicode-12.0.0":"^0.7.9"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"b9cb4af953afb1a5aeed9b18526192ab15bb45c1","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"readme":"# @babel/parser\n\n> A JavaScript parser\n\nSee our website [@babel/parser](https://babeljs.io/docs/en/next/babel-parser.html) for more information or the [issues](https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen) associated with this package.\n\n## Install\n\nUsing npm:\n\n```sh\nnpm install --save-dev @babel/parser\n```\n\nor using yarn:\n\n```sh\nyarn add @babel/parser --dev\n```\n","readmeFilename":"README.md","_id":"@babel/parser@7.6.2","_nodeVersion":"11.14.0","_npmVersion":"lerna/3.16.4/node@v11.14.0+x64 (linux)","dist":{"integrity":"sha512-mdFqWrSPCmikBoaBYMuBulzTIKuXVPtEISFbRRVNwMWpCms/hmE2kRq0bblUHaNRKrjRlmVbx1sDHmjmRgD2Xg==","shasum":"205e9c95e16ba3b8b96090677a67c9d6075b70a1","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.6.2.tgz","fileCount":7,"unpackedSize":385617,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdiTdmCRA9TVsSAnZWagAA+eoP/1TrYrQRQ65M1nmPOrjK\nVDs0baY2K2/whw+eqNrz02YNuZ+siFSWV4gfuo+2x3lnEuupCF9pOf9BR1q0\nncRM87r0kdH9T3MrfnSmfwqGXp6cXzVdeNJvaqZxadaoZ165gye/FpDFlboO\nbScQmuG1pUSwUG4ga0gWSZ+VOdhuoY2xOij5y4deO/kmkw0fHK36TzPewaqa\nX60SornVRYeNsz/h2egWDDCpb5i5irzN48Pb/9nTNhLU2x9Z88v8Sp4eOwuG\n+DAKXFChemMOMP3XkU1GzuxwX69WS5H8s5fcT1inzB7b1OvN27YGdeAM0QYK\nzAy/TrnjcAo+2HOPkqZ3dlNbMVFMshiHzaV5FgrpmhZOXt7Oi6KmsyIFbSRS\nN9VLCfYlakkHYBp3R1cUrm9tVRWOb4fJGazAZCEqCkDTf4t6erKuDy+MhqYK\nxnuYb/3gYQeY3gKWjUjVDRVKsKZK87FbMHCCMX+KX0DiLtP/wpG4CorahVfs\nsm2M/+lEKgmIyBHl7sGldOmwI68DIb298jjzO/kxPgb9cIM+lXM7wmD9/HV/\nnaDXW8bkb3il0U+2rZREcofUe2BOK7GiTcq0sp8QTfhCC0q0qyqNnliYwPKV\nlAjA5QkBPBuZKeYIxHT7sCt5Ah5J6SdPyipX/j1rA4CzVUaevja/Bknb7csC\neuZn\r\n=clRS\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDOo44rvRI8qU5G+fkmI9M94sf0GQwyqw9HH4ke7xMcsAIhAOE7hHK1WJh+XHtmJETwRvbJEp4mNQeRLLMRvvGSdPUS"}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.6.2_1569273702098_0.21253110154096833"},"_hasShrinkwrap":false},"7.6.3":{"name":"@babel/parser","version":"7.6.3","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.5.5","@babel/helper-fixtures":"^7.6.3","charcodes":"^0.2.0","unicode-12.0.0":"^0.7.9"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"d329156ebc17da01382acb83e212cb4328534ebc","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"_id":"@babel/parser@7.6.3","_nodeVersion":"11.14.0","_npmVersion":"lerna/3.16.4/node@v11.14.0+x64 (linux)","dist":{"integrity":"sha512-sUZdXlva1dt2Vw2RqbMkmfoImubO0D0gaCrNngV6Hi0DA4x3o4mlrq0tbfY0dZEUIccH8I6wQ4qgEtwcpOR6Qg==","shasum":"9eff8b9c3eeae16a74d8d4ff30da2bd0d6f0487e","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.6.3.tgz","fileCount":7,"unpackedSize":386992,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdnOhTCRA9TVsSAnZWagAAWQ8QAKG5aphIsZbW4sek0dof\nctdMeOIgFw2wnCGPlorvGkHbJoFWntged/oHpdkYyak5TdL/2pWwwbvVWVKP\nRO6U4yqSDovB5VDDzOSO1Y9kGaZwYYxf8GZSc60qvFjeAyBgvH+hgFRutofk\n6zwCJ/c+Qq+b1bHN9hysBAn+UEjE3K56RWewPjk6d9FBoOZeYRRc8KSUp3PA\nFbRM4RG0rB2RgiI0Ywh0OKI6rdR40CQolRfqEIXn3PWOLUuKHS75rnQ8mKcG\n+13aO3zk16jbkkLPKwM+YLq3fAe6Rmi3LoUWmSsDn5ng/HSgI/kbMK0mACQa\nSLDFnhbO6/56kUlnIKz2zMQ3uhdeOIT+DdOJM5seZyhXOY9nY++XSPL8dLKO\nBuWmU0d/r4KRHHqla130XEnAkm22aDrOfwQwSd6HTyK5ESJwAddAgCpcskI1\nnSeI/pJLC4Xkq9XhgUroZy8WxcfR9cnXVUGgIpX6SdJxGJnzf9WGYOXECDDc\nBUNU0gmWYZpHtUmAh/HAoGS+2/CEJNxDkwWt3aeLiPgQcGLKl4Kby0TV/xAm\ncKWIl+BJ0xapKPBdPmxK6PHmRVRpJW0GWYZLDjwKqcQPstWlTX/Mvo1t+tR0\n8qcrj59J9BWsHj9SMwcFBUHeXJDdAiGvpWfnlyE5wf2w+n++mumz5o+v9lw2\nDMVj\r\n=dNVM\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCD/M6Ej0Hec37gdQgaFAonlPQY9ACmqdltAqj6XH0LbwIhALemru3Rxlmd0REOeS4Lu2zXQflM8Qfz3810EhdjCzhG"}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.6.3_1570564172112_0.07908607724101291"},"_hasShrinkwrap":false},"7.6.4":{"name":"@babel/parser","version":"7.6.4","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.5.5","@babel/helper-fixtures":"^7.6.3","charcodes":"^0.2.0","unicode-12.0.0":"^0.7.9"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"a422ea64ee2208a55dda33f990a422e14b917f5b","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"_id":"@babel/parser@7.6.4","_nodeVersion":"11.14.0","_npmVersion":"lerna/3.16.4/node@v11.14.0+x64 (linux)","dist":{"integrity":"sha512-D8RHPW5qd0Vbyo3qb+YjO5nvUVRTXFLQ/FsDxJU2Nqz4uB5EnUN0ZQSEYpvTIbRuttig1XbHWU5oMeQwQSAA+A==","shasum":"cb9b36a7482110282d5cb6dd424ec9262b473d81","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.6.4.tgz","fileCount":7,"unpackedSize":388020,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdn0A9CRA9TVsSAnZWagAA5eAP/0pLhki/oAnydZPnDk6p\nYOcuCNlgJNqt5GPhXBfEvx9xaT4TpY6obvplPAiuMGxQyRNjx/ZEAI97v0nO\nlG/h0ER1v0o0C1qorZEu/5RwUls3vwDcVaVVMie3lL9sqW8OeArY1plgvFXp\nZIl2lvp/uPRoFUFLO4DskPyaUHb6gTOaL2xCAnTmnBh0MB6uCBIFDwg3m8yi\n1DsY+aUGlht9S6ewrzcp9SkO5E0BOnR7so/NuPwELssZlg1oKLMKEzeo2SFa\n32CGOGPDU1d7lJj1HTACzJnjdYrEZdGiemxzPWwTK5OhZqIWXj2juk3wO1yh\nllXd3f8YDNMPLhApPhQWCiyLC220qXmmQbasY79xnE6nUXHuV2w67ua9UnVB\njd+KdC/x7eFClavt6e5oxcdrEKaLjhXd9XrZweM9jUHJoJlM0Pi8W58e2Bsp\nUd0HnBWomJH2kjRiU8gvgqVRraRRlEbiSmsoG1ZDjPFnnXxGxrNnEpYY3tCB\noVpiDRfskTTmardgnAQDEEJny5Fm73R97HagRkypU8dISuRCdoWMB9PtBkS2\n+JNvVhZw6pbG+us70zkmYf1FE7vGg2dzld4YRWy1uarcJHWck1ZrrFMDhpYY\nayiM74n9FxOD1jEXwPD7TeXdOVPU8sy5e+8dNCm5zGJvqwmUjQ/GKFa3z51f\nf95o\r\n=ZAvh\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIC6v2yY0UtVNYv68WJPpE1cAgc19q6RpiuUQnJE+iRLeAiEA1QTfqoHBjT7RsDhInxBYgljftSVQPxyd1Qxs21A818A="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.6.4_1570717756377_0.27279107385465706"},"_hasShrinkwrap":false},"7.7.0":{"name":"@babel/parser","version":"7.7.0","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.5.5","@babel/helper-fixtures":"^7.6.3","charcodes":"^0.2.0","unicode-12.0.0":"^0.7.9"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"97faa83953cb87e332554fa559a4956d202343ea","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"_id":"@babel/parser@7.7.0","_nodeVersion":"13.0.1","_npmVersion":"lerna/3.16.4/node@v13.0.1+x64 (linux)","dist":{"integrity":"sha512-GqL+Z0d7B7ADlQBMXlJgvXEbtt5qlqd1YQ5fr12hTSfh7O/vgrEIvJxU2e7aSVrEUn75zTZ6Nd0s8tthrlZnrQ==","shasum":"232618f6e8947bc54b407fa1f1c91a22758e7159","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.7.0.tgz","fileCount":7,"unpackedSize":407523,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdwVSYCRA9TVsSAnZWagAA9hYP/3y2hE6FkhSshERMJLKR\nwEPGcXzmm1EgOMFAZZvRLpCSvnCeXZRTuYo8l+L/SNA9hay5lgWSc64+4MmM\n+172v8nA+UM+GW9d6mHqIdXOmFljYlN6wnoMdLBu7jjojWCIle0oNxiNNrVt\n8PkZ6/bhP4KQyjf+Z7kabwWwuedp8+Ol66usy5fsFu36HhPcIYhSpJUaMr3V\nJCBUG/JtUB9TZLdb+ETamw2KRgjnhjFnkZ7biWkDbccF3t+o2LeJ/Pkz7w03\niLHHdNAskjJ8IwjpYZ76SBPjPic3Dtzgv9Xo3e+ZcKNpTNNsyo3HQ4NIhm7T\nGmwqSWAaKYZMfMPEY1pkdrDpEqMA8m+VXREniGAr4vuCzKg/yG+ddZj7vhsQ\nu0dHTSmg5ItczX6tkQxEwqBjnmYlqR1i6vzHsfpkmesUXKZk9cVLnDPhSo6c\nWiCOeJsUC7bs39WYnhrsspSkCtiSe1Vdkkz1aLsvniz96qZVgdoQO6GYPPUy\n28O4tC+BwV+8Ha+ZCcpVu0zkYAjLEH6Qo9vnZTF8mXfkm+Mh+WnGDYZB22YT\nMu4CwxJ2NTRwLbXelnk1WAZU+KhW+y30fKrD/GsPu43Wp1Vxe0rlx/cWjn5+\nHh0RWFfvZsxvgLcyVZkWUlpJ/Q/H5Pa+UIq/3MuHJDTGm3c9Yd7DoNLklMO9\nyCy7\r\n=UIFL\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDbZQWHOtdbs4juJafO85FbefQE+S5GMZje8P6wGO+CJgIhAML6m7cxKM9G+fIs8h9xTdIAldeJIIr1+JMl6enMZtIj"}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.7.0_1572951191879_0.9227319478564149"},"_hasShrinkwrap":false},"7.7.2":{"name":"@babel/parser","version":"7.7.2","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.5.5","@babel/helper-fixtures":"^7.6.3","charcodes":"^0.2.0","unicode-12.0.0":"^0.7.9"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"35f4d1276310bac6fede4a6f86a5c76f951e179e","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"_id":"@babel/parser@7.7.2","_nodeVersion":"13.0.1","_npmVersion":"lerna/3.16.4/node@v13.0.1+x64 (linux)","dist":{"integrity":"sha512-DDaR5e0g4ZTb9aP7cpSZLkACEBdoLGwJDWgHtBhrGX7Q1RjhdoMOfexICj5cqTAtpowjGQWfcvfnQG7G2kAB5w==","shasum":"ea8334dc77416bfd9473eb470fd00d8245b3943b","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.7.2.tgz","fileCount":7,"unpackedSize":407556,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdw1bdCRA9TVsSAnZWagAAnF8P/2hc5XrCQmgogAdTr4jY\nzThYg7Y+jLvAv/iow9jo/6INmjSLbDAmXmTZzVkAEKfI2LX4iPfrLdOFy0U9\noP5zYItf7i09RAdz7OwhINiL4lAF4IwplzkqgM9B9UbMMhJo9rgkbKEn4qIS\nT1lMQeuqVCGHRcDkOg+59Ye13ET8LHIavEbogBtjT78FVgVkVYwfwrVCIoGs\ncxPi/0q5r4OfpZdqC8gZKfIwZnAXT/66Mg9TTwh/oydIVsPoTVECNWsRA4LF\nJuijfhKjc7OS6zNXBAVJzsAuqJGkJXL9TltMT95yyIr2gi1lT8OdVvshOn6I\n1pbapwt+9pPRiOsSGX/QY1AubPnDYIRLxQqHg626Gne7GkA9DkG8BjK/Weu4\n1+9oNPTLiqf7H00PjQDCZ9mq09rHgMUR1YT++2pcxDToBVZ8TI1S6y29/l4D\nlSrmCMICbyHQgkmpVVsgRgBOHq0y2qstk3qcctIG/RnEYpBQs8c9dxLyxkbe\nXArVt6AHEGirZF72Mf3pVw9m+6llwL5yZQU0n6pvcewBQbvHWP6beJ/qGUgy\n9U2U5AKVTA2IJZF+ycAOtrKU1YP8gRQ7j95xrGEUIMiGnkR1wO+4hZPBgzwV\nXzZAwfmEiZQLrZd4X4vsanfrzGfQW+9BmUtM3Pq3ETD0W6n8YN4vZky1NePI\nz2VD\r\n=Fzso\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFDD95NEx+WY18CQnWGG2d1E3OP6fS0Ivn45N2NDQsXmAiBdn/Y5OYvT70BsYgsTa6rsG3HRr6HsoTrBOalLxEXnww=="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.7.2_1573082842933_0.564848942031748"},"_hasShrinkwrap":false},"7.7.3":{"name":"@babel/parser","version":"7.7.3","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.5.5","@babel/helper-fixtures":"^7.6.3","charcodes":"^0.2.0","unicode-12.0.0":"^0.7.9"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"e315d65a7a8cedbe0476b4a2872890e93a1289ba","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"_id":"@babel/parser@7.7.3","_nodeVersion":"13.0.1","_npmVersion":"lerna/3.16.4/node@v13.0.1+x64 (linux)","dist":{"integrity":"sha512-bqv+iCo9i+uLVbI0ILzKkvMorqxouI+GbV13ivcARXn9NNEabi2IEz912IgNpT/60BNXac5dgcfjb94NjsF33A==","shasum":"5fad457c2529de476a248f75b0f090b3060af043","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.7.3.tgz","fileCount":7,"unpackedSize":407486,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdxdUWCRA9TVsSAnZWagAAd2MQAIFKoytL5qCIbiCw6dyF\ndbJ2oj2+TxptJx5zgh0L0fz6ZtEqqLmQKc/EdhFZy/Nn2qMIsh/lWQ68qOSv\nD3bS+KDSM6aay3sN5YWSY8KZYUvmupDe7ECtWnedpk5zRC7IKxlTOzmOaar0\ntIat3c6ldFXGS2ZajsLA6OSa+wsjvGSNFdbhTRxfROovYAqq4anSy6wjnn24\n5WQPEgWKigGjgNIsf0rIrad9nGvlAwMnq2y0TX16Sc9JhHQYe1HouuEVg8Pb\nq+cMi3VTM03LFsySldB10uj7JIvUoVZ4GrTBkGn21MW2Jyz5t81QYKpNrCvo\nCyxckrOa7H/TcrhHHsAGYf03hrGgkh+FIyE40tVPUhohtezGDMMU+S42gQWH\ntqdNTzOf0yL5ZrKJ2EI6bUsGVaor3Kz0BYUu2NGBnemD0wiEo0a8003LAcI5\n7uuuxR9W0ZEuunHB0WyQeXRgXIbzbyC8xo4NeP02cUx00eCkVojfTsGdMPya\nNnuVeAlcRUtG/DkSTQQRxKzSRYqQUbt41x/F/Ga8aqSHUfu0fnoGQ2ScGqcv\n//3XCnw6NJmTvWanxmYoB+1OgV8KweX67r+ULsAwG55fjSD/VUbyXxCRiDqw\nMCjVW/t3Yj6uFJBxs50eQkUWV8+vacsAphCKLSQE3T20GQXCW7u55UME00uQ\nOJFw\r\n=5F3V\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCBUI4scVC2gAAQ7Fl5fv+v3Uo9TrEaeYvo7x3qtjSZDAIhAKuHt6uzIGFIaTWpa4Hjo2/vZneYJAIaD+7kCOoeWpix"}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"jason@developit.ca","name":"developit"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.7.3_1573246230388_0.03600726500871909"},"_hasShrinkwrap":false},"7.7.4":{"name":"@babel/parser","version":"7.7.4","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.5.5","@babel/helper-fixtures":"^7.6.3","charcodes":"^0.2.0","unicode-12.0.0":"^0.7.9"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"75767d87cb147709b9bd9b99bf44daa6688874a9","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"_id":"@babel/parser@7.7.4","_nodeVersion":"13.1.0","_npmVersion":"lerna/3.19.0/node@v13.1.0+x64 (linux)","dist":{"integrity":"sha512-jIwvLO0zCL+O/LmEJQjWA75MQTWwx3c3u2JOTDK5D3/9egrWRRA0/0hk9XXywYnXZVVpzrBYeIQTmhwUaePI9g==","shasum":"75ab2d7110c2cf2fa949959afb05fa346d2231bb","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.7.4.tgz","fileCount":7,"unpackedSize":408851,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd2G/jCRA9TVsSAnZWagAAs6IQAKQ+4WcsP1B+mQW67heb\nnZVanZrXLKotNXYmFVjnpH7hVXE8/+PZ77TsqPhlBG+9p9Y/OjBw7eX8vM4u\njVHZC9xElrP3l4H+OxoyLSsqAsyrrSAN0W3l0q3FqY9bJ5tLlmzQmsQRjxKQ\ngjpGm6taKJACb0BMIUvIpt8RrfY57SmIsJ9w2HmUdWRLt726el+FNBl/5EjP\np2eUzPvRU3NMc0MkbwIZUDBHC4Jo77/C7lWSZuA5WuuI20TffEY8NHCAMW4L\n5ofLuUwyrNW3teq7AhgEal7bleeNecAZhLbtqrYinf68odt1+hil5UKvfMnV\nhQJCi6A5ms2aopBg8HBwNFNp2r/U/BjkLCYDtbTZA4dwJJxx32NmtX7gSO3n\nPSBn+2f24BEWc4iB2ThDbao032gy4q012ErYuldBKl2d9Mm3on4vgrn+/r3s\nlfagxNJB74KdV7b8UDtsYXq/fxFtxZBW+SdtcVM2kRBN9eoDtHGMDuyJkhUl\n7t2Fe0yqK1yWJAyeMnJRZJiVwpqSIQ9w+HCWHwoly8xxd8P9l52J8Tx3Sk3k\n2DV8VaUwBUbrMzfhL0nWCCzfs0D40KM6/OsmDFGIRaiYDkTLkYy+eSmYThcS\nQHGrH7RYT8+j4PJ/KGHJ291TOmRn6Lv/HuX1u6h34TXVoT7OxKILdzyN7Jpf\nrOWH\r\n=8MXl\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIASD0cdZGYSmcn2QYoRDhDLMV+ffw9rWiqLZUeZk9D5nAiEA3yDxZAPzFDAFzU9VLBz9q2dMb5gA9GwTf3w4LLzCPgE="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"jason@developit.ca","name":"developit"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.7.4_1574465507141_0.5893449388452949"},"_hasShrinkwrap":false},"7.7.5":{"name":"@babel/parser","version":"7.7.5","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.5.5","@babel/helper-fixtures":"^7.6.3","charcodes":"^0.2.0","unicode-12.0.0":"^0.7.9"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"d04508e510abc624b3e423ff334eff47f297502a","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"_id":"@babel/parser@7.7.5","_nodeVersion":"13.3.0","_npmVersion":"lerna/3.19.0/node@v13.3.0+x64 (linux)","dist":{"integrity":"sha512-KNlOe9+/nk4i29g0VXgl8PEXIRms5xKLJeuZ6UptN0fHv+jDiriG+y94X6qAgWTR0h3KaoM1wK5G5h7MHFRSig==","shasum":"cbf45321619ac12d83363fcf9c94bb67fa646d71","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.7.5.tgz","fileCount":37,"unpackedSize":1700219,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd6lT+CRA9TVsSAnZWagAA5lwP/1dsOUjcSywtC1KiksqP\n3k3QptFAc7js2odHYXwaoBEWuRAtvE65DJCWYRCytX4NuiqStAMdpw/foqWC\ng1blIoVnV7lyqV8Wosf7ZPJCuyIUrzrgTd2g/MvR3zQEPGKZqzKpGPE9sXpu\nV0Dx3A83WF7k4yZ8hbG4DXaa/OLZkPhYb1BFFpHts9RNsOb1ws3qDNDekD6W\n6/0B9g7L++i5PSi9g6402ZzbEbCBkpRrJAmKY9iXFLFEgwclZHIWQ69Xyxbn\nV+qoRn03GKhPa4u5kRwte8WhocXRy6mobTOMtYV4+TfiWU2UgAz7N0+Wvqs9\nYXFpy4Dz3P5VI1w3O0XbhF95XQvm4zRQmuhJNh3rx6rhDv/47ad7PiWPTL8a\nlheXK3Ha7AsCeZXJeJqGi5NoQqGbXRrsf5WGQUU2m4F81TBAVg/2t2RPr8EX\nVrTNj4OETiWH6vY6u7ySfvSxt3aUkkTfuxtXnF+a7d4wx38nELNNj7vwyzbN\nGiWV+lIjTg8teflvDxbaSptQEXKGobkU++bRoEYOe0nkGxL8WO/N8ABoUxh3\nT1EAPfLaZIOYHor7C7/0pUwBZ9eIxSmUl5675XlAEmQZ9pXTSfUoBU1OMOdt\nGuW3pdT2B04LfFR/rcycqN1/prixUNtXtXDPnRXx7iMbMorQNenSELjYmBsC\nFCXS\r\n=PHXg\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCs3Stj+fGyX6W+tGjXfclQgMj6mUutao3gGUMjIoOfcAIgd/H3EHE8vIoXzxbkeKczDDVK23Gmi7fM9+SrKU5s6SM="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"jason@developit.ca","name":"developit"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.7.5_1575638269853_0.6792494162220146"},"_hasShrinkwrap":false},"7.7.7":{"name":"@babel/parser","version":"7.7.7","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.5.5","@babel/helper-fixtures":"^7.6.3","charcodes":"^0.2.0","unicode-12.0.0":"^0.7.9"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"12da0941c898987ae30045a9da90ed5bf58ecaf9","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"_id":"@babel/parser@7.7.7","_nodeVersion":"13.4.0","_npmVersion":"lerna/3.19.0/node@v13.4.0+x64 (linux)","dist":{"integrity":"sha512-WtTZMZAZLbeymhkd/sEaPD8IQyGAhmuTuvTzLiCFM7iXiVdY0gc0IaI+cW0fh1BnSMbJSzXX6/fHllgHKwHhXw==","shasum":"1b886595419cf92d811316d5b715a53ff38b4937","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.7.7.tgz","fileCount":37,"unpackedSize":1703156,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd+sn2CRA9TVsSAnZWagAAjZoP/i6BR8jehKZo45lFdLdX\nri6fGyNAJ3g0+JTgJTaXoUgax2KmJJuW1OMfZjvVjMNEBt398fpZunLZjHVY\nFsnCT7Gf77V8qa2qLpUcBk4P46ZLbWAxf/yw3yKi0klOvQ7YQ9zPD39Pv2b9\n3ZDQg34fQ0aUNiMAPs/RZk2SCYVhr99aN2cl4pKr13xmPKGDherLcJQCKxD4\nTV0C85NNnpNhYJllA1jSKJdxeFaX6/+uWOlbR34JTjUl9RIg+OQEorJT6xfC\nmBPmWSwH+N1m9aLyzzhD8W45vtE9mCE9SeYckzEG8km+Atcx8B3SqB5VJLHb\nJubY1AeZO/NuETXLikok9dDxcLn9W32DqPWQCU3Jz/1Wv7K3tjxJScCnDg0B\npPN5Irf3DUYUZ0Nxq56cTMG2/x+52gG02g7PA6z485BpktPhbJBmGFQdCK8u\ne4IgBNoHJA5S2zuhJ1UlL2VaXgUoUKB8C93Kx2Cb/KdwaNAcewGq7yaP/aQh\npcfu4Jcb/JPc9RkNsaY0q4iirtrQr2EXYSdkvuhIcTsFVP4ezSLey+BidrlR\nWguU5GL50etjeDkBv6K1tQYa2uakDuWvFHOvgo2FbR08WE/13Id8Obe+WYel\nlt3OULKgc7ggoyUWBeAcdJZMVHWbAKvstp0sAFDj6hSKXBd1UiHINQzt7iEJ\n90ps\r\n=1mcD\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCyKqwcnnT/o0j1ZBuxlVuUm3bcQyyMUlBAYiRm/Uf2qgIhAL2PosgNAWsA4gN2kuxXJ3aH1vx6GqwHiGaysWIVUI/m"}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"jason@developit.ca","name":"developit"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.7.7_1576716790074_0.7631632058736537"},"_hasShrinkwrap":false},"7.8.0":{"name":"@babel/parser","version":"7.8.0","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","type":"commonjs","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.8.0","@babel/helper-fixtures":"^7.8.0","charcodes":"^0.2.0","unicode-12.0.0":"^0.7.9"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"2486615a74580283c49475d66067bd7fcab3330e","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"_id":"@babel/parser@7.8.0","_nodeVersion":"13.6.0","_npmVersion":"lerna/3.19.0/node@v13.6.0+x64 (linux)","dist":{"integrity":"sha512-VVtsnUYbd1+2A2vOVhm4P2qNXQE8L/W859GpUHfUcdhX8d3pEKThZuIr6fztocWx9HbK+00/CR0tXnhAggJ4CA==","shasum":"54682775f1fb25dd29a93a02315aab29a6a292bb","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.8.0.tgz","fileCount":38,"unpackedSize":1714814,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeGmVDCRA9TVsSAnZWagAACDIP/17UKltrFxgVe/fN7peX\nTohEQ/bmoQeerceo4o14HeRz6ckKFd4jsYo9+WucGz4xJSFKheXperPt/xgL\ntor9r45wPqdAuMlOs/bnERM8lOclzDaTe7xUHgOLG537jdlfIhURhR8AmXBl\n5/VJ890L9dSKIqe/yH7r/y1K64jtwNOWUUig4DTL8oWXiMJD+mJltsLO2na9\nGaqyb4jlrZk7vPv1QkHz0i1SU6IXEwhOSQ6rBjXMWGzwJkpWZDakQlAnJ2gU\nrlaLaji/DvSZzMaqEUShi7Cyb9FMgqhPLH+5n4o6iKv2EaT7ZU4GU8Mq5SKY\nty3/utk0G8fde7vc5U40EvvmyIw4eRFYuOer1PT1yCXivkTem8cifN3Kua2f\n/mGxdkLHhx8KYATm9NG1VKyeOk4NKW3zgBAVJuU9pTZfply6g9I9A2piBkhg\nbll8wUrxLG/roG/I2HIaDMYHMS1O+m+kDAx8N1oMwiP5D8eOYakIx9GURtkS\n4Qd/np0OrVVgr0KzTrUD2NdFM53bJFhp8Pw2op4PUigJpS636d53GsodRvFY\nSdS0eQ+Q5/uk7ZggvW336mylnmTJEL/8REMgvXuAcG9az0DCPiUVzDi07lzw\nHsFvit0N/clbVh1nfndjHVM99Bc2kV+WGKaAxGFY99aa/9pIBPjTiAWeVdEu\n5NVw\r\n=SYn7\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICT9sdEdbU4gvKBQyz57kCJw0rfI4Dx3kd+V2O+JBtgPAiBCQRLZh07JDUajGx4rfJZ4PLhk0UPEx4LER1+woqqhUw=="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"jason@developit.ca","name":"developit"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.8.0_1578788163161_0.3515771185773513"},"_hasShrinkwrap":false},"7.8.3":{"name":"@babel/parser","version":"7.8.3","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.8.3","@babel/helper-fixtures":"^7.8.3","charcodes":"^0.2.0","unicode-12.0.0":"^0.7.9"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"a7620bd266ae1345975767bbc7abf09034437017","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"_id":"@babel/parser@7.8.3","_nodeVersion":"13.6.0","_npmVersion":"lerna/3.19.0/node@v13.6.0+x64 (linux)","dist":{"integrity":"sha512-/V72F4Yp/qmHaTALizEm9Gf2eQHV3QyTL3K0cNfijwnMnb1L+LDlAubb/ZnSdGAVzVSWakujHYs1I26x66sMeQ==","shasum":"790874091d2001c9be6ec426c2eed47bc7679081","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.8.3.tgz","fileCount":38,"unpackedSize":1714792,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeHOPyCRA9TVsSAnZWagAAO6QP/3WBXfyPAl5UaTogg1X3\nt+dOvMoUsea2kA62eqEaQx29rT1PiZes7Uz/P/fSxaKZj0apv5Ren7MquEYr\nuNyiFK1zpC13Bdfv2OB/UVolFs9/A421FicCRrQoSocTZTd99QCEHtUFSfJq\nW5dyoL/jifARKmnqx51UgOWSBrgBG78lSxhv0GNBeeQzfaroQQfebKecd9cK\nvmkE/EKtpIv0Nf/9f4bgjYsZFt4hi+z2eIihvrAM6ulpaAcvNok/g0uTSg2c\n3S9uG35AQwdGt0CdsGS4iuv0dg446zHTtyV7BMfVGi2Qz2LMiIZlKzanLyzY\nYal4F0owxxIdQiclTzv5qOBEq2YbPfBmjqRNC6kbYH7jqlksZeil7uncOfqR\npXrzu6Yd4Z2h7UMvqzSSCUfhMg2+T0jUyOArCYEErT7fmN6W2vj1nmyIo3Fo\nbjI2UZr4ZFxV/5p8uRmKpvTsUnZVmyS31ZRcXWByKeSZzH0LDlTrDqkZ07qy\nMfKiw0Spc7kw8KN3HrwBeryYCdvy3d0YQ2AGB7LXpKgQA3M4tchqYyLgzpBO\nGKpD17XLvJIjkXKV5cjfQM+JHQF1u5j0azqo7sm3rJJbFyI61x54uelcR5Bw\ngK173vdBPXlWBjXYKAPYLyd8xRkvYJkFz75iY23jdDuaXEy2cMNtSlI4k2fm\nuIdk\r\n=lDCU\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC6/LQLx/kyfS5H+lNnmIX7eEDGFDWHTt9kmnp/cT7esQIgV8vCvn/AE+Rp5eavSAxeSw6rE7Ia//iVbhvk0rs3OIU="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"jason@developit.ca","name":"developit"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.8.3_1578951665726_0.2609691682234143"},"_hasShrinkwrap":false},"7.8.4":{"name":"@babel/parser","version":"7.8.4","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.8.3","@babel/helper-fixtures":"^7.8.3","charcodes":"^0.2.0","unicode-12.0.0":"^0.7.9"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"5c2e6bc07fed3d28801d93168622c99ae622653a","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"_id":"@babel/parser@7.8.4","_nodeVersion":"13.7.0","_npmVersion":"lerna/3.19.0/node@v13.7.0+x64 (linux)","dist":{"integrity":"sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==","shasum":"d1dbe64691d60358a974295fa53da074dd2ce8e8","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.8.4.tgz","fileCount":38,"unpackedSize":1715052,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeMs4GCRA9TVsSAnZWagAAIuEP+QANn3lN+20RKkJC9kCh\negRqlLKWX1lmuy1RzSpvjYrSV4VjO++APQF94PJS0Vag74kGGAmDFY8YVZAy\nGrvQW1MhDlpdRqcutHiS5G329jITKQxqE/HBdEPKiQKbK/dF+7qNaCh9fej8\nj1gcbwb5cPegxlZGPlAOYz0xUQ1lTCvRLEmvYJKvKJdaOFzZ5kkWMixKvRAA\n6IaBWP79x08r2Kxde7Vg2oPU+EN3YI501ZsBliUYfi5MdjpaJhjyL5DNtqjh\nLEs4NbFkd2hGDlt9S/u4MXOGk6k9Kc2CrF4vnPa8TmDC7huGCJ3zYBpu+5wy\nWgLe1d54pJkjEk41kkyQZEEbUjjAWSfkVGHe/zRbitUh1yhjSS/cfXDny70d\nn8cnYZsvLFULr5qMUv4VKZmJyBJxo/YhmHzpJJobi7WnjqNRBUh6s9y+8b7M\n/O9NeDK8z5RQNAYaAddeRFglkA+YBsSjqQILDc/zgT2XtPKll3iQoDA7x4bC\n2zlK+el+F9y7sKEUrIt0qVnG6PqdehB+1yfulJqKbItPNFDuojFaKyLQeZHx\nmhOJ1avhOfGjQiz+0MxG9B+fC9d/vwvPJK21fFcvpkF568eu8SjnyABd4PW7\nBOQv/asBTxTnFjErrR9fCn0/NfXdZYt1ix6C+Ib5yaIvNsf2Zj915xr+dVCU\n+av+\r\n=mgY9\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHg7aG+c1UrI2FQXPz8Rnu5PldlQD8+bx1FetvqWew8TAiB3VkY7RCx6xfB6r2CrXXIaq5a5/tAaN8/BjxmYublarQ=="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"jason@developit.ca","name":"developit"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.8.4_1580387846411_0.8385726471324357"},"_hasShrinkwrap":false},"7.8.6":{"name":"@babel/parser","version":"7.8.6","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.8.3","@babel/helper-fixtures":"^7.8.6","charcodes":"^0.2.0","unicode-12.0.0":"^0.7.9"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"750d3dde3bd2d390819820fd22c05441da78751b","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"_id":"@babel/parser@7.8.6","_nodeVersion":"13.7.0","_npmVersion":"lerna/3.19.0/node@v13.7.0+x64 (linux)","dist":{"integrity":"sha512-trGNYSfwq5s0SgM1BMEB8hX3NDmO7EP2wsDGDexiaKMB92BaRpS+qZfpkMqUBhcsOTBwNy9B/jieo4ad/t/z2g==","shasum":"ba5c9910cddb77685a008e3c587af8d27b67962c","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.8.6.tgz","fileCount":39,"unpackedSize":1723532,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeV7RGCRA9TVsSAnZWagAARM8P/jhcfTYooe7fxQVMMUf/\n9czqHzprMEwiTt/dhl/eQhMOeDM7cheJmjN2Ak+KFUJBGQIjhC56MuaVaZPj\nS7MtYR2liLC8GuzIlgRHoy3qpCb9kW4Y0MFDCLX9mNCf/ZuyjiYKaR2vZ9LT\nXTuykPyg3TUMkJ+Y0DqaUmgY9wIY8rhQGvQxlIwOETYdt9HDnc9VOrmb7PSN\nX1T5jYuNL+UN5apPQ9sMNWfXd/KpCNSBLYnNgNg03SdT0wP38FPes9xlDtAh\nkUYq9l121Ldiy5bmcYFf1sazC1r8NZOgJotcToIs3u/0Ys4X1JK5LpPNRwdg\n1NNP0pRvLGYUBMwd5PF2KdfAIekp1nDr5lJcYv3FQcJ7Y8S8bXcHJXogZDRx\nInWXrw+a4lGuKzoOc/NyBhsgC52GOoshQBYImuIubi5E8IG66Agwvr/xiyKW\nve3OyIcNgpIBWt+PV+cYLzg78dVz9H934YQwseWkoleAnhgv6xz2gNqV8tNO\nEJ7on1hS+Ff8KHk8ZPhIQBHvmLSVflJgpxmxlqktVcZoSzc7xae50vBsDs8P\nC0Nsrjkw0A7Yp/lwFyqZ0DIToz9ROuDh/GkvWpfQycZ1qeRXnSq+LvxDtNc1\nJy+LtNnJ8twxdNzzLZx+v26G+7fTvQlQMuwhWV1xoLkYyVVzA5wkhw6HrFb9\ngo0a\r\n=RUC5\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCgAbu2cuZcRWFuAAc/2jL9CQ3sT3GlabpDL1b+G7FX6wIgPIcWvnvBjVHvyGY/rpgY9X0Sg0Oyp7lFoVmetyXyhHY="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"jason@developit.ca","name":"developit"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.8.6_1582806085711_0.43477520047067597"},"_hasShrinkwrap":false},"7.8.7":{"name":"@babel/parser","version":"7.8.7","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.8.3","@babel/helper-fixtures":"^7.8.6","charcodes":"^0.2.0","unicode-12.0.0":"^0.7.9"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"595f65f33b8e948e34d12be83f700cf8d070c790","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"_id":"@babel/parser@7.8.7","_nodeVersion":"13.7.0","_npmVersion":"lerna/3.19.0/node@v13.7.0+x64 (linux)","dist":{"integrity":"sha512-9JWls8WilDXFGxs0phaXAZgpxTZhSk/yOYH2hTHC0X1yC7Z78IJfvR1vJ+rmJKq3I35td2XzXzN6ZLYlna+r/A==","shasum":"7b8facf95d25fef9534aad51c4ffecde1a61e26a","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.8.7.tgz","fileCount":39,"unpackedSize":1770613,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeYFw3CRA9TVsSAnZWagAACRUP/A/CPW3DjvLn/d6w51Xy\nWIKmpZVsA6akvKII/sbjdKfZq7epJN6IvpcHk8vaTOeZwq2Fu7C+qHk4/sCQ\n36sPGuTY5sWFWJSWIunaxDyXPWix1In3SRyQegG/cq3pApcBUaHttepR71yS\np6NWRFAghy4c3tUNv4fD3iVdmv5xRKpilfz3nKhozY2lPOi/Qg0NyQUiJqor\naX3ghCKrefWV5m14l9tQOD9jAL90T4+PjN7I9WvOrnEz5GSR1rsS4F2h1nPL\n6viy49zf134rp/wu7PpLajzTZbzyamjETgkvEgJlLWfNzvP50r5SGkUrWSD5\n0yFWPlde9wl+sQXk9HfQVXbVoX9iOsPVyM6xFu3obRMwBiHZYd5XJMYsRm/5\nok5bD6zHSj+/Ran4rMmJI9Gqx0JalconbHPHSFo7riotJ48RIhoxAZ0hyGT5\n/e6cqVwTuBEwheu/KEUS5RVIOZMclFQfVgid0MinuGgjhElqlWlOuLSU3Nc5\np5DmkfvU+tKSAisS+wZ+pQbdBTjd002CP+y8cRocUW9MUNejE2vLuhVqm+WZ\nwhzevnhM3LNjo0BbrsKsGdDrjSQ7GfdU7fv6/dCFdj6bfVUYw0epYySEokOU\nHSBw6HZWWplU013T56hufQ/XlXKRh9i89N4y5eGpK79nvnEnbu6M+STeTLeM\nfoAm\r\n=3cCA\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCcIhf+lLSqlAp/0+h2TRfUzAbEfDlBAVm8ymf+7NBB/wIgchd2fhmLf4PXCn1+Yghod8LAim2d+35ev67SJ2pXfVI="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"jason@developit.ca","name":"developit"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.8.7_1583373366838_0.8861236394216647"},"_hasShrinkwrap":false},"7.8.8":{"name":"@babel/parser","version":"7.8.8","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.8.3","@babel/helper-fixtures":"^7.8.6","charcodes":"^0.2.0","unicode-12.0.0":"^0.7.9"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"c831a2450dbf252c75750a455c63e1016c2f2244","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"_id":"@babel/parser@7.8.8","_nodeVersion":"13.9.0","_npmVersion":"lerna/3.19.0/node@v13.9.0+x64 (linux)","dist":{"integrity":"sha512-mO5GWzBPsPf6865iIbzNE0AvkKF3NE+2S3eRUpE+FE07BOAkXh6G+GW/Pj01hhXjve1WScbaIO4UlY1JKeqCcA==","shasum":"4c3b7ce36db37e0629be1f0d50a571d2f86f6cd4","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.8.8.tgz","fileCount":39,"unpackedSize":1818941,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeaoQiCRA9TVsSAnZWagAAbLYP/AlmX1zLjZ8sn1I8QCIM\nEduJuYae8ZjKg7WniJExPpXY5mntYA3kHojsgBcieTWqrCBmdvQAZSinhDW/\n0k4bq4UD4sh3gWtwqrFSY+7ygH6owSV0YiJyy4X07joDQRl6ivl7uwsfW17H\npcVklsA+/J+YzhCBozjS5RZ/kbn2PchcmSxSCiGkJzrxFIhrTxtR6d/M31DW\nn81gJoDfk+de/1L0nu5BljpRr/eZopxtWUi0HR6FB3WrM4QCylovDilPnmsm\n8zaxU6jkGfFKauyHjSxjDovS2MBOXZlEkXu9nbJM1Hxbpw2HFUKB5DOYQMqP\nwGDJefRj7Ym7eYEsQ35s+GurXuAQO7slNlUYpmac+ED3M816QvkWtp4jT8qD\noF9Lna2yD8DGiJQnzOhcdbLQDEEsN/Mj3NUy4evyUsaNplQN1D829lbCRvPP\nCkrfuMcuxSS+KsTNp8HEA0Jeg+bnqwKwobVxs0ko/ix8/bMSJ/icbPArXvVO\nDDKlT51WlnB/X2z+0WZYBTNZdgscPIOdChFo66U5+3svvs3oP4WMO99KrtiP\nSxw5Hf6iIStNRSOdwZI8z6H+WfAQCUZuQguASNHwuVXSuqQ0q1bEL1JN5YAN\nj9FVRjJasGY5aQQx9YLekxfzbBPH50hQkC+JEaM6VhqqVRMqJ5cOY470JsVH\nMQ4V\r\n=TaS1\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDPfiXt7NDuZOZYsEXdrXs159A2Lcu6TCjgOrjCuVVOEAIhAJCLntwoYyT1OREUafHE1B9ZZ2Kg8IKkjrPlslMrGnif"}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"jason@developit.ca","name":"developit"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.8.8_1584038945913_0.19482960759255374"},"_hasShrinkwrap":false},"7.9.0":{"name":"@babel/parser","version":"7.9.0","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.8.3","@babel/helper-fixtures":"^7.8.6","@babel/helper-validator-identifier":"^7.9.0","charcodes":"^0.2.0"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"8d5e422be27251cfaadf8dd2536b31b4a5024b02","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"_id":"@babel/parser@7.9.0","_nodeVersion":"13.11.0","_npmVersion":"lerna/3.19.0/node@v13.11.0+x64 (linux)","dist":{"integrity":"sha512-Iwyp00CZsypoNJcpXCbq3G4tcDgphtlMwMVrMhhZ//XBkqjXF7LW6V511yk0+pBX3ZwwGnPea+pTKNJiqA7pUg==","shasum":"f821b32313f07ee570976d3f6238e8d2d66e0a8e","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.9.0.tgz","fileCount":39,"unpackedSize":1843888,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJedOOsCRA9TVsSAnZWagAAF7kP/RuZp5WdQKWPyZPrzBDf\nMltXtHT9BUdwCQFHSxRF2uNBWDudmnubwrQTHmVv1FeNLp2ycDpN68Rn2Qxh\naKXPH1N6O6qovGzKvEAHQI0qJxv5bzph/otPViQG9SexSn9+AdWfqiFnGSZ5\nQ/OmbNHiTpN6PO06KV5L8x6Njxov+pqgAhwcwWyQZ3JNTCMyZw6ZJPTL8mfQ\nXDmocpf0/L9eMMPDv8jld8dQ4uOy4k7Cm0XPw0WEvOHd9k/DHEYgRftCxyM1\nCOgHnl8XyHmVRNqKdnuh1rJm16vh4LUxVNNeZdALnqcoCxs+fZzRg9YVmc7r\nwOD0nx6HZVQuuZYrvfcjN0cwzmZsTCJ7byond6XVfQKmzYZViJhPfcr5XONN\n+B41cxdjRMrklS9bHqppQgvibrHLmFzgxT5wTfy1RtLxHqTOFczaCdarfZC9\nq/vB5WObdnrA3VeqfsaVi9IlKP5hXc1I1vuzYHbyN3muZ99mi5x1v9VOxJ/1\neT6stbCsmdxKXOsYYn/Ti3SHUjJiMtrpTeoNl47rRrPJ6pTFKZZdwToUKGV5\nx80Wi3gIGfTxQotmlD5m3iXAY/vDjPOiEp8LbTq3uZ0TcOdc6Kz/2vqj8V8F\nw6Kohhw9EkmorW1JoHBCJBnE+DUrz4APUxM/vpq8b6Mfl32qiFgV9HRqnonf\nPJXb\r\n=kjIy\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGUqn9bx5/bFQAagUczvPGsD2s3G+TGzrlzVau7MX8LlAiEA/loosNEXEn6Wb7PpNbMf4Cst+5a6SJJ5H6ZFnFhpwLw="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"jason@developit.ca","name":"developit"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.9.0_1584718764348_0.6120134453634685"},"_hasShrinkwrap":false},"7.9.2":{"name":"@babel/parser","version":"7.9.2","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.8.3","@babel/helper-fixtures":"^7.8.6","@babel/helper-validator-identifier":"^7.9.0","charcodes":"^0.2.0"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"2399e0df23cbd574a5ab39822288c438f5380ae8","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"_id":"@babel/parser@7.9.2","_nodeVersion":"13.11.0","_npmVersion":"lerna/3.19.0/node@v13.11.0+x64 (linux)","dist":{"integrity":"sha512-2jyvKdoOS1aWAFL2rjJZmamyDDkPCx/AAz4/Wh1Dfxvw8qqnOvek/ZlHQ2noO/o8JpnXa/WiUUFOv48meBKkpA==","shasum":"4e767f424b479c514077544484d1f9bdba7f1158","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.9.2.tgz","fileCount":39,"unpackedSize":1845137,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJediE8CRA9TVsSAnZWagAA07UQAIaXenuAIIjAnZrUJ3lR\nvU4wUcHD+Jko3bNbB12iuNivkv66Kh4tU4e5czt8BLWTHKnUgTkhBTOXlPPs\nTSmhEuaG/vCjmd7i8zt4ygRGjHpYXSLZuknNxZ5qVapwS0cpT4cn4mY5HP8y\nKTLJzkS03CojlVKW2pdjo++1wqVqhWkLkb8uhfYYWI8DozwMvu/PZMQZLcs/\nk6JM5FYH0cYKu+n6/bYPe6oLncdDO5AS0o89DfR/G0sByuaypEY7XqRpUiWg\nzufjwsdtrIQsmwopC3y6GIGgDfw3yKkMQIG6981JcgaBXsevDkl/B0e9UjVA\nqSUVExQjwbc6XjyjOyzeyo4EVwxv4waV5WGbLnDFy40sDKYP/+e20MoSInTy\ndWCbpWtbhEjPXCkked9MqNCxHdBQLilKhNAmxCSE3CS5wtjguZgRN9GqZdbE\n4G76ZcIudtayosPA8B0Jr3ywQ1WGtnJQxZYPipYyxVgkwNmgLpTuqProWQq9\naCIMhKVjyurIeGsHq4RqVV0E6ITRQPgG3t5kATnD0pOz5+WAGV9C4yNOyLsR\nXOQ1JevlRauFTZL9YcRJOeZmKr8PFfXJIGZ70tf2SWdmT91zJ995rrqayTpV\nkvlr2R9WHXkzVUZ8GoUKtXbuKVsjYGm+OblSvsJk1cVl47c+rsWzujYLHEEE\nz5y+\r\n=iMN2\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCdTiEOqGTHigZfTyFZLkje7P+bCqzjHQAj/SwiO+u61QIhAKOZ1kk6osQ9V8Fq7VGOqeJ2/W1zUij34SnOLAPPskde"}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"jason@developit.ca","name":"developit"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.9.2_1584800060116_0.054291313376471084"},"_hasShrinkwrap":false},"7.9.3":{"name":"@babel/parser","version":"7.9.3","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.8.3","@babel/helper-fixtures":"^7.8.6","@babel/helper-validator-identifier":"^7.9.0","charcodes":"^0.2.0"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"1ae85560a7e1c24e80aadd04a44e0dfa3e2699fc","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"_id":"@babel/parser@7.9.3","_nodeVersion":"13.11.0","_npmVersion":"lerna/3.19.0/node@v13.11.0+x64 (linux)","dist":{"integrity":"sha512-E6SpIDJZ0cZAKoCNk+qSDd0ChfTnpiJN9FfNf3RZ20dzwA2vL2oq5IX1XTVT+4vDmRlta2nGk5HGMMskJAR+4A==","shasum":"043a5fc2ad8b7ea9facddc4e802a1f0f25da7255","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.9.3.tgz","fileCount":8,"unpackedSize":1434835,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJed0XdCRA9TVsSAnZWagAA/9UP/iZtRFGwQjsECHKVoh9K\nANJIuz3U5IzP8jwGxGjjLCXssSlwpzR7y4O31B1Iit/oPFxq1ia2PBxGDr+y\ngOwkJsSXvy0X6b1ndgK0ICZX1zsMh560mx1L8UL2t8+3pVkfoiXR9sKACRvI\nCdoWvIHpjobKFdcIGe7vj/r9NWmZB5zeSWxdzIN8BlGVZV8kGpiKRmVZmBvU\nrn+jNjbsqb1pqAOxNc57+gLQAKMBTYXwbjesFNBmrsVo+lb7jc+1mctFs91n\nulJ3qML7m3PJuVOatMqeRDrTj6MKz4FFOANWLl44Cb1HVUKcAx+ePQOAJ5x1\nnGsj61cW8ErxW4CjXv11MUwpCMxPs+/tuxvEIp3PNSJaPCmjx5+JwRzHBQ/y\nLqrxbnxYRpm0/lR40foRDEXlROeEkvczkKave/5IrnvvUla6ouzEXCG9Vl3W\nsUEmhy7hh86iLQXzPigXVE/kLgK2n3jscWIJuk2ai89zRsQQcVeiZ4h7KsfE\n3UNSn60pp8ChVs+pBpWeBXJHvmsXDm5A8sBXw8m19wh+IgMZQx9g9IJ0UVMo\ngyR4K+0BO8BjvMGMhzqagpJF9AS5+LBo8sUF70XGSVhQFTj0H3pDiu9cVa7K\ncDyQGjp40YE1BKOj3mjvUo7NV5mp+t9IVrH6ZcVJEm5cnWv12F9dH0b53qUy\nN7U/\r\n=8HF5\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDRcMpHjPEdGnfXX+q0X3iLBjiqjcmXTD0crTBlXsX7BgIhAKurdexRWMCvcVGLLXK3Lpihd0RoCALNL/wXShA3A3G6"}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"jason@developit.ca","name":"developit"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.9.3_1584874972620_0.44836192686422205"},"_hasShrinkwrap":false},"7.9.4":{"name":"@babel/parser","version":"7.9.4","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.8.3","@babel/helper-fixtures":"^7.8.6","@babel/helper-validator-identifier":"^7.9.0","charcodes":"^0.2.0"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"d3cf5fb5f4b46a1f7e9e33f2d24a466e3ea1e50f","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"_id":"@babel/parser@7.9.4","_nodeVersion":"13.11.0","_npmVersion":"lerna/3.19.0/node@v13.11.0+x64 (linux)","dist":{"integrity":"sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA==","shasum":"68a35e6b0319bbc014465be43828300113f2f2e8","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.9.4.tgz","fileCount":8,"unpackedSize":1435324,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeecVbCRA9TVsSAnZWagAAF9YP+gIWWbhxSRiEgsidFRJ2\nxDYkXk/VTHpAUR3eLpwdys07wHW7NK3eYdA0RCEAjMopa6A3MKiGrt3v9HEN\n298yGyYluX9erbzWtoTyeuldXLJcXbX5QsvZMaOzn8zI5TGuNhpEUlyBtlvM\nIQH4pnMs7xY9CjVpywLevdBhBiCSjyB/bily1BA6Hq9sQUAYOvla7fgaOgUO\nfJo1Pd3fZffAHB5BrxBojD/8R66FzSCQxTX77Di9Ts89t766bDCOK0DxEQII\ncjhJKWrVrBDrIbrtBp/VRP5a+53vRyUG+HI2TsMBR9GCKWC9lV9F2pogn1fV\nBSnx5ehNcql2HrqejGBYrLxICugPGzrg+opurQCo8kyVKb2A8hgAYHJAVPjq\nRA/TpI3lXCv1jPQMPOJWB0j5r0eio2z9gH3aor61Xhuwcj6Bwa15v2kyQ9/F\nZK7A/RqL5lE/tVcLolbNfJ9h7RS1Ep1Lc0492KjXirWlukvTAqdCbWEYISRN\n1aOy43yVuU/Mu6zYnLxiWCcqKMxQwQ/s/AAGz4ObBIYfxkXoHGPRgvWvxqTA\nmOnu0U9y788oeGjQGhFausttoCjP0vdTGlq83BshtrmirIqSM+0lSoxPOklF\nFR17OApfpRDMPAnsDneBoSaEdZ6OwXoGqWRa8TByAu+oF0bWlEqm/rz35nQl\nhE3y\r\n=mhns\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCS7gIrSWIYiYNEAw1dNNv6l1dN1kNGhvkrozHrD1vXqwIhAIgKUHRohiw0ZpP0nmz72OEqjcqLcjzltu+2yrCvaC9C"}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"jason@developit.ca","name":"developit"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.9.4_1585038682994_0.29666034728529"},"_hasShrinkwrap":false},"7.9.6":{"name":"@babel/parser","version":"7.9.6","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.8.3","@babel/helper-fixtures":"^7.8.6","@babel/helper-validator-identifier":"^7.9.0","charcodes":"^0.2.0"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"9c2846bcacc75aa931ea9d556950c2113765d43d","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"_id":"@babel/parser@7.9.6","_nodeVersion":"14.0.0","_npmVersion":"lerna/3.19.0/node@v14.0.0+x64 (linux)","dist":{"integrity":"sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==","shasum":"3b1bbb30dabe600cd72db58720998376ff653bc7","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.9.6.tgz","fileCount":8,"unpackedSize":1438793,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeqcmNCRA9TVsSAnZWagAAORUP/1TeYpEdRtr2RtIIPBG4\n/g1bGwTscRLj8IK8opBts7No8r0/L6v/MflzvIxS30rZ2jK/WKZLngFnfx8k\nWRkciXA3qHUa0VqKmsTUr4tQGDOvfFZUYHon1vQI2wWW8/s3XQ5oOWLFncZq\ndMTkcvdyBDiOSFQjF4Fedp8hsT24eQO5kw3TYXoHwJ7Om22eKhMWwxZQaRia\nuL2HVbz7qq1zP+szpZJI/FjHZxLeXa1ukZ3p0chU6rTBoDA/lB4sljAguwTH\nCkarUj8QEq74Fz+xm5+SiPA0wb5Qp+3FR1lxmfl+turMtCZ7dv6MEDru5w8L\nnEY9HAL+jPEmsCXNC6hbg5JVba9nBcjv0S6AaezfSrE1VAaJvNhOR0aPjupf\nrygaGyTZ9hxQbrlmrKGRWBZQyUoIfbCFK6u3qJ3POWf4zZWhC4uCDHrFCTaS\nDZ1uxM7y7RVQfUNEKj8peKtE87ZRqaKm3pgmHTH0T1RuIDkKG/aYo1+brK2T\nPQ3YS3nQ8BEjIFoKr1sDUYBHrHbsFU1fqj9WyFgaGuHd2ql730OWr013UZm/\nD2JySs27Fxy6gOygZ9kRVR0PvthSc1Td5Giy6+ZDGSU729hhl83khPSpP6vE\nOPr+Mnypt34e9HhYFT1tOFc+QoomQFqzGepB4rpI62++VRKcdM1ftuo0OVjU\neaUl\r\n=McMF\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDT4cuya0FIF4EB+rO6KgjibM3olQVs6iw6HZ4G6XnD8AiAQcaYvdCrgqGMKR4RETpP5eBkTvtWnhCM0i1s4WftwuQ=="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.9.6_1588185485200_0.9509753147815743"},"_hasShrinkwrap":false},"7.10.0":{"name":"@babel/parser","version":"7.10.0","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel/tree/master/packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.8.3","@babel/helper-fixtures":"^7.8.6","@babel/helper-validator-identifier":"^7.9.0","charcodes":"^0.2.0"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"5da2440adff6f25579fb6e9a018062291c89416f","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"_id":"@babel/parser@7.10.0","_nodeVersion":"14.3.0","_npmVersion":"lerna/3.19.0/node@v14.3.0+x64 (linux)","dist":{"integrity":"sha512-fnDUl1Uy2gThM4IFVW4ISNHqr3cJrCsRkSCasFgx0XDO9JcttDS5ytyBc4Cu4X1+fjoo3IVvFbRD6TeFlHJlEQ==","shasum":"8eca3e71a73dd562c5222376b08253436bb4995b","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.10.0.tgz","fileCount":8,"unpackedSize":1398085,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJezY16CRA9TVsSAnZWagAAz7wP/Rux9prGFhwpePTC+0+c\niiJ6PijleO84QgbXsLGQJX1dXL6/nAldi5B8mDuIlXeKFF1dYDuRsezspUxL\nVLadcwtCsA0FVFp9ZQwj1jlZqARNje2BXDrxFscQuIdIhTr/SVgYXhduyrtb\n2JSPM0EVkl2SQ9nQy5+LdrO2gyXNxjTFNPnUH0Y5zfuvq+N+gLu4P2amyo8B\nn0g6SiBURy39iyxIBFAE/9AevF0ByYqVMgX5bRMP4Grwu0AT3GJ/YA/IDo3/\nLJ2/1ZlFwCuwYu2rFXCtoR6FVvTo5nGqJy6jL4P2Uh2xfa9TA14xl/k7xF1o\nQC/6VoNvVk5en5hx53lqr3Ztrezz1ZsvqqYNTd7jA18xYAxMz/JjHMY5B4JX\n6mKHaLD9XCeKGxsSnecKFpzKF56QA372Bkq1Hlz+2Tw2pekRomWONXT9Iqfj\n7EgcpOG2T1P455+IT2fMO9q24vqmP8Kxpc2WNRJBg2+JhsMElW4rW9LE6bQj\nLTQDGtABN4pkx68FodxUKNrg5dIbij2edExs8sNWJ7k4ognDCyN+a03BDNmn\nxedIXt3UYg+93CkWdmzHoPOvW7Pr4pYwOsJmtlV7zLCzooWUrLmIoEQBhxI4\nLaP40Q/Cpl/XkNrfDGIm99uhdtUDk2hDd0LsPsXc4tO+MbyVenk5192b5arf\nG8y2\r\n=B2u4\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCIXQhJ9ju3PvFIAZZkGJMS7rb1VrFsocKx5yw3GQ2GIQIgLpahTDu+NdhtchhYKfpE/AumZFP3Pop9oVb6A+lTKQI="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.10.0_1590529395448_0.6360338306807312"},"_hasShrinkwrap":false},"7.10.1":{"name":"@babel/parser","version":"7.10.1","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"git+https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.10.1","@babel/helper-fixtures":"^7.10.1","@babel/helper-validator-identifier":"^7.10.1","charcodes":"^0.2.0"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"88f57a7ea659d25232bf62de1efceb5d6299b8cf","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"bugs":{"url":"https://github.com/babel/babel/issues"},"_id":"@babel/parser@7.10.1","_nodeVersion":"12.16.3","_npmVersion":"lerna/3.19.0/node@v12.16.3+x64 (linux)","dist":{"integrity":"sha512-AUTksaz3FqugBkbTZ1i+lDLG5qy8hIzCaAxEtttU6C0BtZZU9pkNZtWSVAht4EW9kl46YBiyTGMp9xTTGqViNg==","shasum":"2e142c27ca58aa2c7b119d09269b702c8bbad28c","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.10.1.tgz","fileCount":8,"unpackedSize":1398136,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJezuR/CRA9TVsSAnZWagAA8yoP/1cXtTNi1bBwMkAjnphg\nH1jQfKahZV6g8LCckjwIzT34pnRIqCVORXmce9MoBwhW08ALHjb7CYIZBT/2\nqmRhjXBE9kN6joEsaaSlIKcmCdc/cjDbCnr9RmnqO01t69rO5hrxalAX4Vx6\nxiVlw6s+5Y4Tv4BkkPHK3GskS4ifGMMvCiZqUcuvDrWCErzgwSxT1+uKgRBb\nC+QOjpuylYfcHCBN3Bk+g3fTqmcTsE4J621exYA0BNy7MaJ1NHgC8bEPpMQA\ntBzr+4ajSMyvInyxFqyrPkSaNW6xkLoFbzsyNOH00z0z8D+xZAsKsRHyN5vK\njVqE+4WeT5Fuo8oNkuYADvbiMmqNuQMC/WxiV1r4rmKtUJSbTkKVYJumuS+w\negh1RTeQKlKxKEC1iMEvA/pknNOuikGOnltvWnmDUxLy+TExD8m1vxfuFN0P\nEBhQtmkr69djsfsOV24vtrJGljhkjeAmAyQ+xH1GO/mH5Lc7BMPcFZB5r3o6\nftayj6cXkh6Boz6kz9RfMpYrE+mxYpUFABghqDvXFysDAWnzzTvyJQqQRv+n\n58Fn///LFoFFDFVUF+KAoexGMW/dGoIpotno6bV5iHDnU/gBa2sm6rYcBhhD\nRuZLoShGuka9jIei3sA0Xio5Y0NfuOqvfCdWhoe/GT31N9OBTbqF21Pg1CGu\nk7If\r\n=6JM/\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCqTmiMBsfDMNNpgLbvqaoUvBCsp5HJh1xeqG3T/b6G0wIhAL0PuycTe3KUw6KfEBke6YnG4hXnvmaUUmsnrwNK/W3y"}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.10.1_1590617215297_0.6323533844234692"},"_hasShrinkwrap":false},"7.10.2":{"name":"@babel/parser","version":"7.10.2","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"git+https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.10.1","@babel/helper-fixtures":"^7.10.1","@babel/helper-validator-identifier":"^7.10.1","charcodes":"^0.2.0"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"b0350e5b1e86bd2d53b4a25705e39eb380ec65a2","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"bugs":{"url":"https://github.com/babel/babel/issues"},"_id":"@babel/parser@7.10.2","_nodeVersion":"12.17.0","_npmVersion":"lerna/3.19.0/node@v12.17.0+x64 (linux)","dist":{"integrity":"sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==","shasum":"871807f10442b92ff97e4783b9b54f6a0ca812d0","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.10.2.tgz","fileCount":8,"unpackedSize":1399406,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe0rMXCRA9TVsSAnZWagAAc9AP/A4hTcJgROTW3ncges4z\n4EWImTXMSsYRqDT2+66yf83lh7kARhFyG5IouyquGFs8yD+aPKpRprlbJBon\nLDhB4HpoH4Rv5mF6T7miFA/M73kdnl4AyUslIjSP6JyEqGKs2R1u+3kv7mfH\niQMtRTQN45/xfvbdVMBgrQdLiSQgr0qyqKhykDYNYTC6tm2yTOKhtuvROmuu\nAKCYeyXMtUgmic/inxylPKYUvEU6DQQi9IVWO8aupp6RTmq+KzMDQa8AEWLg\ni6J30kQ8F+fzY1zZGzUVS2ueA3gncRlfMEj+lqpgfBRZ3ypFR3jCpU95wrMa\nIqRZEn35bqth4w+SXygkql76FE3GYp4ruZFiPDhHcPQp4LV0xdCTP7Q1GK5O\nxyenF7FeSq24gDdCCGhwHCUZopl2pnH+iXIvQ0Pn2JBzoD1dwgnE/XYI+oHH\niojKEE6GRu3QlRUjPixkLv7w+FRGsBdbwTW0DV5d6mp1HrKhyR9gMurmSHp4\nd2xq9C+kKCl95w0WC1wJF62va1qWPnjG6J/nWDZuP2Ps6WrlsrgOfnvtehxc\nefVP3d1B8YJmY77+8HLC8jVEKaRkGaRc/aalCBwrX2yO6CcsGPtAyvnIdh7O\nbdQRzsyrVuyKo3bk+nIYnADZTeBIbTp+lpw/zAFduCjGwWxGnzmqDy5P06Zy\n0wzd\r\n=BcoU\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCpW3hbOpwJ3I79jcZtC/TY+rIqntC2gny5OiYArDqQiwIhAOs5wVGFGSTfZROQz/ooTnNSQTaIh+0fFhRJAvKEXusY"}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.10.2_1590866710542_0.47536170866076377"},"_hasShrinkwrap":false},"7.10.3":{"name":"@babel/parser","version":"7.10.3","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"git+https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.10.3","@babel/helper-fixtures":"^7.10.1","@babel/helper-validator-identifier":"^7.10.3","charcodes":"^0.2.0"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"2787ee2f967b6d8e1121fca00a8d578d75449a53","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"bugs":{"url":"https://github.com/babel/babel/issues"},"_id":"@babel/parser@7.10.3","_nodeVersion":"14.4.0","_npmVersion":"lerna/3.19.0/node@v14.4.0+x64 (darwin)","dist":{"integrity":"sha512-oJtNJCMFdIMwXGmx+KxuaD7i3b8uS7TTFYW/FNG2BT8m+fmGHoiPYoH0Pe3gya07WuFmM5FCDIr1x0irkD/hyA==","shasum":"7e71d892b0d6e7d04a1af4c3c79d72c1f10f5315","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.10.3.tgz","fileCount":8,"unpackedSize":1405459,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe7SXwCRA9TVsSAnZWagAAfMAQAJ3uIQaAC6AK407LgfAz\nFTd3dZZExoo0LhxP8i+xN5Sc2go/I5YoSjQe3fC2xDoAKvOwbYDE9KbTKJDn\nI7rJDoMoZRWC6fJ40NKcDMLtXx2JBd4jYdXZZeLEBPDO7wdP6u6AJM3vuFRd\nvKtLnHkhfBxhDW5Or5UMlGnTdMtNiQZFYmUPFW30/g++URAjjIjVZErU93kW\nTaPgaUViiGegkhOUHxOyv39Pr/oH/irh/H9nnR8xGCo1hHrJ8I0TYRskR9k2\nrol3bvqmgHKXFq0hnPxj9vLAMhbLLM4QeyGjaZE+7pJmpoeRt4DUrLyJNfGV\nCwQOlOGAsRtUQ9UC/2z48evH3vJO5Ej+IpwtDo2YcD/NSeUp6zR+/QaEHLj0\nVv3lnTHQslY6XiEdkhcftkCwLV6F+yf9QYxEqXwj5mURF23iWzXtU8LXqtQr\nEWmyevM0PgJ//NtCJj9dgcIFvqceEkwheZxiDud3k5Xczd1bMWaBPS94JWfA\neNBthNyzU5LGMar3edhzTCl0ctveddXEezS+iexCtNbZ+Xe4vKwQX65FzmcQ\nVpZCxH79zIrtrW4Q2cY+yYiDWfaYevQM+OxJWA6AeYaPFFvs+nZh2dDcWg/g\ns92swk3+RV+0pnrd7EFGkeoz+UcKbxRH0u+3zkHKYfvXW8suZtLMg07teC7c\n7/Xc\r\n=LmWh\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC2rz7o9o8tkAg9ZUIKqVZoMV6i1lgRcMXuKDxm3iJSfAIhAKvejXfjDbhbfiVQlvcqNgD0EEBjdt7kFUS7yw2DP14d"}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"i@jhuang.me","name":"jlhwung"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"jlhwung","email":"i@jhuang.me"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.10.3_1592600048265_0.21923254132312864"},"_hasShrinkwrap":false},"7.10.4":{"name":"@babel/parser","version":"7.10.4","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"git+https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.10.4","@babel/helper-fixtures":"^7.10.4","@babel/helper-validator-identifier":"^7.10.4","charcodes":"^0.2.0"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"7fd40d86a0d03ff0e9c3ea16b29689945433d4df","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"bugs":{"url":"https://github.com/babel/babel/issues"},"_id":"@babel/parser@7.10.4","_nodeVersion":"14.4.0","_npmVersion":"lerna/3.19.0/node@v14.4.0+x64 (darwin)","dist":{"integrity":"sha512-8jHII4hf+YVDsskTF6WuMB3X4Eh+PsUkC2ljq22so5rHvH+T8BzyL94VOdyFLNR8tBSVXOTbNHOKpR4TfRxVtA==","shasum":"9eedf27e1998d87739fb5028a5120557c06a1a64","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.10.4.tgz","fileCount":8,"unpackedSize":1407877,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe+zn6CRA9TVsSAnZWagAAfR4P/jdlZEyFksGeG3pVLB+T\nEtDygUHsrE8FLKq2FRjw0/MJ3583N0qYBOG330OCG/vtvTtq3kANveqd+zDp\nQMQQ64HQYIMW8af3KQaR4G1WJAX6RnU5m0rRvl3PQqb4mHhH9YSkLjxannut\nsSzxDemRIWfolhdKM0NaZXGAviCtW2fMKFXYIl/YCWtjBxVKCZT0X5thvQ/y\nLu+h+wV3uyfc7G8sp1fCVM5AhFEkhSjFILFMwyRIHzfiP3lqMIZEg/zU+Fcg\nHL6FNI04QvhqA2OsDGmqUF0QNYRsIRMeCEY8AgxEUqF0sTc+U0H31EeCuavd\n7UJbn5wlybJjzrJShnNrJpcTIUFJ5yVi+xTG0Gx/M2JsTgAcif31+CqI3/Fo\n+H1DVIkMHvwE9t7b+Tq+477clps0gyMnW92aXJbUqMke6/qbmVorTtO4YCqQ\nNn31gOxc2Bgv5l9uNyf9iiXL7RDOAbzBBltVr4K4r5ki5DGViDW2XcC+dazi\n+HcKl+92AlDWfsfsUZ1JuqRpD9w6BgOy90VX02vNVhWBbR8pYaeTwD5wofvq\nvcOMtlQRTbkVBokHFOu4MX63zixh5ajxoMIT7q8KS/GEOhDRmAqjXna4+uII\n6Q8+h4Zh4zXirNRiq/04xU/xJyaHI6o/bLbd3co/Ore4C7EGF3+EC0V36CLD\n3g8w\r\n=Gcqf\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICu0DE04nH4o9bBVb+kQj9sNOsuPqW8+CNiprsRYrDtgAiEAmzv0Xc8KnZZMV5/CYhydh56McUbQ2XGKc7QGFp3vN5k="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"i@jhuang.me","name":"jlhwung"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"jlhwung","email":"i@jhuang.me"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.10.4_1593522681980_0.06945285942465418"},"_hasShrinkwrap":false},"7.10.5":{"name":"@babel/parser","version":"7.10.5","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"git+https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.10.4","@babel/helper-fixtures":"^7.10.5","@babel/helper-validator-identifier":"^7.10.4","charcodes":"^0.2.0"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"f7964a9ac51356f7df6404a25b27ba1cffba1ba7","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"bugs":{"url":"https://github.com/babel/babel/issues"},"_id":"@babel/parser@7.10.5","_nodeVersion":"14.5.0","_npmVersion":"lerna/3.19.0/node@v14.5.0+x64 (darwin)","dist":{"integrity":"sha512-wfryxy4bE1UivvQKSQDU4/X6dr+i8bctjUjj8Zyt3DQy7NtPizJXT8M52nqpNKL+nq2PW8lxk4ZqLj0fD4B4hQ==","shasum":"e7c6bf5a7deff957cec9f04b551e2762909d826b","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.10.5.tgz","fileCount":8,"unpackedSize":1408584,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfDfbGCRA9TVsSAnZWagAAKfoP/2CBUlb5uMkYnIbzIam6\nYWiZm4W14Ej4/1mny1SAmTYHonG977sUgbfuCaizWbV3VwwKDLjoyKYujVyX\nxJCpVoypoVu2+yMD6nyd1XtDvckerqaHz+jD59/oFVSk/sDclGdV60VwWlhv\nnboSqtrVyiwfz9YKyiwD/fS0KVd8175D7o05Tg58FKOFcitltAtE5RSwBt70\nR61W54zT6pAh7bgGjKAEoRGGDfjmZZb17PLmWqXvVjJDLM3xwekFF+8hpAAF\n1Hiar3t94H/0Ug51KbHXbV/x1aPSVcb2yU5Cv3VZhijJ507TITpxEtCkvMhp\nxiScQyaw1I5T0hY2/YrUm3hRTuHwzDIhKSW73Bf9Rp17BAzet/3nPdtQprax\n1EwtxUDIRKHmpFZwfqcQhpwX/PknayALB2vn9dF+YeMgN7qHX0WbR4z2laxi\neG9eXytblCckKa+UdOxvn4HhrLgI2lhLaF7aszSS8fcQlEcFGTpfyjbovesB\n4AM+7N3c+xv+9Xr8bJpFJDgyLl9iX7OBfBBMXri4btzHueLL7y31p+XdLhPM\nMy3EDREEC1aUyJbfOg5us33rmlf+s8LCsfkwQXEJ8s87nkXrMQY2ICwDfcDd\nDGk+GgGk6aBziXMZuiNf3hsVfajE6IukWKgoxsg3A5lfCyO10arAWGQEmZ7j\n64Km\r\n=IuJK\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGDxueWnLg5Cbg75rm3hBWM26veUbKZns/vElyKLxMQgAiEA0pbbyww42FhWR29Ta9rtBIJWH20yyrf5on8jRbigm9E="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"i@jhuang.me","name":"jlhwung"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"jlhwung","email":"i@jhuang.me"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.10.5_1594750662035_0.6266355812444604"},"_hasShrinkwrap":false},"7.11.0":{"name":"@babel/parser","version":"7.11.0","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"git+https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.10.4","@babel/helper-fixtures":"^7.10.5","@babel/helper-validator-identifier":"^7.10.4","charcodes":"^0.2.0"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"38dda069eeac2e31bce3f56290998d30bee1ed6b","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"bugs":{"url":"https://github.com/babel/babel/issues"},"_id":"@babel/parser@7.11.0","_nodeVersion":"14.6.0","_npmVersion":"lerna/3.19.0/node@v14.6.0+x64 (darwin)","dist":{"integrity":"sha512-qvRvi4oI8xii8NllyEc4MDJjuZiNaRzyb7Y7lup1NqJV8TZHF4O27CcP+72WPn/k1zkgJ6WJfnIbk4jTsVAZHw==","shasum":"a9d7e11aead25d3b422d17b2c6502c8dddef6a5d","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.11.0.tgz","fileCount":8,"unpackedSize":1417718,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfIzQMCRA9TVsSAnZWagAAgXIP/1U7wNTJYEZSdk7erxJv\nTbCIZ1eK18Ko+btHGeKoOdNLE/AlhmmtmOPcCMhde4bVk2r2eUtFLJUPu9nv\nq6X26ZOEEWWn8BvY3D6HxEb6tLkZ1hbvQUnu/8xR6r76OfdIfyiZboFC+7Ux\nw+fQlTp87UekYcF/neJnkL76zX/W+xdSNxH4zqVs5YKEGASHnltN4SvBIBRb\n0bFf2m3bHNUzI0wn9YleccGTlOUXmvF4bq+LI32U6Cxf1qUm8nfp19cscsvI\neEwth512/iSB/LcR1Qeg3YHw+r3SY8gXTjtNJiiZE8/D+vC+xiYTeeFgmzlN\ne5LEcReTLFqOHJ/WS7VJn9XX/GJ8SaXv4Xjxu0MJVsPU/ER2f4ZulAyrfjmv\nadRP2JXOAapKCWhKS+8D70yg7megey52vmZiaJuXyzZl4Or2VWlzJXPmGsqW\nuTZcpmeYgeMatUPASDAM8on3Ez6/7kkenip2rpqwLqOOJ81I9p2wx/h59N6K\nA3Da9RcobUPuHq95GPqBG7hQ0GtpCExMeATRuOZKSDlZrtyUt3ShtDBE4Jpw\nL9Yss4NJ5CwE9+TraZGJ1raG7OWYPEgp009F1RyHop0/YTkKhWGGFp8ziJgH\nQgPt2ZmSgGVNksKWzbLvgAKNH85yBYqJzIV/+0zxJd5WPOFiAIq2oqP9CA8U\nvBWl\r\n=RaCe\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICBjZ9RgXCMTbWiyGkbRkN/IG7KllYfrermIQHxAeS/yAiEAnuE20UHKJpDPwYOAZDXZZkJTixVw0Ou3ccaNWRKqrHQ="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"i@jhuang.me","name":"jlhwung"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"jlhwung","email":"i@jhuang.me"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.11.0_1596142603872_0.8699674672024991"},"_hasShrinkwrap":false},"7.11.1":{"name":"@babel/parser","version":"7.11.1","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"git+https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.10.4","@babel/helper-fixtures":"^7.10.5","@babel/helper-validator-identifier":"^7.10.4","charcodes":"^0.2.0"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"953ae82159b67b4487f837a17a1b8d5e305a8e5c","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"bugs":{"url":"https://github.com/babel/babel/issues"},"_id":"@babel/parser@7.11.1","_nodeVersion":"14.7.0","_npmVersion":"lerna/3.19.0/node@v14.7.0+x64 (darwin)","dist":{"integrity":"sha512-u9QMIRdKVF7hfEkb3nu2LgZDIzCQPv+yHD9Eg6ruoJLjkrQ9fFz4IBSlF/9XwoNri9+2F1IY+dYuOfZrXq8t3w==","shasum":"d91a387990b21e5d20047b336bb19b0553f02ff5","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.11.1.tgz","fileCount":40,"unpackedSize":1845074,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfKdu7CRA9TVsSAnZWagAAr1EP+welDaFmNHbCFEKg/wff\nju90f6Ucy2YTQHuII5RmJ8g8mvjEpxzwTkf4BwN1tfCSw2p7XVoBgZlyEEOW\n4xSEj1KlFrGL4Ecm/G5FB5K2qcr0Bm9V/CLvQlEt0eBo0q6dlqKZx+Mh21c+\n6olk0f9Sq+LvMptw87XcJ7nEyiamF8ITyJe22LvfUn3uAQJ1cK3mlt/G1CTV\nuVBtJl08yMXuhpNk6IhxFWIqjjjdU5uMLNEAakG0vlvb8EEWSBL6Ja1RH21K\nX68gqliNFvJ4+YuBfjPuIrG2TKwuiNHTGLFLV8YB6Pv5THVflQ0jT9Dne5aB\ngfCjJ7SAhhMWO75r1/jqpN8O+w/ywSSoV6fKGaojbfxScCb78fD0ToxkKNgM\nxPqMYlcTJSus3qeuwtVQ/KBj8BAvAeIK16fg0ZOIlvwIMv2FfX33bi+1mflW\naDwvH/ZvS4MxWHFKx23R4YfR/0QWU5kFd/dyQWK5ACo2+LpiKeVnUj4cii48\nqzcKAkVAwWqhtCRBaRJaZWQZq0j4lN1Y2CC5KUthNkboVBknGhzIuJcvhbxg\nwUG/9mzAlK+Csvvx/iNbgzXuf3YZeKKlR+6QzFgwkWPr1xVjeDXZH3AiV11o\nsXR7Lq+F0XztJeb0qu0bCi3mYFuy3MSdw49+4fmAq61Djdy4PEGZG5HUrDec\nZShd\r\n=P0C9\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIC62m0duktzAAVSdrcacmH6k8uA0nuRuGDtxLRcOHvZ/AiEAwAL7xEzbkSOrbMjrUaeqlhJs+o8wOGDHqr533EPbylw="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"i@jhuang.me","name":"jlhwung"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"jlhwung","email":"i@jhuang.me"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.11.1_1596578746863_0.8236042750412917"},"_hasShrinkwrap":false},"7.11.2":{"name":"@babel/parser","version":"7.11.2","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"git+https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.10.4","@babel/helper-fixtures":"^7.10.5","@babel/helper-validator-identifier":"^7.10.4","charcodes":"^0.2.0"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"bc7a811fce3ceeea393229299c1cdb63858608e6","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"bugs":{"url":"https://github.com/babel/babel/issues"},"_id":"@babel/parser@7.11.2","_nodeVersion":"14.7.0","_npmVersion":"lerna/3.19.0/node@v14.7.0+x64 (darwin)","dist":{"integrity":"sha512-Vuj/+7vLo6l1Vi7uuO+1ngCDNeVmNbTngcJFKCR/oEtz8tKz0CJxZEGmPt9KcIloZhOZ3Zit6xbpXT2MDlS9Vw==","shasum":"0882ab8a455df3065ea2dcb4c753b2460a24bead","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.11.2.tgz","fileCount":40,"unpackedSize":1845103,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfKsIOCRA9TVsSAnZWagAAYmEP/1jFDm1sHSx+LdQJGdjW\n9FFCwjzPyb93VlG75cPF6Is8rrFvWLH6pLiYiROkcPOYLQLecCL/5mD4lPod\nGc5yWQ23fiVnPWmcFQKPeKejmHtlDsIeVE6qs+JOz+P27E65B3JHN+FhIP8K\ndbAf5BnT8+m40iLSy6JbCzpknQviDnfbmOmOCqZD7blJN4ESecQyT1tVaN/h\nSyS/TxAQ4oEmU7SJwK5Vr3bcAbB5c6aIcF6R9xfd1dBMylAiN/CFoB2xnzCL\nDvF4DH4vWC9ApRVvZOwv0sKbyIJJ+Gtqnrul6SzOHi5bPkDiG0u9Mcd9+d+1\nEV/ShIO65PLR53R9RCpQgDUPyDVn92DKzmmQvo+X1+w56TIqW1LoBT76DZO/\n37Xo/rMR9a8sPUjtRJ17yTB/h4Hfv1vsoMwsKZthCa81Kk6dIZ4dc0m9onqC\nd99YBxQhiEFbt6/KBQP3cyLu/87rh124S7ijSGeU/galoRdavIoDcjYa45vU\nAbZ0BiVimsOU/cY4YRA2pQ9NWOUr+PQi3WiJ9CZBol0lT6Jorx9/LCxxDaiB\nc0EroPiqkqpztslsQAatJ5BT1eh0LvZp/10cm7lyWxD2sZFJfxlM9Iiya9d0\nF7U/TrpqnJuA/Iiw5W54utC5COgDOWbJS13wdrd7xIBJjuCFyAGh8YQeSHJL\nQx5O\r\n=DpTN\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCCRae2+sKcYhWcunJ845wbtsLLSqz94VC3wG3J/Ux53AIhAOll/kLg4K/P6BC2w6M6e++SH82PcG78LJGcxGxE2cwb"}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"i@jhuang.me","name":"jlhwung"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"jlhwung","email":"i@jhuang.me"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.11.2_1596637709568_0.8214580666748146"},"_hasShrinkwrap":false},"7.11.3":{"name":"@babel/parser","version":"7.11.3","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"git+https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.10.4","@babel/helper-fixtures":"^7.10.5","@babel/helper-validator-identifier":"^7.10.4","charcodes":"^0.2.0"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"57b658c4d83db6874dd3d72a5a653c5b2cec6e78","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"bugs":{"url":"https://github.com/babel/babel/issues"},"_id":"@babel/parser@7.11.3","_nodeVersion":"14.7.0","_npmVersion":"lerna/3.19.0/node@v14.7.0+x64 (darwin)","dist":{"integrity":"sha512-REo8xv7+sDxkKvoxEywIdsNFiZLybwdI7hcT5uEPyQrSMB4YQ973BfC9OOrD/81MaIjh6UxdulIQXkjmiH3PcA==","shasum":"9e1eae46738bcd08e23e867bab43e7b95299a8f9","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.11.3.tgz","fileCount":8,"unpackedSize":1423216,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfLwYHCRA9TVsSAnZWagAAqFMP/ivE/kWjcjYNo3QWmIFR\n9UfwCETTZBx/4VDTs6I3NlMvWO7Wyqva88PaPjfwpo/ktR35baSYhXkkVDuX\nuxq+B+hJxHm/CYxjf9n7a2H9jl8eCcfRw1h3xssVveBXXNVoNUuYTX1FZOt1\nIeS2iR3YclIlXgn6Ue+DkHg0U4Uh/UCp7OubhbLl32Ke2qMNlI5tXqHTPtv7\n/ur4jNR8EA2nCEssYRiTOaSSazAMLXwXoaIi+cVTgN+m4WpDv9m710vIndIP\nPt/8ggeSv0A5PuSZEPhP1T/2MnT/rO5rd2GOyGaR6vamP7nVKmYJMwHUpmw5\nhii3bIYaN8U5NGGcN8Cm7wYY2feKaHdvI+Y6O9frQg7DYkZgEVPm0Y62DL8Q\nKUM50N28G+oeQMjqGC+lkh0g+Xv1Yz5nriTTSPmxPB11EIEnHove0OnvyVAf\ngobNyVDJXXnQ1YF6XaiT1LFiMi1vXoNC5TbKsHdRnwPsxywmFx3H/7i81JVg\n+mgrpwmA3odTcKUmGqaBzIXG89piTGMqbS2o5NxTaMZmNt0P2Bs040qeu4Jt\n//am7o+nSuBRYhWdwCLEcQrflRVS4MaW/uZFL4yCTnGWOwsq0gaJC4A05xCx\nDEDuOf2V2raoQAR24/Qwc+JwDTJ041EDs/E4czgFr5e92JaqSfZ4j6kjM3LJ\n7VMT\r\n=VKP4\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDOCUe7XTAnaoCeQSzNsKer4inPD4H7M/j1S+vKU4GPVwIgAIqN9c9izIP5u12Dg0Pg8TR6NVR6/6/gP8xMko+Ql5E="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"i@jhuang.me","name":"jlhwung"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"jlhwung","email":"i@jhuang.me"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.11.3_1596917254770_0.5883922625570004"},"_hasShrinkwrap":false},"7.11.4":{"name":"@babel/parser","version":"7.11.4","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"git+https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.10.4","@babel/helper-fixtures":"^7.10.5","@babel/helper-validator-identifier":"^7.10.4","charcodes":"^0.2.0"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"90b198956995195ea00e7ac9912c2260e44d8746","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"bugs":{"url":"https://github.com/babel/babel/issues"},"_id":"@babel/parser@7.11.4","_nodeVersion":"14.7.0","_npmVersion":"lerna/3.19.0/node@v14.7.0+x64 (darwin)","dist":{"integrity":"sha512-MggwidiH+E9j5Sh8pbrX5sJvMcsqS5o+7iB42M9/k0CD63MjYbdP4nhSh7uB5wnv2/RVzTZFTxzF/kIa5mrCqA==","shasum":"6fa1a118b8b0d80d0267b719213dc947e88cc0ca","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.11.4.tgz","fileCount":8,"unpackedSize":1427066,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfPsgkCRA9TVsSAnZWagAArAYQAJ6GjnUqNJGJU3fnOkng\nzNFBCy4hTjVHhAy83IrGhlVn8qDqSx21FRWWmYPX5U098rkmS8q3kIvUB5Da\nrgWhZmvNmISlpbtqYCeMw96UvG6KQzHEWWq1Eed7701OqRWKTuoqFBVCRYnT\nYIzEvLX8ESNCAL9wBpLFwbxllh2ZJL2rK7o/pFTMYNltF+Gnb760VZCMD1f2\no9BbZIktSAeREx1gtg7T3MXg9HSvMXc05egLNYakYheFF5DyjjOeBKAYWf+Q\nmV9Lmlh9cmTGIvwOYP9Ij3Xc+6lXWVpDePU/293WkF0HkNs/R7mQapeIYu88\nPuykVOPGQ0KEPjmYr9merUW3C4z9k4fHC/hCX5yEeLekeuwcBb8GDTU+5pQN\n5d5TJqG+eGarxYDW+7BMMjR+Bg5WwrY5eQlmNFlAsyZDkhPPYaHMozUrBCTb\nhe6jqbfxIbOUe/7E5V3QUtRNuJGbypBzY4QGCcE5V1xLLqGjD0AHP0MlBlCj\n5p+dY1ZIkyPAtopFBsDkCL+fdIwNei20+1BqYmITMNAQx4lUGI9gWdvt+T7T\n21pgdN2ELLaegqmpM/7HHbvZUlOXAQPFvbWApfmtd9Fc5yWtkdoII5vZvwH5\nEWfx1s3Mh3sk4/2kqTHmjf5DJCn+eZYWAejLyyTEd2enCaNVgQyJJGIxxtgJ\n5g2i\r\n=pbtk\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDyBYcd6+qrSVe9NFBhDxCHCdlH4Bdiq85tpj3Eo6oNHwIhAOB6atsJsf3vCn5n4usBcEBOITTdu8nmDzmYGS0W6C5p"}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"i@jhuang.me","name":"jlhwung"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"jlhwung","email":"i@jhuang.me"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.11.4_1597949988524_0.6822645120132651"},"_hasShrinkwrap":false},"7.11.5":{"name":"@babel/parser","version":"7.11.5","description":"A JavaScript parser","author":{"name":"Sebastian McKenzie","email":"sebmck@gmail.com"},"homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"git+https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.10.4","@babel/helper-fixtures":"^7.10.5","@babel/helper-validator-identifier":"^7.10.4","charcodes":"^0.2.0"},"bin":{"parser":"./bin/babel-parser.js"},"gitHead":"af64ccb2b00bc7574943674996c2f0507cdbfb6f","contributors":[{"name":"List of Acorn contributors. Updated before every release."},{"name":"Adrian Rakovsky"},{"name":"Alistair Braidwood"},{"name":"Andres Suarez"},{"name":"Aparajita Fishman"},{"name":"Arian Stolwijk"},{"name":"Artem Govorov"},{"name":"Brandon Mills"},{"name":"Charles Hughes"},{"name":"Conrad Irwin"},{"name":"David Bonnet"},{"name":"Forbes Lindesay"},{"name":"Gilad Peleg"},{"name":"impinball"},{"name":"Ingvar Stepanyan"},{"name":"Jesse McCarthy"},{"name":"Jiaxing Wang"},{"name":"Joel Kemp"},{"name":"Johannes Herr"},{"name":"Jürg Lehni"},{"name":"keeyipchan"},{"name":"Kevin Kwok"},{"name":"krator"},{"name":"Marijn Haverbeke"},{"name":"Martin Carlberg"},{"name":"Mathias Bynens"},{"name":"Mathieu 'p01' Henri"},{"name":"Max Schaefer"},{"name":"Max Zerzouri"},{"name":"Mihai Bazon"},{"name":"Mike Rennie"},{"name":"Nick Fitzgerald"},{"name":"Oskar Schöldström"},{"name":"Paul Harper"},{"name":"Peter Rust"},{"name":"PlNG"},{"name":"r-e-d"},{"name":"Rich Harris"},{"name":"Sebastian McKenzie"},{"name":"zsjforcn"}],"bugs":{"url":"https://github.com/babel/babel/issues"},"_id":"@babel/parser@7.11.5","_nodeVersion":"14.9.0","_npmVersion":"lerna/3.19.0/node@v14.9.0+x64 (darwin)","dist":{"integrity":"sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q==","shasum":"c7ff6303df71080ec7a4f5b8c003c58f1cf51037","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.11.5.tgz","fileCount":8,"unpackedSize":1480522,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfTVdGCRA9TVsSAnZWagAACGcP/2lbxOyXY6rVuUn/wCWG\ng7kq1QfwegUD4DcUXb6Vn6lE7g5JYUXgAXVdrRMxIROiNXhTUVSECaCtRW2E\nURFAFibgMTFbA73br5fWwedQ/3/eML3Bj8EG5U+vPTOSBjjRKj6cCkUxqpI4\n7NfiTxnIIyGYd+GFL/0sFnvreW8RQRqyLB9+qNHZlBq8BDDxFatam7simsR6\np7ZLiehcfPxguUKqc4WsurNChnl5P1jXg+OLjdSDjFUPDUYYDW+/g7YHj1tT\nt9RUVjUkEze5FVJvigNwG5+LKRsHuQFExRIg0iRdZyWLeEpYhwB4FnGGBh0R\nBuaVRHN0cbwJY6zQKMT21EZ38biYt2wEKrfLGkTqHFbCajROBmkfEzGlMqOM\nn1p4aH1bVEKhWccPpT00KYPMF+iQ/I3+uJ9JXk6hwi21iqKJEEEN6KDCQj1X\n3ne1EfvdVryYyPmwAi3D0N7IXzJeLD1wwNmas7A0BNEduNKMOCw+Xj+FuilK\nSX5YVJfXsFpyxmyfJjFucGg6TriqRINXb/I45EeAp+DaR3zA0ze4aX5RzlK1\nz3yBhjGo6kqhsR54z5FdNe8dsEDbQFqHLsluwj4bfsfUgQnxTi90qytHe6VO\njlZnky6/PDcZJQbg0kMpS1sDUf2prvsrHm5JhOFL6OzWcHRu83IyjUp8pgM2\nOFfZ\r\n=Hl3Z\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDoM2hUYNDIRTZBerJ7Ayh4f7Ql1ZsNv624M72x+WpW7AiAM88JtBoLBy9sJ13UWpeWaty8hxVcniLPgDNFzEni3dA=="}]},"maintainers":[{"email":"daniel@tschinder.de","name":"danez"},{"email":"bng412@gmail.com","name":"existentialism"},{"email":"hi@henryzoo.com","name":"hzoo"},{"email":"i@jhuang.me","name":"jlhwung"},{"email":"loganfsmyth@gmail.com","name":"loganfsmyth"},{"email":"nicolo.ribaudo@gmail.com","name":"nicolo-ribaudo"}],"_npmUser":{"name":"jlhwung","email":"i@jhuang.me"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.11.5_1598904118497_0.8845642115591275"},"_hasShrinkwrap":false},"7.12.0":{"name":"@babel/parser","version":"7.12.0","description":"A JavaScript parser","author":"Sebastian McKenzie ","homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.10.4","@babel/helper-fixtures":"^7.10.5","@babel/helper-validator-identifier":"^7.10.4","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.12.0","dist":{"shasum":"2ad388f3960045b22f9b7d4bf85e80b15a1c9e3a","integrity":"sha512-dYmySMYnlus2jwl7JnnajAj11obRStZoW9cG04wh4ZuhozDn11tDUrhHcUZ9iuNHqALAhh60XqNaYXpvuuE/Gg==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.12.0.tgz","fileCount":8,"unpackedSize":1509468,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfh1lgCRA9TVsSAnZWagAABDYP/08xIWMan/Eo7XG3ZV4o\nEMD8bcufWpm5piob0FcURC787hC2eEry9+WuM3FyqGEpiqPK8qvOTqEPuAzg\nlwIWIIpzExW/7RHQmXd2fLr6UPTTE2XCTBhokUR/GRWhLxdU3s3DprmZdRPr\nd0RfEEMfkkJOG2xzNqGVnc4mzvZZJFYJ6+Nwe7Ihw0GrKTOIM/SGqxd8FCvL\nXwLy9cZW4M1upcy/JHfAgcJadaxuB65fS129j2cssuvyIYDjbfqTdXmPMowb\nb1fK3W9p2Z2t9zB8wJLLsoOXu1a6Q44QY/mN69jU+8ZQZZdDKfBumD1JfQRk\nshJ8BF6TzA09u3xRqfIuIePagZ1IsI1G8UrI7+X73xJy+8sqjXkgIfS0/GwK\n1AvLKNnPkWLQuuce3ZWM0H0p6MWJ+RSerSDcJ08m3liGvkLx8rKmf946WjLB\njfLDYLC3UNsfShwhb3Pf1XVzLaSh2223aN43RylN+y90KjiL3Ltli1j3p4m7\nyEtRVXnMjyNgBUfdf6hqNI6eVMlXOcAQrIzDwLe0SGlfdNKqL05L/DjbxXJa\njWweAnzbGpk9ck9gsMAaGqcxCuUbD7A1BLPjUckZ+/IS6wG/dEaw2Y/GL9NJ\nChntpCZfoSysCAvaQWobcLUynwQ5MatIb6MvTyZgo4MDUVqxzGoPsE7UrQTS\nUFOm\r\n=w8zh\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDdEAl7SWoL1mvOOdIznIooa/KxSAa0GOvXEsvZDReaFgIgBgiBieUbxVpw7HPPn8JvHZG3aHpXuMDVclnYEc8qJbA="}]},"maintainers":[{"name":"jlhwung","email":"i@jhuang.me"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.12.0_1602705760302_0.06424367707312584"},"_hasShrinkwrap":false},"7.12.1":{"name":"@babel/parser","version":"7.12.1","description":"A JavaScript parser","author":"Sebastian McKenzie ","homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"7.10.4","@babel/helper-fixtures":"7.10.5","@babel/helper-validator-identifier":"7.10.4","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.12.1","dist":{"shasum":"dc03f543a0ed51396d4081463df66ecb3a2efa53","integrity":"sha512-xjZsx0sBjb6J2+QkoHI69UeD2EWbsyUW0WyZKOoJ9sBrQLxfOApWEefR9dIVOYJVj97VRXnLKLDvnn3dPDNgww==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.12.1.tgz","fileCount":8,"unpackedSize":1511816,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfiM+ZCRA9TVsSAnZWagAArJUP/0V9k/gVlUWVpWTUoUPD\nZnLWlIt0V94ISMKYxpeVSxsYMXFadEAUI2GgPoBtNy4ReIswXamWHW6J4cXW\nkRDx03heqIYgVD61h52giNxReh6FABBFls6qQCB2412Lbxwk3aIYon6UJzse\nORmbJ23SG0ziNrVVoImzouSKrLkB7U0CYD2bq21UVT1NG2dWXS+TVK0gwIW7\n5CDcSKlC8QCzNhesodV7QZpYJJeala7BXEKwmlwoxGfO4bUWc2Jh3xkOlJJ0\neafewH0a2GCjpe7DaHZauoXZ80oL0hJOXeD9X5CkNKaQHTlKFAYkBcAZqVZs\nZ/WvL4cGCPUXpSuq/zYFmJWI7jMXFagVhQKvUyz09ILnw0+f/TdiZOGtmzMo\nBimbZcM/b/xmTfQO6m1+WbT25vlZQ105kxJ615ytyfLs1FZuA4DyE6SBNV93\nL4RCOlmEPbU/pfxZuHLxWKelBNP5mv8GgbAHV44xGRSfRLnh+EsffZ/pAEa4\n0cHpblzrnnYtR2Y1scR/S2MaqOzSc+jy6+h/i9gKad3m3eYNdOnhHlNfqcS5\nX0XLA7yqlD9TmEo30KRyQLcwHVWB3MGijFhY263A9Y8Owikf5gIMFCyc8utk\nVILjHnwr/7S/nTkoklHA4P1ZNfIHPKmQ/Ru/QX9QNxrWXLWIzLpXVuzUIpWO\nYO4Z\r\n=MGxS\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGC8qdFA0gxwS5IYRNQfln/Iy9GMEO8vyOJ8TYn3RC4YAiEAm4yAQJ388wGlP97YlCk+ux1D5hGQZ27T4dMAkCNY3CQ="}]},"maintainers":[{"name":"jlhwung","email":"i@jhuang.me"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.12.1_1602801560608_0.6759203773775995"},"_hasShrinkwrap":false},"7.12.2":{"name":"@babel/parser","version":"7.12.2","description":"A JavaScript parser","author":"Sebastian McKenzie ","homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"7.10.4","@babel/helper-fixtures":"7.10.5","@babel/helper-validator-identifier":"7.10.4","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.12.2","dist":{"shasum":"9d2fcf24cafe85333ab0aff9f26b81bba356004d","integrity":"sha512-LMN+SqTiZEonUw4hQA0A3zG8DnN0E1F4K107LbDDUnC+0chML1rvWgsHloC9weB4RmZweE0uhFq0eGX7Nr/PBQ==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.12.2.tgz","fileCount":8,"unpackedSize":1509465,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfiUKaCRA9TVsSAnZWagAASKoQAJlzY45UG4wZo+Qs5+06\noY5h0PXpdw2MwY2Ij7aPnmPPCygiMwaZcstt0+OgcPNNmeQa/9ZiR+RLsuxK\ntULaR7WhxXtHWbOBfOYdML8pHjP5g2jYmvYddZwUHYAeeYZFqGWJEo9cnrJm\nA0CCAd3/YDyI+fYYBRq68uzDh82l5LbESGYHSU465oPOa6C3D7wPSstut/un\nN0F9WEJC7a3Uj0PnkVLeBZhxBCVwvXOt00oRu7EXy7kIYLidB1N7QmzQiPhr\nNIDBmMISMgp5RO7MeMNWiVzSze4Vi2dVkm6zs0ijhM8vDsGxh8OHy39iLcI4\nZ674S1HbR+cyWh1bF+/UzREAryZKEQtLnB2PlL+fwu+0Nz9FHI+Aej1EfQQf\nVo2FNzGhew+XLsx7+7S3MLsSMb3PskmSUfj7CW7RANtuu3BfMmkwdY4a6DWL\nwDkHXUwNSGLHr9cUfzJa1Gas9AqsszdDmIwxgSxhmGAsBxWeQNXVMLrF86fP\n6ItC5K9wfDk0shXvfzmxwSE4KuBdz15i0VJkLwryPpekCJbmLdjY1g5H8s9Q\nOROn1UU6Xw+NronWd4SHz80W9XQqfdNWMeYA72bguUYq1Hc5obcsUuA+b91g\nv0lNAEwjSaAlgmmyJZ06hUYgD5HM/IGuQpkZ3E55jKpLYDtOeUbdwRnMetY4\nNFSs\r\n=OiwC\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCZ4JlaMH6//dt2/MUgJQ/tv1by/sRneStSZINn0KsTjQIhAMkwJrtiQVh3jODCuoB+o3XWd5pmhXxhrW2h+0Kd6+Ky"}]},"maintainers":[{"name":"jlhwung","email":"i@jhuang.me"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.12.2_1602831001748_0.8064044858587178"},"_hasShrinkwrap":false},"7.12.3":{"name":"@babel/parser","version":"7.12.3","description":"A JavaScript parser","author":"Sebastian McKenzie ","homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"7.10.4","@babel/helper-fixtures":"7.10.5","@babel/helper-validator-identifier":"7.10.4","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.12.3","dist":{"shasum":"a305415ebe7a6c7023b40b5122a0662d928334cd","integrity":"sha512-kFsOS0IbsuhO5ojF8Hc8z/8vEIOkylVBrjiZUbLTE3XFe0Qi+uu6HjzQixkFaqr0ZPAMZcBVxEwmsnsLPZ2Xsw==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.12.3.tgz","fileCount":8,"unpackedSize":1509905,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfig0vCRA9TVsSAnZWagAAGgcP/ih5RhU5Po9WGBgdP3gU\nB/3rY72SxGgvBNR8adby26Rqnh/NkEvTynT2zc6CCZE77mAjTw1EfZLwAJeC\nRYaip8Ev6e7kHSWCiYFwZ1BewYKlDGz7M4/JOpwUHYrO8LblkFnNwEiHUZXC\nBbxBas7SFlV1oJRDJMBVP+YOB8LRz6n0A4B49az6mkjiTckIjWaw5X7au0Td\nqsDgmrzQhV6wntexPc19buaAGMuZuS0ujBKk3vUyRWeOt8HvlVK0292kSGMI\ntmu2wBrZYs14Y6/gTfwLH3PFEMTBI5GOBK+Bfw985B4X4pMkWwIZ23hGD67k\nw9n44ORQCPhuMyxQdD7QL29/1cWch6qSRTyLOv0Vuw6X2sT1i+/P+CWHgoaz\nrow3A+bCk9ysjyglmud+xKYEIlZmCyRWyzLIkZpvuPhBwPFtvbhe+vIGcXp1\npQbAumYAg5dJ1lAKcweobtYfCpK+P0bxPSbfIn6y7t4cBFzIK+IA7RYaQM4a\naI/zFhkwmgeQ9FwaeWJv1LZM6in5t8CIt2pwEHrl7wOBEblaKbF+yFQNU4V3\ntTHU3SLMLnaCsjWgayQlSA62lmS3LoAghUvmoaFUbdijzQ4PcAfale1KkIcw\nZL24iCPCbbiFKPircsBL3h0ySkY2UIRO1BPgIYHHRYHFPkHAPRm/jV5AtOcX\nRiX0\r\n=558V\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDOFV8zKCyxx453eQaNDvGz4m5Iv0Ufpwe7w+VfdTNBygIgCgMdV5sJ5tTUD0GlXqe652baWXQmVL8CjglW2ZkYchw="}]},"maintainers":[{"name":"jlhwung","email":"i@jhuang.me"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"}],"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.12.3_1602882862966_0.7466341951761857"},"_hasShrinkwrap":false},"7.12.5":{"name":"@babel/parser","version":"7.12.5","description":"A JavaScript parser","author":"Sebastian McKenzie ","homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"7.10.4","@babel/helper-fixtures":"7.10.5","@babel/helper-validator-identifier":"7.10.4","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.12.5","dist":{"shasum":"b4af32ddd473c0bfa643bd7ff0728b8e71b81ea0","integrity":"sha512-FVM6RZQ0mn2KCf1VUED7KepYeUWoVShczewOCfm3nzoBybaih51h+sYVVGthW9M6lPByEPTQf+xm27PBdlpwmQ==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.12.5.tgz","fileCount":41,"unpackedSize":1949896,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfodrlCRA9TVsSAnZWagAAwiEP/3XhcTV2Y9A9lyHD0Jdg\n36NTUKvlOnd6n0QSqmSXM7pFB+7g2k4ZvP/IjOI9Vbzd+5QCmx4bjpWkgy1f\niicvXB9caEAxfzXvI9ONYdIhpbH4A0JylDxFMdlGg5zWnX7WuCYTovDWgcUy\nJ3tzKgQ3U0sFBlD6AnJeyTO3UTYuTnsNY6inFW4bcOs7dPXfiNnF0H+WM1Om\ntKuDxGvqRZ17CIDN9XNyYnN7LXiiK5mlHyCDpgQXZ8nb+2aT4T91zWVaEHaJ\nbSSCARb0cvl1tMxyFqjPR6HZSq3yH8xSM9M0xSSOQRCBB5i+UaQc3EwrnblC\nhOOgjH+ABJkrdtwOp74qlwl72t1rOGMxfbm42PGWJI/d33/UjFM54YyMVPiD\nfdMW83s08AlWsbiU5PKJ9auvVdfYAN0u3Tnoc/nt5GtMuB85vJF5xJ8adIlU\nCX4dJb1JStHAuHRtMF3r7Y7AtrQ/TmouQdqaol6fTGyIhFpQzrbyZWCTthNQ\nGG3cISqC9qaE+oRM2tZ4bwkqVLPUFZfFMIxy1i9JRyU6MoxJxrurcfgILYmJ\nEZW++68FXarZTUI49Hw+QUgmJaa1fmcGvLjOaAWRmgH8IdVGFOSAmUuj2RXp\n5Y1HqYzprjsCod94CTy0VM6cjr4oDAswOirb33SVS4mT848aan6ouz76Z9cq\ncRq2\r\n=8nX4\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD2RgDhVmYybh2IzYJ2jv5tO+pXQxELqhcO7/L2l/HJXwIgITp21OV+gpCa4pqfZ0nLllAhrxdJrXOGZGFQ4jwUjq0="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"jlhwung","email":"i@jhuang.me"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.12.5_1604442853493_0.8297220219054695"},"_hasShrinkwrap":false},"7.12.7":{"name":"@babel/parser","version":"7.12.7","description":"A JavaScript parser","author":"Sebastian McKenzie ","homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"7.10.4","@babel/helper-fixtures":"7.10.5","@babel/helper-validator-identifier":"7.10.4","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.12.7","dist":{"shasum":"fee7b39fe809d0e73e5b25eecaf5780ef3d73056","integrity":"sha512-oWR02Ubp4xTLCAqPRiNIuMVgNO5Aif/xpXtabhzW2HWUD47XJsAB4Zd/Rg30+XeQA3juXigV7hlquOTmwqLiwg==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.12.7.tgz","fileCount":8,"unpackedSize":1519298,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfuC+fCRA9TVsSAnZWagAAmn8P/0jC8hWmIxPaw2snOvH0\nL2TsI7rNqRFRaEjFoH4k+HG+rUbPVCPe1V554hYopvz+wWnkVM6FRHDPH+nr\n5frNa0cxMy1rbpxnlXhmyPyvI+IpwYLtz3vXiev6gSl27xGka0y1SeD0X6en\n4enQEwotxoyPhUA8VBSlmPyD9JE7ujX86hFd4i3/13g0m1F+r615rezxIHsv\n34Q5DKq04b678d3jqY6FvY7ZZsdFXkC8MAwEdWVki96R1oPZ52f0vrPtjRfm\nBhhZx5Ar/0qyosHYKdK2/cna3DBpGxn3BvpBPJBhFRUu/LXyYkqwqY4eXDWO\n7Qor/txNfWkz3XQOIcJGTgbdLYHx8tfzY5CL+QgvDKfH35uSfB6B3LVinv4Y\nsDfRL63mSrEE9cK0Nf/IoURDwm3xMOXMVIp4bqTJEGBSS2yqU5UVJrJbBhG7\nKwp7nq7G+nenfqRT0kncsq5NNkc+lhk0179I2ighBARA4wtgKc/DumKeRYxP\nUZlaMjMCb8vGw9krINiwgJWCxhrc6wx+VKvMUbp/C5n19210qi+akIoGN7rQ\nEhIQl8SzmRkeWKAGQH5J85QechfQ3ZBzOE2s+yFm2oHEsNdLwHpk87kQOdkR\nvhHHVlSRVySLkzOmbmyVdGXhZ/NesrVS3sk7jSekl/VdPkVDfGsR/2sPkEWS\nISDD\r\n=bimu\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDvW3wFHQlDaaXbsbNoJ9DlKkXqN4NkiLTRffR6bitAkwIhAIeO5ml8JK4JS9y3n8ynvbGJlkulLvlYbdgehdG3KnXN"}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"jlhwung","email":"i@jhuang.me"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.12.7_1605906335461_0.5872443362517983"},"_hasShrinkwrap":false},"7.12.10":{"name":"@babel/parser","version":"7.12.10","description":"A JavaScript parser","author":"Sebastian McKenzie ","homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"7.10.4","@babel/helper-fixtures":"7.12.10","@babel/helper-validator-identifier":"7.10.4","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.12.10","dist":{"shasum":"824600d59e96aea26a5a2af5a9d812af05c3ae81","integrity":"sha512-PJdRPwyoOqFAWfLytxrWwGrAxghCgh/yTNCYciOz8QgjflA7aZhECPZAa2VUedKg2+QMWkI0L9lynh2SNmNEgA==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.12.10.tgz","fileCount":8,"unpackedSize":1521188,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf0VQYCRA9TVsSAnZWagAA/RMP/A1r1QNzKOgp7H2iomSL\npehku9oClYbvhD1QAMgrI5t4+ImpPNNXwwW7V6yiNS0QrYvgjABUfUiA3/XH\niuNr0GhhusA1oE1y4Gdbt4gbBs5r7QJ53qGmLjj9aBt9tnKD7E4EYMJCuT75\njWMjPOM7zX/vIyF8QDxhJgGNb4qlUIdyFgMoIye6b0cPpfeNC6MDraD2FuYw\nNkhEwTDB+E/t/z51xY1ifJc2DOgdCV0nj0pvZOLvYvCeiZ6WEcVwwlaCcCm0\nx1+/obuhlnoXxxdzDtxq1bZ4ZkHci0ZzqxDt0ZRaRKIUYL+JVvPWUGv0anaz\nc5aYyHtkM/22ihyLBm28QQhIE5eL7nbspYQWiJqKK5gzbnD2aboddb1LsDi0\nhlN2uUpPKZuk+1u4kv5hR2sWeILUTO77Gp79xxaE/HvKj9dNQXOF8DXBlR1j\nnDtfmYcNOQqFPg9k5RnbhDsAAG9F7kZ4RD8BWIjVpIwIHxOjgrfocCXKasDP\nEc3hFazKFNJCbPHC3Ms6m0YCfcwcxiD5ZDbkLV2CuAVb09gagRWI2OxxN2k6\nVyLjtGzlsFgxV1weByoLgw9a0fp9R1sSTSML5QkW4uf/E8h4YlGE8GXKR4q8\nrVtQ8cJbZTCuh84pCG3D7T5cqgMaQbeqnYVQwNCoYSymqdYkskrlpZQfvKns\n8aQK\r\n=9hO3\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHovf829VDhbC8Wkt77nkmFeyFNFXQlmHdcgjWV3Zi5UAiAVSs1IBHMwEK39no5OAWsNre5GrloL2IWpxKyRn70AuA=="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"jlhwung","email":"i@jhuang.me"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.12.10_1607554072335_0.08019929620093524"},"_hasShrinkwrap":false},"7.12.11":{"name":"@babel/parser","version":"7.12.11","description":"A JavaScript parser","author":"Sebastian McKenzie ","homepage":"https://babeljs.io/","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"7.12.11","@babel/helper-fixtures":"7.12.10","@babel/helper-validator-identifier":"7.12.11","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.12.11","dist":{"shasum":"9ce3595bcd74bc5c466905e86c535b8b25011e79","integrity":"sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.12.11.tgz","fileCount":8,"unpackedSize":1520522,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf2U3VCRA9TVsSAnZWagAABUQQAJinBuUdRQPQ6bmhLC1J\nJjpm7lDkVcs9YNHjQRRVpOn7HMIriaNQwXL67/8RFsya2XPRnGAf0rFd9uQT\nmupcxB6lqtzV583KufUU+qMoj0zlQn1/VZeEUB83qAKMHJTo/Tqub0MWJ16h\nGT52PZTD1srBVah0nvMWvuJJyKqe3mev8TKhPpYrFLv1DEhF81+4FhsRGdiJ\nfrXXd92gYb4FxZhMtz0v/+szAMNzlXi3hVEumXyUnB1GqmCp1I0avTVqco9V\nrEH0FNkSX4oWUSoybeXEuGHZ9faE5X61P/Z0pp0FvsJjnwCLiTX/C22z6mXy\n5iZ56MMm1wDXit3EX4l4gRFdyPhF4G/MpUNIxwm4hAE9rzorTKDqtnnX4DOZ\n+G564DHn6VmE3VEpbB9NEdPtSx3SazCERQPE1JTHuC2l5QldAvFot86TbmrV\ng+VaKTyr323jBke/caockLDfNZnLo7Qj2S3bM2owZOjB8oevguj1cMWGVZ9a\n7O0jWUurgxMgib27Nk7/Pn00tyW/XmQ65KuVFeZ3c0v+czCw5obR7SGRvpIQ\n9MH8Os0QxX4WgSK+L6qBZdhzXmLkf4CG+p4nYtMtCaYC1hWwhePmr+ftp/pM\nouRWIUnvKKuYr50PFJnjoNF27Yi8ktDTRtXQJnThEjj1ER8Wq4fwULKzamGJ\nSYKJ\r\n=1kIz\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC7XiGXJzw6g4iAAe8ZQoUWmx2oq41DzoufQb2g6MR7VQIhAN6ZNlsVA+yiIqauMU2CU9UGfa11iA2j+CJybHa1rd0U"}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.12.11_1608076756592_0.37835680069460587"},"_hasShrinkwrap":false},"7.12.13":{"name":"@babel/parser","version":"7.12.13","description":"A JavaScript parser","author":"Sebastian McKenzie ","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"7.12.13","@babel/helper-fixtures":"7.12.13","@babel/helper-validator-identifier":"7.12.11","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.12.13","dist":{"shasum":"3ee7be4131fe657ba9143d5c5b3a9f253fdb75e9","integrity":"sha512-z7n7ybOUzaRc3wwqLpAX8UFIXsrVXUJhtNGBwAnLz6d1KUapqyq7ad2La8gZ6CXhHmGAIL32cop8Tst4/PNWLw==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.12.13.tgz","fileCount":8,"unpackedSize":1531794,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgGfffCRA9TVsSAnZWagAAnQcP/izpG/YntzGHlB7MiJfQ\nFSNf4m5EiXbW9EgGRhQFxt17Ujva8eOQZ0EARvCUnFx2gx0JYPwq74da7BTg\ntv1dvXrG9MyhiANGfjqKYmDBsI16adrDEYtcUeOZ0bD4A01nh4AjtCZWUxYB\nbOlWF3Td7DnUKqGBxu0lsJVJPa2/a0Rt8AV2oXgl04qoFNzftIbZltkKtEhU\nBKlyGCtiyKIo47Y2r1qvn0N5qQJqjurCC9PO1l2FwHOmGnA4drJXW6HNPE88\njOFhZg25rzvvFmrDdtLOWcyMrzKAdsiBoooluPd2EmBTm5LMX0yCKamfRUlX\nC3jvckHb07MwypmRa/5HiAV/8RdOaXkKWIcXAniJbfT+RHNBUh75cW6K3Gis\nDJb405omOtTN3qZsJ6YVFY29MQttq/RGdilsbpZiK3sFEAXkDTOc2d99SAAH\n+G/pJHiVcWEVU21Gqq5H4gMW8dUXH1GMQhoavLQ1HCvR77BKNO3Xq0HGGcdV\n8KbCST1oHkMmMKTjW2JIeca0rxEjTwwHszS59LcfL7hiK0j6+BXYeTa8B2nU\nH45xahsqSDsdA7LWXwFB1sUsqN3wjDIaTavUMFDp1tci6Efoq4TD/dxXij79\nBwcSV9yX6lbXzJVRLPkH9CmGlRA2qG/UD9qBLtHt4p6sB/hyZ12UE0a9ATf0\nnaWi\r\n=txsj\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBsZF3OM6cxlQQ1KeHpKJUQwWtpFBbRqCVC1PpxiVSDQAiEAsk0xOxKUmKdCl3vKozbGAUYuxUYi1LMfG4sxXAz3S5s="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.12.13_1612314591173_0.06402163959312834"},"_hasShrinkwrap":false},"7.12.14":{"name":"@babel/parser","version":"7.12.14","description":"A JavaScript parser","author":"Sebastian McKenzie ","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"7.12.13","@babel/helper-fixtures":"7.12.13","@babel/helper-validator-identifier":"7.12.11","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.12.14","dist":{"shasum":"4adb7c5eef1d437ef965ad1569cd826db8c11dc9","integrity":"sha512-xcfxDq3OrBnDsA/Z8eK5/2iPcLD8qbOaSSfOw4RA6jp4i7e6dEQ7+wTwxItEwzcXPQcsry5nZk96gmVPKletjQ==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.12.14.tgz","fileCount":8,"unpackedSize":1531794,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgGrv+CRA9TVsSAnZWagAA+F0P/0xLdyZPsAVwipypX1n5\nI8WXLrkx3nMAl3P2aZN3IhBBXuc2TuvZ0p9qb2X5WacIPTJfsLkAxwABQPPk\n/5feyBRChWG1zFs8P5SC5VBV/MOOTnqXs48sdhH7sPIqq9y3cN93r0vUNhcs\nqTiQqntCeT51xsFK9VI2y7UcS2zsDddZSJX2Osbh5IwiL6DARAw/Y8V7FV7G\n7slAd1G3P6AE3g7o72vtNJN9cbFePvstBIrX1/1p94WJCLyDkGvnUPpWlHZb\n7EnpEa1hgyecSoZ5Q6y2N7v1yumKhIIMSfafvhE8ZaiHfDdU5vjq34zxheTG\n9Ft3t6fdC8SnSswXbzTuaLqcGHgnWapwVOojxwRic+2NsmKrR9MwK073qx5j\nDH63y7jpkRzZ/yN9W9r8QOZ3Zjd7s/hFwxsmoZFGZyFGSl5xHdoJQeWslHw2\nE/LYJsidBnpfoi6oBDEGa0Ekffxeq32U9lw5ze2xHvOhWLHssNITQSsTKXNq\nrTl3a2mXAXKciyDeN4x4PY9pNXXMU8SAvkkd8Qqhf8orsmj1bagH/W9Xm/7K\n+8YaejI9ityqRiH27xWOl0RysliPRWPiCXzttqC8sfo4r3CX2CdWAdgDbkCG\n/+qDFHdxR5TOfreUmMN37HtMTLst4yErI2hvgYQrkjS3mCOykeNGHOnu0A7b\nXqv8\r\n=cHdW\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDAgk9Ko0ZxNlwB/62JcrHXnuEOdXUqca2yBiA5BSS1fwIgUYFerSxTlVdW4YRJ66QqFIzcc1Mu9yGginXgRDgPsaw="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.12.14_1612364797457_0.12477093407354323"},"_hasShrinkwrap":false},"7.12.15":{"name":"@babel/parser","version":"7.12.15","description":"A JavaScript parser","author":"Sebastian McKenzie ","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"7.12.13","@babel/helper-fixtures":"7.12.13","@babel/helper-validator-identifier":"7.12.11","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.12.15","dist":{"shasum":"2b20de7f0b4b332d9b119dd9c33409c538b8aacf","integrity":"sha512-AQBOU2Z9kWwSZMd6lNjCX0GUgFonL1wAM1db8L8PMk9UDaGsRCArBkU4Sc+UCM3AE4hjbXx+h58Lb3QT4oRmrA==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.12.15.tgz","fileCount":8,"unpackedSize":1531735,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgHGk5CRA9TVsSAnZWagAAanYP/3Jx6HQTKtUzZEfU/Tz4\n7U8Sz4EIe469BFPVXa8ipAXLIX4AmQj5nHefd5mviQC6WuMjcW7iFk5jgl8U\n1oDb9MwnUnhrRxcXsKYNNqgKQSeBcnBpOsxaXJmVSaAy0hmqvGBQcwXWLfYP\n/Akv7xfEdmMuW2A2uHnx8hnc4zBoYdICfOjGNP9EpTipqRV2+9abSkXQ/0w2\nfat3pfLPGy2bwvEf84/TTaDJz4ZSwCjfG2sWPvguOaZirPQ7JgUP7aEVprgg\nyfk080eQYO7Tz7bc6dGWtBsjn2Wx3HjncLk11ynuRilmBedNNEpkQHYzEJEt\nBHVdaGRLTJusFdGOASbkt7aStHL3plYSYkLWiAZp4BrzA06bNdDKDHJtcjE5\npOcROgC8eipvnn/L0J2L+El9XUani6LdvwiG4veGYuCiP/cOC/2YE2ujLbJy\nZcOmbU7TRv3+S51SzcvROC5svcqfimla6XRE+PbaQ5yNC0PDesu81LWDa0AJ\nIkbZjO06Y527NH56APIrSJk5CRM9EzJ/lju6Td5JkbWixNZlFd2jP3txLG+B\n/39Z97rTiOBLpAWNp3rwRSHsqSS2bdpAg4A+u93Y7h3SmQnj3B9RhUUJNy6t\nsZvoYizJtNvlFVQStlDoeRGH9X02VTcRvVAOF6jwrbQY+ng8Whs1SNDSTaXx\n84LA\r\n=+6pa\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCUdI7+LMfgb/o/m6tCfLlcT3krM8UlyiRxwnmZVuV0UwIhALTXLtaEDS3UxqxiailoTd956YhOJiQkPEw2nvp/sH5X"}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.12.15_1612474680548_0.9720103998281782"},"_hasShrinkwrap":false},"7.12.16":{"name":"@babel/parser","version":"7.12.16","description":"A JavaScript parser","author":"Sebastian McKenzie ","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"7.12.13","@babel/helper-fixtures":"7.12.13","@babel/helper-validator-identifier":"7.12.11","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.12.16","dist":{"shasum":"cc31257419d2c3189d394081635703f549fc1ed4","integrity":"sha512-c/+u9cqV6F0+4Hpq01jnJO+GLp2DdT63ppz9Xa+6cHaajM9VFzK/iDXiKK65YtpeVwu+ctfS6iqlMqRgQRzeCw==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.12.16.tgz","fileCount":8,"unpackedSize":1540097,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgJbPjCRA9TVsSAnZWagAAxt4P/18+LwwKMUQlBrv3LIy4\nFsBLLlRZosI7vlss23L/h3zAINKUq8wQMs8eniD2jp6icbIOLw+a/2a6xUa3\nzjl7rhkAVBe1Rr5c/JkIR9KEfeRghQbBcYDTnzQWGfiuzwCocfdNqDc/RGPP\nBpoe+jxWGTeAmj9JPPc3vxXJeFMuXM4DnqhvBYAvZrsNxgLOB5yi1diVv7SZ\n6I5Ll1sAYPXc4+J6gB+vN+uLa/D3z0tAFBgD4OuTguUucjlzNRO2nRc3RZLk\n/3IKUIGMJngkLWmNnwT6QtnG27kP2TtqIs5KY4kNFsE2nAQC6u9RbG7Vluv9\n4hvg2TvmieXsTz+sMbkn3Z90Rby+Sc5W5HDChlxhn/dyAWGeCdhOvgVRZ830\nim2KpHPGv4BcxAPr3VtaZ5jmKXj1ziwX5xXwWlut3k32V5swwvWw2ZHiWzgp\nVP+Bg0fVrrGXnGpTzTloVVkgpS6uYGNvDNsXLbR3eCi4xS+xt3pzrXgYm4Lf\nD994Fgu35/fJ/Cf/yP4Ezjd5h3dB7jH6Qu1bFmpaPYHk0xE172NISLJG9c0f\nc8Ms4wvYcZJI46PWnkiywk6uRnJfUv3rfLIkMWJKdEFAFoNyRnAiX+qHFbbM\n9o1Dh3SWMN4XgfR4zCPGkHHyKqTf4kOQj7/q728KKz4WKkOWc2Ol8ZyXsjic\nieI1\r\n=Tymf\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD84nfNaNIv7pMzqDBnuXjyKJb1JSYuc72AENVnXKESEwIgDNnuV6v7fvslXBQ4VJdODodPaETod5enPXSKB80VDQw="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.12.16_1613083618548_0.11393158518300961"},"_hasShrinkwrap":false},"7.12.17":{"name":"@babel/parser","version":"7.12.17","description":"A JavaScript parser","author":"Sebastian McKenzie ","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"7.12.13","@babel/helper-fixtures":"7.12.13","@babel/helper-validator-identifier":"7.12.11","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.12.17","dist":{"shasum":"bc85d2d47db38094e5bb268fc761716e7d693848","integrity":"sha512-r1yKkiUTYMQ8LiEI0UcQx5ETw5dpTLn9wijn9hk6KkTtOK95FndDN10M+8/s6k/Ymlbivw0Av9q4SlgF80PtHg==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.12.17.tgz","fileCount":8,"unpackedSize":1541792,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgLoOeCRA9TVsSAnZWagAARVYP/1eyFawDTs2reCAOG9uQ\nM3iFWRDvjQ6hr0UeypYOae71AcgVGReTB81iVW/pAL0AbhcnRhij0W2n1DIe\n/DKYfQJvWdcR0Pat2Jszrm8iQOTJcGlmNIi7uEd+J3TB/AzO38L0wkujRuyn\nzQ0EvR3yTFTwrVd+/Z+YZR23cw4CFRcgXhp9V0S+TW5Grc2J1X98oYN6ywbm\nNYfM9AkleOfFvZK9dTNHYoaI/nK23bW8DT8gg7Wca4aF7AdqC/BpG4hwMUBU\nQ5rElj8x2s7RsJnhRLSfYZmqocC4PXsViaqBAoiUaxUni855/uxAlcnx+Set\nUCcknN9E28AS9VJ8bt+/MIh9iQ/OVEpXuJx3J/2CGcrE/Au1JWb03PkeN6oz\n+9mk9mKORcxhLnMGuYr0ah/vZpS4d2cjxEbebDeRR9w7VFiPC2fFaZunlvVb\nJ7vNleqbcOLYKTYcXqK5ZOHFhKLotTaWgpzjWJDcmr+6SrJBMbxLi60sdP2w\n5kqQGQWLts3IfiKAcZaw5cugT9AlwDRREPR4bMRSTnKk8JVpLopuP/NrBgi7\nC/LLmfxtSEkh9nDLdHebK5PC4h7bVLkyahQm4VrbBpl59AED4ClIafffrGLQ\nJ0cGkhT5jlG6AzfZjduha75wVvDq95VRDBrjb8FtaqLSVl6JhRfOqlNNYZSX\nx81d\r\n=b18q\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEAQn40SFh6aBKbWbm2TN+h+cNTADUGVvOasZCm3zrIjAiEA88ibf/3Goqda7rL+8n4UYliKrR03v/NGF+leTpWBp38="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.12.17_1613661085579_0.2092093904526109"},"_hasShrinkwrap":false},"7.13.0":{"name":"@babel/parser","version":"7.13.0","description":"A JavaScript parser","author":"Sebastian McKenzie ","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"7.12.13","@babel/helper-fixtures":"7.13.0","@babel/helper-validator-identifier":"7.12.11","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.13.0","dist":{"shasum":"49b9b6ee213e5634fa80361dae139effef893f78","integrity":"sha512-w80kxEMFhE3wjMOQkfdTvv0CSdRSJZptIlLhU4eU/coNJeWjduspUFz+IRnBbAq6m5XYBFMoT1TNkk9K9yf10g==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.13.0.tgz","fileCount":8,"unpackedSize":1566505,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgNDT9CRA9TVsSAnZWagAAu1MP/3UYffefLgK0VIWY+lOu\nc0pIt0OV6lOKGYMdzc1JOTdgs1Yt25XYnxiL3g/sILeEZb8kBb5w/QBG0jat\naw8+EqR6lZlPfJkAqDVX2WUrVPnhmCOhEwNo0La9hAWHWQ57r83YLKDppCag\nBDj2T/HfHt3+Wgfgaj3/91tsdFrKR47muF+c7nOBS3k/q2TWdzfrN17BwBuM\n6JQXxFa8LsK3bpD5YjKXnrblM0yMoDXBZy6H1Bh+fKf4Yh/TimjxzzGP0MOb\nNe2NSs83dWtFx3DGRNTSUGehgqX6+NeuvZICqFz4PiRebZn17g9+Y+2O662w\nUXeuVcO8Ve52GSN11exIHroX1krTuXi5jeEO6w7KExKgTl/4Df1LHHgvJopN\nYX7QZEfDA59CJA36/GdgVlRRVWD3k9CND+4o1SPjyz3TCnXX3nUEl508ayxF\npnwtMNFH2/Pr9aXXKRsHNOJg+rb10SWFzjuz3ILvdqnuTYj76XxqVINM1a84\nPKTonxsGpCFKyiG9f36GPJPTzE7p6nB5lY09ePeHO3aytGSUoUSCEkXInRuz\nh7/jggn+Oy5r79mw2EiplDmBlCmkvqFNPudrdtwnwroMjNMXURd0TOqSd9TT\nakb1G4To0CYkWrc52RSHn3MurMkIEHp0J2ERTDOZ9jyVcA1wT7lmJcJqcrMS\nzzm9\r\n=HmGB\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIENAfuBE8K/qkCveNZe3ttN7WupjjzaE/h+uNU1gvO6rAiAi/hk7+vFzoE0ta2V3fJZG63GNc0aPe0RP6HIbxTTt5Q=="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.13.0_1614034171769_0.3242259984474012"},"_hasShrinkwrap":false},"7.13.4":{"name":"@babel/parser","version":"7.13.4","description":"A JavaScript parser","author":"Sebastian McKenzie ","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"7.12.13","@babel/helper-fixtures":"7.13.0","@babel/helper-validator-identifier":"7.12.11","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.13.4","dist":{"shasum":"340211b0da94a351a6f10e63671fa727333d13ab","integrity":"sha512-uvoOulWHhI+0+1f9L4BoozY7U5cIkZ9PgJqvb041d6vypgUmtVPG4vmGm4pSggjl8BELzvHyUeJSUyEMY6b+qA==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.13.4.tgz","fileCount":8,"unpackedSize":1567784,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgNNuWCRA9TVsSAnZWagAAPF4P/jZAAGIn4hdeXFoBBsXy\nt/cvzOGTFY+XreHwlSR3Aj9utlZCcnyCtI8QibDTv+G8O+V7QbMujGMzNIx9\nTsUTJ3rBn4P2igXx3IzbwYhWkcW42lHzfJDe5LMO3S/E3wTMy8UShsbiJ36Y\nOBvQEkp6ISJlQbxsbsoFmaf01kPif3xMMlh637bhfInXcROlNf/VXNREES1M\nIDjR0ZHC11IidZGUkTp+QCxtZGVz+TwXhrGfTmEWnnaEEWLqz5fTi8QhqkyT\nJHxOKAqf675c3wzAlmfKgDovNHbqciTgRFMvUkbI74x++TY4KtAOqjYFsFyH\n01jNaJPyU9ZPU+LGM2Cs/QoKdh9BRN3jbNzaOXpw8Cv+uhjgL5ljsJ397zBG\nfO9WLP8f0okNwQVOqO2uCKSVLAgaLlY5JHKbQaMpbV3+Uwop8eYdudFhE0KW\naD+aWLUNTnTVtDcC20EHCObjmQYgSciJAw8NQalnA64IA4xONNKC+BxbWGZE\nN40wu93RNtHQP+GmJ8ZlLanIrSyyJKWXacominYCx30oB9wkakGgsH5Q8Eh0\n0kLgpvywgiIjNkzMosvWMpcdF4XfJjdPkZ1Mb85NAeUFJ1DwJtIarmv5uaVY\nJ3g9ID3U2ok2santaluqhGAZdANCgFKHl5As0O1r5sG6hcS68rUuy29U/S/P\nu3Iv\r\n=NH39\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHSuvT0oxNrVm8wQjGOTIAaONci6Yd1tV3GL2kFiLc/KAiBOYcNOkqxF1wzE1GFAyrXWnOFo4DGG2AbfZlG3rOvCRw=="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.13.4_1614076821832_0.2806814257250856"},"_hasShrinkwrap":false},"7.13.9":{"name":"@babel/parser","version":"7.13.9","description":"A JavaScript parser","author":"Sebastian McKenzie ","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"7.12.13","@babel/helper-fixtures":"7.13.9","@babel/helper-validator-identifier":"7.12.11","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.13.9","dist":{"shasum":"ca34cb95e1c2dd126863a84465ae8ef66114be99","integrity":"sha512-nEUfRiARCcaVo3ny3ZQjURjHQZUo/JkEw7rLlSZy/psWGnvwXFtPcr6jb7Yb41DVW5LTe6KRq9LGleRNsg1Frw==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.13.9.tgz","fileCount":8,"unpackedSize":1566001,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgPWAfCRA9TVsSAnZWagAAbEkP/1YazCjG1Efdco+OMs+3\nUYoinOfOJ1xp+LOr1/jQ5qXoclizQbofIQNWYsIYV9ovAxiCdYysJKeVlnWe\nhrMpp2kf9Ca8K09KWQ3Tt0mH1X7O+lXXtay2ydS6ZHilUBO+3j900R0IDkzb\nj1G7YMl9FzsUGKQil3TIfUEO3sTjxnAjEGngmu8hKoNhCwquTnDXassmnNL5\nBop4edhNyaN2uJgjW4Bwn7D+7fho6EezAQ377bcVXrYElBf5zQPaNus6/NFe\nxmzANJBT0Yz6P3wKW6McMlqP2IT8CMRZb1fjRYrxkmAMvrrUJjr3nU+rkFA/\nvnUDdESSwFQ1stNCc+uByNFBKhM7prAY6RPoX3iDmHwzpaBwJhskHF8WQnkA\noEHNzx63gxMTbxDk7jbPQL38X59K4qJ25NUIBp4QiMRmV5iCVDj7eol4FGG8\nzVOpIlXYkAhVqzfOJTvnIpSQKhU7R6XlPVAZmaJAq79cI+CJdXYzCSy9SB6F\nItKIYxzSNkAV9nGwavyUESDCrKKuSiDKnNroZkIVDZRRZm78TWdFiQSe5X4x\nX/TUZcpfP2ZPykCPqCdmemh+j8wrqZOVJHst6yz2a/Cd22YuRJkvWixnyLsB\naIFbdG/Kk7EncCR9Qnp9dfVQUeSk50LbGB7wcr1tW0n2nZol65bwC6Ad5CMh\nwTCg\r\n=bhbl\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHl/S+DZ96082OnND94EbZITF9kH5VTwqOrfjfAdvUJGAiEAzvLn8ZS3BCgqo+Eu1lqyi44BRLuWSbfsusDGl5CZ08E="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.13.9_1614635039073_0.24044719156890393"},"_hasShrinkwrap":false},"7.13.10":{"name":"@babel/parser","version":"7.13.10","description":"A JavaScript parser","author":"Sebastian McKenzie ","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"7.12.13","@babel/helper-fixtures":"7.13.10","@babel/helper-validator-identifier":"7.12.11","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.13.10","dist":{"shasum":"8f8f9bf7b3afa3eabd061f7a5bcdf4fec3c48409","integrity":"sha512-0s7Mlrw9uTWkYua7xWr99Wpk2bnGa0ANleKfksYAES8LpWH4gW1OUr42vqKNf0us5UQNfru2wPqMqRITzq/SIQ==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.13.10.tgz","fileCount":8,"unpackedSize":1567938,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgRqbdCRA9TVsSAnZWagAAsPYP/iSsbqHqKhT3psuqV2TL\ngHBAMiOS8nBKWBgRX8f4aVcxLiNUqQf/Q91dc/seNSMxwpGdg08WdJ9qrfrN\nmgPx6x9coSDBy3A66fzTKYkBm1j6vV0AIdbtLTCcTvOH7vRnR+jPmkqanKcf\naOyKs1600KcxXSlpkDXT9VRuo1K+0NAXxJoPlFWxxEVurpz15tVM1PMXXbIp\n3htOTwZzDIw+Nl3azTecuRcrLKLrbLr1Xo5z/rJNfGc+ZQ8aQFWqfpe2Bgyj\n9fPsEIH1m1Fm8TyNvOVtdzMRVo40oES7Do9GFq7ERx71N502wvJYF6M9k+aQ\nwJ4cnDvYcdJI04VUXeMP6VBk4sTNX91vf2ZL3aRFBFIrsPrKvhj10T6TNn+c\ny+C3n8sWxilgBEQUjwExizFcLdaHpLt9wb9h07MjSqxziETTWmaYw3QSOK24\no6zEZErFj+P/QY5EJtS/2yTp2t2U3q+o92b/j0Pm6+H9KJj4eh1DvQkF2KoC\nz7G3uPSsi6ru2s/YbTI89b+kEri/gKBGQsisav78hdg5ePl6sGlPWOfpPyFh\neMHGRP1Z6ApyQBE8vDCeak7Gu91QiDLXmgEjA6z0Zu2EmNw+1JIfyYIwc5uq\nr885owthBbtODfH5v8AHNFaTr8FvVNmIt3udHxmN30XEMM2EQSZQxs0PeNyU\nlxpN\r\n=7ad2\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDl+y/NjyItTYiSZmE5wYmmHdpGDZMJdL6R2pq9JahsKgIgbEEGEb2jIVyBLvFPaEHfb71Le+NCqQjsfmSQnbvBbgM="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.13.10_1615242972543_0.8889620284911071"},"_hasShrinkwrap":false},"7.13.11":{"name":"@babel/parser","version":"7.13.11","description":"A JavaScript parser","author":"Sebastian McKenzie ","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"7.12.13","@babel/helper-fixtures":"7.13.10","@babel/helper-validator-identifier":"7.12.11","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.13.11","dist":{"shasum":"f93ebfc99d21c1772afbbaa153f47e7ce2f50b88","integrity":"sha512-PhuoqeHoO9fc4ffMEVk4qb/w/s2iOSWohvbHxLtxui0eBg3Lg5gN1U8wp1V1u61hOWkPQJJyJzGH6Y+grwkq8Q==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.13.11.tgz","fileCount":8,"unpackedSize":1568723,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgTyx6CRA9TVsSAnZWagAAOsIQAJN2Mwd43k6gR0v1Phw+\neIkJCk5mmjmfKExddmdHzTgMcjYz6Uj6ID1ZUTkX47DZgGfEnBg+U53Yok6/\ny94yp3/qjJZhb0IIO+vfRQBbrEfhQgPCsCWWO5o28BqfOOkvpLMPp6bWRe3H\nmTG0OH7ez0okggkVniDX+MiEhTaQ4wfV8YPDm3BAKrDzAXesqFkuPwhWW76X\nQVLdV4atR4MpWEeUj/NH3Ev+CGeswTqHz3ZfEAuxdsF4pdRnkyNvzetv+vnz\n/tov0aStJfetI6ZVobSpd1lZcYOQTIVJwJYudBw0ZpVzJl4zi5pWLLS9Pk3Z\neGDa4nOPA7xcDZFHkDU3n+wrMz3OQAJGCe6yvAgwjkruJFxLbRMVLk6qDj0J\nO4UJp7WES/jfvX0Pn3ew+ozINnvc3NIstpYc1FNiYksMI8cYEkLwTDIfyzBE\n/MYmatnlRL/uH9mffY/lm0sVYSE5r46pwF7pDKaJFEWXXFEHQaxms2bDAxGj\nlM5NAlJj4MBjRe+OAFz+v+HhMIfsiJMnvxf4BgRV8uu7zeUlbGlDHZp3pTMj\nvXN5tHbglvF6w79p5fOdc6ooFPyhlXusJ97exmEs0k8gL7fUpjWNJNW4mtYN\nmMUYTp0Ox48Kc8jB6Nb2T8O/YmUpm68+4Z/FpYEgh5K0rTPol9oJq6GqahOW\ngsST\r\n=sZsg\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAPLyPXnXHFGgNSJ2z4YKiqj/YvTe/3nG+oSpILh8JrsAiAKcjrmMSsMBOLtWfG8EfEXRwYUKXR1YKXau40qBcgDYA=="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.13.11_1615801466126_0.9877424740924732"},"_hasShrinkwrap":false},"7.13.12":{"name":"@babel/parser","version":"7.13.12","description":"A JavaScript parser","author":"Sebastian McKenzie ","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"7.12.13","@babel/helper-fixtures":"7.13.10","@babel/helper-validator-identifier":"7.12.11","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.13.12","dist":{"shasum":"ba320059420774394d3b0c0233ba40e4250b81d1","integrity":"sha512-4T7Pb244rxH24yR116LAuJ+adxXXnHhZaLJjegJVKSdoNCe4x1eDBaud5YIcQFcqzsaD5BHvJw5BQ0AZapdCRw==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.13.12.tgz","fileCount":8,"unpackedSize":1568857,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgWLvzCRA9TVsSAnZWagAARcwP/3BQoPDww/sbp+UIk1Wt\nDzmamGk3Wqx1aF7sVw0+aCZKDKPEpQWz98zUHD2S5Gin5s+AGCS7pesYuplX\n9ESxWKAG7ce22fscuca0H8PotCvBCjgs20V80RKoG7P4aOEhxEUr1Yo0ckzQ\nbH6hcEBd4SLKEzaA5mVsn9tYyJJppSzONdQTU6mr2HC+UXvvfM575v6ileWt\nW17kc0/usz5UCWUTG+OLlyhyLLfmdDdAsuBmEH4FNpK92+H8XJQG6XMsBaGc\nCmAEJzfVpyXuws3M6r6wd/oIQHRJjJhsJOT/CFtR3BubQBu/17RMdtpYLuE4\nLdNCMB58CYwssJKGUd48PLNTm1ma3Z5pC6EnGP1K7E6JDizQq4r0gQbURjBu\nAIBm0ngj3aEyyvj1CWzl+OKAFhasIx0yMlcr8RtY1c6cFdJ7+u41ezv/gEJM\ncEiAtA+mHjPgRHr8umJMtdUDe4Mh0n/HR1aMOW6x49NiiLnv/ZRlCMjMRMqQ\nxTvP37F/cmUGM8qbzb740uHaZM6HMdTLJqxdnUCE311AlLXGtupIaRfTEzaL\n/WbkIHHB7j69s6BQZBa3EAhIVdQ+EQ45m6bpSyqqJNYWVScpLbAyfKfmNNXK\nGnBGDEv8DXNTrxGhJIP0c+SO4QVy4/pPAgH2eqAvNWNBGzkgFum1ncNhyL3p\npf5I\r\n=UVD7\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCyFgJeRFz+FYJG+1w54JQjY6OR88SvCwhlRC+qGvqT2AIgX+8ue2gZlHb94rdvcejz2+GqAdHibRePm92n+N5/xsk="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.13.12_1616428019465_0.67526935398349"},"_hasShrinkwrap":false},"7.13.13":{"name":"@babel/parser","version":"7.13.13","description":"A JavaScript parser","author":"Sebastian McKenzie ","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"7.12.13","@babel/helper-fixtures":"7.13.13","@babel/helper-validator-identifier":"7.12.11","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.13.13","dist":{"shasum":"42f03862f4aed50461e543270916b47dd501f0df","integrity":"sha512-OhsyMrqygfk5v8HmWwOzlYjJrtLaFhF34MrfG/Z73DgYCI6ojNUTUp2TYbtnjo8PegeJp12eamsNettCQjKjVw==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.13.13.tgz","fileCount":8,"unpackedSize":1570679,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgXlAVCRA9TVsSAnZWagAAlnwP+wTLXFGqkZgJpq+aY573\nBWeZfWwT2ROS66FDBXayejHhzrdEf+1iURJtYFn7Ygy5Fy6cfDTU9LdHZSoN\nrChRFdl6WoB6s3EwktR1gimOKllSzI1YlbVpBFqKimiIIsd2dygREKR/R04C\nt4D0uXPYTHjaf8u9CAC3Okk/nGSkOzu3OMzzY3k41gwtcyrHL0eEON30HAWd\nWhvlfKTEnBqDkMap58zp7dSVN2d2VbHFt7HFPuyunajL9DOVedZbRdtjLX5E\nretQOfp6ycOxT+7veUZEpK4tNFpWvQFMH2sD5x+RW54bJTpVqywFCR2VO593\nrW7tkvzphwUHcqVioJtF/WGFsZ+OP+nYnOuCubeLQzXB+p1xePOi9A7pSoIb\nPfitUxK4s0Q562E1YcKTRcolzVx+/tMpyv74MbmQ8aafVC4AEhTGzVZn0K+g\nCbzImREbVRN0QY6V6H3NdbvHdqUyGPSFgc3MUlMQXcJg0UTbQ7ExgiQeC9P4\nc8pCWD4GIasAdwNu849jef3OIqPowu7JjTZvgn14tuKUp1kEw/2e9QuQPdy2\nTO21CgBQGiATBCalksje8G1tZoFesokKLOoJQBKYlvd/pH5DeeObkv+dFmrF\nnF6mDzB07wCuOAI80PN5YWXuvoH4q6/DFtmev2SdxwzPK0m5P8TPvisyejLX\n08XX\r\n=d+1S\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICwpI4Y7ERYJkBGnt6aO7zNaXf4F8FwxOx1rMe0tC43iAiAawdJCHEHfKKqKib/kSnbpHbF34+V2dCP4h/q0UUGBUg=="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.13.13_1616793621134_0.506839298478019"},"_hasShrinkwrap":false},"7.13.15":{"name":"@babel/parser","version":"7.13.15","description":"A JavaScript parser","author":"Sebastian McKenzie ","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"7.12.13","@babel/helper-fixtures":"7.13.13","@babel/helper-validator-identifier":"7.12.11","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.13.15","dist":{"shasum":"8e66775fb523599acb6a289e12929fa5ab0954d8","integrity":"sha512-b9COtcAlVEQljy/9fbcMHpG+UIW9ReF+gpaxDHTlZd0c6/UU9ng8zdySAW9sRTzpvcdCHn6bUcbuYUgGzLAWVQ==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.13.15.tgz","fileCount":8,"unpackedSize":1574055,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgbyY8CRA9TVsSAnZWagAADHQP/1K+Vi4Zu7W39O3MOxAn\nsjdGUqPm8SQs+j/mbQwNjQ5i3QOhAkdNmapTQ9WQdCa4S/akhEKLnCHlwYD8\nVG8p/BXnhBUZ08eZNw8xSANNINN0riLwiCGTnNQfqRTGz+MV8LKOJ8a/oirv\nzWPyKzx5BrMiq25uUHWbZx3eHftulZSqCHDXNuCssbRn4KUPHPRpB2wB9GUk\nYZc9KnlHB67JQTnMmszJFw/ChyF5JO4Qv+cxtBrD5sIgOJa/CeYOVGwwzaPD\nN4a8Ee0187Eeg3tjnQgbHQ1w8bVhNjhaAB1Lsbh4/4//IsGpU8FcNV0F7o6O\nNH0tJ41dwoXdtBfGSpDT5ATe8Qu+LEN4A1IXkkdNO3anZSrBcldor5hzfjN9\niWl4ef2ZYoyNTJnTyGfHe9DzTudMUK1x9cnpN2aP082JONo1AsFW/u0vN9So\nKLzpPVuGulLA1deN0rwtncAsulJrjHfIYkGl6EKox2NfthOfyCh4bzej50Te\n9QRFrzWubLREdFbrWyS6QEcuK33YrJaunjCYfMqg+geWE1WYlVYOT3b9xWOv\n+8BCHGJRAiC7jnPRpKz7f/vyFn2sOtcVjjvTtArhpR1E3E7Um74BuSlif9iV\nblvy45jQ3uGh/uqZlYJ5ZZTngRZ2bjEMFetYX5r/XeCv45g2o8mY4j2+9JH3\njzCF\r\n=aH3I\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIASfojKIQ4hfovXGsFA+682W71rDEN/wUKU5ptzfHM7AAiEAlRY63LI8y264hCol7pdMKvirur3jKbJtlAf9DEAYoMY="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"daniel@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.13.15_1617897019700_0.9992938228737922"},"_hasShrinkwrap":false},"7.13.16":{"name":"@babel/parser","version":"7.13.16","description":"A JavaScript parser","author":"Sebastian McKenzie ","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"7.12.13","@babel/helper-fixtures":"7.13.13","@babel/helper-validator-identifier":"7.12.11","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.13.16","dist":{"shasum":"0f18179b0448e6939b1f3f5c4c355a3a9bcdfd37","integrity":"sha512-6bAg36mCwuqLO0hbR+z7PHuqWiCeP7Dzg73OpQwsAB1Eb8HnGEz5xYBzCfbu+YjoaJsJs+qheDxVAuqbt3ILEw==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.13.16.tgz","fileCount":8,"unpackedSize":1569999,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgfrkiCRA9TVsSAnZWagAAe0EP/ROCpPDD5H15wMBpfdnO\nMYTpH0FuZMSVdOFRUaUgSe78kacqUF+9t3LMxxis4XEv7pydSkYsDvvAq2jR\nMiJzCL9I3Pl79xDQ4bV7qsqjWdYzJRFPKNAjPudkwK5QrhsSheAcQpUXmcB+\nUBb+IVqy5/XzJpi/E8VN9FqGsioz0XJpbLKeEoaC/uGbSddL76mHr4dy5wD9\nFWcC7687D8UEbi1X8yLSKIJndhCJ80Qd6GPfQSlckBgF3xUAPvYQ8YkWHFIh\ntgm/0QgC+Nw5wovw+8rI07G0gv7j8+1K9P41FKofHA8QWcwGzBJqSdtzqdH5\nuseLFuf9z9bJwoSOxogwATKbJS6faxbzB91geF2AP1NaAeO7RXKxCBd/AE9Z\n0GxHCEijPxBR0W7ATvyzM0cnO6QmFK8mDahjqhgYMahcbvc4JKoEoRpXYb9/\nR8vB0JKOj1pHqLphLpWu9bXRDZowSfuT2+gsTDrznmKAkKDfzigiKX9zR5xs\nweVMKtKFqtpFnOLMVz6CQdUkBnZ6hyAtQkXVyubdpX29Uzo7MbbwnfLGXPIH\nbYxHbqqVHJSkNUihw8lv+ajxqN99W0WVnuyuVLVXmEMEnNHIO1IA1AlumKdU\nEv4ndiW2FEUdWlvBvBw4r2hoYypovLXiljrUwIZEoUJYSkQPjPB6v1JcSKAb\n7Nd0\r\n=h1Q9\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFN1guS5WHXLAFscud7V86lvApAfVKlStndNt6cEtqcuAiEAmHdADgPCR2CoXBvLI+9AIy48VFBJc1FQ2IfszVB8LHc="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"npm@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.13.16_1618917665878_0.6344716287404515"},"_hasShrinkwrap":false},"7.14.0":{"name":"@babel/parser","version":"7.14.0","description":"A JavaScript parser","author":"Sebastian McKenzie ","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"7.12.13","@babel/helper-fixtures":"7.13.13","@babel/helper-validator-identifier":"7.14.0","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.14.0","dist":{"shasum":"2f0ebfed92bcddcc8395b91f1895191ce2760380","integrity":"sha512-AHbfoxesfBALg33idaTBVUkLnfXtsgvJREf93p4p0Lwsz4ppfE7g1tpEXVm4vrxUcH4DVhAa9Z1m1zqf9WUC7Q==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.14.0.tgz","fileCount":8,"unpackedSize":1593149,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgixKRCRA9TVsSAnZWagAAqqgP/RKnpT4s7lg5JU2jbzp5\ndpHo0xDEdkgRnqnlzpVHBaIPjtMH7UvWhxmSGP9fItn98yT3kkjBTAnGBhYR\nhBVqX4gnUZlrE364hcSe6liFJeIpzYQeTuQxhQrxEi5yNXOfGldpLLNbFtFM\npBql1psc9Bi8xGZ7qj0wXh0DDPiDPhHj3jJu4Yxu24da7ayVMHm7E/hM7p/I\nLnAASckQPADYa1PGUIq3c9O7ArVf5YE45Pch0uYg/RJ0b0ux/1lBGehMZJLJ\nnUyBSOdJ4uuvNNlJwwrdamX3xuNWt7ls6kZJep2UdXWASzXo9Ld7kowj8Sqn\nGnGvBD+0WM0+DqOckR8eiad/IqdXRoOOSwz4L9ZY85eAVMkd6OGGLmSX18yR\nPmbmfWaSAAHf8EbgsFgcYlH03TQ+HhgkaTINiVjtZ6Onj3vUq6Wju8AYjY1d\nG1RyEa5GBz8mImVf3IIr0q1FJQ0ZfmvBiL3viP38HZ+bGT0Nmyn0GNhlFlwX\n0Q0jdmRmbSixXwUqCv7UHq49jwT/QiolXcQBWznGEz2Tr3EO7uu1qM9/5bVw\nf9AFPogOVIUzeRC/Z89GCg/Az31F2y1QcMpN4dpyh3v1RdseWf9eMoDb21V8\nc7xp5TjSxSdRLibc8QaiGQEAhm8vChkUlmKIHdrMRkrRUASSf0gpTJqSBbJC\nuARV\r\n=sLuJ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD2ekFoucwoOwBaI6/Jbo07varXhVnc5ZFIVyzSkbw4dwIgXWBJ2v8mTfOE28n6oCkduBgtD0o/Dl2k5je7H08pj6Q="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"npm@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.14.0_1619726993175_0.23675192738709305"},"_hasShrinkwrap":false},"7.14.1":{"name":"@babel/parser","version":"7.14.1","description":"A JavaScript parser","author":"Sebastian McKenzie ","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"7.12.13","@babel/helper-fixtures":"7.13.13","@babel/helper-validator-identifier":"7.14.0","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.14.1","dist":{"shasum":"1bd644b5db3f5797c4479d89ec1817fe02b84c47","integrity":"sha512-muUGEKu8E/ftMTPlNp+mc6zL3E9zKWmF5sDHZ5MSsoTP9Wyz64AhEf9kD08xYJ7w6Hdcu8H550ircnPyWSIF0Q==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.14.1.tgz","fileCount":8,"unpackedSize":1597946,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgkKmvCRA9TVsSAnZWagAA8PkP/0QEKebRtHEFDQ3oykMN\n+vWF26Z7KK1KoEAMoutd3gur+NhVXjEm4cApIzO+qvL2V6VuU/UhufxcCJbz\n9/393xLUP90/F8KcFobx4NA8TqZEBzK72GXkaqSoapWqbRr4E3eYxerdOxuu\nrqEVQ2V2rv6i7M3F3YlIZ0uLB+Cqd2eo2oPypR2Go4AVIVGpuhPS805AOzWs\n2v9wSmwuiBOAWrZ87gyEoJV3np3sA3q8RKi81w93seH7wldojgNcjSpvgPx+\n6+wpa/kVwbnQ1AwWA8eee/9cxyqwk5lfKNc09my4i7PQbXflrqaldAvVz03L\nVkSlLSYmb3AJQjFQEZdX2bMj+9j+eXqaSVTa1MOKrBZhNNqBgtnLzWB+5pmm\nE2HgGqN2xqigba4ZVYNHrEQQo1ASNdbBrYZekjBODeeoyTYgGKebVEIFaHbv\naMnVaLuPZKkv18YhJGSVqFnHXKgviOlPq0EZua0PJtNUshmqRBdc6UHPiI05\nwkA48bRON+vARjuDk6fRxDWp1pgjc5enyywIccfScAtsGDi8QSGikRCLRY2m\nYskg0mXPqxL+ZP9v2iIwSRfrrr1eIC0im9l4mTvDqOupx0c7CxOySuad2rpz\n84FhzXsbtZdayWCkXzsepRAV0uzOb7Uf7wFWT52yZLStQVZ0uDUccZSk70FZ\nJA1E\r\n=sPTX\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDzksZhB9nM8ng5bfChQYzScuINWcmC9a9CgA4Unodc2QIhALhxVJ7uG/J9YGDuT2ws2bwn9U/qqUqIbSawg1YAn/fV"}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"npm@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.14.1_1620093359487_0.8778768843742852"},"_hasShrinkwrap":false},"7.14.2":{"name":"@babel/parser","version":"7.14.2","description":"A JavaScript parser","author":"Sebastian McKenzie ","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel-baseline/parser":"npm:@babel/parser@^7.14.0","@babel/code-frame":"7.12.13","@babel/helper-fixtures":"7.13.13","@babel/helper-validator-identifier":"7.14.0","benchmark":"^2.1.4","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.14.2","dist":{"shasum":"0c1680aa44ad4605b16cbdcc5c341a61bde9c746","integrity":"sha512-IoVDIHpsgE/fu7eXBeRWt8zLbDrSvD7H1gpomOkPpBoEN8KCruCqSDdqo8dddwQQrui30KSvQBaMUOJiuFu6QQ==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.14.2.tgz","fileCount":8,"unpackedSize":1607570,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgnAu7CRA9TVsSAnZWagAA0aQQAIX6aDr0jTp7VLxgi1IK\n2N53IIOHvlOTWF/w9WJF3beg7Cu3uC25eFyJ/iv2i42bedPagA4NJm8aZWaJ\nUsIX3RyzMRA8KzP5bIRptKuA3BmcFcw5ZW1DVCrOCJBqXvz79lGF2WAiL2uv\nQUonckYWcDMAj4WnddjyQFp2Ps/ZD/EgB+aSsiEJ6HHXKLHCmZtyyxRE6qZ0\nnMxARSkFipukzCV8Qfui+JtJJFciUUREygYiUUC+SnVZo67PlrwwqP2BRW2E\nmDtneqbvRRFj6R+gXW8AFsgLvhd66SBSWuOUI8sspqaKMLyX/xSzY5RuAsHt\nR0ydA2pvpsjKI2CbsVONQo2ePUvZ1jY8s6MUTRLohymWrKGgqqF9/+LxWVXS\nT+J/JhDOh+X9HP+8rvkaWmGgk7RQVd92u82azjx72OeGYMn3L1HniMpBEh1W\nfzrNnaC2xrssE9xtf2ahlMNas7wRlAwnxXtdd8r3L0ZmYDOc36VpmES3YsCy\n89bgYCwu8YdE9ayhTvgYeOypJZBbNncMkg7R0okEjNB5dAF846bTpasXACJq\ngypL9fBImKsDBr+ZALnkwMrl9CS31+KExnZ+bQxK56dRA4/uEcRlwsbFcjou\nmZzRx458vDeTT+hfcsPJ7U4eOM5nMuV7zh/sGljXV19N27SGnOuxTSLKU8Tp\npICO\r\n=EI77\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEhpR6VwD9rNnX8A5nq4rXa20slr7bUWAUTBqTd95SmFAiA4vbT28OLhuKlHJKa5ubnObdN0qewoZJv5pveBfM4bNw=="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"npm@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.14.2_1620839354628_0.9044037481642004"},"_hasShrinkwrap":false},"7.14.3":{"name":"@babel/parser","version":"7.14.3","description":"A JavaScript parser","author":"Sebastian McKenzie ","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel-baseline/parser":"npm:@babel/parser@^7.14.0","@babel/code-frame":"7.12.13","@babel/helper-fixtures":"7.13.13","@babel/helper-validator-identifier":"7.14.0","benchmark":"^2.1.4","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.14.3","dist":{"shasum":"9b530eecb071fd0c93519df25c5ff9f14759f298","integrity":"sha512-7MpZDIfI7sUC5zWo2+foJ50CSI5lcqDehZ0lVgIhSi4bFEk94fLAKlF3Q0nzSQQ+ca0lm+O6G9ztKVBeu8PMRQ==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.14.3.tgz","fileCount":8,"unpackedSize":1608470,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgotWnCRA9TVsSAnZWagAAGtYP/iiraaDZ/fS0Fbn1b/A8\nfCSTmHpBOycYomixMwbcwrS4HkW3TmNme4U+ehMEPwt8mdWmma3KkhDKtiJm\n2BBzBx095Izrg0OsQoWY5N6b5HVM2n9xJurni7aKAZhYiuWmp681DjrWGY6o\nf/Oec7pN3aFCR3D83QahyA3iP7+/LN9g2+7mQUfcoHVVmD/0Z6IqLNMhdXFo\njLvzUp9VTaRRoNMOZUtJQNFOnipEhaoHqxFE+AG1nATv+S2Ey735AvNHjWQB\nbhtRERDXZ84mhESBGGIUSwoG2AUHgfgTJ6jLslTvG1VdHDB1kgGoOUd91mSK\ncmiH/7KPxmPZq+yHHOxfUt2EqMcBaIDaAagbv8mg/qO3BVn0QHsGrFXQQRpu\nmE6STUVMpmk/apvak6VirrxIrfzqh9XUG/YNIqgqQvHrjHxM2tRNnnkZjVoJ\nyKEykTYy/5cOJ+cYoCzsosJPB6ebUQfOCGDCEArSogsV2tuQY7eA7Ht7xRcy\nAMcGPFKu5ybP2I+8B2Py2o0q7xCCcF8Emz/JjP58vrs7U29Hh8V2EGmX322M\n/cRcQLpv6FfRcOiBSUJfp8IG9JfVARPC6kyr4SlTur/ez5PLYlBQZWpT3Bw/\n1sDTfEvYFoiAEmB8H2c24BB8bp+uxszvA9hIuG4V0LHBCBn7klXZX4AkCLkK\ndM4/\r\n=Yw7o\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFAWsL/0oz+k1UBZ5qwm3bVTdIKsZpM/xAx7uEhX50cTAiAcqTdUp3c9/VyL+LEdjms5Xl+sGqV3zRHvna6BzYXV3g=="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"npm@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.14.3_1621284262466_0.11621926651777992"},"_hasShrinkwrap":false},"7.14.4":{"name":"@babel/parser","version":"7.14.4","description":"A JavaScript parser","author":"Sebastian McKenzie ","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"lib/index.js","types":"typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel-baseline/parser":"npm:@babel/parser@^7.14.0","@babel/code-frame":"7.12.13","@babel/helper-fixtures":"7.13.13","@babel/helper-validator-identifier":"7.14.0","benchmark":"^2.1.4","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.14.4","dist":{"shasum":"a5c560d6db6cd8e6ed342368dea8039232cbab18","integrity":"sha512-ArliyUsWDUqEGfWcmzpGUzNfLxTdTp6WU4IuP6QFSp9gGfWS6boxFCkJSJ/L4+RG8z/FnIU3WxCk6hPL9SSWeA==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.14.4.tgz","fileCount":8,"unpackedSize":1612578,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgsSGDCRA9TVsSAnZWagAA5BwP/idzgqGr/uJfFq/qZOYF\nAZJG6aNa7auHXmV9m47ZbVpoTXKvD9rRy1npGsSWsDSoH2XB+p1Jp5k2goVL\nztcVSfhCPr7CTv8K9VOq2hBucnjLJVK5qhPKBTVCQo9Bv6Z3/jh8bNAm9BmL\nx9F0nqBfSCFdW1p0wVxDukFNEqvnaApdWL7UercZ7ekwT6RPWjqw7+eJsxxu\ngX2UFjHpZMOgVoxkuhRQQtIWASRft0LKw3GKkAp6Ebj28u/8eNAq1VGmDEc9\nooX92Ne9PBbpAxKkWsUQ/+TTcB0B7ocw3Byffy5048Y6bxUanbSnqHuy0Alc\ninQqin4aujbmwjFprHxWAPEx62c3iHJF7SJ937vqNBZBk1kME2ywHyDiogIQ\neJvfXmB2pa77pt8umu12pEvED8uj3C1i/Pr046mDR9GvrMtqzwhEUJ908wpm\npCk78QM10637PUuAUnzStX42pzTHDOrTvxDx3jSgzhuPEEG7y7LYBRuNehRP\nvwrpxFOOUqePeqylyi3RppuoiLIECd8iMOLAZtdBpFa2fv4JK/wGg1GJlgG6\n0gwHDg1TxeYtpE8PZZ+mRjedB6eUPZOhqUeQZVdpZXUQMR9kqGZ1mWzEkjpL\nQvcEweWUftVvLbDEZub6h61melz01gRHby6nMHTDVdTVsoC/BA6APQ/I3qZd\nXj/v\r\n=BxHN\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD3BzTcw1hBmUpD/NHN97x5nvclPcoipLZS75fzdI1gUQIgBOr8VDYGARZ/xhGYanrkPN77OgD7Kngad5BQ5cHvqaI="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"npm@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.14.4_1622221186641_0.7115894541721963"},"_hasShrinkwrap":false},"7.14.5":{"name":"@babel/parser","version":"7.14.5","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel-baseline/parser":"npm:@babel/parser@^7.14.4","@babel/code-frame":"7.14.5","@babel/helper-fixtures":"7.14.5","@babel/helper-validator-identifier":"7.14.5","benchmark":"^2.1.4","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.14.5","dist":{"shasum":"4cd2f346261061b2518873ffecdf1612cb032829","integrity":"sha512-TM8C+xtH/9n1qzX+JNHi7AN2zHMTiPUtspO0ZdHflW8KaskkALhMmuMHb4bCmNdv9VAPzJX3/bXqkVLnAvsPfg==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.14.5.tgz","fileCount":8,"unpackedSize":1601613,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgwUqYCRA9TVsSAnZWagAAaqAP/jY6vajwo6wXqt8s/KK1\nXrHVp62hAK6ulEX47aYKRUX8tgbAqOVgptYRhiqSZy36ezownB/2HKJepsYN\ne8FRHtElapvTfhfLek4NrAHn8CLXogYIF2eF6SixtR8k91ZST3hzdfAO4nN8\ntJkg5L82v/YXM9E3pgSqUGcKVwUz/sNExwJDOhLb6rw7Ezz6ZtW7HPVJ+1Pr\nH0hyWeEJeXBOVpNVptO5h0YeCdRfAFbtF9c4WTJ0D05mGoG3f4xfaVf5EOmi\nhkNE3AsfCK3bre/mPxHEPtaTrB9KPlJknSSUO5MTAmzE6ymMo+ttUykMSQpW\nNFth0IYtWWKqK7rIqQ+HnoY5GJL6D3TRK/+XzuLtOUp3oxsTVB1QUnsbfEI3\nw34KjtjWmfJcAjrQ5m+yBin0X8WL5dHBBEQjt7I9438AqLYaAJXaps/ZqAPN\niROSRHv3i5nT7NXH3Tngv2kebKEC+VY7jGEoDs+VYiMS05XsgGG1kHyz9UxZ\nyZ3dCTCzcDxHYRq/GbeKjLn4Rw187H8zRe3aV18ACSI6S2mzhVEl0sVuMACE\nICB+NYkzteiLiqPGkDeMz7fd7V2Qv553JtuCr4PEUgMRV8KIiJC6GFghKeEg\nQrioLI6smWL9foJO37xeaPG3lkXBG/Xbtg8lcUj+a+YDJ21/DvmCcN3gxozp\nOI+z\r\n=fVSm\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCOMmslRctWQr14GBPY/xrLMX4uhj7Z8qfyFw23VIu90wIgKH2Hm+4xX9pdLMFiLEPa7uXB55PDRWoIwcPapnuSYQs="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"npm@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.14.5_1623280280137_0.7222352425119472"},"_hasShrinkwrap":false},"7.14.6":{"name":"@babel/parser","version":"7.14.6","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel-baseline/parser":"npm:@babel/parser@^7.14.5","@babel/code-frame":"7.14.5","@babel/helper-fixtures":"7.14.5","@babel/helper-validator-identifier":"7.14.5","benchmark":"^2.1.4","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.14.6","dist":{"shasum":"d85cc68ca3cac84eae384c06f032921f5227f4b2","integrity":"sha512-oG0ej7efjEXxb4UgE+klVx+3j4MVo+A2vCzm7OUN4CLo6WhQ+vSOD2yJ8m7B+DghObxtLxt3EfgMWpq+AsWehQ==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.14.6.tgz","fileCount":8,"unpackedSize":1602823,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgx9CqCRA9TVsSAnZWagAAAiQQAIa2kMArzdYtFqwvQk0x\nKX9GljtHgQDZOY7ASLgxDg4o6ReLjXnj0bOWyCGpCt7S+jbekUexWjS/ocl/\nH7YYKZHTIMyjKwyfRh+DRTz4knscnRHSLIIJiDz1iajYTxKW6hkfnjwt8aVA\n/oBG6igivLstOjfWOmqLykcthZOSwYdt9XSphvlW5VqVRu8h2JBbbrXC3a65\nesENB0Z6S8JKTjvVNWe+4qRSkoFpOwD85BT/xKhG7isfbkC+RE8E2IecWs7l\nVX7lW2CpWbLQlBotlEYpIdkENI2qQwzre3nqQi6RkYW7YKZIUTjSxPjlZjYt\nV71h6oPwxaHMckEO5yhPRJ3wpVZYdcW0HLWrR8QOES71L591PDOjhhp8Jjw4\nTHK3olRch2M72fGYTQ+LNWMPbofHgKSEYUCOhvCZP6tmvc6ucVj4O8dI9kah\n75HCpVsF/EPBjDnfN8FffaQ2gZWIxXPo+a8Dpf3D+Z3FuVwO1ObsoV/xkimA\nJur3OzRq3pDvwqTLxJj4RRCyBasxiwlIvazaQpza8jIMrNPw4CGn/SMoTuSZ\nC99vcb222RThIbxeVlwyhr05youPHicp4MdG1iDE7KaF5rk5e1Y8O0nAzY9v\n4pE6BFkOzLvUEtq9Rfnds//RcV3eRj4E3RyUCz3rEzW8TczDQTavBDOkRHrn\n4Jrq\r\n=54eV\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCKJ4sV4SAPFkWIOV8xABxRjywxasHqgqV0ZESVITg57wIhAPn0fl3k4iGL0N9pwBn05e3LnMr12+7R1gGe/bvNfdMW"}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"npm@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.14.6_1623707817944_0.6827228349415881"},"_hasShrinkwrap":false},"7.14.7":{"name":"@babel/parser","version":"7.14.7","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel-baseline/parser":"npm:@babel/parser@^7.14.5","@babel/code-frame":"7.14.5","@babel/helper-fixtures":"7.14.5","@babel/helper-validator-identifier":"7.14.5","benchmark":"^2.1.4","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.14.7","dist":{"shasum":"6099720c8839ca865a2637e6c85852ead0bdb595","integrity":"sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.14.7.tgz","fileCount":8,"unpackedSize":1600989,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg0Qp4CRA9TVsSAnZWagAAW1AP/0Vc9J1VeQjji61UDgw9\nscufevrvdxE/YsXDZEuO1eg+QF0TrCmmFlu+7BLmI/IIg9SO9Z50HTUCutvP\nqvUtzoeyguAPBCFFJ+aTEDfJPzJ/TtxzJ1K0ZY1xxsNUZi4uCA4BpH6BtP12\n1x850BpapnioiPAhvg2Xy/RLg6jDDqs0pp+kEZLynM6beiXx4gGXOa20l82X\nvCpD0pgK2fIBLEqNA+TMjKHeTT0YI9Lz02WUwuykmpdLS9WmWwyuN/criCel\nli0BYoTWlgsBNFnqW0/0qqIW21qx1HXw7lBNGYIbebzZj4lm9T81MO/rcxiD\n0EeJ817tQSxf4CViFNenQsj1YSlFHL3uuHzGDE7iOflg8FlXsXBqdCKDi/U0\n5lKSrfCaRjdVy4nQ1Yacj6/qxMFfEU7O4Qw9WHCvT9aJfc+SdYMAC0fvj/LK\njgtD2yUPfEO4QCWdJP0VtoRAi8R4ViGyJd6MJvmxRLyKjuPrs2s5lb3xO+Se\nD/cPZi5klqMAN1nf8AsdjeC/Rd0i97zHE++CAg/jphzv95zSJ/aGNxJQH9Lu\nnyoEzklVAoEMwmqs335hu3DDInB19ujJ3sJhgbULmkMtSa0M/mYkIWuhpCHJ\nNeD/m+PO8nPhhIlqdOtSHsB6QYyeqlMH9GaiHI80ajr9KOj8rP3Mpige54K0\nhsuN\r\n=+H0R\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGtUu4/vtzb95yn7cJjVzp4DfgArlflsf0HhrcDN9BWAAiACTDc/sf63YnzWWom44/rgP1Fa3LCRvB8N44atcv4GrA=="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"npm@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.14.7_1624312440188_0.025546294773536538"},"_hasShrinkwrap":false},"7.14.8":{"name":"@babel/parser","version":"7.14.8","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel-baseline/parser":"npm:@babel/parser@^7.14.5","@babel/code-frame":"7.14.5","@babel/helper-fixtures":"7.14.5","@babel/helper-validator-identifier":"7.14.8","benchmark":"^2.1.4","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.14.8","dist":{"shasum":"66fd41666b2d7b840bd5ace7f7416d5ac60208d4","integrity":"sha512-syoCQFOoo/fzkWDeM0dLEZi5xqurb5vuyzwIMNZRNun+N/9A4cUZeQaE7dTrB8jGaKuJRBtEOajtnmw0I5hvvA==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.14.8.tgz","fileCount":8,"unpackedSize":1600391,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg9w+6CRA9TVsSAnZWagAApFMQAIypHVmjpV4zLkD9yJI4\naAb3eipEyasIQZPDL0VyNS7mexCx90SIcOcKluGrl++Mo5IbJmTXq1lTTr81\nvUBze4bx/fNdfSRyExyhsVR09xa1qEggPiXhPZxQTKWdw2dzmu21qw4Oaxve\nw77Gy8JSIPcrjxzD945af5CJCj5eJ5ckGS+5TLx5VZUTBiAboF+kgbFEv3YY\neJWHjWCFrGbOP2EoMglIiQNLz9EcdXJXkAqJe/51i216wnZRyOCZ1UH5eSi9\n6Rto4h504blGXJlCvXYNpSUxd8p5Skt+07gbCxxoCynUZ0Fw+JXzZ97KlkRf\nFXRk/h0krT1/jBdZTffF5172H0sve6Mg+1u1Kma8Ux0bLdUPErpdbeejAO2z\n40SA7yHxykz1XcFXBRqE+UoxouIVHoMTwmuJUmlNlC2xOgf39EImd+KDbufI\nTT0VDWaR/8gnl9cg/AtWJ9WXKE16TEPkyKFvS3wnjaQZwgNxNc1a01DKmm0r\nzZ6fnYAsffVDu+PvtIDjs900llwVJYIDTjXnnClDXPxzFcxSvzDKtieQ+h7j\n2pBztN0BxkATDJCEYjINaZzwY30NuPlNA0Zjezq9j5osD/jc2iw3wcbEMI6N\nZKpdhMx66VlBSMoVfj3u/w18Wv8k5vEKjUPWKIiBp92YhdI14ot1XkT2CN7S\ntJ3n\r\n=rbqK\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD9NKsMvLJQv9suqIQEKoMGxsbNvvEvknoK85gkFuKieQIhANVH4hGqDutbW4cwwGXROO4F6b4AxMdWcuw/2lnXfyCV"}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"npm@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.14.8_1626804154817_0.43825952580985383"},"_hasShrinkwrap":false},"7.14.9":{"name":"@babel/parser","version":"7.14.9","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"7.14.5","@babel/helper-fixtures":"7.14.5","@babel/helper-validator-identifier":"7.14.9","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.14.9","dist":{"shasum":"596c1ad67608070058ebf8df50c1eaf65db895a4","integrity":"sha512-RdUTOseXJ8POjjOeEBEvNMIZU/nm4yu2rufRkcibzkkg7DmQvXU8v3M4Xk9G7uuI86CDGkKcuDWgioqZm+mScQ==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.14.9.tgz","fileCount":8,"unpackedSize":1608037,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhBlLpCRA9TVsSAnZWagAAi5YP/jEEZAq8rn4BHlNjN+rf\nc77UGJ6ld/y7KaMC4HeFIwsr801PZNvzyJyq7m9ilnjEjznAvcovM8NXs/ex\n1Bsl0827m0A26pHltWYGhmWwJJU/wLFRCuUPSVf5xFJ4+cdDvRG+KgZ/BPgg\njtnMQvbwd2muJQuhuu1GgvKZ368OTr2ZNpLSyZtltm/qz5qJgzuKkWDZGlxC\nVRPnTWQcpWB/wJpfxOJaJF7PerprL935qV0OptvmrciI0cWMCMzt0jkbM6zg\n4sTEajj8jgjRMfc4P++AeMfFVO6okewDBlket0IojC2kwJ24xu0qd1QISKRe\nhzSc3/ItND/Cjh5bOsFFmInD6i9RPcrunQbNgMzOthZn1Ian5yMpOAaFLy16\nHs7x9u4oFDAx7ax+we0nj5UczatUYpwpSErZxah+N3u1GAWBSigzqITXRy2A\nfGaSBUBKBLPM4v9Iy5mSIte1D4wfVGQepyU0egM5c+apd/Y/KLAbU504RykO\n+XZjx+u7ZvM3rdU4zF3RBNGkwE/ed9uzP5BZxAhQUirh62C3EeQcoE6rvA7n\niIy574+2Ye8pRKgtLyktOqOvJfJVfRQmzTeH0rhSwHxMHvk6u0tKtYouL/4I\npfBony5aOPahZ2RfdRNFM5PpYUxtJWmzKSu1+kvLNuK7db9jjfmJnvLp110i\nNY6Z\r\n=7dSU\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC26NAcDAr7gPgh3fMTzpECovGnVbD7B5zrwZryaNbkMwIhAMwrXTZ29i24bj67gp0bhzVxZeOYSK42Uo4BLtHvUlBD"}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"npm@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.14.9_1627804393445_0.4721966860829212"},"_hasShrinkwrap":false},"7.15.0":{"name":"@babel/parser","version":"7.15.0","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"7.14.5","@babel/helper-fixtures":"7.14.5","@babel/helper-validator-identifier":"7.14.9","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.15.0","dist":{"shasum":"b6d6e29058ca369127b0eeca2a1c4b5794f1b6b9","integrity":"sha512-0v7oNOjr6YT9Z2RAOTv4T9aP+ubfx4Q/OhVtAet7PFDt0t9Oy6Jn+/rfC6b8HJ5zEqrQCiMxJfgtHpmIminmJQ==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.15.0.tgz","fileCount":8,"unpackedSize":1632248,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhCwLXCRA9TVsSAnZWagAAXawQAIshUQ+aeMtKMUgQv6XR\ntcZSmzcLTOqJ+Ue86prq+7N7ZRQT1cAVvm/+5PRg5FcGPPoPyRh9F4gjHmcT\ngf5jFWUPL7xSzZaWDUtIudQ/TZnNOQrg1HMFeV9ZjEvlAwu/o8k1Qd+XfiFK\nwHv3sdfpEUrP6BWBivnV7RR952+GUaNFgZj0LUiBrfsSp9ApxBCdDVf3BzX5\nppemFmy2S8vrjBBpE/a57AUMdI0+4NOMTYdxFP3K877jVdooIYZ2wiRCAOTZ\nKBYq7dAZHWU5AnU+AMkPr7z4JaI2CbN0D0Pt+6ANLNESpqF+f8YDkowW6Zj8\ngbQRTgUz3jSFEoFbVkHFkSEhmJC2xerm08W8+BZehLbbGT9+fyoON0ZZIL2X\nR1jLVSRPslWwrPgxRpTx4VzBM/xe3XJUF+rpqwu0MPUp7rI5k7TGyZjdahp9\nE3rTZEBs9Vk4mU9O4xNqBvHWzNzqYwAJ543p6t4RH54ka8+LVxZjY3yh3xOI\nfTWAM4GCB/Esx8fWL/HgIP05c6awrGmD/manRb6ilgoQ9efNh0W86i0E3o7s\n/JLKOtTwofgh0sn/AjsQlvB0blGJS4g8WldZ1FKYZ4suB8tCa6dEl1whNF+E\n6NqN4+tr/LYbvaXyqwgxbXIHsg8cycqt66JLsTD8U1eABculEgE1bymR+O/T\niitk\r\n=R+OE\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCYSo6dolsQgZWhrmOfyRDljkZkxohcPkUayhQ1NrX5jwIhAO22l4UpkkAqZZwoFpTnk+V1qpaZ0CdPv3Umvks7S6ut"}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"npm@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.15.0_1628111575070_0.6024110542778771"},"_hasShrinkwrap":false},"7.15.2":{"name":"@babel/parser","version":"7.15.2","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"7.14.5","@babel/helper-fixtures":"7.14.5","@babel/helper-validator-identifier":"7.14.9","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.15.2","dist":{"shasum":"08d4ffcf90d211bf77e7cc7154c6f02d468d2b1d","integrity":"sha512-bMJXql1Ss8lFnvr11TZDH4ArtwlAS5NG9qBmdiFW2UHHm6MVoR+GDc5XE2b9K938cyjc9O6/+vjjcffLDtfuDg==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.15.2.tgz","fileCount":8,"unpackedSize":1632451,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhEALUCRA9TVsSAnZWagAAi58P/0/U5j72jmvHIgaXj27n\nWJKTa3FD2ljYBwyWfT6OBtCJRu9Otpu0P9mtqF9sfE8n/J/m+NZ1HHhEn5/J\nDeoFaWNM0ytQYbBFWYlVWGaFRPWqFzX8PcEikKwHuWhN76orYzn9La4puQEC\ns9+PAyEhfYHg6D4O4wO7HyBUbvcAhlFb1GDtwevUhZ7xdbNj/OR9dzOQs/US\nnMvtyS0bDHgYIx9H3FwkvdFOkWDVShmeQHiwODec/+CdZk7bdK4VQ+SptKm8\nTN+oXMSp0Ra8zXiBOj/am74fLTJfwhNcum/ubSMuk+RcZ+6ZadgRB+x+TDAO\nubPCyzNtA1E1GyYX4GRMmH653FBdq6iFiSZEA3ulwD+KtRl9c/5BZUAw374u\nNwaU/HEyk9dUK7oHs3yqLk0Z1oOsTY4SQvzTeErxabUfYHbSQ7OqtBUmWnVW\nltfTfzgit4z7Q/O1IUVfzzy0avl+b6XFwJIszrb9K7Q+po8iUPYBRF2/H2rp\njScMg/1Qt09sB/D2a+5oWsUjo/X66xPVVg/3jom5XWG5f7Nn2vTSBcY8DxiG\nE9R/93RubNb3AwD03dGLpGcskNniT9hSNMBSD96Ek/zhTgdXIAUub8kfpl0i\niz6QtZNWPip0fAM/WoaEcm0af2pQg+Ts6zGfY96IvKo+QpS8it7uFN62CaMF\nwn9S\r\n=8iwz\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDtgNWvxGE0a4gE+hfz7gNGK2hERASJwJZ1Oqa9qvF2/wIhAJUrsAAIb/8XioOcKu4Lx8MVg7dc6dHNe2AudFlKFR7b"}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"npm@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.15.2_1628439252743_0.650328630023471"},"_hasShrinkwrap":false},"7.15.3":{"name":"@babel/parser","version":"7.15.3","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"7.14.5","@babel/helper-fixtures":"7.14.5","@babel/helper-validator-identifier":"7.14.9","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.15.3","dist":{"shasum":"3416d9bea748052cfcb63dbcc27368105b1ed862","integrity":"sha512-O0L6v/HvqbdJawj0iBEfVQMc3/6WP+AeOsovsIgBFyJaG+W2w7eqvZB7puddATmWuARlm1SX7DwxJ/JJUnDpEA==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.15.3.tgz","fileCount":8,"unpackedSize":1633488,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhE3oFCRA9TVsSAnZWagAAQE8P/1JJ8JY/xAl6ZxAGE4bP\nYx14Lw+FblR4J2OCvEl5dECciCR1IFLRVv/JMLpjzel7ZxSIoB9NDo1h6Y25\niXLP6MCFaVyHCzc1x9FMDaRvHZBTuOjxNvPhdeYk6tUXE3i8F/8ucMpvt4Zu\nEB6PX3Gy4EmpdnKFcAu4/hZgHxszR/3FsWRxBpLrBk5Us9+eDk1/LUikfEHE\nZ+s7yyFjQwgKGcXFJI5DBjtTC+8nBOn8+taUofUFO3jj5Z58Cf9dRZB3gwUI\njQK1BC8avewk4xyuArcBWqVjGjNrzWuJoc1nMoKY0vPWbIuhdrkWrDBEbrVO\nMSPI4o9iL2McI+bptjVYo8bfijALfk0xwEieVGfV0qAwbhSon2Qzvmk1Szng\n5kZj651FZpPxmLOjwyZwR+LUNCT1ETMaLEejWUOyzj4RNoNEDBo0L050MvdF\nm6ySmv7T01mY0m8tnawMGh9sD1stsN65cc0/KfuR7vx8Az2qyy+/1bFPW2PD\n41cuBdI4P0bDgs78SQaCfdBGo2VeL/i8RkFs2Hana9TldxvUgRSzqQxsq+8M\nBoyuw5J80tjKSVzjWv+P0XlOoMBzNJjn5hhVbcz1B6ckyI+6oUhROmzytgAB\nRc7iRrsi207IKHBU1xKYGf7iWw/wCsc+o3TCc/YooxbNfmuD1RvOEGFGFSCo\n9jre\r\n=Iv7O\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC4Jm1KnH/yvUmt80/fTQUPeUO4H4apUzE9O5gayOP8HwIhAKi9a/iFjpUpakCDg5xjlTdM1mDGbwf+xTzf1RIM8SvR"}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"npm@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.15.3_1628666373354_0.8859443444395279"},"_hasShrinkwrap":false},"7.15.4":{"name":"@babel/parser","version":"7.15.4","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"7.14.5","@babel/helper-fixtures":"7.14.5","@babel/helper-validator-identifier":"7.14.9","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.15.4","dist":{"shasum":"02f2931b822512d3aad17d475ae83da74a255a84","integrity":"sha512-xmzz+7fRpjrvDUj+GV7zfz/R3gSK2cOxGlazaXooxspCr539cbTXJKvBJzSVI2pPhcRGquoOtaIkKCsHQUiO3w==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.15.4.tgz","fileCount":8,"unpackedSize":1635976,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhMUSLCRA9TVsSAnZWagAAtL8P/3SpK9aGcqfeLcFX4l83\n2Vbtzj2xVKffyDmyTsDbRHelZQm6WDEKs2Va/hCwty6rYqGLqR+JRE1qT3jB\nT5Ab+hGcjIashGlCJAHHGRkNH9IxrqHab7vnFRP1Q6Yq4BeXHAZ7RKg/8dfq\nPUkGd2nTJRuJ3LMqgw6BlwaGnP/TG/VYmNEnAJqe1pkUhzQrCwtgS9Z+FRfw\ngDOmMIDTf3TcMHY01By6wRFpvpr536lkpJ4l216HchFTrvhkz5gLdjqwHbEK\nYRocrg0PIMSEt7bQ9VKIhXU6WnrI2YuLChffTO7e61pVfi1+b8UfbX/ArD0Q\nSobgoGLeJZAa1Y9L2oJlXjaoaOgUb4Np09tAnD7EEAOoaN80j2ktIIDXQ/fK\ndBi5E4quA3jtXAapoxL1FqVT3RJSeF/tCb+QY7KUBRv+oPm4yMoGnQgwHZad\nYmLjupuBZH6l6dQT63cL5U3wI13PRpGpnREu6aJ5Kh/b4uJFb769uBcr23Bw\n578Dj94GiuEcNYQGOmpbuFgH6ArIdESKVu5pD7/9qx1UlQVkfetLpywdWbot\n009Tn5I/3rzmF98ZczVUaJzFHbJd0ohqWaTzw0httN3KQeO6JKqlnzN5kJyE\nFJc87S7SmSogbgathSFzAjvg+Px/u9rDx4Xu0Y9t8yPfoDyL/9zv1Fl4m5n+\nP3ev\r\n=6u7T\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCN7uRCe3yNpZISCVieUXRewTXBy/r7WDW1ET9/UdoIHwIgT2fmjYk0Grjw6+ZTlB2i9TyChzovqytPhsBqzJKURGg="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"npm@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.15.4_1630618763489_0.030635948998752216"},"_hasShrinkwrap":false},"7.15.5":{"name":"@babel/parser","version":"7.15.5","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"7.14.5","@babel/helper-fixtures":"7.14.5","@babel/helper-validator-identifier":"7.14.9","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.15.5","dist":{"shasum":"d33a58ca69facc05b26adfe4abebfed56c1c2dac","integrity":"sha512-2hQstc6I7T6tQsWzlboMh3SgMRPaS4H6H7cPQsJkdzTzEGqQrpLDsE2BGASU5sBPoEQyHzeqU6C8uKbFeEk6sg==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.15.5.tgz","fileCount":8,"unpackedSize":1637754,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhMzVHCRA9TVsSAnZWagAAKZwP/RDzLNVJzX5yVvmwkHh5\nWX9ZpZTqNxQyZarCLcMUMCIqM/auNkKotZWg4WD47B8S8Xdlb+8J3BWB6KS/\nPiq5zZ8KOg7wPVOGT0WkT8WLmBB61VG9SOj3L1+e3PgUb1/jlyLtiSARI68i\nhoLKQVz7YfAYWyqStFh4KyolwK3pcms/m1IpuxP0YWSWbvDal0jGIHpMN0Eo\nXjYnKIO/pj+U9oJQNJLc9pVAGI8DhFAZbASnySjuncaiI7DgKnooBnt3WjKM\nxlYQaLofiaFrrbLvPfFncOnp1wHD9AsJPk4QY9g6jlM/mGFMiJnEWghI9udv\nXzkK9rN1gkN1CVfVvGrUgnL2s3E4dBRmtGzKYft8y0gF+YqaFA3DQGBw97e0\nbv85cTHaVOkgIcYoM/yjKxu+uTNOKawPR1SxTyYCjN516jXLlfz/bqqmtKus\n6umuU9TWP+Hc5yGtAANaa74XjxCOic3CX3BVjXYIB7Ebk9gCTu5AplHCZ3kb\nIpNBKFANkESk8MCeCOxD0iHLi+dYWf+0qrqeB0cp/+8rJJdq1Hb0xi+CaTnK\niIYFF91CFFKpekOMJIvlowYNARVd+hJRV2JWZl+OF2xDIAvoRF7vQIv1SI4L\neshCMy3jDEC5z6o9eEHHENPVEIlQsmryqVajzxOPGIj9oiza8CkD1jczhxOe\noziz\r\n=0X26\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIA3N40QTetPxCE+jLIBXe0C7QWAYotciqRJfdH3RQhT9AiEAk3oqUCW+Hng/1WJuh/NZEymwtxMiTlSWXmdk6+fENLc="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"npm@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.15.5_1630745927183_0.09013099121125068"},"_hasShrinkwrap":false},"7.15.6":{"name":"@babel/parser","version":"7.15.6","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"7.14.5","@babel/helper-fixtures":"7.14.5","@babel/helper-validator-identifier":"7.14.9","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.15.6","dist":{"shasum":"043b9aa3c303c0722e5377fef9197f4cf1796549","integrity":"sha512-S/TSCcsRuCkmpUuoWijua0Snt+f3ewU/8spLo+4AXJCZfT0bVCzLD5MuOKdrx0mlAptbKzn5AdgEIIKXxXkz9Q==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.15.6.tgz","fileCount":8,"unpackedSize":1635565,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhOmHyCRA9TVsSAnZWagAAi4IP/1kthSMo8oSxUbLj27B0\nJKwEkYEGlXKpgxqDr7Icl5CEGQ/M6hxEZunEPgA4cQs3Y8kveBWfMo7gVaws\nImGzzqMORMvsnLbsN8oYrGD6E2EbKrT4QZSHJCg7V+0Ce14Vr6+JAfD0SzzC\nwoM8HlT7rP1wD0fdmC/T/Pg0ahjITzc+sknALEJgEqQOkQOxXBgOL7O2Ud9N\nCUr7eWb3x5v7epumklM3bfprqLASy8YmDMj7Sv/rPCeqVF1pCJsA6dEzOwVN\ncehfkPkZtqkbyWEltmHVmjJ6ZP6iqrpqZQDTLpup0TIu3Xp18MDAqn7ObL79\nRuHYKZ1sla9k8ETqfhUSPO/2BRKK/IedbrUPXSZ9JMUbqeuiQ4CiqYBp0bFQ\nxZ/Fi9qrEi6JaZnQ3DOJfHxoNdKRpYQDmOw3GmtKCrVqfpJvgiMcbJvHUSIL\n7GMq5nOSu7+O3YrLCM6UGP4VoRGCuHRoDGnqRWbfOVmmZCnKOvEcB/u6HURS\nvMHizdtIKl+apnVO8paSKvsRrOy862e3cFvB37YnhPaj6LBqj95kQhBK6e9F\nlkj+052FXW7hT77unyNcz+4HzngI+pJxyILHQqq5KPHWP8EIZrloUkDE6y2S\nIWAMe3q1sPGroj8E2BMQGlamdnAyFVcMy3OKFJ8nR/yGoM/yriVJHeRYmFS7\nhtaQ\r\n=jFBG\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCn8Lj5La/i14gyxJ1n8rIv/n5cRVOt2n0OBL8RtCP93wIgOd5RlQ6QOcCcZedfIYu8xtrHdXPOzU24NQAEhnVbyjc="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"npm@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.15.6_1631216114676_0.7201172300193395"},"_hasShrinkwrap":false},"7.15.7":{"name":"@babel/parser","version":"7.15.7","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"7.14.5","@babel/helper-fixtures":"7.14.5","@babel/helper-validator-identifier":"7.15.7","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.15.7","dist":{"shasum":"0c3ed4a2eb07b165dfa85b3cc45c727334c4edae","integrity":"sha512-rycZXvQ+xS9QyIcJ9HXeDWf1uxqlbVFAUq0Rq0dbc50Zb/+wUe/ehyfzGfm9KZZF0kBejYgxltBXocP+gKdL2g==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.15.7.tgz","fileCount":8,"unpackedSize":1614099,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCrlHSfbU5kH3GOWKVXxyctSoB1W4e6f3Ajs+I+X1ccAAIgFYIZxX6uSenMbm3joqWIwb7v81KCK1GQyN99jvMKbvk="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"npm@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.15.7_1631919976941_0.845559410039807"},"_hasShrinkwrap":false},"7.15.8":{"name":"@babel/parser","version":"7.15.8","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"7.15.8","@babel/helper-fixtures":"7.14.5","@babel/helper-validator-identifier":"7.15.7","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.15.8","dist":{"shasum":"7bacdcbe71bdc3ff936d510c15dcea7cf0b99016","integrity":"sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.15.8.tgz","fileCount":8,"unpackedSize":1630102,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCf22Z/A8U0zbyrNJUXJ/pGL+/TCL5qgUHwzWqo1QpgHgIhAPQ9HDZzTWkIFqNRMJ2pqrwgudKfcAVALmDUywD6LGoo"}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"npm@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.15.8_1633553696044_0.3457177603393946"},"_hasShrinkwrap":false},"7.16.0":{"name":"@babel/parser","version":"7.16.0","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.16.0","@babel/helper-fixtures":"^7.16.0","@babel/helper-validator-identifier":"^7.15.7","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.16.0","dist":{"shasum":"cf147d7ada0a3655e79bf4b08ee846f00a00a295","integrity":"sha512-TEHWXf0xxpi9wKVyBCmRcSSDjbJ/cl6LUdlbYUHEaNQUJGhreJbZrXT6sR4+fZLxVUJqNRB4KyOvjuy/D9009A==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.16.0.tgz","fileCount":8,"unpackedSize":1651921,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEcMqnCgKtkZyWxn6o+27sqz/XThdsCL0CdAfJjSQmVxAiAHtVz3p/WL31wZvfHMSjGAAGnyyONBxMAfWhKw8pJgIA=="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"npm@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.16.0_1635551243139_0.8314809901565026"},"_hasShrinkwrap":false},"7.16.2":{"name":"@babel/parser","version":"7.16.2","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.16.0","@babel/helper-fixtures":"^7.16.0","@babel/helper-validator-identifier":"^7.15.7","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.16.2","dist":{"shasum":"3723cd5c8d8773eef96ce57ea1d9b7faaccd12ac","integrity":"sha512-RUVpT0G2h6rOZwqLDTrKk7ksNv7YpAilTnYe1/Q+eDjxEceRMKVWbCsX7t8h6C1qCFi/1Y8WZjcEPBAFG27GPw==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.16.2.tgz","fileCount":8,"unpackedSize":1651921,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDZO63JIFbg45RhqC8ktq48YFmu58g5BSuG6bejYwOSuAIgKHShr/ywzixfacV6f/6N9qmQCTZbrjmu4OGmabxRRYE="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"npm@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.16.2_1635803814825_0.9416337494283111"},"_hasShrinkwrap":false},"7.16.3":{"name":"@babel/parser","version":"7.16.3","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.16.0","@babel/helper-fixtures":"^7.16.0","@babel/helper-validator-identifier":"^7.15.7","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.16.3","dist":{"shasum":"271bafcb811080905a119222edbc17909c82261d","integrity":"sha512-dcNwU1O4sx57ClvLBVFbEgx0UZWfd0JQX5X6fxFRCLHelFBGXFfSz6Y0FAq2PEwUqlqLkdVjVr4VASEOuUnLJw==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.16.3.tgz","fileCount":8,"unpackedSize":1649971,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCAF5Xfv2aNsLxaTWmBd0XqDJwVzIq0jWVi6W4qNn1xrQIhAM0LgZL2ORgiK2C0mjuc5cBHvriNy7dgSJjOezvsGmLB"}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"npm@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.16.3_1636494782895_0.44197662494419543"},"_hasShrinkwrap":false},"7.16.4":{"name":"@babel/parser","version":"7.16.4","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.16.0","@babel/helper-fixtures":"^7.16.0","@babel/helper-validator-identifier":"^7.15.7","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.16.4","dist":{"shasum":"d5f92f57cf2c74ffe9b37981c0e72fee7311372e","integrity":"sha512-6V0qdPUaiVHH3RtZeLIsc+6pDhbYzHR8ogA8w+f+Wc77DuXto19g2QUwveINoS34Uw+W8/hQDGJCx+i4n7xcng==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.16.4.tgz","fileCount":8,"unpackedSize":1652803,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhlDS3CRA9TVsSAnZWagAAhzkP/3Myb6HE4Px3wTXgI5Ia\nc+ieDTz925ux0jrGLwe5jmbpeFPD1e6bTdYAC7WQLZDD/KaW7FlDnXTlod6X\nxVCAutjOTSA9q9qOX66X5UTFoAaiM6PStnhqxVV798y19z1jxKPRJVb0PF8v\nSX3+aB/si4iJlWkAn7l0AQqNwMfAbH9FSczwUUWySIhIejz2pwHAZJWphyxG\nP/O/0YLAtxm3/VYHEHn88kjbajNNaIt3bG/kHtXPsyKu802kVGwuUG8nTCph\nR0v1T6OZNVNvqWk9yNcPot+f9/DWBTjmRNZcEPlgg4FB16lY3fB4uLMyFjA3\nKoFdq0saznPe9KfdfRla75Nr+nYM/PvfrdKYS1xbJD6H+P2Pa90opFr/wC3S\n0ZFWFI/P1hBrTdHCbFh+837nUSBaqaXuiqnEocBB+0T0erXMlLRDFwQckVa8\nropWF1JRv0o12sJq8g8qGdZdQdjNrzu3CmerDXkNFfChcRR48dQyqQcy7cUH\niY7sVBg26dHSxqvJ8E66u6nZCjsCD7TQQi9bHDVX8kB0iC81AjBq+gjemY0E\n1UPVpCgZX3XSKOYiZCGnqdBMmCs15oOoMgx21HFRyBIYE76AJNha6sm1OF0A\ncWTrKrPLNe8TMW+fGmEQctkWs13wsiNJPPndSPkmNxj6nbwuQIKqnQ3tps5N\nC4lM\r\n=EW6p\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCID1sdcdDnh7ZAq9IUi3zoYjBnogJUyLSegIMC+Izdp5NAiAH5TVayyt8VX0cNm8OtuyN9sKhJb4rQ7wLfQb8fxBZSg=="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"npm@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.16.4_1637102775773_0.29858597265425124"},"_hasShrinkwrap":false},"7.16.5":{"name":"@babel/parser","version":"7.16.5","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.16.0","@babel/helper-fixtures":"^7.16.5","@babel/helper-validator-identifier":"^7.15.7","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.16.5","dist":{"shasum":"beb3af702e54d24796341ab9420fb329131ad658","integrity":"sha512-+Ce7T5iPNWzfu9C1aB5tN3Lyafs5xb3Ic7vBWyZL2KXT3QSdD1dD3CvgOzPmQKoNNRt6uauc0XwNJTQtXC2/Mw==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.16.5.tgz","fileCount":8,"unpackedSize":1668741,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJht8jVCRA9TVsSAnZWagAAzFcP/R+5/aVVysGpXJSTaha6\nzQvkQjok9WnjMeALaggVZkHh7oLgcpmOLFJpRmi8Dz7BFtl8Stvs5C8nfY0J\nVfMKKsRDMyV+9XnWm6nztrUmkvhu/JvNd8Eu4GWnRtBr1HfhIvSuzBt40yrA\n6IZ/Bhq5XB042O3+t0aye6upCmtjC1wKAAsqlOpXNm0VIAh5PT3bZ7C2IqZw\nQFyLA7HRh6xw9UETHybVr/4AHYz0SLReP82QaQlmUVn/gjUoLYGzMjBVi8h2\nMdE08QEaWPKHFyPPptCXuRv77EnXLMlak4zC359Jm49UeepG+6WE4UaaT9jH\nNMRH+mGy5Et3OcNAqMuCFkQgcX+EhHe2O2Djg0QxB0SzfXWaQkcsx8O2f4jF\nrPdSuRIvKZjCiUXujy2uZ+I8By+DL/MlYMb2XHJUonnsefMRbecqwqjEOIsH\nZU9nlifINkHuTCyIXDQLw/87Ognnmud4Vg0vt47SixRE99CncR+m+bAIwC3+\nwDYDPu9yNITMqb3UpBscggaNA3kDNbWVVsTKlI3tRBLwbpljCsaLs9uKbNBz\nmw5K/a0ZE6iSOm8X65VJ1Td0RtP5MLJmWt15rkeI57YVnn0PC0PjHwm8vbtp\nBYPalkfNcRFjqo7v9V9v2FUECiF9YzDH++XSbTcPpxecxeRawGxz/lmmAMEL\n8raw\r\n=kNof\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDyG5lKy2jVcc7bP4KxnnIvF2YtDoP1swg+iO3F27jvwwIgFX0Dk2P6BCYnZ7r5kQ6zHCo32XxXdyYsUnZCnpDt5gc="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"npm@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.16.5_1639434453131_0.316649426485492"},"_hasShrinkwrap":false},"7.16.6":{"name":"@babel/parser","version":"7.16.6","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.16.0","@babel/helper-fixtures":"^7.16.5","@babel/helper-validator-identifier":"^7.15.7","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.16.6","dist":{"shasum":"8f194828193e8fa79166f34a4b4e52f3e769a314","integrity":"sha512-Gr86ujcNuPDnNOY8mi383Hvi8IYrJVJYuf3XcuBM/Dgd+bINn/7tHqsj+tKkoreMbmGsFLsltI/JJd8fOFWGDQ==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.16.6.tgz","fileCount":8,"unpackedSize":1669018,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhuSsjCRA9TVsSAnZWagAArRsP/0czjA0YdFwPRd6rhG8j\nBsd2QRdp6wuwOf3cFFolYAoQC+MUAErLbKlQQg52rm7fvAYTT/xTe0S341To\nnDEeDRi/iqlsfQxbpwFwdDENsSORh0cLW3x4jWy2ZVv0StLGA7YKkZXmMKgd\nEBC9z8H4wXd6yygT5lg0QEPrzBqDI5IeYUtdIRlwJXE+65RuazjBmAW6HYSF\npYZpPBmtwKko+CgabcovpJ1lXefq2FKJ+qEG5a9r93RrYjsEsSAlLg96nxHD\nJdZwzMOz82oukTGIQcYJ3eWB9DXWsHtCYeq3JEIn12gpnNf568loXSUCYpqE\nqKUZV5oZHLX3x0QDIbt88/ooZo7jd1AIc8TGW3DnqQ2JvfCZEAuyb/vyoWxk\ny4TGvj0Xh3pIjZ10sj9BfKfwacTBPcPX/GL+6UHja7+c6d/1EGSfRz+74xse\npTVDSmojZXr3gB+3IHKjC0m+ZxiPM8fcDDFjXwbo+mUEr/VzWcDgUDiE7GGe\nTFhcCKK8zb5NTf1Dy6wuRRDusyzNGDRe3hqOamgYOWzUPCsWWo2ItGDgUFUc\ngrEmeyXhNXLQiwTFIcvp8Int95CPdAnDsLvEzebOCEHgfavfvd+21iO1svRG\nzildiMXf9Ej+4gBA3PypZ9H8qnI8YUXJyDP/tdJnDpcbym7X9YwtjeahFVdj\nNKqW\r\n=kXpk\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCXPJIyBZbThoIHdzIQMvL008iZA6VBkRPb00VCfyB+WAIgeYFdnTdoLXuigrQvPyclDr8qu3lEs0+ter/2zs770g4="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"npm@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.16.6_1639525155318_0.6825487066353182"},"_hasShrinkwrap":false},"7.16.7":{"name":"@babel/parser","version":"7.16.7","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.16.7","@babel/helper-fixtures":"^7.16.7","@babel/helper-validator-identifier":"^7.16.7","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.16.7","dist":{"shasum":"d372dda9c89fcec340a82630a9f533f2fe15877e","integrity":"sha512-sR4eaSrnM7BV7QPzGfEX5paG/6wrZM3I0HDzfIAK06ESvo9oy3xBuVBxE3MbQaKNhvg8g/ixjMWo2CGpzpHsDA==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.16.7.tgz","fileCount":8,"unpackedSize":1669144,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhzk0CCRA9TVsSAnZWagAACsgP/A9Mo8deJBZJ0RY5wxZQ\n3tNG6VYaG1r5tH2YgeiFjwDiNchtUVNbxDEsSaHvH3J9M+LSpSwbrhsxsaNk\nbvTuYhbhmawP8/dsq9DXNCnk3b9okxuaBbvZZTaH4eN9JS7wC0X2Fb5NKGXe\ndpf+WLWn+GardUFbNPrtkZ7OYXnS/6rzWvpnT2zfCS0DzMcWLz3FrmG3wM+c\n6BNG6qAxAEg3uNlIsO4hm/qYgjVgYeGjktBqMTVARmHDjisah/9hZjs7wT15\n41+1Q7NdQwuZx0+dRjAXAxWDwB0OWr5HdwRMYd/L6Ww84+jAaJwVh2qWkUkN\nw4tNhodvWN0hk42osY3r8o4RQw6Fnk1SD82DV3dgNRdzPmgMj4FJOemtEIHT\nRllTC4uxyThrinF+qbr+/yzk+AK9ffxVj8m/5WnNS4v8Gc+y0oBu21RjVW1x\nCwGveLq0q/KwnVu1W83JpA8Cv0P+S4PsFqgxdLq+pNwxVJO37yukv9VMSRJv\n0Q49wfRMdJAN77VJTKy7A7J6GXnk+i1mUgLuSsOGgzNlI2DinwBuUDWrvPNT\n8A8OyUw4JusZteO9G8/IgoE/qGm5jrBldY4/XKTM+kOUgb7p/xE/cikL3c7N\nPfXZQvkOi/Vi6CGdwYm7BLSV4UcO1reo1J14JYke5s1pM9tx+9hLWur3fPaa\n+vno\r\n=lzGb\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCaqWTsjnbL5LW+kxRbId+Mbu0jNzXRG5ltjp9CvJfAKwIgCx8QcdbGwp/S01Vj8ssk4lwIaQHoRWMwLviOdCtC+f4="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"npm@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.16.7_1640910082709_0.4548234915086127"},"_hasShrinkwrap":false},"7.16.8":{"name":"@babel/parser","version":"7.16.8","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.16.7","@babel/helper-fixtures":"^7.16.8","@babel/helper-validator-identifier":"^7.16.7","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.16.8","dist":{"shasum":"61c243a3875f7d0b0962b0543a33ece6ff2f1f17","integrity":"sha512-i7jDUfrVBWc+7OKcBzEe5n7fbv3i2fWtxKzzCvOjnzSxMfWMigAhtfJ7qzZNGFNMsCCd67+uz553dYKWXPvCKw==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.16.8.tgz","fileCount":8,"unpackedSize":1669968,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh3KKeCRA9TVsSAnZWagAAHoMP/RGerJJSwGqkCNJD3z5s\nwtzisUwUg3zBJPNT/6yPB93cDn5z0hgyiHCcT0uLOi9Uj3jXqxOUHwfusR+J\nskTkNbnBkAySkh2qd71vv/pC9eefTDrsG3y50gIRPfQw4hpS7Y3WG5MY8zoz\nzXxNFTvCaoJHr5wVMdd5XmA4yU+ZTd2ieevr+5Y27dmheeLGrmH4gTDIYgYd\n0mjPHMsiYZkyEO7sbz8CsFuJmb/fv4J1rUOhGy8MF3LH1Esi1luv8VRVj5c9\nlNFDNWs6bQwZHKDCeP73M5QhKjjAuHBkgaGI36LSJikbNVsLHzk5ScEEVsjK\noz/k/1w+xOYAt8qdrnpbTL0JEyl2NCETO25WSiQ4z9vf0sKfV1rWQ9IQVEtc\nalLYcU97uHw2Bfvhl69YXst6UgGDslDe+WVHVUT3JVrK2YHqSTL+1ynwIgZE\nWNULEuBm+Cvo2L3LxC33exU0UgJPU3Ny7DjD76rmkoQMZD2+E7aqvVMe0OON\nxTrycZ5Upuy4dEX3mMxmBN8BMdaofWpswF0Ryt2hiYGA+VOqqnWglpTuzOdY\nnQJYB/2Ym1d+qpJGAC3BpdjcSgf1BmhbUWcddI85s+qSEIoQhuv+kHbw5MoV\nyUDaZKclxIws7NjoY5eEUXTci5PPi+BnvZtDTGxfBcaY7NPyx4znMBIT0arK\n/Ie5\r\n=t60W\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDB6Fl8eOyBiMDq/udskRwZLoHMEEUOoFTDaxpD3DQg8AIhAJBCEFFPCXl+AAJz3dRM6d0VeL8afb9HgSwu2FRRSu5J"}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"npm@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.16.8_1641849502056_0.3401771439273591"},"_hasShrinkwrap":false},"7.16.10":{"name":"@babel/parser","version":"7.16.10","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.16.7","@babel/helper-fixtures":"^7.16.8","@babel/helper-validator-identifier":"^7.16.7","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.16.10","dist":{"shasum":"aba1b1cb9696a24a19f59c41af9cf17d1c716a88","integrity":"sha512-Sm/S9Or6nN8uiFsQU1yodyDW3MWXQhFeqzMPM+t8MJjM+pLsnFVxFZzkpXKvUXh+Gz9cbMoYYs484+Jw/NTEFQ==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.16.10.tgz","fileCount":8,"unpackedSize":1688651,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh6FrECRA9TVsSAnZWagAAQH0P/3PRGtAX8Jn9vadoIPwo\nORpvwrHNw4b18VRZeIuzdzF6xkXKan1OipW5BN9/xeEqGX5NEPglG9pP2NR9\ndrtl7iSRNBpzjIqwSCxXaz0hHQOpI1uAXsOHsojmGEVOw75UCnyfmSe8nxgY\nO0gDYC1EpRGVDCjwJgD5iWNOAPbMLzw0eKaZ6rtFmq1xLth1xaY0OxESam+l\nn6SDNo5WzEoNiAP2kwUrcdVngzUAFVfBoHqdRQlKtXnl85qYJFxyOC2yfPBy\niVrehQfe+P6q4Q201iCQvy+xbBquSq1PzpqJnXV5drHPAbo7ZXZRIYfJBtJ/\nsLqrWfQgFAeI0RtIbd1iBgSKMg6GubQbcyTwiko2o4Mu++cBY3YTB801+orC\nV4sq563W4CjYmi8x0twLAjKdiqeKOEGORu1eUbCrI1OVMmMETY6Iu5kwm4Xi\nBD74QcLTLYFIb1CkXBORvHSYoMc1AuA+/812pdcRaqz3wAefIpm4faH59Jih\ncr1+YEEkDt6caV902w8AkpNmasQik9MjMnbyciKjDA2dRdxVGG8FxZgOSPJd\nnRiOkj1YmvBK1JAbjpblKMFzNnLS7W5Tc6ZRV+4q7zvOjbhk2WV8PLcLUVA/\neeC+4Cz38hZHDXbaKIYVeaixP76J5CKhSAvbP97DbW6lMkCwJzbAYuYl2dmK\nRQAn\r\n=h29y\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBAIpGe2fGCkkAp/Y6yC1d/n6nmMNpo31gMf48E+efHDAiAFXLNvU+r2c3cpu0BV6+jrHOR3rxuQ7tZvOfIdr8reUQ=="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"npm@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.16.10_1642617540484_0.14970869687086097"},"_hasShrinkwrap":false},"7.16.12":{"name":"@babel/parser","version":"7.16.12","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.16.7","@babel/helper-fixtures":"^7.16.8","@babel/helper-validator-identifier":"^7.16.7","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.16.12","dist":{"shasum":"9474794f9a650cf5e2f892444227f98e28cdf8b6","integrity":"sha512-VfaV15po8RiZssrkPweyvbGVSe4x2y+aciFCgn0n0/SJMR22cwofRV1mtnJQYcSB1wUTaA/X1LnA3es66MCO5A==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.16.12.tgz","fileCount":8,"unpackedSize":1688720,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh7B5vCRA9TVsSAnZWagAAhpUP/1DCuot+V8RAmD0O8gdh\nAv9qg40MZs840l6yrD0KBlIcqWnFjAfeJmrjKfWYOugNWOtIcWfvxKXI8ooz\n5iCzAVgGat38f2D68obRNPBsNFTNmuB8/Ibl07qT66XwFZwScXkeJH5ZKbxE\nb4L7dpxHWTSWOU9poEyPqN7byCoHMFah4071xMn8YbkvoTegg7//2aXVBguM\nKOu76Alss0e/t8qo0utMNMFq8P37cJ+IJsJUy9qpHoAPa0BOtHNDND2HQk9/\nGIAhWcgcwzH5uMbmBiRk49cgho5HDKIrTrXvy7wzCcezFrQSHzRV5/x1EP55\nHdI9HvvHEfNzbHuZ3J98ZBXQDjthWMj8l1d+fkI+KzceS9CJ5ynIhmKUdPxM\nLr/YC33JLBDPJLqfX27ykDBcayZX1sib4y/ZONq8bJARrgOjNy8b0Dz4Q3ga\nUQ92s13cRYFU8qtS5Cd7i4QBbUVOs185zTaAUfdC0/MDWdLD7bep5MpPGRE2\n1qvTlY0sGEbAmFFotfm1V/5YVPYgy6bp5p2P9AfttMZDAGNllBLHEe6QKr7m\nzzP2C28G9LXszNYdjtE+lEkl0z/3NXitOF2bU738EbsFlrosnoMmgGbb2snR\nhFjz7ERoP1OS0DXBm9Us8CBNMVUR5tsmCTg5JeXoF55j7dSNte+LnDKvwp6G\nM9wY\r\n=gNnY\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIANW7uzlh3UGIcdCky7TMXPr1JY46rS5aQyaIarxkpxjAiBalf61gGBpQtzXf44h3XGZx/wxQBlTVpvrtHv0YN47pg=="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"npm@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.16.12_1642864239280_0.5521351996760828"},"_hasShrinkwrap":false},"7.17.0":{"name":"@babel/parser","version":"7.17.0","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.16.7","@babel/helper-fixtures":"^7.17.0","@babel/helper-validator-identifier":"^7.16.7","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.17.0","dist":{"shasum":"f0ac33eddbe214e4105363bb17c3341c5ffcc43c","integrity":"sha512-VKXSCQx5D8S04ej+Dqsr1CzYvvWgf20jIw2D+YhQCrIlr2UZGaDds23Y0xg75/skOxpLCRpUZvk/1EAVkGoDOw==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.17.0.tgz","fileCount":8,"unpackedSize":1706476,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh+w4OCRA9TVsSAnZWagAAMlgP/08KU+NTpScb8FrnO+uL\nv8MRqSksF6mjZcYg0QE4hebm7V11CeticYvGRCB4GloBXBklpnCNOs5EZFdG\nNofignK8mvAZY47cjBhKp/VvKuv1Wva8ixX6rcXgrHzKV5K2dDQ4OL9QOMUw\nGWUGgFGfF2efrBH2YkA2UZCE7sh3CryRKo68rbIi7v5AKkte48Gh5Ai0iPrK\nir+dvy/FYzX/YCqpTIpc/4OJtdAOnfB/pUmP9ne4ZDer7RRZtwaRhLxmcvfZ\nnlF5YElj1rmt5jaiK0O/15lZdTBS7Tinm6H+x163XHRW+3z2e9nWXGKWdnUQ\n+GWhQkt6yL0gcvrHeS+BKBPu8VpSBf4KTEMlGYr+K2NIC32+Vy/n5ypoW55a\nQF1xcLGOazw9EkbG32PgckliSdMIlIh09jlHGnPK/d8XbaG/w2v5LdbCu4wW\nEKv5SCe1lxBH3M+B+2zP4iW/X3reo8mjfoi89U906mVlpuotGMcss2Adj8rz\nY0AdSKhAOZ950Nv6AJih/0z2h6wZaObZKRFGQW7KVi7SEwFfvNwjFb5Qccy7\nRDYvjQB3QlVqIC57z2zb7eDxJ2c4wqXLtsZvpIISKfWsW5Jo3eflDCRmP7zA\n+pqH3LkrxXxG+pWpUJtV87D1cQ+GQ9v7tWsGkBaAolon4qGKny4WZn4WFXoq\nmXeZ\r\n=Ydal\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICJwNbdlquk45ZLSh8etzCheDfOqRRG7pGQ/YpPy5AeSAiAd+yt3KHY1DLuPRyj8mLkVYJWBlSdLQZvAUQVzIiWdBQ=="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"loganfsmyth","email":"loganfsmyth@gmail.com"},{"name":"danez","email":"npm@tschinder.de"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.17.0_1643843086474_0.05743802763886885"},"_hasShrinkwrap":false},"7.17.3":{"name":"@babel/parser","version":"7.17.3","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.16.7","@babel/helper-fixtures":"^7.17.0","@babel/helper-validator-identifier":"^7.16.7","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.17.3","dist":{"shasum":"b07702b982990bf6fdc1da5049a23fece4c5c3d0","integrity":"sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.17.3.tgz","fileCount":8,"unpackedSize":1706519,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJiC8pTCRA9TVsSAnZWagAAV6QP/irQPxvjFXRRN2Jkr9LR\n2JlHLtloFxS9TEixTgrmVTGUcj2kzhplv8o6+R1WKThbfSUXmLtl4mGIM3mM\nAENcLSJ8Qvlugb8wwLnVTWUJTS5WqtSMUMndQNY1yJoUDwo7ML7g2xvNen4r\nLp4xMGnFuCzLn/tIRpgHxvosaFXAjCmEiKb6eKsbszwu0DvGdCITcCqxKTlE\ndPVYkLgLwIJEsw8pPiridAfCPCr7/DoHESN5aUW5U2BuGM7uK++HTcskCSW4\n60eJZTXa9k8wyO7vWRztOsPNo81HnI85U6rcijqLi3xDUXuLvflge/3+ywfD\nvfWJutj74VfmsdBwDq2ZUlRq6E+l4mZ1px2HnHPdYTVFSFnUFfm/wRAHYKYv\n3OxDBHWPyfmgf9HWJEGjlYoV7LgJRCsWqpqCKYNSOH8AvaWdnh7+btcSWHn0\nBiP67mRATuy+ysZbxKDBtNHdcqI+AiVJZBYdFxemNxBGpr96CxYm0nELZg6L\nltqwGS9ivvX6MN5cxzVUSDu/+n4aAbqBvtSuki96InavyKkeAsY5xKJ3Q5BR\nfiFMrESZGVsveccY7zvffTYkRVGz1oQAia60XPRb084mVpfsgBJ3Ds2HA4Oj\nQpFcEAnH+dplUrlBAW+/2d+4EBjlLdciDEaUssMrg/+FZE1lM4NOE6mxRFYz\nB3SW\r\n=UckR\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIB9HOa/S68INi6FWMU4Hbm0bn0q67sUJgD6eQZa2T+LbAiEAkr6CYMADdxlh9GXKTA9N5q21muRS/NKkDzCKy0vYMbs="}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.17.3_1644939859171_0.388907407333998"},"_hasShrinkwrap":false},"7.17.7":{"name":"@babel/parser","version":"7.17.7","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.16.7","@babel/helper-fixtures":"^7.17.0","@babel/helper-validator-identifier":"^7.16.7","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.17.7","dist":{"shasum":"fc19b645a5456c8d6fdb6cecd3c66c0173902800","integrity":"sha512-bm3AQf45vR4gKggRfvJdYJ0gFLoCbsPxiFLSH6hTVYABptNHY6l9NrhnucVjQ/X+SPtLANT9lc0fFhikj+VBRA==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.17.7.tgz","fileCount":8,"unpackedSize":1764250,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiL3Y9ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp3iBAAnyrzWUnry4C5OjLddaeWJzjdVFF6WXTmUmhE0sKX5juyNnwH\r\n5jJToc/T0VocSlsluJ5NKLQdvFCk1Gzvcl7gcRIIoCyUz4XxzwjjmMxwJoQm\r\n82hcpSOA3epOFFVR+AdY7o6diw40Ao97aFHHhtpGZDoDUsNXVZqPW5no61wf\r\ncqqDuLQnTgFQ+zgys8Nrk/EocpDqtTqblyEYXLQQGhYd1Qp3pE7tXagH+Vr6\r\n9hkRnLo541MT2hNHIm9uPQkF8VAQ/T0R4ybbRZglpN/shCClOyBjXDbIMLKP\r\niCdj02YrJ4zN2bvmG5fawixIszKPulFMvDxDgAL8eiwFGzy6KPRZAEgQ4kbs\r\nAIGM5YKiMSHQc/In7jC9w3MZZhA9IpZxdcayWLulMQqwPg/n1TDKaPYVz24B\r\n7hf3EkppiMCQjbDaXEQjt3ohf4Vim/2bp+oDCs5ZKocTwBaSHmAZt5gx3eeM\r\ndaUy1UjxFZhT0lSkFVu5qVGvf0KaysLytzZnCdlNUh6haMmehUmW1zTX3xdw\r\nDzYVoqKNVdxHW7nSz2rbd5zNEW1WV4K5JhuUvlfcyTDqjVmNrvykW7adwvYP\r\nQcH+V68ZH4Q4wEGIBjqiOxToaXeUTqpsWgabY4cPikCwMn6gmo49bhhBRfj5\r\nnvGQ36cWdrCppVk/mzEOk7QXS0bdRd/kRJE=\r\n=KdBU\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCWK4Z47aKJ+auMHGDlKNR8sXCDzZTw1xlTWVivM3FsRgIhAJfgGvceneeojNnQUpdHZQ+lKhhD3TmFrARzgX4+RgD3"}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.17.7_1647277629333_0.4949106253400868"},"_hasShrinkwrap":false},"7.17.8":{"name":"@babel/parser","version":"7.17.8","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.16.7","@babel/helper-fixtures":"^7.17.0","@babel/helper-validator-identifier":"^7.16.7","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.17.8","dist":{"shasum":"2817fb9d885dd8132ea0f8eb615a6388cca1c240","integrity":"sha512-BoHhDJrJXqcg+ZL16Xv39H9n+AqJ4pcDrQBGZN+wHxIysrLZ3/ECwCBUch/1zUNhnsXULcONU3Ei5Hmkfk6kiQ==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.17.8.tgz","fileCount":8,"unpackedSize":1761568,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiNOwNACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrE2A//U3asvqYCEX7wUPbDM9iYkjFi1C2USQ2HPi2b/ezyTxr07UMu\r\nzY11YMOyyNruSH80nvQScQqtl2ph1pmBAm9bAIRnDT5uGhWzgnnJXvLXOfzx\r\nZxTUTzeQk4opato5AMPPogzYqmoWmSYAwVfkZoygzZCNgLKcvAY69256clfh\r\nN6GYfbY1h4UIDfyLK65vnc5QTUmphTRuQAFhMZvF1WqjINyfZ6s9BlDqmK+K\r\n5k5Tejk40egTQP+cVUi5Fw7yxP/KO3sLGrZRWUz3H4p3tEi0dC0Zi6zWmnnR\r\nte7nmpO1ypBcpLDsaDp9Y32ZdxF9pBt47GGJrnQJ/M7bVTw43OPcy0ITsCLS\r\nNM4Iq3gnEWJQ6uLT0hWYSl4EnfodXmduMJtuHKzhJiIF1nw+K4DSIkICEcwc\r\n7Q35tPXqOZ7sboIoTepkLi0BOuSbsqwdt1JjsQ8hNu73NWRgRX84TNpaXCsz\r\nYHZ4GeyVZVn14zmWe+KNvQN48tBKmsrJQaEEt0sYcNIxNXSz4q/EA4bfog2a\r\nGOVIiZLW7lMPmGVTp2k07rGddXI7rXxJMIERHMPpRpJEiaaXBF+agwJMn19G\r\nvNxO2SiXiSCYUbQXMt/GlydcyFkVY/34aHPk8Pj3BxFRm+l/LEfa/c4Sdfe1\r\ncICLNXktwyEQxahZgJB02Weaqd5AjE361fI=\r\n=bzf5\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDHLLsioQicfFuC3RnyNTjZTNGU1Wlzu5H4qjwLyV1s1wIhAJ3JFFQw7jz7GUa/vjHg5OFezET0rlKyi+BF2WNNFDhk"}]},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.17.8_1647635469377_0.36274322692546446"},"_hasShrinkwrap":false},"7.17.9":{"name":"@babel/parser","version":"7.17.9","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.16.7","@babel/helper-check-duplicate-nodes":"^7.17.9","@babel/helper-fixtures":"^7.17.0","@babel/helper-validator-identifier":"^7.16.7","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.17.9","dist":{"shasum":"9c94189a6062f0291418ca021077983058e171ef","integrity":"sha512-vqUSBLP8dQHFPdPi9bc5GK9vRkYHJ49fsZdtoJ8EQ8ibpwk5rPKfvNIwChB0KVXcIjcepEBBd2VHC5r9Gy8ueg==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.17.9.tgz","fileCount":8,"unpackedSize":1762051,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIG3ANc8MHRSYNKrMcLjvBNPcUFikwTjWAuEDrC+m72njAiAgg0vFUF5sqo5J/O2g6PNDC1f9GUDPYRS2zqmXSQ0Ocg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiTbfqACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmonvw/6A76Qk6pgBI0gq9MytYwuaPb1Z/o7Cni3tG04QIFaTE81fXx1\r\noLyj3MppMRlMOCpf0w6AlhzIfzFAhb+EHrKQyqyWcgLa4HkrEqqiNIFXlssN\r\nstoOXE35zHHpGCBwnkKdq8Udo/0/lBKoZcEvjxDsA1RuZ3xuHreNgYNjhvJ3\r\n1It6zeLx8Diun2QuOa48ymt0v8t0q88biDoNA41gN6XWMkAIRIM6nUuntRwN\r\nDNYMpWaGtv8mGDksH+UJNp0WJDoNIKhSHCNoMYxvXyxcr860tnb6lSQ/p0QT\r\nVf3JynYQUNlVB1QtRCoxXpJP9PG9o306FFv9ughb88GmLYV2JFOZohRB1NOo\r\ndsPfI6TSGAFERYBMfVWEEa01ucWkOJprVp0o/tBMUuosE0z3CKcr1cdDh+vr\r\nJjmYeWiN7j0CdmNF5do+i3RUlbKUoHNTjv3Ihg/lDeWaZJNabCTiWDoPEhDo\r\nbEKqv+FJOnwTTE3EmQQCLpXRVfwQZWZYiYqrjl7hSBj8dukTOXchfZpYlT2x\r\nZ6ocUvTDqGbismeiO7PP/1RoeU8gq52EBK2bCP0e5jyyx72C6jcbCYHWOb5Y\r\nX4lKT87h9iP0P3Js7QEOtfTAAGwTYY5Q89gOJJcCYm/v2t72UgoOL6XIPPzo\r\ndWHuJ9iuZnNg5K4Ah/9oUAlYr3fBRN7Ljss=\r\n=PQ+c\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.17.9_1649260521612_0.6262227589396177"},"_hasShrinkwrap":false},"7.17.10":{"name":"@babel/parser","version":"7.17.10","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.16.7","@babel/helper-check-duplicate-nodes":"^7.17.9","@babel/helper-fixtures":"^7.17.10","@babel/helper-validator-identifier":"^7.16.7","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.17.10","dist":{"shasum":"873b16db82a8909e0fbd7f115772f4b739f6ce78","integrity":"sha512-n2Q6i+fnJqzOaq2VkdXxy2TCPCWQZHiCo0XqmrCvDWcZQKRyZzYi4Z0yxlBuN0w+r2ZHmre+Q087DSrw3pbJDQ==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.17.10.tgz","fileCount":8,"unpackedSize":1886108,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFq9KRwui4aqW/Xa+kYcIlVVDcO2HBFPNvku4OxFfgyYAiAWn9wi3ShwUfMqNWYKXxr+ghHdAHf04UjAjYgo45fYVw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJibBRSACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq40Q/+NDXUA7/JZgRFqPF8uAGPxiqcCRc4XtB7R0/TThcM6Ss4yQfd\r\nIvb+qxjgILg69bC6OuylapYK2skTx5b9cj3oWTS+DlV8rUmepV+BXZ81KhGp\r\nW1/n8BMme/8YRF8fVzPGR0RPcRz2F1noF8GBwQLO2QVzsuAZQaHHQGqsxbRY\r\nijPF7WEXvmitSInURQsz6mrniVluBGxNppNS/xq+MkfN//hgOgq7sRMMlM7S\r\nClAGw5upNnA2nXCB5blio6WNgDpXnRK9bnLQmAKLgCA0iiBza7FP/BzOQDts\r\nh9J+4w6PuHMpPlZrcd6mI8AoJ4PTXTYvJaDI9drnSCpW3b/zjF1eWOBeBZPK\r\ntkaSMTaV8z9g5FhCfHW73Ixaktt13IcpHJ586sNKEBIL+1PeBmrf9cktkTPN\r\nTEl/3IpOzqGE9csdCNHPTAu4l1rWfQRJzzCyivwQsmNikFj2ubSd/tlD/AN1\r\nKpu3d67g1tpthtfeZeToT3Q1SqV4tKwDB6C4bVO3n7QUZy7QTKtknfxobw48\r\nuknxMw9BX0b/TyPbCnGrOkeNxiSaKbf1frukfd+Hl8ZR38dSy0G/MufroKo/\r\nXXnVQ4okzx2XEQYCrO9N8nK+3DdhRy8VcR3WA/evxAgNRxVCGk4n5F7+fTQA\r\nzOmo/ryT0xuVWay0mQb2eUjB7uYeuLsADcQ=\r\n=tZcz\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.17.10_1651250257965_0.34414916123286377"},"_hasShrinkwrap":false},"7.17.12":{"name":"@babel/parser","version":"7.17.12","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.16.7","@babel/helper-check-duplicate-nodes":"^7.17.9","@babel/helper-fixtures":"^7.17.10","@babel/helper-validator-identifier":"^7.16.7","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.17.12","dist":{"shasum":"36c2ed06944e3691ba82735fc4cf62d12d491a23","integrity":"sha512-FLzHmN9V3AJIrWfOpvRlZCeVg/WLdicSnTMsLur6uDj9TT8ymUlG9XxURdW/XvuygK+2CW0poOJABdA4m/YKxA==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.17.12.tgz","fileCount":8,"unpackedSize":1888050,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDxMCC4Y/Zsg8xSH7FilNWzx4ygORqVbQF4xQa1o+OsVAiEAhjZ4ExDGWvB9UU3EROvVKqaprXgtjHOxmOU+LfDA19Q="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJigqa+ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp4DA//byBo+iCZhgbiGzN6ycrawyznNIrpwYasSeqxTXfiLAbTOVqV\r\nYgxgpIY3QqqPRtarSupO7FJ3H5X4NiF9kYfRHXnwYfLoxzXvP9HZWsQxW0dc\r\nKmvu0Y2Lxr6ZcT4vnA1XqZYtMPY0UIiUzaEiorF3JPlC1qbnOg4manRigQd1\r\nIhifB8wdNYvxgCpdCITLuCXhFBuuzRypxUrRZ90oU1Lx+CJbyAwzWteO6kJV\r\nOmEDi+6Vu16wfm9rlEpkZ5Kk9H3+zLvyQ7kKHWKl81Bc6iOJWmLbRrffyp74\r\n5GPc/2fIih9dCjAsbm7saBGrRdoHI2yBm/498JiDBLLN+b8q+7BGYe4oeXxC\r\nHn90R07menVw7b1JWCSsFSbZTOXomF8o2Br/FX6lqqUf4eFqMPK/xBh2vc9h\r\nbfC2IaekL+OpYYvTpfcbyuHAe+KgnK25ScyA+tGz+AAxiK6yhSbOflEJ2Byq\r\nrm1bPTxU6E3LgxIgh+EJMuUsprY6/hUQTnzvf7nq0TktCNxcZbo/95RfYUeX\r\nxvpfeWxjaU7owfKq7AxyCzlhGj8Z/DTxhwWTvzrdWNOm7j1L7Q2YNWPJy7Vj\r\nC6F5mrnWYYjUaK4RPKPJbVpzQPUa55plbsNc2tADX1o9GtQBIrwrDUIcoMo3\r\nAOrlyPcRzDbXoX9kQG1L62XLf7xqGoKn5rI=\r\n=imHS\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.17.12_1652729533796_0.7421292228239917"},"_hasShrinkwrap":false},"7.18.0":{"name":"@babel/parser","version":"7.18.0","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.16.7","@babel/helper-check-duplicate-nodes":"^7.17.9","@babel/helper-fixtures":"^7.17.10","@babel/helper-validator-identifier":"^7.16.7","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.18.0","dist":{"shasum":"10a8d4e656bc01128d299a787aa006ce1a91e112","integrity":"sha512-AqDccGC+m5O/iUStSJy3DGRIUFu7WbY/CppZYwrEUB4N0tZlnI8CSTsgL7v5fHVFmUbRv2sd+yy27o8Ydt4MGg==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.18.0.tgz","fileCount":8,"unpackedSize":1900942,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCnIrvvfuGNEceLSkm2izmkh1fkH/raVAwHgyonyi7H9AIgElNFjLwij4WGLKhX/V0L0P88bKa1SVortQH8OqCRQRY="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJihomAACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr+TA/+OqSDBrCdR3fEF+JMzs5mO9A3CxMxLsnjmMtX68uLdo+M9tyM\r\nueb8kyGLm+uoCnPoLgmDbwliMixRL0aPdTgSxXyIpv+tki0drZvnLuGMz8Hh\r\nZoKIEQJECAIeS82FLCjJWJ0J9k5RPThjcViJ97VAWXZnUqM7o9+5ZLEOdNJJ\r\nCNMWMpiKJmkmezrC04n79ptfbrgg8EBz5G9zBpXlicqUY3reRlU9ULHWS3I6\r\n+vn3FWRDCIUh/HM/9xz3hgltYmNv+8bYADoHmxfprT6aRQiyOsowHhVenyyM\r\nhQzfye1KXzUak4knaGwSwmmhYPJB+Q7Ciycot+EiOFYBBGfhXAQct02KF7c7\r\nJj+k4bLwax8D0r+h7+ibUAiV6cNlezPsDZD/UgJj5ILTY27ONrMgKrO5+Gnw\r\nZFe/sJcgepajx4DgBBlVOHiUSh09lSkzUjEBAfjjykYbWTX9aNIieoWPFIKw\r\nRf/rapiczG4fZCrgtxY/6zH4Y3p55aDbfxoBQxXxOD9JusMfr3tE+lOGosiE\r\nIvi9KeDnDl/r+RHju8HmujAjXvQkYQXr6kqSVX9mo3xLMEilFD6zM5S+UQGS\r\nFQzjr/Y6lJdLUYuEvUtBPb+JyLrW8vM6NKGfD5bnpU9+luJ4v4njHZ+l/o7z\r\nszQco+5Hske3cNndYSu0JdgrE3kVzvBcslc=\r\n=fPkk\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.18.0_1652984192161_0.19709880515209588"},"_hasShrinkwrap":false},"7.18.3":{"name":"@babel/parser","version":"7.18.3","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.16.7","@babel/helper-check-duplicate-nodes":"^7.17.9","@babel/helper-fixtures":"^7.17.10","@babel/helper-validator-identifier":"^7.16.7","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.18.3","dist":{"shasum":"39e99c7b0c4c56cef4d1eed8de9f506411c2ebc2","integrity":"sha512-rL50YcEuHbbauAFAysNsJA4/f89fGTOBRNs9P81sniKnKAr4xULe5AecolcsKbi88xu0ByWYDj/S1AJ3FSFuSQ==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.18.3.tgz","fileCount":8,"unpackedSize":1879960,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCdA2Hnf+V7maWU9/prjLvCmFaH4pL6XjDXOckZvzhmRAIgNDP3BCBYHsLiE3zCujKjP0ahtOY91hi3eb4qPsn8dzw="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJijkDPACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmosrw//Vg+GmR7x1FoqZn6Pjoi2sHi7tn5zrev48zScprNfjcr6C9fg\r\naBZyKfn/Tdy92YYEpcVZZSJsHcmrNIFmYoq/7YUcfjyK4zs6o2dzz6Qz3lIc\r\nmAJkjzzwDWv/XlE+/xk63U1KxmtfdGKOFaKaawVySJ7M88vQWhrLCYl1lFc+\r\n9NiNl3+yQx7vgog3UOTHJZOH54XbcitwC94KJzrfocchoxfMfl8w1Ekdi2w8\r\nR/hEaVuNMH/ehI8eSc4EP6Q0hvofo14mOsRvNbFSjaL04vq7CpSRLhLwRjog\r\nQJpTdqdFuZ5xcBIgML7zeatJj2KyzkYQd6bHG2oXLW2fhQR2XLVr5r3CLE1Q\r\ndB8y02UMrSIHwuZGI/yqHduVVa80QXIe5y16Aki3FQono9ZbyAxaX6+9RpmD\r\ntle8yxb5sRPFo5RNiBaUpOKUMYuHV8Ns3tlZTMXoSFt9JZ1mQAotJhuY9X4+\r\nd8AuYrqe2SjucR4EMraqDo4HmfwjPfcmghygbsjsQtG3ZbBdODEu5z9pCx2E\r\nIQ2gVzZCQwsWpWXBmNMgChPSPOI37Bq1zf61fVvqcw4mljYStImrj292v1kq\r\nvCJcv/3HFTqWCxqutY5OZGFaWbXa9dSoY7r+oy6vqtIfSDZsdp3pMpYap/nU\r\nbK+vyN6DZpqS+mFkzyIw1GpCVJAaeaS7UNw=\r\n=n/pn\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.18.3_1653489871375_0.6124965700037464"},"_hasShrinkwrap":false},"7.18.4":{"name":"@babel/parser","version":"7.18.4","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.16.7","@babel/helper-check-duplicate-nodes":"^7.18.4","@babel/helper-fixtures":"^7.17.10","@babel/helper-validator-identifier":"^7.16.7","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.18.4","dist":{"shasum":"6774231779dd700e0af29f6ad8d479582d7ce5ef","integrity":"sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.18.4.tgz","fileCount":8,"unpackedSize":1880764,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFqUkDDUhM/KN0RRLzNZhWwprBAeBc5T4vwo1XfaOOtqAiEA80+AZGGFn28KINwbD/XBgpPqa8SCGHdvlkhvnSzxeIM="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJik+qTACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpQihAApM79UyYhq7Qa3yKVLpIOaPhEZc5PskGLV0hKRkNHl0hIoyWT\r\nsbH3g/G1Oid9eTHGprnyHGFz2FwKgQxv5qETEFHE5xKSp8jCaEzxUcJlA+Tu\r\nc9rvRqBzpcEycFzNhsDtaO7EDFU+N1V2MD0nB+K9CmUmqGkp4bJcuv9ES9cY\r\nfGxaz99dA7DrNprWYHy+4SXl5N+kzeHwlyepzwDRF8NHJdHHz7X6zneunNMh\r\nRdS86XlBHmlAf47nVcJM9ylWTFEa0lVyap5glAj2SFLtzzl5o8mmY/0Xvw/8\r\nc1XS6fC/YZlbz49URzAQRREhnfk4WqSasVfC9hOVhngG02KZqsY78p7q5Iyv\r\njxU20OrFGAVf8P9HE2NYxrgB97Eeg1zsKENi/4pbO8/7zL/DpT9RAJwodFKL\r\nXtwrDOd1cx156IdqU1GBXnWw6qBZetN/h6bHDQIBjcE43oGwyWUmbBjGEwUr\r\ntuWz4gw7ZKN0jv0TvWPFugJopw7B97Wn/bHWwaLBzoKdb36ub13POfh9o8uK\r\nwo94kFsHFwiIUZTAnCnk0hV9P2EfvndjgHal5jadutKdOMMaq1znprdpbRwm\r\nT9AKb6Qxj2T3fNHnrvRUion7aBNsQeG67uPR5IhSPPk8qSklzqjf3vra54cy\r\ndxyi0Z4XAJ/IjC08UkH/IpLzSd4ictXThY4=\r\n=iwH2\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.18.4_1653861011473_0.22635477602200504"},"_hasShrinkwrap":false},"7.18.5":{"name":"@babel/parser","version":"7.18.5","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.16.7","@babel/helper-check-duplicate-nodes":"^7.18.4","@babel/helper-fixtures":"^7.17.10","@babel/helper-validator-identifier":"^7.16.7","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","_id":"@babel/parser@7.18.5","dist":{"shasum":"337062363436a893a2d22faa60be5bb37091c83c","integrity":"sha512-YZWVaglMiplo7v8f1oMQ5ZPQr0vn7HPeZXxXWsxXJRjGVrzUFn9OxFQl1sb5wzfootjA/yChhW84BV+383FSOw==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.18.5.tgz","fileCount":8,"unpackedSize":1880268,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCEAmqK4p1UmPRqWrsMpToWgOcdZxBd2rQm+KLI9gyJ2wIhAP/zRf2DGbFby5D1wlmyo9K7I0CplZ3eGB4R4RJ7AvH8"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiptvVACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqIaQ//bvt7ji0JQB5t/UzfrFn3FKbGiohByYy/rypfojDTothSs1Yz\r\nAzJqXjFmh+Bw5hLBJuwxHbq0lymkysTIVNS1Q8TvDtbENxa1uStEruts7ByO\r\n2PXscabjt7jjFcsv2jBi89daylGS3M1PJkQEjUcdkb968k0OvOrrt0LoTfH1\r\nDQT5qqg7WSZvIrSWtel74hgaLgbcFWfQFAGQa8DMA2Gw8k+zyW6UsP/WwSjA\r\nNQXPyNjB4UmDNc6dY0mzTpveP1/SKy0zXvnSJgl7d8NjkUxdvsU6Eu4G2oka\r\nK1ZUs2aKU48cHGhu/oxs8P1+GLI3JPOpunjPo0yZMqrSabNqxAaZ1Kw7Auj9\r\nHk9/heNeQNlJsVjq30VsJhfEXLwBOccHqKgqpWMpaSkY6dzo0RJt4oQ8NbOj\r\n+fFM496xjTfZosG39O+cVY5Tb1oaJkhBiMRZSEebQn0S5lypEA6fEzVuHNOR\r\nS8pRNEz8Cg4+MoU4PLFqNPdc6msGCmcnyDXsT3sPMQN3bl4P0fHAZTF0Ptv8\r\nICsH+fz7gxoye34NC2PMJH3cnH4PtelRYMWqit0MYrM0MzylIHL+OHiwMG7Z\r\nB7LNFSqDR4GpkuqADvcFe164X79jccG/MRmHsM5O9td9OknJ8ulfyxJRrVIf\r\nOvbAhNm/QOfSRuVTwVXRU/5oppCG6Q5xSp4=\r\n=OuC8\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.18.5_1655102421675_0.6167061403624714"},"_hasShrinkwrap":false},"7.18.6":{"name":"@babel/parser","version":"7.18.6","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.18.6","@babel/helper-check-duplicate-nodes":"^7.18.6","@babel/helper-fixtures":"^7.18.6","@babel/helper-validator-identifier":"^7.18.6","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","type":"commonjs","_id":"@babel/parser@7.18.6","dist":{"shasum":"845338edecad65ebffef058d3be851f1d28a63bc","integrity":"sha512-uQVSa9jJUe/G/304lXspfWVpKpK4euFLgGiMQFOCpM/bgcAdeoHwi/OQz23O9GK2osz26ZiXRRV9aV+Yl1O8tw==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.18.6.tgz","fileCount":8,"unpackedSize":1885546,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD/Y3XvK8IAjL0lhh1fbt7fxSrHZlFWEKJiXuMjfOtiFwIgJspv1JnSqA3XeVQ84HzZ4Uw0hONU2ZHM7ndAs7gTBxw="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiugnZACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrrzQ/8CSjX1ALGNJT2+aZDCI1H6WVCc9Kv8JbcVWiuEBflz0TLMWOS\r\n/+MqwqGgyr60GwXA5JcS/g/5xrHJD/cFfIDLz+lE+34UIZdFOSy7QICvnplc\r\nYiGQ1C2+xlpEsMmOUDzPnlA8uWWscUtA+VUpohvNzyE5pQe6CVQVRcCpHIOL\r\ndCJtM8cJOAs2LwP1JT79IR4m6gErOABuGnCm29cK7p1JMKIPBQGp21E102W8\r\nlyOb4J4qOewkqX68zpgQ8su+dkMdj0rY0KcbRkHMOJ8HAuS87xAQbCg2LEi6\r\n4+uKxbrO3h6nxlW18Eh2C7bRzb15qlF5fKeSPKHDVPNHPbpPoCWvOnGpD/0P\r\nHo0YeJAfthE+AEJfKKFwxKWqOENleC+J+BVpDvJnVHpVQRGr0NmuYyHBkffB\r\n43R6rmR0dz2BdVLdInHRdcv0iEF0TqSt0PQ+uAPcOBBG81GdizvTjLh6il5+\r\n2K4VETEYuqAfa7Og7X+q5by6snFEd7dwoqe3uhx0SFqHYs2yBpq6xp1FYQ+A\r\n+akGB/UQm+ufR1g9JiTtd+y/YtT13MaCoSOJQvC+oKe6lFQazQv2rt18yQxZ\r\nB9ltzwcQaWl8XxjaKxwyqnP+ag8rXa0KzPYfju3jE47gsDRpZwqLVy6JYjjq\r\n1fpNf9AiBhCbAuzN688pNSideWOzamVyuHI=\r\n=vvfM\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.18.6_1656359385419_0.07397570814862942"},"_hasShrinkwrap":false},"7.18.8":{"name":"@babel/parser","version":"7.18.8","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.18.6","@babel/helper-check-duplicate-nodes":"^7.18.6","@babel/helper-fixtures":"^7.18.6","@babel/helper-validator-identifier":"^7.18.6","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","type":"commonjs","_id":"@babel/parser@7.18.8","dist":{"shasum":"822146080ac9c62dac0823bb3489622e0bc1cbdf","integrity":"sha512-RSKRfYX20dyH+elbJK2uqAkVyucL+xXzhqlMD5/ZXx+dAAwpyB7HsvnHe/ZUGOF+xLr5Wx9/JoXVTj6BQE2/oA==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.18.8.tgz","fileCount":8,"unpackedSize":1885544,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFKLeoFckRyypJcgE1zau5PXICp2hbX9iw2YU6zI21yZAiEA72uCuw2UqjSgSDdRzuHuK1C/+3tB2q+QHTe2a8e6ZWc="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJix/myACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpG1RAAk+MEVrpD9lEehMLw9eNAEmlE3v6Yepj2eVJ88f+vV5QzPcnu\r\nmDvIB/BZh7HcieqqXGqV2HKKBHh92rv3fxzscsOD9GdjpZ7Z+alUBdzJLIQ4\r\niDnONYFdcW/Wskm7OplCQCBtaKuK+dKQuFNQNRO3ti/86ENndN01vYIlAdCA\r\n2j7FRAerAqjuT5r+Y397wcDiPQf+ceNLbwn8dtG3Oem5dkEhvXRJY5DptpLz\r\nt60QFVDaLZGInfbGzsBdulOwT1X8qRYxpkJzR76RyCtO4+wpD+OT+uBAIygY\r\nF+8tCikG97glEBHrY6mG3N1gk32R/ghMo4UcZhU/j8N8hzgDw1IXbzOiGjO1\r\nckp36Xce5XGVyFdu6k8mbdv4XEdp83WgY5NozXB39rYq8egmi0ZDItyrksun\r\n5nsLTnqWBlFqYVBE8HKXR5Tw1Vif0RIWCBxf6rsO/9qe07PajzkIsbnSXakL\r\n/6+mMbBC1g7Fa+CfKeCOPg0hpWzYU2Vdo3j4TRyRd9OxHJvlelcyTNu9/jbL\r\nbfNWS6orS43LhU/sZ2lcDNTTS3x1i5D47D3zhcOx0eRXG1aI9rKVt81k0TrS\r\njjPLsoP9RSrT23Er+VRE9FgTGQtcC5BmjfRGc7ZZzF9TLD3dSVGHJsKq/94k\r\nUtlyN66Ohow7fn+IQEfCxr5OvqOgWAJOT3I=\r\n=RGOJ\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.18.8_1657272754123_0.7842763312402985"},"_hasShrinkwrap":false},"7.18.9":{"name":"@babel/parser","version":"7.18.9","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.18.6","@babel/helper-check-duplicate-nodes":"^7.18.6","@babel/helper-fixtures":"^7.18.6","@babel/helper-validator-identifier":"^7.18.6","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","type":"commonjs","_id":"@babel/parser@7.18.9","dist":{"shasum":"f2dde0c682ccc264a9a8595efd030a5cc8fd2539","integrity":"sha512-9uJveS9eY9DJ0t64YbIBZICtJy8a5QrDEVdiLCG97fVLpDTpGX7t8mMSb6OWw6Lrnjqj4O8zwjELX3dhoMgiBg==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.18.9.tgz","fileCount":9,"unpackedSize":1885672,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD/0Qn7tw2FhelyEDVc2GZY4Lg5qj8ONxPOqtCpha/imgIgdNlqD643JDC8ShJfocIsJmEijjIPy/DVazPxyjylMgQ="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi1SUjACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp1dA//VIQkV0UJiZ/l14dEnrPgUoozLNvzhwqOcKKuESsEP7VSw1iE\r\nOKVkUN/GGbgJp0+nW8tu5EflEViiikT2S+UlYQXNluK7lx01/i0ktlIO+mfM\r\nbX7PxXuA6mh7At/cJ+L3bJEuMnHsgDa3X/IeEb/8i9BKfvseGlLdQe2YtZm5\r\nkEvqPPn88GIqZ2iNvSst3Mb6qapWzZNn1LT+y7zTmDN9uwyW+xJhnUdNqanh\r\n1QkFCeee7unXGdzvPVA+0ShDO//IAPNfuwtEgyVPbVjfzOkQBd4atgXn5mBt\r\nwmfAPcqFojOMolKUQGUzJyodjqYYF+XRwLMPaandT43zzyNgU7in+9ew7wus\r\nfhMyeOLmEmNsSVF4IC4+tZxk8HVpOV33VJeGNZ5eT/AxrHRiKvVMYQ+yQa8r\r\nM3p7y4io0S5NsvvuZr3gGtylIogoP9YGK0a8Pv3HLva/tPuwlF7Kb48cillE\r\nl6CTVUawE+wcXw7+wiRYC9GhBaHUeW3RR8iEXnJPYtbRnILMQmnch21Ew67/\r\nrjmKkpkA1I3ET7l2QmtDKVJ+xnuqwAsZGQqfu0sxjZ9FhVXBkWBi6b5+kWit\r\nX3bVIPcdRI/Nc1E3UMKtRTZIvjbd19seCE6NGi05xsXyhR7seRmKXu3fhloe\r\nZzecN3RSHrHl3oT/WJLWGqiZCBKxqisfETI=\r\n=Jgnh\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.18.9_1658135843487_0.5769948220189218"},"_hasShrinkwrap":false},"7.18.10":{"name":"@babel/parser","version":"7.18.10","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.18.6","@babel/helper-check-duplicate-nodes":"^7.18.6","@babel/helper-fixtures":"^7.18.6","@babel/helper-string-parser":"^7.18.10","@babel/helper-validator-identifier":"^7.18.6","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","type":"commonjs","_id":"@babel/parser@7.18.10","dist":{"shasum":"94b5f8522356e69e8277276adf67ed280c90ecc1","integrity":"sha512-TYk3OA0HKL6qNryUayb5UUEhM/rkOQozIBEA5ITXh5DWrSp0TlUQXMyZmnWxG/DizSWBeeQ0Zbc5z8UGaaqoeg==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.18.10.tgz","fileCount":9,"unpackedSize":1920633,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBE0yRl4c7yey8fagb1L73JPMKvs4UWkuEy+qZwfDMeiAiAfjUtNYDMyE+81JRtSlESiykUc+pZLb75kNfEjit5paQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi6B+QACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoGjw//Qx0VQBMIi0/yagaSMkwWvdtEBuY8TLYPdzTm5hbBpl176cT/\r\n7iju/lSXN+WQjJ39IbmbJ76bXXoEG+bMlqLhVv3DnIoCQibBkUvNCzBim2xq\r\nc6AinXXpn2Mn1b9NVPw16N16PTVLeJlVHtSyivjpksJzx6vLbhYE4X5dzoAu\r\n5OcfBTw6OJe7fcC3YzOJTP1PNNuJZLLVN2SEm2l7ej6k60vGJcDQ10UWpyOJ\r\nq8F7xl2EJNT6O1ADxncBlLgaUsNModzNUFPMKS0G1PWWXrw0xa98QFOElINj\r\nnotpRCrT5CnN+o3P7RHPgIaN14lzxU6JJ3zMBgnYxr5lQYcn/srQMFizRIgb\r\nsCsl0fK2RNlwp5ghMR1n3dkRxnA+IFfApnp4TRmysZdtaVQEyD2BmTZX5YWJ\r\n3gFtC3BEx3g4byAMw+izH7KRNcDIsoKWq3QGt7Cg7khKHxn5e9gTWT6l4jNM\r\nQIZi9KNXsJe/vBUuk7P1cvpC2BwwdwmZ2gWxu+P8s9HytjORhtUdMHf3izyh\r\nW1f0k24lQgphUc9MT4bCdDAd02Yiri42kP4ZQveDlxsDiNsxh2O/NAig974v\r\n/YRueYkJ7x5wbal2Q0sflKgrObgS1Hjc5CbbMyMpNDblCFaHLgBmrIOcqp2U\r\nZKzx5l6qoXd7Z6hKEwz55aP4CkpXyB1P7ww=\r\n=ZZOD\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.18.10_1659379600734_0.07303051251735826"},"_hasShrinkwrap":false},"7.18.11":{"name":"@babel/parser","version":"7.18.11","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.18.6","@babel/helper-check-duplicate-nodes":"^7.18.6","@babel/helper-fixtures":"^7.18.6","@babel/helper-string-parser":"^7.18.10","@babel/helper-validator-identifier":"^7.18.6","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","type":"commonjs","_id":"@babel/parser@7.18.11","dist":{"shasum":"68bb07ab3d380affa9a3f96728df07969645d2d9","integrity":"sha512-9JKn5vN+hDt0Hdqn1PiJ2guflwP+B6Ga8qbDuoF0PzzVhrzsKIJo8yGqVk6CmMHiMei9w1C1Bp9IMJSIK+HPIQ==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.18.11.tgz","fileCount":9,"unpackedSize":1923058,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICDIZ2vFCdqjyaQt58jDpCioARrq76oVGBC5Gqp1sXbWAiBFXMwRwwXBWwAZ96M2tbfF8sFuMdlvKmD12QVktoWXvw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi679zACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrmfBAAmHNMxj+4v/bkIpKrKIlXhujIlzdVmVI9xA/0O2GGsY3q5hYw\r\nYWJFTB97qVZCMMzlPkaUwJcmGOQNO2Mv/ZAltdPNxwOsj2FkkouE96bmwpBa\r\nQABplp9VntoGy9TmC+3CT8nHQ++hKhXg0iet1rYk3Amm1GtZJkuUzym/Oe04\r\nW43neGYRvoihSgNIbb9PwkCevQLR0v/NMji+foq6BGwNJZE2rhiysTHyf4S3\r\ng/7hejc1Nn369F7jZB4QfNOpHbir6kEDoZn9jBneu0FOkBdoi8Pok98ORoWi\r\nbjHXD2i5LVx306T9YhcWbHdpHuRlwhhH380lCrYv1iQSIr96ptuADsWWUDau\r\nYgY7gk5EWbH2b834KUsomt7xYRN+oINxDPG0MgbzaHdYqSOeNXU1Sz/D7yCD\r\nYGIa6FAxFbCDfjB2P1ztozv9ejb0Kh9DMr9S7xwITkiLPvdU6gGNGqKiaRsr\r\nqvC+dx0t8fVZHNm1NLn+XV+EKTWwFfXOnpIKTW3eL+9G4O7edCUjfbdhV7Q4\r\n4rAxhyQK2SVC3ZezDqUFlTc83VAvIiM1vSVZfq9h8q87DaOGQ3KFWyBZuedR\r\naZzo8zH0x8d5zeVZnwTVQNxQJaCHerY+Lam1VEn6Q6QVbt07oa06/jYgaLDP\r\nr9fLbQo1VDBLpNh4Sdz7PRW4TNTW6gX3+u8=\r\n=Pn6K\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.18.11_1659617138796_0.6784841680288765"},"_hasShrinkwrap":false},"7.18.13":{"name":"@babel/parser","version":"7.18.13","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.18.6","@babel/helper-check-duplicate-nodes":"^7.18.6","@babel/helper-fixtures":"^7.18.6","@babel/helper-string-parser":"^7.18.10","@babel/helper-validator-identifier":"^7.18.6","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","type":"commonjs","_id":"@babel/parser@7.18.13","dist":{"shasum":"5b2dd21cae4a2c5145f1fbd8ca103f9313d3b7e4","integrity":"sha512-dgXcIfMuQ0kgzLB2b9tRZs7TTFFaGM2AbtA4fJgUUYukzGH4jwsS7hzQHEGs67jdehpm22vkgKwvbU+aEflgwg==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.18.13.tgz","fileCount":9,"unpackedSize":1923489,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBXP41V/7fRc5E0u04GXObiTrgVHTEo2FvOXEjJH7l13AiEApfDGuPwDSROhT512WxWcB2AWzVyEjCSf5WD+RXcZszs="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjA6k2ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoOdQ//SLvTSH53Z7J2AVcO8UVQ7KqJO0hTpk4Pp7axwxh6d3T8Wk4k\r\nOQm4wJA0ZN84r/Ya6axHtvdM1eUNJm3rRiv0vudolTnh+KbuHYIjBQNQg8EX\r\nTdNHrgRGd9IarQ93tXQTXqdA4Ak3kLGCiNC1FQUmoaAUo9xcD96oWK1saz+s\r\nzoIIKEjiPYvLO/+PDt2lT4y13Bj2lUAt5qU81jiy1GyPeniyYzKsFn+X7/fn\r\nmy6/SjRdZVt+/WDwvXulR5RIHz0PpOzAPHqlUMdOS5tSlHIZEsT8UtTcAZoo\r\nhVUZMaqAQ/fYbxq6Dqg+DeZGgdInxk0DUFqtMYsPifBgCLSw6F/ZdJOam3kC\r\nsFC2XtowfTIq7+B0KGHWJOD2G3KZUmrv5oG9nY9DXvQfkmZdePtHRQd9/VUA\r\nWqeGMHQ3PcxqljeGfgkl9bTXmFG87kpPJkC+30MHdNmLqXF1nUgGRvT1yHSx\r\n1RU1shTeH6zhzVrCkcdJXfCPI8j0oS3TIb/8P7fPqnzj7xydEQnhE6UjSRfA\r\nr6WH+VS9S3Sk28yiCtTukTO/p3GGvcDnbiSE5XBEwmZXWNujoK5zFLn6BYfd\r\nQ1U400R9Ak1Vby7ae2tp3SwQIDjjX5RVwJj2ybObLE1CICaGgIpAXQdBo5dq\r\nFAgKg38tp6ACoLhkjMHl1vWvNeYnIA/aHq0=\r\n=1dqJ\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.18.13_1661184310586_0.6774494198143322"},"_hasShrinkwrap":false},"7.19.0":{"name":"@babel/parser","version":"7.19.0","description":"A JavaScript parser","author":"The Babel Team (https://babel.dev/team)","homepage":"https://babel.dev/docs/en/next/babel-parser","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen","license":"MIT","publishConfig":{"access":"public"},"keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"main":"./lib/index.js","types":"./typings/babel-parser.d.ts","engines":{"node":">=6.0.0"},"devDependencies":{"@babel/code-frame":"^7.18.6","@babel/helper-check-duplicate-nodes":"^7.18.6","@babel/helper-fixtures":"^7.18.6","@babel/helper-string-parser":"^7.18.10","@babel/helper-validator-identifier":"^7.18.6","charcodes":"^0.2.0"},"bin":"./bin/babel-parser.js","type":"commonjs","_id":"@babel/parser@7.19.0","dist":{"shasum":"497fcafb1d5b61376959c1c338745ef0577aa02c","integrity":"sha512-74bEXKX2h+8rrfQUfsBfuZZHzsEs6Eql4pqy/T4Nn6Y9wNPggQOqD6z6pn5Bl8ZfysKouFZT/UXEH94ummEeQw==","tarball":"http://localhost:4545/npm/registry/@babel/parser/parser-7.19.0.tgz","fileCount":9,"unpackedSize":1926947,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDLyuxYEcwPpnDSd5zj2aROo6jy2I5H16rb6yp5bNvX6wIgIO6qzfHVZrGoqEI+b73UoltOUMNIGX5xfRipuXpJOvw="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjFke1ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr75g//fJSB/F+s79C65oFQclZV5zUctAHp2uUZxhBecOQM6CiVDH0X\r\nrhKpS1pvKH/TwknXHNx8dQfqgYB/fHBmHixftlQ6vcPhrX4R2dxTAbgOj/kJ\r\nB9VDiVVK4rKhm9OuuTLA/xRpWtFE3H18Qlo3Zoxh8SIR8udGSXGj7fYXNUgk\r\nGuZEFZqp5FXDY+Cx34BH0nVfcZGe5HUcOfRjpVc9yn1DrRWVzHKTZEGgiBXo\r\nJmbSzA+eUqIUDjmuCTKz66TPfMNC9hFRPDqcg4usP7bwOOkZ+xx7PNEeO4SI\r\nP53pUPx54CgR5fOoW/ue5Y4aWSIUrrf/txRwgeEaf+tYzegDeSfliUKEgS2h\r\nH3+1BdwymdJKuv3cveInyj5DRdepcmhTCUS2WHH/d4NnXw/lsutspw6PPr5h\r\nFnfMucSyyoHchCTluV9dR9RzTjZjbtU8X6Ad/SbYR5YlETMs0JhHu54/eWpF\r\nv+A5EBeacpscE1EnDrZOIYYFpexRCPiwr/wy0dqHIuI1Z2CoZ5+0SPt472pI\r\nWH5DCEsSn4H/LzDW1lepdyDfaScCNRzurxk6t4GBI/kk/62UqW5UoJ/tOC7u\r\n4dHRQETuK/szceMTuvHL9epnmiKcILvCxPMbSH5yxENdB8P8RqxB5qv77e2j\r\nIVyBYqXWg2l54A734Z86VjtCavQuooWavVQ=\r\n=35HW\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},"directories":{},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/parser_7.19.0_1662404532907_0.08410819017285243"},"_hasShrinkwrap":false}},"time":{"created":"2018-05-24T19:20:36.538Z","7.0.0-beta.48":"2018-05-24T19:20:37.194Z","modified":"2022-09-05T19:02:13.249Z","7.0.0-beta.49":"2018-05-25T16:00:12.380Z","7.0.0-beta.50":"2018-06-12T19:46:42.798Z","7.0.0-beta.51":"2018-06-12T21:19:10.384Z","7.0.0-beta.52":"2018-07-06T00:59:07.656Z","7.0.0-beta.53":"2018-07-11T13:39:56.614Z","7.0.0-beta.54":"2018-07-16T17:59:47.524Z","7.0.0-beta.55":"2018-07-28T22:06:45.798Z","7.0.0-beta.56":"2018-08-04T01:02:55.925Z","7.0.0-rc.0":"2018-08-09T15:56:12.788Z","7.0.0-rc.1":"2018-08-09T20:06:16.091Z","7.0.0-rc.2":"2018-08-21T19:22:16.552Z","7.0.0-rc.3":"2018-08-24T18:06:11.894Z","7.0.0-rc.4":"2018-08-27T16:42:20.123Z","7.0.0":"2018-08-27T21:41:34.522Z","7.1.0":"2018-09-17T19:30:13.445Z","7.1.1":"2018-09-28T20:02:46.201Z","7.1.2":"2018-09-28T22:19:41.296Z","7.1.3":"2018-10-11T15:52:26.875Z","7.1.5":"2018-11-06T22:21:25.453Z","7.1.6":"2018-11-13T21:10:28.790Z","7.2.0":"2018-12-03T18:57:21.475Z","7.2.2":"2018-12-15T10:05:16.592Z","7.2.3":"2018-12-20T11:12:51.059Z","7.3.0":"2019-01-21T21:30:31.484Z","7.3.1":"2019-01-22T07:13:45.925Z","7.3.2":"2019-02-04T22:22:58.130Z","7.3.3":"2019-02-15T21:14:27.506Z","7.3.4":"2019-02-25T18:35:17.638Z","7.4.0":"2019-03-19T20:44:16.703Z","7.4.2":"2019-03-21T10:17:24.742Z","7.4.3":"2019-04-02T19:55:41.074Z","7.4.4":"2019-04-26T21:03:41.664Z","7.4.5":"2019-05-21T17:45:36.763Z","7.5.0":"2019-07-04T12:57:57.824Z","7.5.5":"2019-07-17T21:21:27.443Z","7.6.0":"2019-09-06T17:33:44.637Z","7.6.2":"2019-09-23T21:21:42.328Z","7.6.3":"2019-10-08T19:49:32.213Z","7.6.4":"2019-10-10T14:29:16.561Z","7.7.0":"2019-11-05T10:53:12.049Z","7.7.2":"2019-11-06T23:27:23.152Z","7.7.3":"2019-11-08T20:50:30.500Z","7.7.4":"2019-11-22T23:31:47.410Z","7.7.5":"2019-12-06T13:17:50.030Z","7.7.7":"2019-12-19T00:53:10.367Z","7.8.0":"2020-01-12T00:16:03.390Z","7.8.3":"2020-01-13T21:41:05.926Z","7.8.4":"2020-01-30T12:37:26.570Z","7.8.6":"2020-02-27T12:21:25.947Z","7.8.7":"2020-03-05T01:56:07.070Z","7.8.8":"2020-03-12T18:49:06.144Z","7.9.0":"2020-03-20T15:39:24.532Z","7.9.2":"2020-03-21T14:14:20.297Z","7.9.3":"2020-03-22T11:02:52.802Z","7.9.4":"2020-03-24T08:31:23.294Z","7.9.6":"2020-04-29T18:38:05.424Z","7.10.0":"2020-05-26T21:43:15.606Z","7.10.1":"2020-05-27T22:06:55.479Z","7.10.2":"2020-05-30T19:25:10.716Z","7.10.3":"2020-06-19T20:54:08.445Z","7.10.4":"2020-06-30T13:11:22.088Z","7.10.5":"2020-07-14T18:17:42.196Z","7.11.0":"2020-07-30T20:56:44.096Z","7.11.1":"2020-08-04T22:05:47.047Z","7.11.2":"2020-08-05T14:28:29.725Z","7.11.3":"2020-08-08T20:07:34.967Z","7.11.4":"2020-08-20T18:59:48.682Z","7.11.5":"2020-08-31T20:02:14.120Z","7.12.0":"2020-10-14T20:02:40.563Z","7.12.1":"2020-10-15T22:39:20.791Z","7.12.2":"2020-10-16T06:50:01.894Z","7.12.3":"2020-10-16T21:14:23.129Z","7.12.5":"2020-11-03T22:34:13.667Z","7.12.7":"2020-11-20T21:05:35.614Z","7.12.10":"2020-12-09T22:47:52.632Z","7.12.11":"2020-12-15T23:59:16.808Z","7.12.13":"2021-02-03T01:09:51.367Z","7.12.14":"2021-02-03T15:06:37.662Z","7.12.15":"2021-02-04T21:38:00.714Z","7.12.16":"2021-02-11T22:46:58.714Z","7.12.17":"2021-02-18T15:11:25.717Z","7.13.0":"2021-02-22T22:49:31.952Z","7.13.4":"2021-02-23T10:40:22.025Z","7.13.9":"2021-03-01T21:43:59.300Z","7.13.10":"2021-03-08T22:36:12.798Z","7.13.11":"2021-03-15T09:44:26.451Z","7.13.12":"2021-03-22T15:46:59.662Z","7.13.13":"2021-03-26T21:20:21.407Z","7.13.15":"2021-04-08T15:50:19.807Z","7.13.16":"2021-04-20T11:21:06.093Z","7.14.0":"2021-04-29T20:09:53.335Z","7.14.1":"2021-05-04T01:55:59.694Z","7.14.2":"2021-05-12T17:09:14.850Z","7.14.3":"2021-05-17T20:44:22.685Z","7.14.4":"2021-05-28T16:59:46.838Z","7.14.5":"2021-06-09T23:11:20.291Z","7.14.6":"2021-06-14T21:56:58.137Z","7.14.7":"2021-06-21T21:54:00.406Z","7.14.8":"2021-07-20T18:02:34.946Z","7.14.9":"2021-08-01T07:53:13.671Z","7.15.0":"2021-08-04T21:12:55.308Z","7.15.2":"2021-08-08T16:14:12.928Z","7.15.3":"2021-08-11T07:19:33.564Z","7.15.4":"2021-09-02T21:39:23.625Z","7.15.5":"2021-09-04T08:58:47.386Z","7.15.6":"2021-09-09T19:35:14.950Z","7.15.7":"2021-09-17T23:06:17.159Z","7.15.8":"2021-10-06T20:54:56.282Z","7.16.0":"2021-10-29T23:47:23.344Z","7.16.2":"2021-11-01T21:56:55.280Z","7.16.3":"2021-11-09T21:53:03.125Z","7.16.4":"2021-11-16T22:46:15.990Z","7.16.5":"2021-12-13T22:27:33.400Z","7.16.6":"2021-12-14T23:39:15.548Z","7.16.7":"2021-12-31T00:21:22.882Z","7.16.8":"2022-01-10T21:18:22.427Z","7.16.10":"2022-01-19T18:39:00.685Z","7.16.12":"2022-01-22T15:10:39.529Z","7.17.0":"2022-02-02T23:04:46.672Z","7.17.3":"2022-02-15T15:44:19.345Z","7.17.7":"2022-03-14T17:07:09.542Z","7.17.8":"2022-03-18T20:31:09.736Z","7.17.9":"2022-04-06T15:55:21.983Z","7.17.10":"2022-04-29T16:37:38.202Z","7.17.12":"2022-05-16T19:32:14.035Z","7.18.0":"2022-05-19T18:16:32.423Z","7.18.3":"2022-05-25T14:44:31.595Z","7.18.4":"2022-05-29T21:50:11.629Z","7.18.5":"2022-06-13T06:40:21.924Z","7.18.6":"2022-06-27T19:49:45.637Z","7.18.8":"2022-07-08T09:32:34.328Z","7.18.9":"2022-07-18T09:17:23.708Z","7.18.10":"2022-08-01T18:46:40.957Z","7.18.11":"2022-08-04T12:45:39.068Z","7.18.13":"2022-08-22T16:05:10.888Z","7.19.0":"2022-09-05T19:02:13.150Z"},"maintainers":[{"name":"hzoo","email":"hi@henryzoo.com"},{"name":"existentialism","email":"bng412@gmail.com"},{"name":"nicolo-ribaudo","email":"nicolo.ribaudo@gmail.com"},{"name":"jlhwung","email":"i@jhuang.me"}],"description":"A JavaScript parser","homepage":"https://babel.dev/docs/en/next/babel-parser","keywords":["babel","javascript","parser","tc39","ecmascript","@babel/parser"],"repository":{"type":"git","url":"https://github.com/babel/babel.git","directory":"packages/babel-parser"},"author":"The Babel Team (https://babel.dev/team)","license":"MIT","readme":"","readmeFilename":"","bugs":"https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22pkg%3A+parser+%28babylon%29%22+is%3Aopen"} \ No newline at end of file diff --git a/tests/testdata/npm/registry/@denotest/CAPITALS/1.0.0/index.js b/tests/testdata/npm/registry/@denotest/CAPITALS/1.0.0/index.js new file mode 100644 index 000000000..f4e8d9d29 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/CAPITALS/1.0.0/index.js @@ -0,0 +1 @@ +module.exports = 5; diff --git a/tests/testdata/npm/registry/@denotest/CAPITALS/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/CAPITALS/1.0.0/package.json new file mode 100644 index 000000000..e897d0023 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/CAPITALS/1.0.0/package.json @@ -0,0 +1,4 @@ +{ + "name": "@denotest/CAPITALS", + "version": "1.0.0" +} diff --git a/tests/testdata/npm/registry/@denotest/MixedCase/1.0.0/index.js b/tests/testdata/npm/registry/@denotest/MixedCase/1.0.0/index.js new file mode 100644 index 000000000..fe1cfe547 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/MixedCase/1.0.0/index.js @@ -0,0 +1,2 @@ +const value = require("@denotest/CAPITALS"); +module.exports = value; diff --git a/tests/testdata/npm/registry/@denotest/MixedCase/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/MixedCase/1.0.0/package.json new file mode 100644 index 000000000..2a36cb357 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/MixedCase/1.0.0/package.json @@ -0,0 +1,7 @@ +{ + "name": "@denotest/MixedCase", + "version": "1.0.0", + "dependencies": { + "@denotest/CAPITALS": "^1" + } +} diff --git a/tests/testdata/npm/registry/@denotest/bin/0.5.0/cli.mjs b/tests/testdata/npm/registry/@denotest/bin/0.5.0/cli.mjs new file mode 100644 index 000000000..0ae8e9190 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/bin/0.5.0/cli.mjs @@ -0,0 +1,5 @@ +import process from "node:process"; + +for (const arg of process.argv.slice(2)) { + console.log(arg); +} diff --git a/tests/testdata/npm/registry/@denotest/bin/0.5.0/package.json b/tests/testdata/npm/registry/@denotest/bin/0.5.0/package.json new file mode 100644 index 000000000..1b077a52e --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/bin/0.5.0/package.json @@ -0,0 +1,5 @@ +{ + "name": "@denotest/bin", + "version": "0.5.0", + "bin": "./cli.mjs" +} diff --git a/tests/testdata/npm/registry/@denotest/bin/0.6.0/cli-cjs.js b/tests/testdata/npm/registry/@denotest/bin/0.6.0/cli-cjs.js new file mode 100644 index 000000000..7b6ba2724 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/bin/0.6.0/cli-cjs.js @@ -0,0 +1,5 @@ +const process = require("process"); + +for (const arg of process.argv.slice(2)) { + console.log(arg); +} diff --git a/tests/testdata/npm/registry/@denotest/bin/0.6.0/cli.mjs b/tests/testdata/npm/registry/@denotest/bin/0.6.0/cli.mjs new file mode 100644 index 000000000..0ae8e9190 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/bin/0.6.0/cli.mjs @@ -0,0 +1,5 @@ +import process from "node:process"; + +for (const arg of process.argv.slice(2)) { + console.log(arg); +} diff --git a/tests/testdata/npm/registry/@denotest/bin/0.6.0/package.json b/tests/testdata/npm/registry/@denotest/bin/0.6.0/package.json new file mode 100644 index 000000000..a9ff2d946 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/bin/0.6.0/package.json @@ -0,0 +1,4 @@ +{ + "name": "@denotest/bin", + "version": "0.6.0" +} diff --git a/tests/testdata/npm/registry/@denotest/bin/1.0.0/cli-cjs.js b/tests/testdata/npm/registry/@denotest/bin/1.0.0/cli-cjs.js new file mode 100644 index 000000000..7b6ba2724 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/bin/1.0.0/cli-cjs.js @@ -0,0 +1,5 @@ +const process = require("process"); + +for (const arg of process.argv.slice(2)) { + console.log(arg); +} diff --git a/tests/testdata/npm/registry/@denotest/bin/1.0.0/cli-no-ext b/tests/testdata/npm/registry/@denotest/bin/1.0.0/cli-no-ext new file mode 100644 index 000000000..7b6ba2724 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/bin/1.0.0/cli-no-ext @@ -0,0 +1,5 @@ +const process = require("process"); + +for (const arg of process.argv.slice(2)) { + console.log(arg); +} diff --git a/tests/testdata/npm/registry/@denotest/bin/1.0.0/cli.mjs b/tests/testdata/npm/registry/@denotest/bin/1.0.0/cli.mjs new file mode 100644 index 000000000..0ae8e9190 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/bin/1.0.0/cli.mjs @@ -0,0 +1,5 @@ +import process from "node:process"; + +for (const arg of process.argv.slice(2)) { + console.log(arg); +} diff --git a/tests/testdata/npm/registry/@denotest/bin/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/bin/1.0.0/package.json new file mode 100644 index 000000000..27118c21a --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/bin/1.0.0/package.json @@ -0,0 +1,9 @@ +{ + "name": "@denotest/bin", + "version": "1.0.0", + "bin": { + "cli-esm": "./cli.mjs", + "cli-no-ext": "./cli-no-ext", + "cli-cjs": "./cli-cjs.js" + } +} diff --git a/tests/testdata/npm/registry/@denotest/binary-package-linux/1.0.0/index.js b/tests/testdata/npm/registry/@denotest/binary-package-linux/1.0.0/index.js new file mode 100644 index 000000000..03ecfc377 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/binary-package-linux/1.0.0/index.js @@ -0,0 +1 @@ +console.log("Hello from binary package on linux"); \ No newline at end of file diff --git a/tests/testdata/npm/registry/@denotest/binary-package-linux/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/binary-package-linux/1.0.0/package.json new file mode 100644 index 000000000..3b450e0d9 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/binary-package-linux/1.0.0/package.json @@ -0,0 +1,8 @@ +{ + "name": "@denotest/binary-package-linux", + "version": "1.0.0", + "main": "index.js", + "os": [ + "linux" + ] +} diff --git a/tests/testdata/npm/registry/@denotest/binary-package-mac/1.0.0/index.js b/tests/testdata/npm/registry/@denotest/binary-package-mac/1.0.0/index.js new file mode 100644 index 000000000..ac8c91f50 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/binary-package-mac/1.0.0/index.js @@ -0,0 +1 @@ +console.log("Hello from binary package on mac"); \ No newline at end of file diff --git a/tests/testdata/npm/registry/@denotest/binary-package-mac/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/binary-package-mac/1.0.0/package.json new file mode 100644 index 000000000..02916e65b --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/binary-package-mac/1.0.0/package.json @@ -0,0 +1,8 @@ +{ + "name": "@denotest/binary-package-linux", + "version": "1.0.0", + "main": "index.js", + "os": [ + "darwin" + ] +} diff --git a/tests/testdata/npm/registry/@denotest/binary-package-windows/1.0.0/index.js b/tests/testdata/npm/registry/@denotest/binary-package-windows/1.0.0/index.js new file mode 100644 index 000000000..57344ca00 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/binary-package-windows/1.0.0/index.js @@ -0,0 +1 @@ +console.log("Hello from binary package on windows"); \ No newline at end of file diff --git a/tests/testdata/npm/registry/@denotest/binary-package-windows/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/binary-package-windows/1.0.0/package.json new file mode 100644 index 000000000..1c0af637d --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/binary-package-windows/1.0.0/package.json @@ -0,0 +1,8 @@ +{ + "name": "@denotest/binary-package-windows", + "version": "1.0.0", + "main": "index.js", + "os": [ + "win32" + ] +} diff --git a/tests/testdata/npm/registry/@denotest/binary-package/1.0.0/index.js b/tests/testdata/npm/registry/@denotest/binary-package/1.0.0/index.js new file mode 100644 index 000000000..5870118e7 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/binary-package/1.0.0/index.js @@ -0,0 +1,13 @@ +const packageByOs = { + "darwin": "@denotest/binary-package-mac", + "linux": "@denotest/binary-package-linux", + "win32": "@denotest/binary-package-windows", +} + +const selectedPackage = packageByOs[process.platform]; + +if (!selectedPackage) { + throw new Error("trying to run on unsupported platform"); +} + +require(selectedPackage); \ No newline at end of file diff --git a/tests/testdata/npm/registry/@denotest/binary-package/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/binary-package/1.0.0/package.json new file mode 100644 index 000000000..dc8859bb4 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/binary-package/1.0.0/package.json @@ -0,0 +1,10 @@ +{ + "name": "@denotest/binary-package", + "version": "1.0.0", + "main": "index.js", + "optionalDependencies": { + "@denotest/binary-package-linux": "1.0.0", + "@denotest/binary-package-mac": "1.0.0", + "@denotest/binary-package-windows": "1.0.0" + } +} diff --git a/tests/testdata/npm/registry/@denotest/breaking-change-between-versions/1.0.0/index.d.ts b/tests/testdata/npm/registry/@denotest/breaking-change-between-versions/1.0.0/index.d.ts new file mode 100644 index 000000000..06dfef10d --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/breaking-change-between-versions/1.0.0/index.d.ts @@ -0,0 +1 @@ +export function oldName(): 1; \ No newline at end of file diff --git a/tests/testdata/npm/registry/@denotest/breaking-change-between-versions/1.0.0/index.js b/tests/testdata/npm/registry/@denotest/breaking-change-between-versions/1.0.0/index.js new file mode 100644 index 000000000..1aca4250b --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/breaking-change-between-versions/1.0.0/index.js @@ -0,0 +1,3 @@ +export function newName() { + return 1; +} diff --git a/tests/testdata/npm/registry/@denotest/breaking-change-between-versions/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/breaking-change-between-versions/1.0.0/package.json new file mode 100644 index 000000000..6eabea3af --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/breaking-change-between-versions/1.0.0/package.json @@ -0,0 +1,6 @@ +{ + "name": "@denotest/breaking-change-between-versions", + "version": "1.0.0", + "type": "module", + "main": "index.js" +} diff --git a/tests/testdata/npm/registry/@denotest/breaking-change-between-versions/2.0.0/index.d.ts b/tests/testdata/npm/registry/@denotest/breaking-change-between-versions/2.0.0/index.d.ts new file mode 100644 index 000000000..9a96451a5 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/breaking-change-between-versions/2.0.0/index.d.ts @@ -0,0 +1 @@ +export function newName(): 2; \ No newline at end of file diff --git a/tests/testdata/npm/registry/@denotest/breaking-change-between-versions/2.0.0/index.js b/tests/testdata/npm/registry/@denotest/breaking-change-between-versions/2.0.0/index.js new file mode 100644 index 000000000..57626060d --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/breaking-change-between-versions/2.0.0/index.js @@ -0,0 +1,3 @@ +export function newName() { + return 2; +} diff --git a/tests/testdata/npm/registry/@denotest/breaking-change-between-versions/2.0.0/package.json b/tests/testdata/npm/registry/@denotest/breaking-change-between-versions/2.0.0/package.json new file mode 100644 index 000000000..ecd5970a4 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/breaking-change-between-versions/2.0.0/package.json @@ -0,0 +1,6 @@ +{ + "name": "@denotest/breaking-change-between-versions", + "version": "2.0.0", + "type": "module", + "main": "index.js" +} diff --git a/tests/testdata/npm/registry/@denotest/builtin-module-module/1.0.0/index.js b/tests/testdata/npm/registry/@denotest/builtin-module-module/1.0.0/index.js new file mode 100644 index 000000000..140f5ef21 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/builtin-module-module/1.0.0/index.js @@ -0,0 +1,7 @@ +import m1 from "node:module"; +import m2 from "module"; + +console.log(typeof m1.Module); +console.log(typeof m2.Module); +console.log(typeof m1); +console.log(m1 === m1.Module); diff --git a/tests/testdata/npm/registry/@denotest/builtin-module-module/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/builtin-module-module/1.0.0/package.json new file mode 100644 index 000000000..5167f18a3 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/builtin-module-module/1.0.0/package.json @@ -0,0 +1,5 @@ +{ + "name": "@denotest/builtin-module-module", + "version": "1.0.0", + "type": "module" +} diff --git a/tests/testdata/npm/registry/@denotest/check-error/1.0.0/index.d.ts b/tests/testdata/npm/registry/@denotest/check-error/1.0.0/index.d.ts new file mode 100644 index 000000000..bfb0483c2 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/check-error/1.0.0/index.d.ts @@ -0,0 +1,10 @@ +// intentional type checking errors +export class Class1 extends Class2 { +} + +export class Class2 extends Class1 { +} + +// these should be fine though +export { subDir } from "./sub_dir"; +export { otherDir } from "./other_dir"; diff --git a/tests/testdata/npm/registry/@denotest/check-error/1.0.0/index.js b/tests/testdata/npm/registry/@denotest/check-error/1.0.0/index.js new file mode 100644 index 000000000..7eb6b784d --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/check-error/1.0.0/index.js @@ -0,0 +1,6 @@ +module.exports = { + Class1: class { + }, + Class2: class { + }, +}; diff --git a/tests/testdata/npm/registry/@denotest/check-error/1.0.0/other_dir.d.ts b/tests/testdata/npm/registry/@denotest/check-error/1.0.0/other_dir.d.ts new file mode 100644 index 000000000..e7254c16c --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/check-error/1.0.0/other_dir.d.ts @@ -0,0 +1 @@ +export const otherDir: 2; diff --git a/tests/testdata/npm/registry/@denotest/check-error/1.0.0/other_dir/index.js b/tests/testdata/npm/registry/@denotest/check-error/1.0.0/other_dir/index.js new file mode 100644 index 000000000..56259f22d --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/check-error/1.0.0/other_dir/index.js @@ -0,0 +1 @@ +module.exports.otherDir = 2; diff --git a/tests/testdata/npm/registry/@denotest/check-error/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/check-error/1.0.0/package.json new file mode 100644 index 000000000..295920a8f --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/check-error/1.0.0/package.json @@ -0,0 +1,5 @@ +{ + "name": "@denotest/check-error", + "version": "1.0.0", + "types": "./index.d.ts" +} diff --git a/tests/testdata/npm/registry/@denotest/check-error/1.0.0/sub_dir/index.d.ts b/tests/testdata/npm/registry/@denotest/check-error/1.0.0/sub_dir/index.d.ts new file mode 100644 index 000000000..f41a696fd --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/check-error/1.0.0/sub_dir/index.d.ts @@ -0,0 +1 @@ +export * from './lib'; diff --git a/tests/testdata/npm/registry/@denotest/check-error/1.0.0/sub_dir/index.js b/tests/testdata/npm/registry/@denotest/check-error/1.0.0/sub_dir/index.js new file mode 100644 index 000000000..3dfac4c23 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/check-error/1.0.0/sub_dir/index.js @@ -0,0 +1 @@ +module.exports.subDir = 1; diff --git a/tests/testdata/npm/registry/@denotest/check-error/1.0.0/sub_dir/lib.d.ts b/tests/testdata/npm/registry/@denotest/check-error/1.0.0/sub_dir/lib.d.ts new file mode 100644 index 000000000..e5834b52b --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/check-error/1.0.0/sub_dir/lib.d.ts @@ -0,0 +1 @@ +export const subDir: 1; diff --git a/tests/testdata/npm/registry/@denotest/child-process-fork/1.0.0/forked_path.js b/tests/testdata/npm/registry/@denotest/child-process-fork/1.0.0/forked_path.js new file mode 100644 index 000000000..aaa106315 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/child-process-fork/1.0.0/forked_path.js @@ -0,0 +1,3 @@ +const chalk = require("chalk"); + +console.log(typeof chalk.green); diff --git a/tests/testdata/npm/registry/@denotest/child-process-fork/1.0.0/index.js b/tests/testdata/npm/registry/@denotest/child-process-fork/1.0.0/index.js new file mode 100644 index 000000000..0482be404 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/child-process-fork/1.0.0/index.js @@ -0,0 +1,20 @@ +const path = require("path"); + +function childProcessFork(path) { + const command = new Deno.Command(Deno.execPath(), { + args: ["run", "-A", path], + env: { + "DENO_DONT_USE_INTERNAL_NODE_COMPAT_STATE": Deno[Deno.internal].core.ops.op_npm_process_state(), + } + }); + const child = command.spawn(); + child.status.then(() => { + console.log("Done."); + }); +} + +module.exports = { + run() { + childProcessFork(path.join(__dirname, "forked_path.js")); + } +}; diff --git a/tests/testdata/npm/registry/@denotest/child-process-fork/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/child-process-fork/1.0.0/package.json new file mode 100644 index 000000000..9ab14e3f7 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/child-process-fork/1.0.0/package.json @@ -0,0 +1,4 @@ +{ + "name": "@denotest/child-process-fork", + "version": "1.0.0" +} diff --git a/tests/testdata/npm/registry/@denotest/cjs-default-export/1.0.0/index.d.ts b/tests/testdata/npm/registry/@denotest/cjs-default-export/1.0.0/index.d.ts new file mode 100644 index 000000000..90fdfe5f6 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/cjs-default-export/1.0.0/index.d.ts @@ -0,0 +1,6 @@ +export default function (): number; +export declare function named(): number; +declare class MyClass { + static someStaticMethod(): string; +} +export { MyClass }; diff --git a/tests/testdata/npm/registry/@denotest/cjs-default-export/1.0.0/index.js b/tests/testdata/npm/registry/@denotest/cjs-default-export/1.0.0/index.js new file mode 100644 index 000000000..ec4ece6b3 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/cjs-default-export/1.0.0/index.js @@ -0,0 +1,17 @@ +Object.defineProperty(module.exports, "__esModule", { + value: true +}); +module.exports["default"] = function() { + return 1; +}; +module.exports["named"] = function() { + return 2; +}; + +class MyClass { + static someStaticMethod() { + return "static method"; + } +} + +module.exports.MyClass = MyClass; diff --git a/tests/testdata/npm/registry/@denotest/cjs-default-export/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/cjs-default-export/1.0.0/package.json new file mode 100644 index 000000000..8da28b919 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/cjs-default-export/1.0.0/package.json @@ -0,0 +1,5 @@ +{ + "name": "@denotest/cjs-default-export", + "version": "1.0.0", + "types": "./index.d.ts" +} diff --git a/tests/testdata/npm/registry/@denotest/cjs-invalid-name-exports/1.0.0/index.js b/tests/testdata/npm/registry/@denotest/cjs-invalid-name-exports/1.0.0/index.js new file mode 100644 index 000000000..75c3f2e8a --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/cjs-invalid-name-exports/1.0.0/index.js @@ -0,0 +1,6 @@ +exports['wow "double quotes"'] = "double quotes" +exports["another 'case'"] = 'example' +exports["a \\ b"] = 'a \\ b' +const a = 'name variable' +exports[a] = "a"; +exports['foo - bar'] = 'foo - bar' diff --git a/tests/testdata/npm/registry/@denotest/cjs-invalid-name-exports/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/cjs-invalid-name-exports/1.0.0/package.json new file mode 100644 index 000000000..fd715eeae --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/cjs-invalid-name-exports/1.0.0/package.json @@ -0,0 +1,4 @@ +{ + "name": "@denotest/cjs-invalid-name-exports", + "version": "1.0.0" +} diff --git a/tests/testdata/npm/registry/@denotest/cjs-local-global-decls/1.0.0/index.js b/tests/testdata/npm/registry/@denotest/cjs-local-global-decls/1.0.0/index.js new file mode 100644 index 000000000..5aa546d91 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/cjs-local-global-decls/1.0.0/index.js @@ -0,0 +1,3 @@ +// package that has all the locals defined +const Buffer = 1, clearImmediate = 1, clearInterval = 1, clearTimeout = 1, console = 1, global = 1, process = 1, setImmediate = 1, setInterval = 1, setTimeout = 1, globalThis = 1; +require("./other.js"); diff --git a/tests/testdata/npm/registry/@denotest/cjs-local-global-decls/1.0.0/other.js b/tests/testdata/npm/registry/@denotest/cjs-local-global-decls/1.0.0/other.js new file mode 100644 index 000000000..810d852b0 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/cjs-local-global-decls/1.0.0/other.js @@ -0,0 +1,2 @@ +const console = new global.console.Console({ stdout: process.stdout }); +console.log("Loaded."); diff --git a/tests/testdata/npm/registry/@denotest/cjs-local-global-decls/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/cjs-local-global-decls/1.0.0/package.json new file mode 100644 index 000000000..1048fe76d --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/cjs-local-global-decls/1.0.0/package.json @@ -0,0 +1,4 @@ +{ + "name": "@denotest/cjs-local-global-decls", + "version": "1.0.0" +} diff --git a/tests/testdata/npm/registry/@denotest/cjs-module-export-assignment-number/1.0.0/index.d.ts b/tests/testdata/npm/registry/@denotest/cjs-module-export-assignment-number/1.0.0/index.d.ts new file mode 100644 index 000000000..0e1e0337d --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/cjs-module-export-assignment-number/1.0.0/index.d.ts @@ -0,0 +1,2 @@ +declare const value = 5; +export = value; diff --git a/tests/testdata/npm/registry/@denotest/cjs-module-export-assignment-number/1.0.0/index.js b/tests/testdata/npm/registry/@denotest/cjs-module-export-assignment-number/1.0.0/index.js new file mode 100644 index 000000000..f4e8d9d29 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/cjs-module-export-assignment-number/1.0.0/index.js @@ -0,0 +1 @@ +module.exports = 5; diff --git a/tests/testdata/npm/registry/@denotest/cjs-module-export-assignment-number/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/cjs-module-export-assignment-number/1.0.0/package.json new file mode 100644 index 000000000..4b2e3a294 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/cjs-module-export-assignment-number/1.0.0/package.json @@ -0,0 +1,5 @@ +{ + "name": "@denotest/cjs-module-export-assignment-number", + "version": "1.0.0", + "types": "./index.d.ts" +} diff --git a/tests/testdata/npm/registry/@denotest/cjs-module-export-assignment/1.0.0/index.d.ts b/tests/testdata/npm/registry/@denotest/cjs-module-export-assignment/1.0.0/index.d.ts new file mode 100644 index 000000000..a7b50005e --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/cjs-module-export-assignment/1.0.0/index.d.ts @@ -0,0 +1,5 @@ +declare module ThisModule { + function func(): 5; +} + +export = ThisModule; diff --git a/tests/testdata/npm/registry/@denotest/cjs-module-export-assignment/1.0.0/index.js b/tests/testdata/npm/registry/@denotest/cjs-module-export-assignment/1.0.0/index.js new file mode 100644 index 000000000..4c0285825 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/cjs-module-export-assignment/1.0.0/index.js @@ -0,0 +1,5 @@ +module.exports = { + func() { + return 5; + }, +}; diff --git a/tests/testdata/npm/registry/@denotest/cjs-module-export-assignment/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/cjs-module-export-assignment/1.0.0/package.json new file mode 100644 index 000000000..b8d3bbd2b --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/cjs-module-export-assignment/1.0.0/package.json @@ -0,0 +1,5 @@ +{ + "name": "@denotest/cjs-module-export-assignment", + "version": "1.0.0", + "types": "./index.d.ts" +} diff --git a/tests/testdata/npm/registry/@denotest/cjs-reexport-collision/1.0.0/index.js b/tests/testdata/npm/registry/@denotest/cjs-reexport-collision/1.0.0/index.js new file mode 100644 index 000000000..0c20973d9 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/cjs-reexport-collision/1.0.0/index.js @@ -0,0 +1,19 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __exportStar = (this && this.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +// collision will occur with __esModule in other_file.js +Object.defineProperty(exports, "__esModule", { value: true }); +const other_file_1 = __importDefault(require("./other_file")); +__exportStar(require("./other_file"), exports); +exports.default = other_file_1.default; diff --git a/tests/testdata/npm/registry/@denotest/cjs-reexport-collision/1.0.0/other_file.js b/tests/testdata/npm/registry/@denotest/cjs-reexport-collision/1.0.0/other_file.js new file mode 100644 index 000000000..3d8f7e812 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/cjs-reexport-collision/1.0.0/other_file.js @@ -0,0 +1,10 @@ +"use strict"; +class Hello { + sayHello() { + console.log("Hi."); + } +} +// conflict will be with __esModule +Object.defineProperty(exports, "__esModule", { value: true }); +exports.hello = new Hello(); +exports.default = new Hello(); diff --git a/tests/testdata/npm/registry/@denotest/cjs-reexport-collision/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/cjs-reexport-collision/1.0.0/package.json new file mode 100644 index 000000000..7befb31aa --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/cjs-reexport-collision/1.0.0/package.json @@ -0,0 +1,5 @@ +{ + "name": "@denotest/cjs-reexport-collision", + "version": "1.0.0", + "main": "./index.js" +} diff --git a/tests/testdata/npm/registry/@denotest/cjs-require-esm-error/1.0.0/esm/my_es_module.js b/tests/testdata/npm/registry/@denotest/cjs-require-esm-error/1.0.0/esm/my_es_module.js new file mode 100644 index 000000000..0613f1911 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/cjs-require-esm-error/1.0.0/esm/my_es_module.js @@ -0,0 +1 @@ +export class Test {} diff --git a/tests/testdata/npm/registry/@denotest/cjs-require-esm-error/1.0.0/esm/package.json b/tests/testdata/npm/registry/@denotest/cjs-require-esm-error/1.0.0/esm/package.json new file mode 100644 index 000000000..3dbc1ca59 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/cjs-require-esm-error/1.0.0/esm/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/tests/testdata/npm/registry/@denotest/cjs-require-esm-error/1.0.0/esm_mjs.mjs b/tests/testdata/npm/registry/@denotest/cjs-require-esm-error/1.0.0/esm_mjs.mjs new file mode 100644 index 000000000..0613f1911 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/cjs-require-esm-error/1.0.0/esm_mjs.mjs @@ -0,0 +1 @@ +export class Test {} diff --git a/tests/testdata/npm/registry/@denotest/cjs-require-esm-error/1.0.0/index.js b/tests/testdata/npm/registry/@denotest/cjs-require-esm-error/1.0.0/index.js new file mode 100644 index 000000000..ba630f93b --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/cjs-require-esm-error/1.0.0/index.js @@ -0,0 +1 @@ +module.exports.Test = require("./esm/my_es_module.js"); diff --git a/tests/testdata/npm/registry/@denotest/cjs-require-esm-error/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/cjs-require-esm-error/1.0.0/package.json new file mode 100644 index 000000000..08cd025f1 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/cjs-require-esm-error/1.0.0/package.json @@ -0,0 +1,4 @@ +{ + "name": "@denotest/cjs-require-esm-error", + "version": "1.0.0" +} diff --git a/tests/testdata/npm/registry/@denotest/cjs-require-esm-error/1.0.0/require_mjs.js b/tests/testdata/npm/registry/@denotest/cjs-require-esm-error/1.0.0/require_mjs.js new file mode 100644 index 000000000..ba58e1a80 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/cjs-require-esm-error/1.0.0/require_mjs.js @@ -0,0 +1 @@ +module.exports.Test = require("./esm_mjs.mjs"); diff --git a/tests/testdata/npm/registry/@denotest/cjs-this-in-exports/1.0.0/index.js b/tests/testdata/npm/registry/@denotest/cjs-this-in-exports/1.0.0/index.js new file mode 100644 index 000000000..21a9d7d7e --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/cjs-this-in-exports/1.0.0/index.js @@ -0,0 +1,8 @@ +module.exports = { + getValue() { + return this.otherMethod(); + }, + otherMethod() { + return 1; + }, +}; diff --git a/tests/testdata/npm/registry/@denotest/cjs-this-in-exports/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/cjs-this-in-exports/1.0.0/package.json new file mode 100644 index 000000000..729b8c34e --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/cjs-this-in-exports/1.0.0/package.json @@ -0,0 +1,5 @@ +{ + "name": "@denotest/cjs-this-in-exports", + "version": "1.0.0", + "main": "./index.js" +} diff --git a/tests/testdata/npm/registry/@denotest/cjs-with-file-stem/1.0.0/index.js b/tests/testdata/npm/registry/@denotest/cjs-with-file-stem/1.0.0/index.js new file mode 100644 index 000000000..f7164182a --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/cjs-with-file-stem/1.0.0/index.js @@ -0,0 +1,5 @@ +"use strict"; +console.log("hello"); +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = require("./tslib.js"); +tslib_1.__exportStar(require("./other.service"), exports); diff --git a/tests/testdata/npm/registry/@denotest/cjs-with-file-stem/1.0.0/other.service.js b/tests/testdata/npm/registry/@denotest/cjs-with-file-stem/1.0.0/other.service.js new file mode 100644 index 000000000..ba702a9af --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/cjs-with-file-stem/1.0.0/other.service.js @@ -0,0 +1,4 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.foo = void 0; +console.log("world"); \ No newline at end of file diff --git a/tests/testdata/npm/registry/@denotest/cjs-with-file-stem/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/cjs-with-file-stem/1.0.0/package.json new file mode 100644 index 000000000..c72a8ae5a --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/cjs-with-file-stem/1.0.0/package.json @@ -0,0 +1,4 @@ +{ + "name": "@denotest/cjs-with-file-stem", + "version": "1.0.0" +} diff --git a/tests/testdata/npm/registry/@denotest/cjs-with-file-stem/1.0.0/tslib.js b/tests/testdata/npm/registry/@denotest/cjs-with-file-stem/1.0.0/tslib.js new file mode 100644 index 000000000..e5c2d6bc0 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/cjs-with-file-stem/1.0.0/tslib.js @@ -0,0 +1,3 @@ +module.exports = { + __exportStar: function(mod) {} +}; \ No newline at end of file diff --git a/tests/testdata/npm/registry/@denotest/conditional-exports-strict/1.0.0/cjs/index.cjs b/tests/testdata/npm/registry/@denotest/conditional-exports-strict/1.0.0/cjs/index.cjs new file mode 100644 index 000000000..16895e48c --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/conditional-exports-strict/1.0.0/cjs/index.cjs @@ -0,0 +1,3 @@ +module.exports = { + hello: "from cjs" +}; \ No newline at end of file diff --git a/tests/testdata/npm/registry/@denotest/conditional-exports-strict/1.0.0/esm/client/bar.js b/tests/testdata/npm/registry/@denotest/conditional-exports-strict/1.0.0/esm/client/bar.js new file mode 100644 index 000000000..1474f5d29 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/conditional-exports-strict/1.0.0/esm/client/bar.js @@ -0,0 +1,3 @@ +export default { + hello: "from esm client bar", +} diff --git a/tests/testdata/npm/registry/@denotest/conditional-exports-strict/1.0.0/esm/client/foo.js b/tests/testdata/npm/registry/@denotest/conditional-exports-strict/1.0.0/esm/client/foo.js new file mode 100644 index 000000000..bb5284b15 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/conditional-exports-strict/1.0.0/esm/client/foo.js @@ -0,0 +1,3 @@ +export default { + hello: "from esm client foo", +} diff --git a/tests/testdata/npm/registry/@denotest/conditional-exports-strict/1.0.0/esm/client/index.js b/tests/testdata/npm/registry/@denotest/conditional-exports-strict/1.0.0/esm/client/index.js new file mode 100644 index 000000000..dc1ec197d --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/conditional-exports-strict/1.0.0/esm/client/index.js @@ -0,0 +1,3 @@ +export default { + hello: "from esm client", +} diff --git a/tests/testdata/npm/registry/@denotest/conditional-exports-strict/1.0.0/esm/client/m.js b/tests/testdata/npm/registry/@denotest/conditional-exports-strict/1.0.0/esm/client/m.js new file mode 100644 index 000000000..fec6807ac --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/conditional-exports-strict/1.0.0/esm/client/m.js @@ -0,0 +1,3 @@ +export default { + hello: "from esm client m", +} diff --git a/tests/testdata/npm/registry/@denotest/conditional-exports-strict/1.0.0/esm/index.js b/tests/testdata/npm/registry/@denotest/conditional-exports-strict/1.0.0/esm/index.js new file mode 100644 index 000000000..38dae7d93 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/conditional-exports-strict/1.0.0/esm/index.js @@ -0,0 +1,3 @@ +export default { + hello: "from esm", +} \ No newline at end of file diff --git a/tests/testdata/npm/registry/@denotest/conditional-exports-strict/1.0.0/foo.js b/tests/testdata/npm/registry/@denotest/conditional-exports-strict/1.0.0/foo.js new file mode 100644 index 000000000..6060c8a67 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/conditional-exports-strict/1.0.0/foo.js @@ -0,0 +1,3 @@ +export default { + hello: "from foo", +} diff --git a/tests/testdata/npm/registry/@denotest/conditional-exports-strict/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/conditional-exports-strict/1.0.0/package.json new file mode 100644 index 000000000..3576e48f8 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/conditional-exports-strict/1.0.0/package.json @@ -0,0 +1,16 @@ +{ + "name": "@denotest/conditional-exports-strict", + "version": "1.0.0", + "type": "module", + "exports": { + ".": { + "types": "./types/src/index.d.ts", + "require": "./cjs/index.cjs", + "import": "./esm/index.js" + }, + "./client": { + "types": "./types/src/client/index.d.ts", + "import": "./esm/client/index.js" + } + } +} diff --git a/tests/testdata/npm/registry/@denotest/conditional-exports/1.0.0/cjs/index.cjs b/tests/testdata/npm/registry/@denotest/conditional-exports/1.0.0/cjs/index.cjs new file mode 100644 index 000000000..16895e48c --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/conditional-exports/1.0.0/cjs/index.cjs @@ -0,0 +1,3 @@ +module.exports = { + hello: "from cjs" +}; \ No newline at end of file diff --git a/tests/testdata/npm/registry/@denotest/conditional-exports/1.0.0/esm/client/bar.js b/tests/testdata/npm/registry/@denotest/conditional-exports/1.0.0/esm/client/bar.js new file mode 100644 index 000000000..1474f5d29 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/conditional-exports/1.0.0/esm/client/bar.js @@ -0,0 +1,3 @@ +export default { + hello: "from esm client bar", +} diff --git a/tests/testdata/npm/registry/@denotest/conditional-exports/1.0.0/esm/client/foo.js b/tests/testdata/npm/registry/@denotest/conditional-exports/1.0.0/esm/client/foo.js new file mode 100644 index 000000000..bb5284b15 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/conditional-exports/1.0.0/esm/client/foo.js @@ -0,0 +1,3 @@ +export default { + hello: "from esm client foo", +} diff --git a/tests/testdata/npm/registry/@denotest/conditional-exports/1.0.0/esm/client/index.js b/tests/testdata/npm/registry/@denotest/conditional-exports/1.0.0/esm/client/index.js new file mode 100644 index 000000000..dc1ec197d --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/conditional-exports/1.0.0/esm/client/index.js @@ -0,0 +1,3 @@ +export default { + hello: "from esm client", +} diff --git a/tests/testdata/npm/registry/@denotest/conditional-exports/1.0.0/esm/client/m.js b/tests/testdata/npm/registry/@denotest/conditional-exports/1.0.0/esm/client/m.js new file mode 100644 index 000000000..fec6807ac --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/conditional-exports/1.0.0/esm/client/m.js @@ -0,0 +1,3 @@ +export default { + hello: "from esm client m", +} diff --git a/tests/testdata/npm/registry/@denotest/conditional-exports/1.0.0/esm/index.js b/tests/testdata/npm/registry/@denotest/conditional-exports/1.0.0/esm/index.js new file mode 100644 index 000000000..38dae7d93 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/conditional-exports/1.0.0/esm/index.js @@ -0,0 +1,3 @@ +export default { + hello: "from esm", +} \ No newline at end of file diff --git a/tests/testdata/npm/registry/@denotest/conditional-exports/1.0.0/foo.js b/tests/testdata/npm/registry/@denotest/conditional-exports/1.0.0/foo.js new file mode 100644 index 000000000..6060c8a67 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/conditional-exports/1.0.0/foo.js @@ -0,0 +1,3 @@ +export default { + hello: "from foo", +} diff --git a/tests/testdata/npm/registry/@denotest/conditional-exports/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/conditional-exports/1.0.0/package.json new file mode 100644 index 000000000..5a2536aa0 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/conditional-exports/1.0.0/package.json @@ -0,0 +1,21 @@ +{ + "name": "@denotest/conditional-exports", + "version": "1.0.0", + "type": "module", + "exports": { + ".": { + "types": "./types/src/index.d.ts", + "require": "./cjs/index.cjs", + "import": "./esm/index.js" + }, + "./client": { + "types": "./types/src/client/index.d.ts", + "import": "./esm/client/index.js" + }, + "./client/*": { + "types": "./types/src/client/*.d.ts", + "import": "./esm/client/*.js" + }, + "./*": "./*" + } +} diff --git a/tests/testdata/npm/registry/@denotest/create-require/1.0.0/index.js b/tests/testdata/npm/registry/@denotest/create-require/1.0.0/index.js new file mode 100644 index 000000000..2ab564366 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/create-require/1.0.0/index.js @@ -0,0 +1,33 @@ +import { createRequire } from "module"; + +console.log(typeof createRequire(import.meta.url)); +console.log(typeof createRequire(new URL(import.meta.url))); +console.log(typeof createRequire("/")); +console.log(typeof createRequire("/foo")); +console.log(typeof createRequire("/foo/")); +console.log(typeof createRequire("c:\\foo")); +try { + createRequire("https://example.com/"); +} catch (e) { + console.log(e.message); +} +try { + createRequire(new URL("https://example.com/")); +} catch (e) { + console.log(e.message); +} +try { + createRequire(1); +} catch (e) { + console.log(e.message); +} +try { + createRequire("foo"); +} catch (e) { + console.log(e.message); +} +try { + createRequire("./foo"); +} catch (e) { + console.log(e.message); +} diff --git a/tests/testdata/npm/registry/@denotest/create-require/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/create-require/1.0.0/package.json new file mode 100644 index 000000000..00539643e --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/create-require/1.0.0/package.json @@ -0,0 +1,6 @@ +{ + "name": "@denotest/create-require", + "version": "1.0.0", + "type": "module", + "main": "index.js" +} diff --git a/tests/testdata/npm/registry/@denotest/d-ext/1.0.0/index.d.ts b/tests/testdata/npm/registry/@denotest/d-ext/1.0.0/index.d.ts new file mode 100644 index 000000000..47326c0f6 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/d-ext/1.0.0/index.d.ts @@ -0,0 +1 @@ +export const test: typeof import("./types.d").value; diff --git a/tests/testdata/npm/registry/@denotest/d-ext/1.0.0/index.js b/tests/testdata/npm/registry/@denotest/d-ext/1.0.0/index.js new file mode 100644 index 000000000..62b353f3d --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/d-ext/1.0.0/index.js @@ -0,0 +1 @@ +module.exports.test = 5; diff --git a/tests/testdata/npm/registry/@denotest/d-ext/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/d-ext/1.0.0/package.json new file mode 100644 index 000000000..a0702a56b --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/d-ext/1.0.0/package.json @@ -0,0 +1,5 @@ +{ + "name": "d-ext", + "version": "1.0.0", + "main": "./index.js" +} \ No newline at end of file diff --git a/tests/testdata/npm/registry/@denotest/d-ext/1.0.0/types.d.ts b/tests/testdata/npm/registry/@denotest/d-ext/1.0.0/types.d.ts new file mode 100644 index 000000000..dedc54b03 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/d-ext/1.0.0/types.d.ts @@ -0,0 +1 @@ +export const value: 5; diff --git a/tests/testdata/npm/registry/@denotest/different-nested-dep-child/1.0.0/index.js b/tests/testdata/npm/registry/@denotest/different-nested-dep-child/1.0.0/index.js new file mode 100644 index 000000000..aef22247d --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/different-nested-dep-child/1.0.0/index.js @@ -0,0 +1 @@ +export default 1; diff --git a/tests/testdata/npm/registry/@denotest/different-nested-dep-child/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/different-nested-dep-child/1.0.0/package.json new file mode 100644 index 000000000..ca58520a4 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/different-nested-dep-child/1.0.0/package.json @@ -0,0 +1,5 @@ +{ + "name": "@denotest/different-nested-dep-child", + "type": "module", + "version": "1.0.0" +} diff --git a/tests/testdata/npm/registry/@denotest/different-nested-dep-child/2.0.0/index.js b/tests/testdata/npm/registry/@denotest/different-nested-dep-child/2.0.0/index.js new file mode 100644 index 000000000..842e368a0 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/different-nested-dep-child/2.0.0/index.js @@ -0,0 +1 @@ +export default 2; diff --git a/tests/testdata/npm/registry/@denotest/different-nested-dep-child/2.0.0/package.json b/tests/testdata/npm/registry/@denotest/different-nested-dep-child/2.0.0/package.json new file mode 100644 index 000000000..9d2e56975 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/different-nested-dep-child/2.0.0/package.json @@ -0,0 +1,5 @@ +{ + "name": "@denotest/different-nested-dep-child", + "type": "module", + "version": "2.0.0" +} diff --git a/tests/testdata/npm/registry/@denotest/different-nested-dep/1.0.0/index.js b/tests/testdata/npm/registry/@denotest/different-nested-dep/1.0.0/index.js new file mode 100644 index 000000000..dee5330b7 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/different-nested-dep/1.0.0/index.js @@ -0,0 +1,2 @@ +import version from "@denotest/different-nested-dep-child"; +export default version; diff --git a/tests/testdata/npm/registry/@denotest/different-nested-dep/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/different-nested-dep/1.0.0/package.json new file mode 100644 index 000000000..879a4e012 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/different-nested-dep/1.0.0/package.json @@ -0,0 +1,8 @@ +{ + "name": "@denotest/different-nested-dep", + "version": "1.0.0", + "type": "module", + "dependencies": { + "@denotest/different-nested-dep-child": "1.0.0" + } +} diff --git a/tests/testdata/npm/registry/@denotest/dual-cjs-esm-dep-missing/1.0.0/index.cjs b/tests/testdata/npm/registry/@denotest/dual-cjs-esm-dep-missing/1.0.0/index.cjs new file mode 100644 index 000000000..6d9b2bfc6 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/dual-cjs-esm-dep-missing/1.0.0/index.cjs @@ -0,0 +1,3 @@ +import { getKind } from "@denotest/dual-cjs-esm"; + +export { getKind }; diff --git a/tests/testdata/npm/registry/@denotest/dual-cjs-esm-dep-missing/1.0.0/index.d.ts b/tests/testdata/npm/registry/@denotest/dual-cjs-esm-dep-missing/1.0.0/index.d.ts new file mode 100644 index 000000000..4628c2774 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/dual-cjs-esm-dep-missing/1.0.0/index.d.ts @@ -0,0 +1 @@ +export function getKind(): "esm" | "cjs"; \ No newline at end of file diff --git a/tests/testdata/npm/registry/@denotest/dual-cjs-esm-dep-missing/1.0.0/index.mjs b/tests/testdata/npm/registry/@denotest/dual-cjs-esm-dep-missing/1.0.0/index.mjs new file mode 100644 index 000000000..6d9b2bfc6 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/dual-cjs-esm-dep-missing/1.0.0/index.mjs @@ -0,0 +1,3 @@ +import { getKind } from "@denotest/dual-cjs-esm"; + +export { getKind }; diff --git a/tests/testdata/npm/registry/@denotest/dual-cjs-esm-dep-missing/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/dual-cjs-esm-dep-missing/1.0.0/package.json new file mode 100644 index 000000000..d17fd887b --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/dual-cjs-esm-dep-missing/1.0.0/package.json @@ -0,0 +1,7 @@ +{ + "name": "@denotest/dual-cjs-esm-dep-missing", + "version": "1.0.0", + "type": "module", + "main": "./index.cjs", + "module": "./index.mjs" +} diff --git a/tests/testdata/npm/registry/@denotest/dual-cjs-esm-dep/1.0.0/index.cjs b/tests/testdata/npm/registry/@denotest/dual-cjs-esm-dep/1.0.0/index.cjs new file mode 100644 index 000000000..6d9b2bfc6 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/dual-cjs-esm-dep/1.0.0/index.cjs @@ -0,0 +1,3 @@ +import { getKind } from "@denotest/dual-cjs-esm"; + +export { getKind }; diff --git a/tests/testdata/npm/registry/@denotest/dual-cjs-esm-dep/1.0.0/index.d.ts b/tests/testdata/npm/registry/@denotest/dual-cjs-esm-dep/1.0.0/index.d.ts new file mode 100644 index 000000000..4628c2774 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/dual-cjs-esm-dep/1.0.0/index.d.ts @@ -0,0 +1 @@ +export function getKind(): "esm" | "cjs"; \ No newline at end of file diff --git a/tests/testdata/npm/registry/@denotest/dual-cjs-esm-dep/1.0.0/index.mjs b/tests/testdata/npm/registry/@denotest/dual-cjs-esm-dep/1.0.0/index.mjs new file mode 100644 index 000000000..6d9b2bfc6 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/dual-cjs-esm-dep/1.0.0/index.mjs @@ -0,0 +1,3 @@ +import { getKind } from "@denotest/dual-cjs-esm"; + +export { getKind }; diff --git a/tests/testdata/npm/registry/@denotest/dual-cjs-esm-dep/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/dual-cjs-esm-dep/1.0.0/package.json new file mode 100644 index 000000000..80c69f87a --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/dual-cjs-esm-dep/1.0.0/package.json @@ -0,0 +1,10 @@ +{ + "name": "@denotest/dual-cjs-esm-dep", + "version": "1.0.0", + "type": "module", + "main": "./index.cjs", + "module": "./index.mjs", + "dependencies": { + "@denotest/dual-cjs-esm": "*" + } +} diff --git a/tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/cjs/main.cjs b/tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/cjs/main.cjs new file mode 100644 index 000000000..51d32ff89 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/cjs/main.cjs @@ -0,0 +1,10 @@ +const root = require("../"); +const subPath = require("../subpath"); + +module.exports.getKind = function() { + return root.getKind(); +}; + +module.exports.getSubPathKind = function() { + return subPath.getSubPathKind(); +}; diff --git a/tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/cjs/package.json b/tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/cjs/package.json new file mode 100644 index 000000000..73847e365 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/cjs/package.json @@ -0,0 +1,3 @@ +{ + "main": "./main.cjs" +} \ No newline at end of file diff --git a/tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/main.cjs b/tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/main.cjs new file mode 100644 index 000000000..990605527 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/main.cjs @@ -0,0 +1,3 @@ +exports.getKind = function() { + return "cjs"; +}; diff --git a/tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/main.d.cts b/tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/main.d.cts new file mode 100644 index 000000000..f969ba996 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/main.d.cts @@ -0,0 +1 @@ +export function getKind(): string; diff --git a/tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/main.d.mts b/tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/main.d.mts new file mode 100644 index 000000000..f969ba996 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/main.d.mts @@ -0,0 +1 @@ +export function getKind(): string; diff --git a/tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/main.mjs b/tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/main.mjs new file mode 100644 index 000000000..b48b9a3a6 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/main.mjs @@ -0,0 +1,3 @@ +export function getKind() { + return "esm"; +} diff --git a/tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/package.json new file mode 100644 index 000000000..18b72e97a --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/package.json @@ -0,0 +1,7 @@ +{ + "name": "@denotest/dual-cjs-esm", + "version": "1.0.0", + "type": "module", + "main": "./main.cjs", + "module": "./main.mjs" +} diff --git a/tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/subpath/main.cjs b/tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/subpath/main.cjs new file mode 100644 index 000000000..18a22e6f1 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/subpath/main.cjs @@ -0,0 +1,3 @@ +exports.getSubPathKind = function() { + return "cjs"; +}; diff --git a/tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/subpath/main.mjs b/tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/subpath/main.mjs new file mode 100644 index 000000000..47e8cd516 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/subpath/main.mjs @@ -0,0 +1,3 @@ +export function getSubPathKind() { + return "esm"; +} diff --git a/tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/subpath/package.json b/tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/subpath/package.json new file mode 100644 index 000000000..149ce36a3 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/dual-cjs-esm/1.0.0/subpath/package.json @@ -0,0 +1,5 @@ +{ + "type": "module", + "main": "./main.cjs", + "module": "./main.mjs" +} \ No newline at end of file diff --git a/tests/testdata/npm/registry/@denotest/dynamic-import/1.0.0/index.js b/tests/testdata/npm/registry/@denotest/dynamic-import/1.0.0/index.js new file mode 100644 index 000000000..4dc3831f9 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/dynamic-import/1.0.0/index.js @@ -0,0 +1,3 @@ +export function dynamicImport(url) { + return import(url); +} diff --git a/tests/testdata/npm/registry/@denotest/dynamic-import/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/dynamic-import/1.0.0/package.json new file mode 100644 index 000000000..fa970177c --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/dynamic-import/1.0.0/package.json @@ -0,0 +1,5 @@ +{ + "name": "@denotest/dynamic-import", + "type": "module", + "version": "1.0.0" +} diff --git a/tests/testdata/npm/registry/@denotest/env-var-re-export/1.0.0/dev.cjs b/tests/testdata/npm/registry/@denotest/env-var-re-export/1.0.0/dev.cjs new file mode 100644 index 000000000..cf7b90970 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/env-var-re-export/1.0.0/dev.cjs @@ -0,0 +1,5 @@ +module.exports = { + getEnv() { + return "dev"; + }, +}; diff --git a/tests/testdata/npm/registry/@denotest/env-var-re-export/1.0.0/index.cjs b/tests/testdata/npm/registry/@denotest/env-var-re-export/1.0.0/index.cjs new file mode 100644 index 000000000..6258d7c05 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/env-var-re-export/1.0.0/index.cjs @@ -0,0 +1,5 @@ +if (process.env.NODE_ENV === 'production') { + module.exports = require('./prod.cjs'); +} else { + module.exports = require('./dev.cjs'); +} diff --git a/tests/testdata/npm/registry/@denotest/env-var-re-export/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/env-var-re-export/1.0.0/package.json new file mode 100644 index 000000000..84f87be0d --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/env-var-re-export/1.0.0/package.json @@ -0,0 +1,5 @@ +{ + "name": "@denotest/env-var-re-export", + "version": "1.0.0", + "main": "./index.cjs" +} diff --git a/tests/testdata/npm/registry/@denotest/env-var-re-export/1.0.0/prod.cjs b/tests/testdata/npm/registry/@denotest/env-var-re-export/1.0.0/prod.cjs new file mode 100644 index 000000000..a84c76543 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/env-var-re-export/1.0.0/prod.cjs @@ -0,0 +1,5 @@ +module.exports = { + getEnv() { + return "prod"; + }, +}; diff --git a/tests/testdata/npm/registry/@denotest/esm-basic/1.0.0/main.d.mts b/tests/testdata/npm/registry/@denotest/esm-basic/1.0.0/main.d.mts new file mode 100644 index 000000000..29da1e6d7 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/esm-basic/1.0.0/main.d.mts @@ -0,0 +1,3 @@ +export declare function setValue(val: number): void; +export declare function getValue(): number; +export declare const url: string; diff --git a/tests/testdata/npm/registry/@denotest/esm-basic/1.0.0/main.mjs b/tests/testdata/npm/registry/@denotest/esm-basic/1.0.0/main.mjs new file mode 100644 index 000000000..0a44f7585 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/esm-basic/1.0.0/main.mjs @@ -0,0 +1,11 @@ +let value = 0; + +export function setValue(newValue) { + value = newValue; +} + +export function getValue() { + return value; +} + +export const url = import.meta.url; diff --git a/tests/testdata/npm/registry/@denotest/esm-basic/1.0.0/other.mjs b/tests/testdata/npm/registry/@denotest/esm-basic/1.0.0/other.mjs new file mode 100644 index 000000000..00ed99da4 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/esm-basic/1.0.0/other.mjs @@ -0,0 +1,3 @@ +export function hello() { + return "hello, world!"; +} \ No newline at end of file diff --git a/tests/testdata/npm/registry/@denotest/esm-basic/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/esm-basic/1.0.0/package.json new file mode 100644 index 000000000..757ac2db9 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/esm-basic/1.0.0/package.json @@ -0,0 +1,7 @@ +{ + "name": "@denotest/esm-basic", + "version": "1.0.0", + "type": "module", + "main": "main.mjs", + "types": "main.d.mts" +} diff --git a/tests/testdata/npm/registry/@denotest/esm-import-cjs-default/1.0.0/index.mjs b/tests/testdata/npm/registry/@denotest/esm-import-cjs-default/1.0.0/index.mjs new file mode 100644 index 000000000..11e545ae5 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/esm-import-cjs-default/1.0.0/index.mjs @@ -0,0 +1,17 @@ +import defaultImport, { MyClass } from "@denotest/cjs-default-export"; +import * as namespaceImport from "@denotest/cjs-default-export"; +import localDefaultImport from "./local.cjs"; +import * as localNamespaceImport from "./local.cjs"; + +console.log("Node esm importing node cjs"); +console.log("==========================="); +console.log(defaultImport); +console.log(localDefaultImport); +console.log(namespaceImport); +console.log(localNamespaceImport); +console.log("==========================="); +console.log(MyClass.someStaticMethod()); + +export default function() { + return defaultImport.default() * 5; +} diff --git a/tests/testdata/npm/registry/@denotest/esm-import-cjs-default/1.0.0/local.cjs b/tests/testdata/npm/registry/@denotest/esm-import-cjs-default/1.0.0/local.cjs new file mode 100644 index 000000000..8d2772dc6 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/esm-import-cjs-default/1.0.0/local.cjs @@ -0,0 +1,9 @@ +Object.defineProperty(module.exports, "__esModule", { + value: true +}); +module.exports["default"] = function() { + return 3; +}; +module.exports["named"] = function() { + return 4; +}; diff --git a/tests/testdata/npm/registry/@denotest/esm-import-cjs-default/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/esm-import-cjs-default/1.0.0/package.json new file mode 100644 index 000000000..f757a08fb --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/esm-import-cjs-default/1.0.0/package.json @@ -0,0 +1,8 @@ +{ + "name": "@denotest/esm-import-cjs-default", + "version": "1.0.0", + "main": "index.mjs", + "dependencies": { + "@denotest/cjs-default-export": "^1.0.0" + } +} diff --git a/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.cjs b/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.cjs new file mode 100644 index 000000000..e69de29bb diff --git a/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.d.cts b/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.d.cts new file mode 100644 index 000000000..43a5ebe9b --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.d.cts @@ -0,0 +1 @@ +export type Value = "cts"; diff --git a/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.d.mts b/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.d.mts new file mode 100644 index 000000000..b762ebd4a --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.d.mts @@ -0,0 +1 @@ +export type Value = "mts"; diff --git a/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.d.ts b/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.d.ts new file mode 100644 index 000000000..1d1cd270b --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.d.ts @@ -0,0 +1 @@ +export type Value = "dts"; diff --git a/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.js b/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.js new file mode 100644 index 000000000..e69de29bb diff --git a/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.mjs b/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/main.mjs new file mode 100644 index 000000000..e69de29bb diff --git a/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/package.json new file mode 100644 index 000000000..1884b65e4 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/file-dts-dmts-dcts/1.0.0/package.json @@ -0,0 +1,13 @@ +{ + "name": "@denotest/dts-and-dmts-same-file", + "version": "1.0.0", + "exports": { + ".": { + "import": "./main.mjs", + "require": "./main.js" + }, + "./mjs": "./main.mjs", + "./cjs": "./main.cjs", + "./js": "./main.js" + } +} \ No newline at end of file diff --git a/tests/testdata/npm/registry/@denotest/globals/1.0.0/index.d.ts b/tests/testdata/npm/registry/@denotest/globals/1.0.0/index.d.ts new file mode 100644 index 000000000..1bbb82047 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/globals/1.0.0/index.d.ts @@ -0,0 +1,21 @@ +declare const tempGlobalThis: typeof globalThis; +declare const tempGlobal: typeof global; +declare const tempProcess: typeof process; +export { + tempGlobalThis as globalThis, + tempGlobal as global, + tempProcess as process, +}; + +type AssertTrue = never; +type _TestHasProcessGlobal = AssertTrue< + typeof globalThis extends { process: any } ? true : false +>; + +export function deleteSetTimeout(): void; +export function getSetTimeout(): typeof setTimeout; + +export function checkProcessGlobal(): void; +export function checkWindowGlobal(): void; + +export function getFoo(): string; \ No newline at end of file diff --git a/tests/testdata/npm/registry/@denotest/globals/1.0.0/index.js b/tests/testdata/npm/registry/@denotest/globals/1.0.0/index.js new file mode 100644 index 000000000..b946bbd2a --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/globals/1.0.0/index.js @@ -0,0 +1,25 @@ +exports.globalThis = globalThis; +exports.global = global; +exports.process = process; + +exports.deleteSetTimeout = function () { + delete globalThis.setTimeout; +}; + +exports.getSetTimeout = function () { + return globalThis.setTimeout; +}; + +exports.checkProcessGlobal = function () { + console.log("process" in globalThis); + console.log(Object.getOwnPropertyDescriptor(globalThis, "process") !== undefined); +}; + +exports.checkWindowGlobal = function () { + console.log("window" in globalThis); + console.log(Object.getOwnPropertyDescriptor(globalThis, "window") !== undefined); +} + +exports.getFoo = function () { + return globalThis.foo; +} \ No newline at end of file diff --git a/tests/testdata/npm/registry/@denotest/globals/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/globals/1.0.0/package.json new file mode 100644 index 000000000..1ce42ded4 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/globals/1.0.0/package.json @@ -0,0 +1,5 @@ +{ + "name": "@denotest/globals", + "version": "1.0.0", + "types": "index.d.ts" +} diff --git a/tests/testdata/npm/registry/@denotest/imports-package-json/1.0.0/hi.js b/tests/testdata/npm/registry/@denotest/imports-package-json/1.0.0/hi.js new file mode 100644 index 000000000..407090812 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/imports-package-json/1.0.0/hi.js @@ -0,0 +1 @@ +export default "hi"; diff --git a/tests/testdata/npm/registry/@denotest/imports-package-json/1.0.0/import_not_defined.js b/tests/testdata/npm/registry/@denotest/imports-package-json/1.0.0/import_not_defined.js new file mode 100644 index 000000000..07864fd2c --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/imports-package-json/1.0.0/import_not_defined.js @@ -0,0 +1,3 @@ +import notDefined from "#not-defined"; + +export default notDefined; diff --git a/tests/testdata/npm/registry/@denotest/imports-package-json/1.0.0/main.js b/tests/testdata/npm/registry/@denotest/imports-package-json/1.0.0/main.js new file mode 100644 index 000000000..9e7c247b7 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/imports-package-json/1.0.0/main.js @@ -0,0 +1,13 @@ +import hi from "#hi"; +import bye from "./sub_path/main.js"; +import fs from "#fs"; +import path from "#path"; +import fs2 from "#fs2"; + +export default { + hi, + bye, + fs, + path, + fs2, +}; diff --git a/tests/testdata/npm/registry/@denotest/imports-package-json/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/imports-package-json/1.0.0/package.json new file mode 100644 index 000000000..2c294e680 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/imports-package-json/1.0.0/package.json @@ -0,0 +1,21 @@ +{ + "name": "imports-package-json", + "type": "module", + "version": "1.0.0", + "description": "", + "license": "ISC", + "author": "", + "exports": { + ".": "./main.js", + "./import-not-defined": "./import_not_defined.js", + "./sub-path-import-not-defined": "./sub_path/import_not_defined.js" + }, + "imports": { + "#hi": "./hi.js", + "#fs": "fs", + "#path": "node:path", + "#fs2": { + "node": "fs" + } + } +} diff --git a/tests/testdata/npm/registry/@denotest/imports-package-json/1.0.0/sub_path/bye.js b/tests/testdata/npm/registry/@denotest/imports-package-json/1.0.0/sub_path/bye.js new file mode 100644 index 000000000..6fc719e48 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/imports-package-json/1.0.0/sub_path/bye.js @@ -0,0 +1 @@ +export default "bye"; diff --git a/tests/testdata/npm/registry/@denotest/imports-package-json/1.0.0/sub_path/import_not_defined.js b/tests/testdata/npm/registry/@denotest/imports-package-json/1.0.0/sub_path/import_not_defined.js new file mode 100644 index 000000000..ffaa2b1ad --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/imports-package-json/1.0.0/sub_path/import_not_defined.js @@ -0,0 +1,4 @@ +// this won't be defined in the closest package.json and will fail +import hi from "#hi"; + +export default hi; diff --git a/tests/testdata/npm/registry/@denotest/imports-package-json/1.0.0/sub_path/main.js b/tests/testdata/npm/registry/@denotest/imports-package-json/1.0.0/sub_path/main.js new file mode 100644 index 000000000..260ca79ae --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/imports-package-json/1.0.0/sub_path/main.js @@ -0,0 +1,3 @@ +import bye from "#bye"; + +export default bye; diff --git a/tests/testdata/npm/registry/@denotest/imports-package-json/1.0.0/sub_path/package.json b/tests/testdata/npm/registry/@denotest/imports-package-json/1.0.0/sub_path/package.json new file mode 100644 index 000000000..3f2c2bbd8 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/imports-package-json/1.0.0/sub_path/package.json @@ -0,0 +1,6 @@ +{ + "type": "module", + "imports": { + "#bye": "./bye.js" + } +} diff --git a/tests/testdata/npm/registry/@denotest/no-types-cjs/1.0.0/main.js b/tests/testdata/npm/registry/@denotest/no-types-cjs/1.0.0/main.js new file mode 100644 index 000000000..bb6cbdb02 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/no-types-cjs/1.0.0/main.js @@ -0,0 +1,6 @@ +/** + * @return {number} + */ + module.exports = function () { + return 5; +}; diff --git a/tests/testdata/npm/registry/@denotest/no-types-cjs/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/no-types-cjs/1.0.0/package.json new file mode 100644 index 000000000..60b8a0285 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/no-types-cjs/1.0.0/package.json @@ -0,0 +1,5 @@ +{ + "name": "@denotest/no-types-cjs", + "version": "1.0.0", + "main": "./main.js" +} diff --git a/tests/testdata/npm/registry/@denotest/no-types-in-conditional-exports/1.0.0/lib/foo-esm.js b/tests/testdata/npm/registry/@denotest/no-types-in-conditional-exports/1.0.0/lib/foo-esm.js new file mode 100644 index 000000000..0ead93520 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/no-types-in-conditional-exports/1.0.0/lib/foo-esm.js @@ -0,0 +1,3 @@ +export default { + "foo": "bar" +}; \ No newline at end of file diff --git a/tests/testdata/npm/registry/@denotest/no-types-in-conditional-exports/1.0.0/lib/foo.js b/tests/testdata/npm/registry/@denotest/no-types-in-conditional-exports/1.0.0/lib/foo.js new file mode 100644 index 000000000..dca03a472 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/no-types-in-conditional-exports/1.0.0/lib/foo.js @@ -0,0 +1,3 @@ +module.exports = { + "foo": "bar" +}; \ No newline at end of file diff --git a/tests/testdata/npm/registry/@denotest/no-types-in-conditional-exports/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/no-types-in-conditional-exports/1.0.0/package.json new file mode 100644 index 000000000..524394480 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/no-types-in-conditional-exports/1.0.0/package.json @@ -0,0 +1,14 @@ +{ + "name": "@denotest/no-types-in-conditional-exports", + "version": "1.0.0", + "main": "./lib/foo.js", + "module": "./lib/foo-esm.js", + "exports": { + ".": { + "require": "./lib/foo.js", + "import": "./lib/foo-esm.js" + }, + "./*": "./*" + }, + "type": "module" +} diff --git a/tests/testdata/npm/registry/@denotest/non-existent-dep-version/1.0.0/index.js b/tests/testdata/npm/registry/@denotest/non-existent-dep-version/1.0.0/index.js new file mode 100644 index 000000000..f4e8d9d29 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/non-existent-dep-version/1.0.0/index.js @@ -0,0 +1 @@ +module.exports = 5; diff --git a/tests/testdata/npm/registry/@denotest/non-existent-dep-version/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/non-existent-dep-version/1.0.0/package.json new file mode 100644 index 000000000..0533da432 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/non-existent-dep-version/1.0.0/package.json @@ -0,0 +1,7 @@ +{ + "name": "@denotest/non-existent-dep-version", + "version": "1.0.0", + "dependencies": { + "@denotest/esm-basic": "=99.99.99" + } +} diff --git a/tests/testdata/npm/registry/@denotest/non-existent-dep/1.0.0/index.js b/tests/testdata/npm/registry/@denotest/non-existent-dep/1.0.0/index.js new file mode 100644 index 000000000..f4e8d9d29 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/non-existent-dep/1.0.0/index.js @@ -0,0 +1 @@ +module.exports = 5; diff --git a/tests/testdata/npm/registry/@denotest/non-existent-dep/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/non-existent-dep/1.0.0/package.json new file mode 100644 index 000000000..4d5f8c5a2 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/non-existent-dep/1.0.0/package.json @@ -0,0 +1,7 @@ +{ + "name": "@denotest/non-existent-dep", + "version": "1.0.0", + "dependencies": { + "@denotest/non-existent": "1.0" + } +} diff --git a/tests/testdata/npm/registry/@denotest/peer-dep-test-child/1.0.0/index.js b/tests/testdata/npm/registry/@denotest/peer-dep-test-child/1.0.0/index.js new file mode 100644 index 000000000..636ec3c35 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/peer-dep-test-child/1.0.0/index.js @@ -0,0 +1 @@ +module.exports = require("@denotest/peer-dep-test-grandchild"); diff --git a/tests/testdata/npm/registry/@denotest/peer-dep-test-child/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/peer-dep-test-child/1.0.0/package.json new file mode 100644 index 000000000..32eb49851 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/peer-dep-test-child/1.0.0/package.json @@ -0,0 +1,8 @@ +{ + "name": "@denotest/peer-dep-test-child", + "version": "1.0.0", + "dependencies": { + "@denotest/peer-dep-test-grandchild": "*", + "@denotest/peer-dep-test-peer": "^1" + } +} diff --git a/tests/testdata/npm/registry/@denotest/peer-dep-test-child/2.0.0/index.js b/tests/testdata/npm/registry/@denotest/peer-dep-test-child/2.0.0/index.js new file mode 100644 index 000000000..636ec3c35 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/peer-dep-test-child/2.0.0/index.js @@ -0,0 +1 @@ +module.exports = require("@denotest/peer-dep-test-grandchild"); diff --git a/tests/testdata/npm/registry/@denotest/peer-dep-test-child/2.0.0/package.json b/tests/testdata/npm/registry/@denotest/peer-dep-test-child/2.0.0/package.json new file mode 100644 index 000000000..3c82c01f9 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/peer-dep-test-child/2.0.0/package.json @@ -0,0 +1,8 @@ +{ + "name": "@denotest/peer-dep-test-child", + "version": "2.0.0", + "dependencies": { + "@denotest/peer-dep-test-grandchild": "*", + "@denotest/peer-dep-test-peer": "^2" + } +} diff --git a/tests/testdata/npm/registry/@denotest/peer-dep-test-grandchild/1.0.0/dist/index.js b/tests/testdata/npm/registry/@denotest/peer-dep-test-grandchild/1.0.0/dist/index.js new file mode 100644 index 000000000..9a0d9730b --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/peer-dep-test-grandchild/1.0.0/dist/index.js @@ -0,0 +1 @@ +module.exports = require("@denotest/peer-dep-test-peer"); diff --git a/tests/testdata/npm/registry/@denotest/peer-dep-test-grandchild/1.0.0/index.js b/tests/testdata/npm/registry/@denotest/peer-dep-test-grandchild/1.0.0/index.js new file mode 100644 index 000000000..7d44863df --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/peer-dep-test-grandchild/1.0.0/index.js @@ -0,0 +1 @@ +module.exports = require("./dist/index"); diff --git a/tests/testdata/npm/registry/@denotest/peer-dep-test-grandchild/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/peer-dep-test-grandchild/1.0.0/package.json new file mode 100644 index 000000000..845ef414d --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/peer-dep-test-grandchild/1.0.0/package.json @@ -0,0 +1,7 @@ +{ + "name": "@denotest/peer-dep-test-child-2", + "version": "1.0.0", + "peerDependencies": { + "@denotest/peer-dep-test-peer": "*" + } +} diff --git a/tests/testdata/npm/registry/@denotest/peer-dep-test-peer/1.0.0/index.js b/tests/testdata/npm/registry/@denotest/peer-dep-test-peer/1.0.0/index.js new file mode 100644 index 000000000..bd816eaba --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/peer-dep-test-peer/1.0.0/index.js @@ -0,0 +1 @@ +module.exports = 1; diff --git a/tests/testdata/npm/registry/@denotest/peer-dep-test-peer/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/peer-dep-test-peer/1.0.0/package.json new file mode 100644 index 000000000..cedb3609e --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/peer-dep-test-peer/1.0.0/package.json @@ -0,0 +1,4 @@ +{ + "name": "@denotest/peer-dep-test-peer", + "version": "1.0.0" +} diff --git a/tests/testdata/npm/registry/@denotest/peer-dep-test-peer/2.0.0/index.js b/tests/testdata/npm/registry/@denotest/peer-dep-test-peer/2.0.0/index.js new file mode 100644 index 000000000..4bbffde10 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/peer-dep-test-peer/2.0.0/index.js @@ -0,0 +1 @@ +module.exports = 2; diff --git a/tests/testdata/npm/registry/@denotest/peer-dep-test-peer/2.0.0/package.json b/tests/testdata/npm/registry/@denotest/peer-dep-test-peer/2.0.0/package.json new file mode 100644 index 000000000..90c24f875 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/peer-dep-test-peer/2.0.0/package.json @@ -0,0 +1,4 @@ +{ + "name": "@denotest/peer-dep-test-peer", + "version": "2.0.0" +} diff --git a/tests/testdata/npm/registry/@denotest/permissions-outside-package/1.0.0/index.js b/tests/testdata/npm/registry/@denotest/permissions-outside-package/1.0.0/index.js new file mode 100644 index 000000000..ec854713f --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/permissions-outside-package/1.0.0/index.js @@ -0,0 +1,5 @@ +function loadConfigFile(fileName) { + return require(fileName); +} + +module.exports.loadConfigFile = loadConfigFile; \ No newline at end of file diff --git a/tests/testdata/npm/registry/@denotest/permissions-outside-package/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/permissions-outside-package/1.0.0/package.json new file mode 100644 index 000000000..447a119e4 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/permissions-outside-package/1.0.0/package.json @@ -0,0 +1,5 @@ +{ + "name": "@denotest/permissions-outside-package", + "version": "1.0.0", + "main": "./index.js" +} diff --git a/tests/testdata/npm/registry/@denotest/require-added-nm-folder/1.0.0/index.js b/tests/testdata/npm/registry/@denotest/require-added-nm-folder/1.0.0/index.js new file mode 100644 index 000000000..8c8c4a0fa --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/require-added-nm-folder/1.0.0/index.js @@ -0,0 +1,3 @@ +exports.getValue = () => { + return require(".other-package").get(); +}; diff --git a/tests/testdata/npm/registry/@denotest/require-added-nm-folder/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/require-added-nm-folder/1.0.0/package.json new file mode 100644 index 000000000..718f1eb8c --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/require-added-nm-folder/1.0.0/package.json @@ -0,0 +1,4 @@ +{ + "name": "@denotest/require-added-nm-folder", + "version": "1.0.0" +} diff --git a/tests/testdata/npm/registry/@denotest/reserved-word-exports/1.0.0/index.cjs b/tests/testdata/npm/registry/@denotest/reserved-word-exports/1.0.0/index.cjs new file mode 100644 index 000000000..73f00fad4 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/reserved-word-exports/1.0.0/index.cjs @@ -0,0 +1,68 @@ +exports["abstract"] = "abstract"; +exports["arguments"] = "arguments"; +exports["async"] = "async"; +exports["await"] = "await"; +exports["boolean"] = "boolean"; +exports["break"] = "break"; +exports["byte"] = "byte"; +exports["case"] = "case"; +exports["catch"] = "catch"; +exports["char"] = "char"; +exports["class"] = "class"; +exports["const"] = "const"; +exports["continue"] = "continue"; +exports["debugger"] = "debugger"; +exports["default"] = "default"; +exports["delete"] = "delete"; +exports["do"] = "do"; +exports["double"] = "double"; +exports["else"] = "else"; +exports["enum"] = "enum"; +exports["eval"] = "eval"; +exports["export"] = "export"; +exports["extends"] = "extends"; +exports["false"] = "false"; +exports["final"] = "final"; +exports["finally"] = "finally"; +exports["float"] = "float"; +exports["for"] = "for"; +exports["function"] = "function"; +exports["get"] = "get"; +exports["goto"] = "goto"; +exports["if"] = "if"; +exports["implements"] = "implements"; +exports["import"] = "import"; +exports["in"] = "in"; +exports["instanceof"] = "instanceof"; +exports["int"] = "int"; +exports["interface"] = "interface"; +exports["let"] = "let"; +exports["long"] = "long"; +exports["mod"] = "mod"; +exports["native"] = "native"; +exports["new"] = "new"; +exports["null"] = "null"; +exports["package"] = "package"; +exports["private"] = "private"; +exports["protected"] = "protected"; +exports["public"] = "public"; +exports["return"] = "return"; +exports["set"] = "set"; +exports["short"] = "short"; +exports["static"] = "static"; +exports["super"] = "super"; +exports["switch"] = "switch"; +exports["synchronized"] = "synchronized"; +exports["this"] = "this"; +exports["throw"] = "throw"; +exports["throws"] = "throws"; +exports["transient"] = "transient"; +exports["true"] = "true"; +exports["try"] = "try"; +exports["typeof"] = "typeof"; +exports["var"] = "var"; +exports["void"] = "void"; +exports["volatile"] = "volatile"; +exports["while"] = "while"; +exports["with"] = "with"; +exports["yield"] = "yield"; diff --git a/tests/testdata/npm/registry/@denotest/reserved-word-exports/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/reserved-word-exports/1.0.0/package.json new file mode 100644 index 000000000..215b561d3 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/reserved-word-exports/1.0.0/package.json @@ -0,0 +1,5 @@ +{ + "name": "@denotest/reserved-word-exports", + "version": "1.0.0", + "main": "index.cjs" + } diff --git a/tests/testdata/npm/registry/@denotest/special-chars-in-bin-name/1.0.0/main.mjs b/tests/testdata/npm/registry/@denotest/special-chars-in-bin-name/1.0.0/main.mjs new file mode 100644 index 000000000..0ae8e9190 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/special-chars-in-bin-name/1.0.0/main.mjs @@ -0,0 +1,5 @@ +import process from "node:process"; + +for (const arg of process.argv.slice(2)) { + console.log(arg); +} diff --git a/tests/testdata/npm/registry/@denotest/special-chars-in-bin-name/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/special-chars-in-bin-name/1.0.0/package.json new file mode 100644 index 000000000..2dce473b5 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/special-chars-in-bin-name/1.0.0/package.json @@ -0,0 +1,10 @@ +{ + "name": "@denotest/special-chars-in-bin-name", + "version": "1.0.0", + "type": "module", + "main": "main.mjs", + "bin": { + "\\foo\"": "main.mjs" + } + } + \ No newline at end of file diff --git a/tests/testdata/npm/registry/@denotest/sub-folders/1.0.0/folder_index_js/index.d.ts b/tests/testdata/npm/registry/@denotest/sub-folders/1.0.0/folder_index_js/index.d.ts new file mode 100644 index 000000000..c3ec6ac2e --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/sub-folders/1.0.0/folder_index_js/index.d.ts @@ -0,0 +1 @@ +export function add(a, b): number; diff --git a/tests/testdata/npm/registry/@denotest/sub-folders/1.0.0/folder_index_js/index.js b/tests/testdata/npm/registry/@denotest/sub-folders/1.0.0/folder_index_js/index.js new file mode 100644 index 000000000..71a2da49a --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/sub-folders/1.0.0/folder_index_js/index.js @@ -0,0 +1,3 @@ +export function add(a, b) { + return a + b; +} diff --git a/tests/testdata/npm/registry/@denotest/sub-folders/1.0.0/folder_no_index/random_name.js b/tests/testdata/npm/registry/@denotest/sub-folders/1.0.0/folder_no_index/random_name.js new file mode 100644 index 000000000..f4e8d9d29 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/sub-folders/1.0.0/folder_no_index/random_name.js @@ -0,0 +1 @@ +module.exports = 5; diff --git a/tests/testdata/npm/registry/@denotest/sub-folders/1.0.0/main.mjs b/tests/testdata/npm/registry/@denotest/sub-folders/1.0.0/main.mjs new file mode 100644 index 000000000..358b4b09e --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/sub-folders/1.0.0/main.mjs @@ -0,0 +1,3 @@ +export function getValue() { + return 5; +} diff --git a/tests/testdata/npm/registry/@denotest/sub-folders/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/sub-folders/1.0.0/package.json new file mode 100644 index 000000000..1402e346c --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/sub-folders/1.0.0/package.json @@ -0,0 +1,6 @@ +{ + "name": "@denotest/sub-folders", + "version": "1.0.0", + "type": "module", + "main": "main.mjs" +} diff --git a/tests/testdata/npm/registry/@denotest/types-ambient/1.0.0/index.d.ts b/tests/testdata/npm/registry/@denotest/types-ambient/1.0.0/index.d.ts new file mode 100644 index 000000000..fc2199884 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/types-ambient/1.0.0/index.d.ts @@ -0,0 +1,10 @@ +// Some packages do this. It's really not ideal because instead of allowing +// the package to be resolved at any specifier, it instead expects the package +// to be resolved via a "@denotest/types-ambient" specifier. To make this work, +// we've currently modified the typescript compiler to check for any "" +// ambient modules when resolving an npm specifier at "npm:" +declare module "@denotest/types-ambient" { + class Test { + prop: number; + } +} diff --git a/tests/testdata/npm/registry/@denotest/types-ambient/1.0.0/index.js b/tests/testdata/npm/registry/@denotest/types-ambient/1.0.0/index.js new file mode 100644 index 000000000..47ff7adb2 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/types-ambient/1.0.0/index.js @@ -0,0 +1,3 @@ +export class Test { + prop = 5; +} diff --git a/tests/testdata/npm/registry/@denotest/types-ambient/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/types-ambient/1.0.0/package.json new file mode 100644 index 000000000..ef927cbe3 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/types-ambient/1.0.0/package.json @@ -0,0 +1,5 @@ +{ + "name": "@denotest/types-ambient", + "version": "1.0.0", + "types": "./index.d.ts" +} diff --git a/tests/testdata/npm/registry/@denotest/types-entry-value-not-exists/1.0.0/dist/main.d.ts b/tests/testdata/npm/registry/@denotest/types-entry-value-not-exists/1.0.0/dist/main.d.ts new file mode 100644 index 000000000..2341a14f0 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/types-entry-value-not-exists/1.0.0/dist/main.d.ts @@ -0,0 +1 @@ +export function getValue(): 5; diff --git a/tests/testdata/npm/registry/@denotest/types-entry-value-not-exists/1.0.0/dist/main.js b/tests/testdata/npm/registry/@denotest/types-entry-value-not-exists/1.0.0/dist/main.js new file mode 100644 index 000000000..d0c5dbc70 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/types-entry-value-not-exists/1.0.0/dist/main.js @@ -0,0 +1 @@ +module.exports.getValue = () => 5; diff --git a/tests/testdata/npm/registry/@denotest/types-entry-value-not-exists/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/types-entry-value-not-exists/1.0.0/package.json new file mode 100644 index 000000000..5eb859c4e --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/types-entry-value-not-exists/1.0.0/package.json @@ -0,0 +1,13 @@ +{ + "name": "@denotest/types-entry-value-not-exists", + "version": "1.0.0", + "main": "./dist/main.js", + "types": "./index.d.ts", + "exports": { + ".": { + "types": "./dist/main.d.ts", + "node": "./dist/main.js", + "require": "./dist/main.js" + } + } +} diff --git a/tests/testdata/npm/registry/@denotest/types-exports-import-types/1.0.0/dist/main.d.ts b/tests/testdata/npm/registry/@denotest/types-exports-import-types/1.0.0/dist/main.d.ts new file mode 100644 index 000000000..2341a14f0 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/types-exports-import-types/1.0.0/dist/main.d.ts @@ -0,0 +1 @@ +export function getValue(): 5; diff --git a/tests/testdata/npm/registry/@denotest/types-exports-import-types/1.0.0/dist/main.mjs b/tests/testdata/npm/registry/@denotest/types-exports-import-types/1.0.0/dist/main.mjs new file mode 100644 index 000000000..358b4b09e --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/types-exports-import-types/1.0.0/dist/main.mjs @@ -0,0 +1,3 @@ +export function getValue() { + return 5; +} diff --git a/tests/testdata/npm/registry/@denotest/types-exports-import-types/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/types-exports-import-types/1.0.0/package.json new file mode 100644 index 000000000..202a2c784 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/types-exports-import-types/1.0.0/package.json @@ -0,0 +1,10 @@ +{ + "name": "@denotest/types-exports-import-types", + "version": "1.0.0", + "exports": { + "node": { + "types": "./dist/main.d.ts", + "import": "./dist/main.mjs" + } + } +} diff --git a/tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/client.d.ts b/tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/client.d.ts new file mode 100644 index 000000000..2d156f5bb --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/client.d.ts @@ -0,0 +1 @@ +export function getClient(): 5; diff --git a/tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/dist/client.mjs b/tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/dist/client.mjs new file mode 100644 index 000000000..938238d95 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/dist/client.mjs @@ -0,0 +1,3 @@ +export function getClient() { + return 5; +} diff --git a/tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/dist/entry-a.d.ts b/tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/dist/entry-a.d.ts new file mode 100644 index 000000000..f49faf22f --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/dist/entry-a.d.ts @@ -0,0 +1 @@ +export function entryA(): 12; diff --git a/tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/dist/entry-a.js b/tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/dist/entry-a.js new file mode 100644 index 000000000..84f1f2c94 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/dist/entry-a.js @@ -0,0 +1,3 @@ +export function entryA() { + return 12; +} diff --git a/tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/dist/entry-b.d.ts b/tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/dist/entry-b.d.ts new file mode 100644 index 000000000..382d1995e --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/dist/entry-b.d.ts @@ -0,0 +1 @@ +export function entryB(): "b"; diff --git a/tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/dist/entry-b.js b/tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/dist/entry-b.js new file mode 100644 index 000000000..162d4f190 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/dist/entry-b.js @@ -0,0 +1,3 @@ +export function entryB() { + return "b"; +} diff --git a/tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/entry-import.d.ts b/tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/entry-import.d.ts new file mode 100644 index 000000000..253279e6c --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/entry-import.d.ts @@ -0,0 +1 @@ +export function entryImport(): "import"; diff --git a/tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/entry-import.js b/tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/entry-import.js new file mode 100644 index 000000000..e69de29bb diff --git a/tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/entry-js-only.js b/tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/entry-js-only.js new file mode 100644 index 000000000..e69de29bb diff --git a/tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/entry-types.d.ts b/tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/entry-types.d.ts new file mode 100644 index 000000000..bd1ff702f --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/entry-types.d.ts @@ -0,0 +1 @@ +export function entryTypes(): "types"; diff --git a/tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/package.json new file mode 100644 index 000000000..cc43cf2ed --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/types-exports-subpaths/1.0.0/package.json @@ -0,0 +1,26 @@ +{ + "name": "@denotest/types-exports-subpaths", + "version": "1.0.0", + "exports": { + "./client": { + "types": { + "default": "./client.d.ts" + }, + "import": "./dist/client.mjs" + }, + "./entry-import": { + "import": "./entry-import.d.ts", + "types": "./entry-types.d.ts" + }, + "./entry-types-last-no-declaration-before": { + "import": "./entry-js-only.js", + "types": "./entry-types.d.ts" + }, + "./entry-a": { + "import": "./dist/entry-a.js" + }, + "./nested/entry-b": { + "import": "./dist/entry-b.js" + } + } +} diff --git a/tests/testdata/npm/registry/@denotest/types-no-types-entry/1.0.0/dist/main.d.ts b/tests/testdata/npm/registry/@denotest/types-no-types-entry/1.0.0/dist/main.d.ts new file mode 100644 index 000000000..8942f08dd --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/types-no-types-entry/1.0.0/dist/main.d.ts @@ -0,0 +1 @@ +export { getValue } from "@denotest/types-entry-value-not-exists"; diff --git a/tests/testdata/npm/registry/@denotest/types-no-types-entry/1.0.0/dist/main.js b/tests/testdata/npm/registry/@denotest/types-no-types-entry/1.0.0/dist/main.js new file mode 100644 index 000000000..63c7ef0ce --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/types-no-types-entry/1.0.0/dist/main.js @@ -0,0 +1 @@ +module.exports.getValue = require("@denotest/types-entry-value-not-exists").getValue; diff --git a/tests/testdata/npm/registry/@denotest/types-no-types-entry/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/types-no-types-entry/1.0.0/package.json new file mode 100644 index 000000000..6abccec98 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/types-no-types-entry/1.0.0/package.json @@ -0,0 +1,8 @@ +{ + "name": "@denotest/types-no-types-entry", + "version": "1.0.0", + "main": "./dist/main.js", + "dependencies": { + "@denotest/types-entry-value-not-exists": "^1.0" + } +} diff --git a/tests/testdata/npm/registry/@denotest/types/1.0.0/index.d.ts b/tests/testdata/npm/registry/@denotest/types/1.0.0/index.d.ts new file mode 100644 index 000000000..afe876c4d --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/types/1.0.0/index.d.ts @@ -0,0 +1,4 @@ +export interface Fizzbuzz { + fizz: string; + buzz: string; +} \ No newline at end of file diff --git a/tests/testdata/npm/registry/@denotest/types/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/types/1.0.0/package.json new file mode 100644 index 000000000..ef927cbe3 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/types/1.0.0/package.json @@ -0,0 +1,5 @@ +{ + "name": "@denotest/types-ambient", + "version": "1.0.0", + "types": "./index.d.ts" +} diff --git a/tests/testdata/npm/registry/@denotest/types_imported/1.0.0/index.d.ts b/tests/testdata/npm/registry/@denotest/types_imported/1.0.0/index.d.ts new file mode 100644 index 000000000..559cdb2ec --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/types_imported/1.0.0/index.d.ts @@ -0,0 +1,4 @@ +export interface SomeInterface { + prop: string; + prop2: number; +} \ No newline at end of file diff --git a/tests/testdata/npm/registry/@denotest/types_imported/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/types_imported/1.0.0/package.json new file mode 100644 index 000000000..ef927cbe3 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/types_imported/1.0.0/package.json @@ -0,0 +1,5 @@ +{ + "name": "@denotest/types-ambient", + "version": "1.0.0", + "types": "./index.d.ts" +} diff --git a/tests/testdata/npm/registry/@denotest/types_imported/1.0.0/subpath.d.ts b/tests/testdata/npm/registry/@denotest/types_imported/1.0.0/subpath.d.ts new file mode 100644 index 000000000..883cf037a --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/types_imported/1.0.0/subpath.d.ts @@ -0,0 +1,4 @@ +export interface Foobar { + foo: string; + bar: string; +} \ No newline at end of file diff --git a/tests/testdata/npm/registry/@denotest/typescript-file/1.0.0/index.ts b/tests/testdata/npm/registry/@denotest/typescript-file/1.0.0/index.ts new file mode 100644 index 000000000..44b441a1e --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/typescript-file/1.0.0/index.ts @@ -0,0 +1,4 @@ +// this should not work because we don't support typescript files in npm packages +export function getValue(): 5 { + return 5; +} \ No newline at end of file diff --git a/tests/testdata/npm/registry/@denotest/typescript-file/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/typescript-file/1.0.0/package.json new file mode 100644 index 000000000..e899f4100 --- /dev/null +++ b/tests/testdata/npm/registry/@denotest/typescript-file/1.0.0/package.json @@ -0,0 +1,5 @@ +{ + "name": "@denotest/typescript-file", + "version": "1.0.0", + "main": "./index.ts" +} diff --git a/tests/testdata/npm/registry/@ljharb/has-package-exports-patterns/has-package-exports-patterns-0.0.2.tgz b/tests/testdata/npm/registry/@ljharb/has-package-exports-patterns/has-package-exports-patterns-0.0.2.tgz new file mode 100644 index 000000000..7daff8ff1 Binary files /dev/null and b/tests/testdata/npm/registry/@ljharb/has-package-exports-patterns/has-package-exports-patterns-0.0.2.tgz differ diff --git a/tests/testdata/npm/registry/@ljharb/has-package-exports-patterns/registry.json b/tests/testdata/npm/registry/@ljharb/has-package-exports-patterns/registry.json new file mode 100644 index 000000000..9a0b27f3f --- /dev/null +++ b/tests/testdata/npm/registry/@ljharb/has-package-exports-patterns/registry.json @@ -0,0 +1 @@ +{"_id":"@ljharb/has-package-exports-patterns","_rev":"3-d0393bf328f2bed4c41c2cb289ca9384","name":"@ljharb/has-package-exports-patterns","dist-tags":{"latest":"0.0.2"},"versions":{"0.0.0":{"name":"@ljharb/has-package-exports-patterns","version":"0.0.0","main":"./no.js","exports":{".":"./no.js","./patterns/*":"./patterns/*ed.js"},"repository":{"type":"git","url":"git+https://github.com/inspect-js/has-package-exports.git"},"author":{"name":"Jordan Harband","email":"ljharb@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/inspect-js/has-package-exports/issues"},"homepage":"https://github.com/inspect-js/has-package-exports#readme","_id":"@ljharb/has-package-exports-patterns@0.0.0","_nodeVersion":"14.13.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-e5d7/9bs2uorgQrHzGfzvT6WTyUbWiaiQXBourc2d7/LzvjZkRpFfDWN96WPsEqRMKrbx6aT/5XFma4WYMvu2A==","shasum":"4bec9d26d79b57021f4069ee42bc1bdb3a222372","tarball":"http://localhost:4545/npm/registry/@ljharb/has-package-exports-patterns/has-package-exports-patterns-0.0.0.tgz","fileCount":2,"unpackedSize":535,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJff/r2CRA9TVsSAnZWagAAtLsP/3YEyKmT4SHRBhHwRv90\nuydMCnl4UygliJrdRO1EFa7Y0RWv3yeJDmiP/BbHvbKx+oH1WuRE+ZkjgTce\n8FMV/XUU9muyaEcdy33bzKosu1lukgETXT28IxrGK/JbGoboMbt+Iz8+W5Fa\n+2D546TGv0o7hf/aHilosi11J5C7rd4YuqSxJGXJVXpaytik+e9OFU7rrV/7\nW9mbFmt8YOxfNiOslNvZUA05gHWPLGhw7I9Rl9Jqd6o2xdY5TvXoMUsy45SQ\nUdC5nnVijDleUmULhkxS8ULMJ6GvQkF6lVa3OHHItIByvhfKY8TnKK+ioHYw\nyEvZ63sj8mjYTIi6f5Jgj5NvQrm6lI/JcXW761vxxEcSLPW/onAsPvZHJqkU\nqlGVFib7Xh4Sp8NjJax5pO6QpCHMVs1+WemklXUFQA27Lxod1pXOzvFmq4Wu\nr3cMrYGLol7aPogRyb4v/bu25oDLdMkLmokEc68J9+Q4cw/ZaNzMa1sBWFlC\nhW503lWySfkpoWkLl0kypoZwbLsUZoIO5YFLldxnsynm7XSMHOZBGv/hzCdR\ndBHTvFAs9PgYFJj8xbtL2Wnja7Uuyu9ThlA3uezeDu0bD+IcPa8IdQvXTNSI\nA3pnOuDVzy1pdGny5oIeO4VGY9YU6mC8XSt/g2qgLoEGSib9VxSBKA4qCZ7K\neCWx\r\n=eDD7\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCxiTdVCltPVhh84T/xXOOv3SQo1hCJzPMuBNIicn4g4gIhAIfVxstRRkI1v3hdPOY1DIjt2oBjGxtI6mi7+NDkUNkp"}]},"maintainers":[{"name":"ljharb","email":"ljharb@gmail.com"}],"_npmUser":{"name":"ljharb","email":"ljharb@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/has-package-exports-patterns_0.0.0_1602222838589_0.9419759981517923"},"_hasShrinkwrap":false},"0.0.1":{"name":"@ljharb/has-package-exports-patterns","version":"0.0.1","main":"./no.js","exports":{".":"./no.js","./patterns/*":"./patterns/*ed.js"},"repository":{"type":"git","url":"git+https://github.com/inspect-js/has-package-exports.git"},"author":{"name":"Jordan Harband","email":"ljharb@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/inspect-js/has-package-exports/issues"},"homepage":"https://github.com/inspect-js/has-package-exports#readme","publishConfig":{"access":"public"},"_id":"@ljharb/has-package-exports-patterns@0.0.1","_nodeVersion":"14.13.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-J4HxcjHI8EzVwXj2HKfZrwnWv4wmOhGxSHyxDQLhiL4ibwRoIkYBqsacZUXFUWQzJtW6QC+FKSNy8HqKjkEqaQ==","shasum":"70f07047b058e0909488a0ab1928afb95a9326d0","tarball":"http://localhost:4545/npm/registry/@ljharb/has-package-exports-patterns/has-package-exports-patterns-0.0.1.tgz","fileCount":3,"unpackedSize":619,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfl7kaCRA9TVsSAnZWagAATXwQAJhbxLJoWKyYSBEsP3E4\n7p2RVYrOy74gBDQSMFGho8tP5WfAaOnApnRYRhjl+eK8EPKJfE1BmC32SJVY\nQ/k9b2l6NkZgTUy/ZvRlBmbVysTjO35OHrIg14tqUvQGoKlZf2thsdw0vN18\n5mRYx7fGFQAd2F+goK3jrdL7FpqZAhIuk3vO93okW6P25yUkeyVEVPDhoN5n\nYtfzOlKaycfNvcQieX24EVzjCBfgWn/sIdVYeJ7ZdQNiXh7YuZCWMa8rgECs\nJDb/4EX+N2DirYzU951LlHaI0j0ZW1MbtERswXnC2Tn9Qtaj5we9vpAongiQ\nxnxpxo40tgJgy2Qzb5WwIvHPJojcRJOEHnrHvvHsRYe2FR4Eh2DHQ55ODIm6\nNuZzp7U6vQXyh8C+1PKlpl6KsEynlefXPBDueB4CnTh9ahLUfSfUjdSfsV9H\n87Hk/HS1kFZTn2lavqaV6vFmgEr3JwozAmbCSnMcP2ZTk7YMAW4NcxvcxcUa\nNqM4+y0t99phoTNCkNDWH8JUSEAVM+OGsJCrd3LzCScmDNgBF61U+lqrdpE0\nFoUOzpjAiGBLzmiL3tXx2SZyQsvC+dPBRW2W2KYcoy+CYXPgUCwfkSYwKz2F\ngF5+9Pyd8VqbcWgIbg7PfQD5KFfXBKF9sCO8hv6UBQgZ6NJpIPYhWpeYfxHK\niFut\r\n=gLnw\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDZDbx3S9jLwbuuoa4n1W4F0fGUJXO6ng3QVWw9nUlmIAIgYpRJ0NPlmsVduuq+rr53hjjGoNeaxmxOjnSkIZn/J4E="}]},"maintainers":[{"name":"ljharb","email":"ljharb@gmail.com"}],"_npmUser":{"name":"ljharb","email":"ljharb@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/has-package-exports-patterns_0.0.1_1603778842085_0.2453392545644033"},"_hasShrinkwrap":false},"0.0.2":{"name":"@ljharb/has-package-exports-patterns","version":"0.0.2","main":"./no.js","exports":{".":"./no.js","./patterns/*":"./patterns/*ed.js","./pattern-trailers/*":"./pattern-trailers/*ed.js","./pattern-trailers/*.js":"./pattern-trailers/*ed.js"},"repository":{"type":"git","url":"git+https://github.com/inspect-js/has-package-exports.git"},"author":{"name":"Jordan Harband","email":"ljharb@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/inspect-js/has-package-exports/issues"},"homepage":"https://github.com/inspect-js/has-package-exports#readme","publishConfig":{"access":"public"},"gitHead":"f0f693d8e03b9be35d8559df09f9d29cc93f0810","_id":"@ljharb/has-package-exports-patterns@0.0.2","_nodeVersion":"17.8.0","_npmVersion":"8.3.1","dist":{"integrity":"sha512-4/RWEeXDO6bocPONheFe6gX/oQdP/bEpv0oL4HqjPP5DCenBSt0mHgahppY49N0CpsaqffdwPq+TlX9CYOq2Dw==","shasum":"c1718939b65efa1f45f53686c2fcfa992b9fb68f","tarball":"http://localhost:4545/npm/registry/@ljharb/has-package-exports-patterns/has-package-exports-patterns-0.0.2.tgz","fileCount":4,"unpackedSize":770,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIB2kq741WzizIG98/ELM99UeZlbDuUFh6N2Frl5pBxRFAiEAmmsPZYZVwIobIPJFHu+DlkHedTV3FZngCFTVkAlstJ4="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiTnmjACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmobhg/+M0JnGNgLGqhKeAP3rdF06hRZnZcwQ/aHufu6K5LKF42LQwNY\r\n0PZIpb4qyfCI+rvSbK+kat3cPuY0ZnV99slZe4ZxR85FpJm3WDm+WxHqkDi8\r\nm5G0rY6dmwTB+8o05g8pUDaxu5Pd+J5ouWXBoySzyrctNoNwslBCvXY5GZZL\r\nowcI3gOFW3uhaBUrZa955LFcB7fUEvZkD7cayMKT21lTBb2lcby3Thl7yVHE\r\nBGU/6a4spdnfOi/YsJx9R67oCqCjwt93gAAa+7rclvsOQZITiR9722toywAU\r\ny64tb8t/MSGsR4cjoBlcjrVfgMPinJSN2rIL34IijKX6pSBvGRFkWY0MqMcO\r\n/YvOH61l2ivdGEMQBxCNPsdfMXKGUKriwJ6NLUZiSMSue5cxGQASj6S5FtkA\r\nqQV7DaQTJut3mrSYL93fs5rvVubBdGw4mmIoKkuICFXAaYTCiROUCrHOnpST\r\nL1G7ZLXLkKyT1k/ISivh5vFQq17IacHCEZ/5Y56UwtSBVistNsBhuVMQSOxJ\r\nwzzi0i0+nAVrSV+OUc9y9rFgx8EMppewOMG+JlLHNMD6V6jmA2wZBgf7ek8O\r\nun9TanuxyINaWKKsqg5/fSZCXjRNDd+uGA+UlrMSoznUACz7zdG+feC1bO+k\r\nkzuAfVPdiRNcilaRUc3ihfQH9TevL0hobPA=\r\n=VOhM\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ljharb","email":"ljharb@gmail.com"},"directories":{},"maintainers":[{"name":"ljharb","email":"ljharb@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/has-package-exports-patterns_0.0.2_1649310115254_0.5270760426972871"},"_hasShrinkwrap":false}},"time":{"created":"2020-10-09T05:53:58.589Z","0.0.0":"2020-10-09T05:53:58.693Z","modified":"2022-04-07T05:41:55.495Z","0.0.1":"2020-10-27T06:07:22.221Z","0.0.2":"2022-04-07T05:41:55.403Z"},"maintainers":[{"name":"ljharb","email":"ljharb@gmail.com"}],"homepage":"https://github.com/inspect-js/has-package-exports#readme","repository":{"type":"git","url":"git+https://github.com/inspect-js/has-package-exports.git"},"author":{"name":"Jordan Harband","email":"ljharb@gmail.com"},"bugs":{"url":"https://github.com/inspect-js/has-package-exports/issues"},"license":"MIT","readme":"ERROR: No README data found!","readmeFilename":""} \ No newline at end of file diff --git a/tests/testdata/npm/registry/@types/node/node-18.8.2.tgz b/tests/testdata/npm/registry/@types/node/node-18.8.2.tgz new file mode 100644 index 000000000..8afc9d21d Binary files /dev/null and b/tests/testdata/npm/registry/@types/node/node-18.8.2.tgz differ diff --git a/tests/testdata/npm/registry/@types/node/registry.json b/tests/testdata/npm/registry/@types/node/registry.json new file mode 100644 index 000000000..3fff1578e --- /dev/null +++ b/tests/testdata/npm/registry/@types/node/registry.json @@ -0,0 +1,73 @@ +{ + "_id": "@types/node", + "_rev": "8944-025a921c7561ec7339c70b87995cb358", + "name": "@types/node", + "description": "TypeScript definitions for Node.js", + "dist-tags": { + "latest": "18.8.2" + }, + "versions": { + "18.8.2": { + "name": "@types/node", + "version": "18.8.2", + "description": "TypeScript definitions for Node.js", + "homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node", + "license": "MIT", + "contributors": [ + ], + "main": "", + "types": "index.d.ts", + "typesVersions": { "<4.9.0-0": { "*": ["ts4.8/*"] } }, + "repository": { + "type": "git", + "url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git", + "directory": "types/node" + }, + "scripts": {}, + "dependencies": {}, + "typesPublisherContentHash": "034172ea945b66afc6502e6be34d6fb957c596091e39cf43672e8aca563a8c66", + "typeScriptVersion": "4.1", + "_id": "@types/node@18.8.2", + "dist": { + "integrity": "sha512-cRMwIgdDN43GO4xMWAfJAecYn8wV4JbsOGHNfNUIDiuYkUYAR5ec4Rj7IO2SAhFPEfpPtLtUTbbny/TCT7aDwA==", + "shasum": "17d42c6322d917764dd3d2d3a10d7884925de067", + "tarball": "http://localhost:4545/npm/registry/@types/node/node-18.8.2.tgz", + "fileCount": 124, + "unpackedSize": 3524549, + "signatures": [ + { + "keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA", + "sig": "MEYCIQCAqI3XibndhBD647C/13AFb58Fhmg4WmfCoGrIYrgtzwIhAIB0b0D58Tigwb3qKaOVsKnuYOOr0strAmprZSCi/+oq" + } + ], + "npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjPFItACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrKAg/+IwaUWPgePlO4IxW7CVhFEEFiyhjEH3FHe0ogC3YmreoBFv/A\r\nPwQrwObdskbGWrBzsAOVFvhzYktzP3kc857HtU2ia9FXeaEYvsSQBqh6jZfA\r\njR1+h+jn+W5JnmbnwRGfNn2riCo/un4tYoZ4o/bKiMdNd9WrdIs0Oii1Dd4N\r\nnsBXPb05UPPP4Uu8cz68u1bj+QQ6aslr6keGNyNeILf8bJsEfcfVkEO3l4cu\r\njyTIrxiD+tM8jrUE9CDeodF8CZNuvLh3hqdMPJeH3U47qkDtPDKEOvZTbyYm\r\ngodto6mcnuBr8F9vmikAQfGiXV0U2cg2XRjWc1lI8HT4X0kESTIo+nzNuliD\r\niTpfjyZHdKBGGIuHP1Ou9dVvx4t5XZ1JsK9EK5WTilvAlu/qZrynxXxAV3Rc\r\nvL9UhIacISprMWB3Sohl9ZtfcmGnV/KMRpM+yPZOWp39gQQCKaKF/j2f/mir\r\n8YFbFUnySZkXKzxgsgjrSsh9QiK2dYAzcqHlazITeFN9jOYRzYUjAFj3qOFm\r\n7o1eJpW0qM5vgR+fPq30WxcdcQ4PaWgHSlb/ll8hiwQG1ZUihO/1RU7FtDoc\r\n1KwcfrGOAJPL6vBSLPReUkhDIUTSBwfmvfMxzqD1aDp6YV5WX7h03B0dWbPJ\r\nmPJmJZjjZje4Trk9jBJ5/ZLpB8/zkrDKvhE=\r\n=LPWa\r\n-----END PGP SIGNATURE-----\r\n" + }, + "_npmUser": { "name": "types", "email": "ts-npm-types@microsoft.com" }, + "directories": {}, + "maintainers": [ + { "name": "types", "email": "ts-npm-types@microsoft.com" } + ], + "_npmOperationalInternal": { + "host": "s3://npm-registry-packages", + "tmp": "tmp/node_18.8.2_1664897581729_0.9746861340465625" + }, + "_hasShrinkwrap": false + } + }, + "readme": "[object Object]", + "maintainers": [{ "name": "types", "email": "ts-npm-types@microsoft.com" }], + "time": { + "18.8.2": "2022-10-04T15:33:01.913Z" + }, + "license": "MIT", + "readmeFilename": "", + "repository": { + "type": "git", + "url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git", + "directory": "types/node" + }, + "users": { + }, + "contributors": [], + "homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node" +} diff --git a/tests/testdata/npm/registry/@vue/compiler-core/compiler-core-3.2.38.tgz b/tests/testdata/npm/registry/@vue/compiler-core/compiler-core-3.2.38.tgz new file mode 100644 index 000000000..d316a32f9 Binary files /dev/null and b/tests/testdata/npm/registry/@vue/compiler-core/compiler-core-3.2.38.tgz differ diff --git a/tests/testdata/npm/registry/@vue/compiler-core/registry.json b/tests/testdata/npm/registry/@vue/compiler-core/registry.json new file mode 100644 index 000000000..b7e9ed04a --- /dev/null +++ b/tests/testdata/npm/registry/@vue/compiler-core/registry.json @@ -0,0 +1 @@ +{"_id":"@vue/compiler-core","_rev":"131-12632c33deebdd0b0cab5a07311221f5","name":"@vue/compiler-core","dist-tags":{"latest":"3.2.38","beta":"3.2.34-beta.1"},"versions":{"3.0.0-alpha.0":{"name":"@vue/compiler-core","version":"3.0.0-alpha.0","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue/issues"},"homepage":"https://github.com/vuejs/vue/tree/dev/packages/compiler-core#readme","dependencies":{"acorn":"^7.1.0","estree-walker":"^0.8.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-alpha.0","dist":{"shasum":"016ebe9d36a65a909164b0ad9d48b2a5b53c99ab","integrity":"sha512-9Yavlt5pA0kP9IxztuEYkNwpgqtyvcL3eHI78d0vZNG0QCRz3nrdJiI4cmTi4aRw8gTzmDN8c1N9k5quwbyzxQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-alpha.0.tgz","fileCount":10,"unpackedSize":447107,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd/Q/FCRA9TVsSAnZWagAAlssQAI+QuuKw9Zta6cn4aMQK\n1CEFx+2dGBjGMLQBX1cF4OuwRRJyjaXVkQpK2NoS0v7UV9v7tgoWTCLMpqks\nHQ+Uhv0LaNIw6mtLW9djGL1BTMUQ4U7f28BDr2QRIU/Zk7jZDFvXS2SemJnI\nNHtbYdanJ0jC24sWw+CzLzmHKC1EPV0ZVlx6PVKoPgxEQS/zZd/R/i4Amm8n\nCxlKYrGFrXxNOxX2GLLS+578F2086q2nxRdTInM7oZK4v/cdaG9EKMgJPamx\noh6CJN+DarQhjLff5ABVRFFH+0ZFdymNVfdQuKDy3htSwqJ3K2DlG5f4o5J4\nA1slFr9vG1x1jSqCLkRMVx98IgWwt1ehLq+PiLJLAJcWxE/0Nso79BKTG6A8\no1Go/miVsBSsH1RbfShqXs79Cn1ID6WUVTYAIVQyElT0/4vuTWgqTwnFcc2o\nwgUuSebk1ImSdPuV2yiXp2BhDVC220Bjzmz2rFTsYSpI5umtGMcuyF87DXyy\nD1SFGTnldl3CC+qVH5ZlO+DxiMG2hIEBfcRzUlxCvJiYNHsICrPcFPZhTE/o\nVtE72z7ZnZCQvjiK24kbisiLnMDpq0saeskvEx8Q44XCGW9sWwLYDRm4dLsv\nKRMGdHQCgyirsiU1eCOiKjRxwFzk3SVB+i4mwbwLP6Y3BNbHIbOJlQOVH2cp\nu3bB\r\n=dX7Q\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCJkFar+Zans4yd04Dk2/DVbs2lB2Ka0n3AErkSTxGCpgIhANXYe6/Exq4hV1RiJvUWbb/o2TDrQyJezMS806Ad2Pbs"}]},"maintainers":[{"name":"liximomo","email":"liximomo@gmail.com"},{"name":"soda","email":"haoqunjiang+npm@gmail.com"},{"name":"znck","email":"rahulkdn@gmail.com"},{"name":"yyx990803","email":"yyx990803@gmail.com"},{"name":"michalsnik","email":"msajnog93@gmail.com"},{"name":"chrisvfritz","email":"chrisvfritz@gmail.com"},{"name":"eddyerburgh","email":"edward.yerburgh@gmail.com"},{"name":"ktsn","email":"ktsn55@gmail.com"},{"name":"nickmessing","email":"dot.nick.dot.messing@gmail.com"},{"name":"akryum","email":"guillaume.b.chau@gmail.com"},{"name":"mysticatea","email":"public@mysticatea.dev"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-alpha.0_1576865733268_0.9141904166579227"},"_hasShrinkwrap":false},"3.0.0-alpha.1":{"name":"@vue/compiler-core","version":"3.0.0-alpha.1","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue/issues"},"homepage":"https://github.com/vuejs/vue/tree/dev/packages/compiler-core#readme","dependencies":{"acorn":"^7.1.0","estree-walker":"^0.8.1","source-map":"^0.6.1"},"readmeFilename":"README.md","readme":"# @vue/compiler-core\n","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-alpha.1","dist":{"shasum":"963b2c19a5e882726242b32872068f6a23501cfc","integrity":"sha512-TKWRUtPfeOQmm4fylfgjp5ENf0nWYuWp2nhzXXZdVn+upqNJNw9nX45WhQDSamyhB1inSyjsg/+jQq5FnUC/rQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-alpha.1.tgz","fileCount":10,"unpackedSize":447124,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeDnvgCRA9TVsSAnZWagAA6hgQAI5GDglwnvabhEDPQZwY\n2HtDkisl9jzuzRJWVyHEfdMwe6Dhq4sFanWOvB3+HO05M73xX4u9uOFQR/I+\nHkRWqeLxASpIc4w2dLwxCVtOpDDqGACdX+qRlA4ggP+1XgHjK00M7dhArYFN\nMEfFsZl9ztHWrjGv8/Er0LdrNG9OqcIwDLutkqPBGM3ekmSatoqut5mVOC4c\nbIbbpJZIHOFygd7+yxIjmDuVH4P99SCawzXcI9vvMrXUmwTVmiL6i5j2EEI4\nwsBfXDlKmv4rXKmb3AYjPgQTi81LVKN0v8M/9T05WVpB84hVbl33TNIf2mEM\n+iZGcBHQwluaMrW67YAByaKpo/ty3pHMUpkTdrclXU0Guma9Lr2P/3jzqrWf\n8F/gaK+J2lTUuocihWJSLBe7beBFex76maSqF/6TWWnMUTqBswEWkM006tcC\nW7rvl0l7FZIlEc4OwvEzry0456xs/T9EcoOoxq3LO6D+Ic0z6RV+J6p8pCMl\nedRLJ+KBkSzFIvuk+sEPJzbK4J3WxjdHIMHi9z0C6G2d0O1GFbsoSZaqiVne\nxp+uWSpLaZ5kM98B9AXlA/uoejc/JTpKnnDg0yo+OpJaHBnX7Kirq8+/QoqS\nOhBn3MMLxu2+89slWL3+rMDQQmK5PP5Z0a5EKEj6uc/reQMGbTiGOOfeda/r\nKXZW\r\n=FUKM\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHiYobD+Q/CgUutMa9nuvjmZKp4mM+lN+ruzr5C7syylAiBgJR4y4K0B6sTnSBWMnNsYMpZ8fAEUXkWIcV1Sp7L7jw=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-alpha.1_1578007519848_0.8228685754205469"},"_hasShrinkwrap":false},"3.0.0-alpha.2":{"name":"@vue/compiler-core","version":"3.0.0-alpha.2","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue/issues"},"homepage":"https://github.com/vuejs/vue/tree/dev/packages/compiler-core#readme","dependencies":{"acorn":"^7.1.0","estree-walker":"^0.8.1","source-map":"^0.6.1"},"readmeFilename":"README.md","readme":"# @vue/compiler-core\n","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-alpha.2","dist":{"shasum":"c37e7b3df56e8c37c7a4085f24a0c4f76e93119e","integrity":"sha512-BJAnc5NKl69Hs7X+W+i0mvu/FksgLvN4tIuXlPAmOKI1bBROTontNtqL6Dq+mZ3yu+eeIw8pM6s0gminDnCojg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-alpha.2.tgz","fileCount":10,"unpackedSize":449832,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeHPLRCRA9TVsSAnZWagAAf1EP/1Eh9+bsOXnGBlj/hLLj\nGYMw8SawL8Ym7y7MLEZaRp2aQN7rsLiVY/vGPNsVGIfQgyzD7bz5SFC2yP8x\nPRVouNW53GI5AeXYYDe4VSkYmIsUdHOuexQ0H7CADsGcF3bC7WVtZY4eP5oG\nIQKsLgTiOprdVqvBY9sPtUkApmxwHDwG8AlyC+PxNgE28JQKDUfp46TV/xyL\nJcyL9XnJDbr9OymZkSybqQmTaa/y/VTvU63YkFU9pyX6Rf161Y3Set84gypR\ncW/7mMBoKAsdv/X/J4k1R108sw+NmdeVYLpu6mamyLaI57s8+TvGMDh3OTuM\n1ZS546fVdyA11BnOMoTp2CYM9CQ6xiZuwHSm5yofIxFxpAO6K21PkMlIswqK\nTSfkKYb69Wwb1jl9Lah5VPm0tHXIc77KmWvO6BYiam/l2aaXi0ZC6DBSxa8l\nYRvRRQQbke4BN6PFfft8IphrhdOShWG2zd9OIO8koTFsT39877rMKblkS/8M\noR6d7U9ozWa2YfMwXrlAC5kqaMMweTViWk46viGIst7zTYHrbD4zAZvLRqcT\nWkXMjnMEbFgJk/ekhpaEH8itabNYIVAsW5jwnpHsMXfpsJtmFH6HYNfINVmO\nRSv5wUMyOuVzVjt4LQmm82XfbCdXjQIL+SEGBtQt53nQT9hTG1aI1p3pHjN1\nxNf5\r\n=Pdce\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD9PCZN/6TEbc//SGroHJL14WahCxjn8VeU15+t9aknRwIgLwZt6CHy1CGY4DTjJGpmYGoolHvV1ftxZARXRXVZty8="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-alpha.2_1578955473036_0.8495446749924664"},"_hasShrinkwrap":false},"3.0.0-alpha.3":{"name":"@vue/compiler-core","version":"3.0.0-alpha.3","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue/issues"},"homepage":"https://github.com/vuejs/vue/tree/dev/packages/compiler-core#readme","dependencies":{"acorn":"^7.1.0","estree-walker":"^0.8.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-alpha.3","dist":{"shasum":"632dd4217e0490aa6aa2c8d2c3956045972b8bd9","integrity":"sha512-xzqlzor8zZXvhfputSUTXlKZ7RT+w8ro9PjDDMOfgRNrdhRLAOUSULvLKh6fB1zMZiBPUYpX/WuAqB5+7ZXARw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-alpha.3.tgz","fileCount":10,"unpackedSize":453078,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeKHP5CRA9TVsSAnZWagAAAoQP/A8kGpC+c+rK2zQGJXVi\n2fVVkQrVWda4YOpWIfF/3MbWvLb/NrmFDQ5sHazpLOFGsgRmBvzRjm3Zss6R\nZZq+xCioEfub2wjWarUWpZqHS06TVjdHuiZcfd9RwJ22sacd9eTqRpjlEfLV\n1dDQkewAmXBr0SjdXrA/vcgXgJ4m9G6//MRQUGYu0cVRTYrBeF5gT7JmJpTe\nJelo0H/7dhWjXp4VW+pvptIXJjQj4MuV/g1EBBRMDe677Ps7K6kiILnKcTqM\n+Vk+TNgmGvvsgPetsImQmuaoLnTIbZBqhx68EzBN6IDM6/IXjPzsoUMzsGAK\nBBDGIzU1CFoYQ45ftDG0r7liUKKBpBoZUz36Z5VBg8rJcM2ACxHpMgN+XqpJ\nV0sWvtzGiQqXg7hA6wCC37oi70Z8KuHuAEHEDoQvA5aX+ZQ0tsgL50U2/puT\nug6tbF/kNxqzJnf1F4bu7m7FFA3L0+tY65oFPaLadbmKEMJaL0pKlkRbXnNd\nzkkaVOyH9MA+d2kmKYM3DIrlOiX6qwD2eshp6qXez5tRr3cXRF8fk02EJg0K\nvTeyy6GPpzLpx+1144ytGO2RhfHnVpNzFXJ3H6fDxS8SXbXPrBR53Pc9T1Ya\nMt1uuaOWytQsqUOvLempbN6v4gpiOBIE6pvKtLMzVzjeX7D4zwtrM0kQTtKZ\nm24E\r\n=ix82\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIE9nd3xf6UAas8d0CNulYke1Sog03rWQl/KOYSanlagxAiEAyYpFWula5oJGcQm520Gf2ixNyE05U/YuhR2E4rNMPIs="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-alpha.3_1579709433470_0.019700959342907165"},"_hasShrinkwrap":false},"3.0.0-alpha.4":{"name":"@vue/compiler-core","version":"3.0.0-alpha.4","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue/issues"},"homepage":"https://github.com/vuejs/vue/tree/dev/packages/compiler-core#readme","dependencies":{"acorn":"^7.1.0","estree-walker":"^0.8.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-alpha.4","dist":{"shasum":"46d62d0fa70495e0fb3d23dd7b4c57fb4344f410","integrity":"sha512-WiRK3LSW4N+L8snXMx9aNANBO1LTlfIPf+2M6ld0GZEsiGj0JNJIheXPYdhSCjRNSIU5GqLFxWvzNgGGN9e4DQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-alpha.4.tgz","fileCount":10,"unpackedSize":453209,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeL1QDCRA9TVsSAnZWagAAUYgQAKQ3SSThMWW6Dp+257zi\nXN85NUGnC5Mf5fniH2YnnfVyHu5KXEekKgN1FEhgFBFE9CXDwejYNeI6/mfW\nqMD3UZNdKLzopHrvI3yuZtbuX0qq8uiMMt0deIrxNTdOHQKM/OjL4Vl3dlaq\nyppq8ChVHh1V9pROn0PuWN+N4OTQZWOvUvYo7it7EcK3DO2X1tx0/MfA29/B\nouR+nCe6dLwEPPmpEiFiiQ+iqTcAQIDbUWtzA3qGC8WxOH56Geeci13EKfEn\na3WFkfGxJ/qvD7kPn1Pp4ORR18D3oxz0ddiHFPN/FHHlfYCSZ3R2XGYkgYSR\njqIUoWTIwke/i0aFrlY5/EN4FY5lHHL9OXzkCvEU+BDCs+w80mIX0/cEUAkB\nOHeYDavMvkgQXfS8PzUTT5rSEWMW+ag3ac9oHUluulq2+ptLhBdvEHKOeSNd\nc851uLrhaExGCINc2gF2FRbs99HepXlJxA87zTxL80e0zDJhgygCUGYEUklH\n754KU6TEMui844T125lxR26kThM/Ap9/sv89Usb30tw4erEO2qXNbCiEAAGK\nrIGvIMfpiHWcaOY+wfYhKUCFzs9lIn/DuYiQPBRADDGeJLk7/aIuoVD4Efve\nR6h5UQCMga7XRGTpFS6kHmWknlLnWm5xq8PTFQJWNKme0ku+bKeA0ewQ5SZC\n5BHZ\r\n=Loul\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDfql7saZhH6mBOzpXpyMQ6BQQEQ43inz2ucggGi72mbwIhAMdFknb4EGChSWqrMfTEEwQfCKwtEjLhQBeQ/z+8BwYD"}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-alpha.4_1580160002637_0.244335005674706"},"_hasShrinkwrap":false},"3.0.0-alpha.5":{"name":"@vue/compiler-core","version":"3.0.0-alpha.5","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue/issues"},"homepage":"https://github.com/vuejs/vue/tree/dev/packages/compiler-core#readme","dependencies":{"acorn":"^7.1.0","estree-walker":"^0.8.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-alpha.5","dist":{"shasum":"ebe16362f7b701dc082036c4b189478d558f21c1","integrity":"sha512-P+r/yi3tWZy7n/A2k0ykVVZheJEqfbgA4tXHkRDm0pESzms9LjmPE8qByJ8AZwjWZmA1sjJY448pIvzNTFfqAA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-alpha.5.tgz","fileCount":10,"unpackedSize":500230,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeTEJ7CRA9TVsSAnZWagAAA0AP/iFervOABqMfCCdUFlFM\nidL+BsUuWIGFGub7yLah7AioDntza/dzr5mJ90LGSZOJ9C45ObZcYGXTYRyP\nCLoP8Mw+KDzaK9zBA0SATLkcSyiwljWEmRCwVtlzx0SKWb67qltJ2v+w5+/X\nULkZtJWC1XfnsNrfShkLtW5MNED/DyM5XZ7yIzAiscaVyLYmmBGBI7DMMYP0\nRDImAC7WRpv0iWC1b35bLtHS30E227U9X9Ko09Rliakxzp/PDDhzMApfjJ61\n6LeMRXzFzZz6QR7+DCYU2WJr2HuYraJ6H+Uvi/2DvwAwq8ZIFjAqwmwIwTNr\nIhYQt4H3fDlWzsmKJz6oNSCBe2ObU+ct7GsFYC0kSr0hhpGnou/Dols4ppxb\n0pNqdfXiKS2oGC8SyRT2FKNAuauoDal5qOAnAW3S901pvfgOv0p/crOLUIXw\ninougOJawpYo8UYLdmCwhuXGc5IDoCxVPi7pR614DV7bu/kF5DN9AHlhYUxN\nFsG7CJTb63HxY698L1O0AbB5levKMiV/CVKDLxl7ebbTvIR588hQh3RKCDhG\n7gjN9HwGfrWOoj1EJkTe+/6H6IfpPgBuEqqKbEDmufIXz/VZpM4LdmU3giL1\nccb2NoxsL3MQZtY8dwWEtxkLGZyuHGdSoqaZwnx0jJd/+3g6Ailif6yRFwrX\nt1S5\r\n=E3yJ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCfiHpZOGjV7lBJkkRgS01DLJeboGT5IUAMVnudGxiikQIhAL0zyB9KLXNTgk571MK6cXNIcPHeLFINRfRLiJs+hgMH"}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-alpha.5_1582056059456_0.5602692206800763"},"_hasShrinkwrap":false},"3.0.0-alpha.6":{"name":"@vue/compiler-core","version":"3.0.0-alpha.6","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue/issues"},"homepage":"https://github.com/vuejs/vue/tree/dev/packages/compiler-core#readme","dependencies":{"acorn":"^7.1.0","estree-walker":"^0.8.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-alpha.6","dist":{"shasum":"3f8774c389a5c339cd74fe4f4dde871a6fe69a27","integrity":"sha512-VusnzQPrXnHiqMZia/q0ZENzgMTVG9fOiDUAc5NhiMkIeqV4drnzFpys9kCFwdPlc+meCFMQvRQcidTAgG/lDQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-alpha.6.tgz","fileCount":10,"unpackedSize":499972,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeUNdyCRA9TVsSAnZWagAAR7sP/RILgtiffvG00QAK++mO\nnqcEXjO17M+fOoSjSTYJSWa6FNtDaZLroYw3viyJVagihSynmHaJrYj8EJSj\nkXFo/AbxjWaOZtcvbij7lF2APT2qFbJGxOm+fYUQo2tFydAsjAfLYM8x3ZNs\nR/yGsPk8OUIdVrynvR/ULrVXO7LKPZlW6NhzK4mmKO3WyPNXNjvAtLC679yz\npBvATFgwGMzBlZg4+ERfmgl3WEysCHGJVLHwPb0NFkYd4GNM6MFObB9Nhe1S\nhpP1Jq5o/p5WRgpiRfBmtkH5zQNCH/N+v6VUPv28BjmoZ6I67YuEYm4BbYM7\ntqaDKBzAZDFFPdaWa1V+ycX/pb7V3n5siQJoJap2R+gH33op8SpCAV5gWqWh\n7DpmUIvhChgWJ6ZPcm2S6n4UuYpXD7eE5jN6M8XbEtKoXqiqdM/5CFl3V33K\n1wGWoVvwfdCtuoKFn/k1wgz72Tr7rhxbhOsLOeaGe8dMsyGnDjiQ5ADlPALS\nPz4HHwPNEVdfCJ80XIuIX4Nn2yDX9o1H8skJG5yqIK1y87ePXAgMCxHwqwm+\nqkh27FHgEEzNnPa2ux3CxghUMCq2Sb5y27DwNHXtHweAz5iJertWlS9QFlW/\n3Ai18LNJv7l3khFkgQGAP0vAR12NvHLQcK1ZIR1s7zNv6nrlv7aL0/Q3lRIz\nsDbK\r\n=WIjl\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDyMph3ccWNtMzaUvjpw6gO+BfmWL4ROeuWinR9JG015wIhAORtt6uPYY/3ZC2/k+gMUvCyX6z6DUf/ulfGsH1bSYgz"}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-alpha.6_1582356337501_0.5831380561230184"},"_hasShrinkwrap":false},"3.0.0-alpha.7":{"name":"@vue/compiler-core","version":"3.0.0-alpha.7","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue/issues"},"homepage":"https://github.com/vuejs/vue/tree/dev/packages/compiler-core#readme","dependencies":{"acorn":"^7.1.0","estree-walker":"^0.8.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-alpha.7","dist":{"shasum":"8e6e71134221f04ae420e76fe68feab87651fc51","integrity":"sha512-IAhE2G2y4qqLo5D/AFxWnBeQcttnTF6kkgnmjoqTLsDAu47bmeawdJG5MViXi1yIvhYHSYjGk7dQS8wXF/63fA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-alpha.7.tgz","fileCount":10,"unpackedSize":502840,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeVsjJCRA9TVsSAnZWagAAU4EP/2QnFITa0dmxQlquvH9T\npara7UFzggygM64Q9OuWyCplRrlLmpSSOcwDbSTCuXhnIc3qDqWwj03ni5j3\n18bFrz6/NWtptNl24dtCTcjH7ToooJunvwXQsyHWJSeNAFT4IAv0usFzXe7U\neD3V3hPvYBf7YjUT8F5B6BBOLSYa5WkS8mlWzXVQx17XQOwW8TVBkbzfwKMU\nPCc9QmYs1L1KGLu/epTeK8oJ+8haLJK7maJXTxrjURXLOCBylkcd2A07j0Ly\nhr39tB56jw21zmbnw1xNhhzGrhtcJbyPUa9n+6/ySeiGJXhfcxiSSgUnIe3d\nAlaRJojJVAfZJlTloTFoOHSb4T9LnbhLy1j/lYbkEuOPWxBFrB2wFHlzAJCk\ntKu+Jg/8cHpMc86w9AwnfI9ltHPm1kFf71bpZ/2C6SpFWTnHFh8cKDNAImB0\nPd8B+2MfNg/fE3NkfaNJrA7foYJyBVm/GR1f4zHm6aYeFWVM2IMWKGBZPZ1U\nUt1jkDMYemZkgKPmIQdGGQxVKNAETI96FxbIz9pZN0Dx1fYIp7XyVWmjDpVR\nCm8WcQtRTKnbmOkwrNxhEu/OEEpK+e+YWor7UPqnl4ujii2m6M4FduUpDE/N\nNHTj83gKj+AXRHP/PJxQrq5O9z29Ydg9PwYwvP4hp/Dpq1CW5hq23YST0q/R\n1AnP\r\n=G+BV\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCMJOezwqcD+39UjkVVIokTQAiDmHd6+Ut3e3DyY0iwQAIhAO8gJtWTuG4x58KiH68+nZAfh86Dj/OivvtboM0YNRSU"}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-alpha.7_1582745801391_0.15511368637527867"},"_hasShrinkwrap":false},"3.0.0-alpha.8":{"name":"@vue/compiler-core","version":"3.0.0-alpha.8","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-alpha.8","@babel/parser":"^7.8.6","@babel/types":"^7.8.6","estree-walker":"^0.8.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-alpha.8","dist":{"shasum":"849dab7a96c482a00e03a273f075e5d12fd7aaa8","integrity":"sha512-TCio1nuzuVUS9oeQycHsjRFTO9Bs4qO43S/73+MyBe/8ZHfhXn0nx6sxYfLytxnoyeo2Z4TGTevGQq7LUKO32g==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-alpha.8.tgz","fileCount":10,"unpackedSize":493513,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeYrmECRA9TVsSAnZWagAAv8kQAJeWAmmHOfcH7ie6ycrC\nI2fhC8rGsdylsctctaIPlCgMuQ2Spwz4elocxPP2fwiYv23NgMlgva1bU1Yh\ntjOI3tlmj4aMHPk9Onry7ZGEOs2T5q0UVqpUSaTIdFmZu6zHVxUlzbmcpoDp\nIlLDsH3fDfvceX1jQI3UEds5EJA58vWi+76MlkU1oL9BUUVrUIBvBWQGLoff\nezkY+gKUnFtJjT47u9VNkZ84lA19pELYIF0kZy6ThFE3cO3t1+WCCBAeguIW\n7WpiPj3C9NBvy+93C3+qyu9/XBPMYx896BWNaLA0N3ADV5MNmgl27YjCkVnj\nGQn1d6Wd279fXAS/yMCpOUKN/K7fnu6ej9T8A3khur1xUTm32NFtjUI228S8\nIoDnXxU4tIEidTXUyfE7G8H+Ops7mqD/5AlqDzhHJFCWqRpy8yvg0ZlXKxJz\nQZKRnRnqlTaMZsRBweciCD+H57e8dZkdjbIIPK13XeE3QIqh0QT0PNjjo19X\nm7GrerAHX5iREgha56p6P3DOH2SwkNMuhkn3FEZXe50Sh1Ps1nqPlAMN44Yk\nRlYcNNUkQwNK+JTRdAeCvHatCVwifdM40X7srazEwB7f/MT+wSaUgbTpEJBD\nXuxEreq+16WaFvVBGyiyPeS7knDy5kCq9sxA/gdvePjSc/9DIPPe0XDnZSzE\nUqmA\r\n=u4AT\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDwH9Rc0TPQyMkUQy6Q5zEnRHcYDNH/uloQFMnnWUrOTQIgHSCDEJ85YYOWD8vICucuJsE9KNAvdtlelK09wwW0524="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-alpha.8_1583528323725_0.6699996099948191"},"_hasShrinkwrap":false},"3.0.0-alpha.9":{"name":"@vue/compiler-core","version":"3.0.0-alpha.9","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-alpha.9","@babel/parser":"^7.8.6","@babel/types":"^7.8.6","estree-walker":"^0.8.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-alpha.9","dist":{"shasum":"d54cee813bb444afbf347da7f49056e523197b70","integrity":"sha512-Hx4yr83DwIS4B6WfEXWJYcD5EjGoBLQKx7EfoKTvp7++ssO574J/BgasJSUbw/DOm3sHumXZtWRDTn/SKSTs7Q==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-alpha.9.tgz","fileCount":10,"unpackedSize":492799,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJecAQvCRA9TVsSAnZWagAAxPcQAIQTgRMhkBJj8vdPhfX3\n7pA6biBkVXUcHdpadEHQLveVAahv/WlFzuocBDPNIq6yyxdUf1N7/BTLdbsL\n446IbmtBk4eCZ516ieTBSF091ltb+0fZGP2kY75lpzSdfKkkfsGv2B3fTAO/\noa3XcK3+72ksazlwUgNEF4VPUe5PE9ut8FV0KiTJDc5TP0bfNdVfAGuhyvIC\naSI4Q6EL8fItNknO9d6D5QfVTEiS4tAO6IPnwC0lZ6aF/JNDI/UBlFFaLGE/\nsx04hjnfaHoCCyvCxpnDlyopTPeHi/eoyYAh1jxWPasJqpGpzN0M8zT5Mp9V\ngR8KHhlFbffrGH44DKt6+t6Wt1PtyF8m+J7Xs7/uRA/7beZ+Hpd3l5oUFfpw\nSCRJR4ZfYockP6BOEr1wRdgMZ/Q+JFNwYmf+SaChDaSx64PLsiAFshJT76/j\nxByuGfUD3/ykCChm6kRg98aHcWX2DZQRbdxA8Lkosv13Rj0X13SfMwruNTU7\nLDsOCWUbVqWdCA/vTSTf6/zQSgYPlc4DxbdiQm1mBaJQYAQ0JLH422cHQn5z\ns2Wa7avhytg1bQemo5vC+kWtOP/W00LMqSiKYmav9n9xLz5JbYtG7a2jByyw\nbGDiHwPWTnvzEypNCujNxMOh98BcY2hjnHV9/vjwiqPWVBmBlX+5PKAgZH6P\nMfwg\r\n=EZjL\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICUbOBtHE6r/d1MGmgYBH5ZYF5WM8l3kZVuiDDa2Mth4AiEAq8THMLXUQ3mvtKaHtWTINMmw4dNRGIEXETQzAelNGBg="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-alpha.9_1584399406760_0.2581875509095788"},"_hasShrinkwrap":false},"3.0.0-alpha.10":{"name":"@vue/compiler-core","version":"3.0.0-alpha.10","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-alpha.10","@babel/parser":"^7.8.6","@babel/types":"^7.8.6","estree-walker":"^0.8.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-alpha.10","dist":{"shasum":"39e8de2d7fe8a932cd08958200f37086a9d6841a","integrity":"sha512-YXJJyFfkgmX3Rnf+sEcL8RR9a9UiHqB6ng1pzN1Dy8STASqUBdwinvi/xBuuCS7mDls12xn562y5CEATAwZs/Q==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-alpha.10.tgz","fileCount":10,"unpackedSize":491365,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeeorICRA9TVsSAnZWagAAax0QAIc5YT6EqLPbIL5bMrav\ngmetIZlmMtQxIRsN9p3n51kzVn3KjjsHTfH3dwOeIfgc+AHD3xU9klIGLzS+\nhYXbw5Y5L5kezMvV18LkYuFYHFsCbkAF58BK4rsNVdVktgwNjcWymhnFLzxe\nzZm/OizpXIxCW/P1ulw2dujy8ZD6eRJPyhIHLwgps0sX56G5USkBldSTKjsO\nHjJ4XHA46zHK0uNk8bIHBtWPG4FTFs3aSJrSopIeBRqNcUwCpXGkG6ZHHmzh\nC27/6W5p18OJ5wkE0plhVKempvtw5Z3YtWfaHFgVL8UjUhn/5On7PfXZE2QQ\nmEwUsPr1ckNp3qNpjM/8j/q4l4cT4mvkBDDV8/Fi/mvnV95Sah4Asq2vseO2\nAODkVwOZRoAQQQTDi5so7mvkMkK/1Z2ik094CoP4soSk1yv+4W6Xla5QOuc+\nhmN32kGp0l5YE9I0EzYtm/x3nnS72vK7MpnGMTcuVBRNMqpLq4Id+PY4SCEg\naOasO0B/Je5x5RQ6NTpM3bY9vWAsMmxEc9FNty2qKbq8y5fp9ZuSZzhsB6un\nsv/PEhwlHexTCzCVrv59oZLGoCEvp2lF2PsZRfvWQfqu+ASRd5NIU45ATQTD\nhtSc5kxTKk++0WDMK+6tlMJYioZeAbx1OSbqRocWGUHuuYfP0P9XGJVfF4U8\nyQ2x\r\n=ZJd7\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDn3yZ3IghgyqS9gnvxHUBhrVI1FGyHoeoDlZS+SnXpQAiAx4jY7gP+UniT/xAYHNIeImgUTwO5PlyRw2YqhNsVRDg=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-alpha.10_1585089223551_0.8793640198075885"},"_hasShrinkwrap":false},"3.0.0-alpha.11":{"name":"@vue/compiler-core","version":"3.0.0-alpha.11","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-alpha.11","@babel/parser":"^7.8.6","@babel/types":"^7.8.6","estree-walker":"^0.8.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-alpha.11","dist":{"shasum":"6b208950c70b9c1bf4e9d3479d7b72a1c98a3d4d","integrity":"sha512-4M+i82PT9FaxeqxIDwkXls2f52iDtifUZkfsNqVdf8Q5YBgeLL5D7O7ZpCqIz8LL+cwNUQCEkhf/JfxKu5nAfQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-alpha.11.tgz","fileCount":10,"unpackedSize":494192,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeh+bSCRA9TVsSAnZWagAADi0QAIP9PwIVtNl8dAB30hZV\nStP/e1y3/lLoYkATldLPM8KWnZNNx2xxXF+uYqo6zdG3ed7qGMKDuCH+mb3z\nPyN7KMI+5MMLcaSeieYVKpwHyLNEDf8DyDeZQs/PLrm8wzEZIH4hPsca8bdp\n7fWT1/kHq9QkzRBdFSLm1vLYN8czaoOuZzEGHip/z5nA9SGiTICGCGaJDfud\nvr/Kq+HAWb7+wq9r/dGVJDlIf5Zm1rVWnlzZWQOD6w0c1nk4RMWXtTWOqiHz\nUJNdR7K9RKRfWsjDrVOzlOCQgKjXXwNWIZDepcDKm2DPsGzicc1w98CAuRfT\nZnghQd/oq4MDapeiFu9TmN1OjObVhL1gHfbNRydWH/4IRRBn4sLX7Bz9050s\n3lWvOlXzHQLF+Rb6JMYMSJoYhOnEQjNPy/nHGYv9GZ0sGCppzLdVNhirrRfa\nMWBCd8LNJ8S3VvdNxR/GouqqausMbXN21hfLIMgAKYNsS3QLi3KrOlr+hB7b\njt3a7TtOFI0QMjL9d5CZj2wh2/uT3KDJaAC4p6qZaIFy8Y1uHMrq/rdaJlFd\nDqFfM5DQZ4fOeopYvtPoapCAakJz1ZpBcU/9q69N8/T7y7i7yMAgecXEjh4w\nQFsw57d4e+HcxB3po1+EsqTK3XDAUPdfDjwstNaHap7VxHKkqCyZYuTQJAl1\nagvF\r\n=Zisf\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDfX59Kkjo/t3/9OZ+Tb3pBYhurLOiArLHvD2ZnfsKwngIhAIZVkDUtJEseH1pV4ntczTuVbuFh78Uk74qfYWc7DyMb"}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-alpha.11_1585964753741_0.045899118764526126"},"_hasShrinkwrap":false},"3.0.0-alpha.12":{"name":"@vue/compiler-core","version":"3.0.0-alpha.12","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-alpha.12","@babel/parser":"^7.8.6","@babel/types":"^7.8.6","estree-walker":"^0.8.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-alpha.12","dist":{"shasum":"f125bdfd637d6bcc95edb2c55483a242932c5d2e","integrity":"sha512-0aDhUP9SS+O1psH2xm08oxQQV+5p5ig/zhSNL8fOreSQabIzfSuNfZqrJ8e2Ffa+zoJkZ0Z0SKJ1+UuzHXm0zA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-alpha.12.tgz","fileCount":10,"unpackedSize":479298,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJejldoCRA9TVsSAnZWagAAIBsP/226mjX5dlg6ADSXhSvB\nlKAW1ajUbDA5osCNcVYulpiTiqI/ORthU3jmjWKB6K+Rfw8L/SWULqCYdj4Q\niJq5HSQJrtApSgefWSAQWpq0nzuwXzffMKNNKLq/YZAC7GDLjL9KgHZU777O\ntX7RtuLQ58aN5NYeOA/jH8/ItdN8o+YcgRuEARHWem/b47U/DpadQ4IKcBql\nUG2bqXDo5vy8i9zBpNtHucZ/oBxXs+6kTIP07nf6icAPUUSEz2TDfive400F\ntEQhsFeNFgL7AHwF+/6ocFH7llEse8vRrvcZgEwbQ2C36Xu/AOMHjhTk7VCR\nClFZ/6h1Nh9eSEHnHQ1EUUsDaxv60ghsZZsKzVMvdEOxt0vffEuyXnlj033o\nomC1hLMmd0LaTRnH61IuD0mO5zKaCbD7Dq7sYp+reTHigfXgdKyin6GY0pwh\nhhNdlfmv8Vi5NgXOWcBfrlqjG0LUc0oV7StrdoURemYSCu3BM7lsWlAW3UW3\ngbJQ0vFRKr05MGI2xQWZx4J/Vt44gMTZKjO1GVIFyriM8p3aiHfIfuRFGiLl\nutN5czxwEAPg8YHbGrWJ3HVehiLs4ah3Mv/lxYMpHiRCY6CN+Potd11Zg1M6\n41iIgxMJhtdULP/IaxfYIoHaecF4avvr2w580pAFNFoNqPG3k12UQtMESmso\n4+uq\r\n=1Bng\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDwNnj3OTSKCxUNEwey0GYfk7U+5Ej7IA6Vefxks/Vl4AIgS8qUdxKV7JtguEFe52ADtlJZVR4+OJX7OjUsm1BkNtg="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-alpha.12_1586386791716_0.4274736735964553"},"_hasShrinkwrap":false},"3.0.0-alpha.13":{"name":"@vue/compiler-core","version":"3.0.0-alpha.13","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-alpha.13","@babel/parser":"^7.8.6","@babel/types":"^7.8.6","estree-walker":"^0.8.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-alpha.13","dist":{"shasum":"8126c92f562af047c28c4ce7f343d77f0ceea7d7","integrity":"sha512-k7VTQnjQlCfsSdfwi867dUHUzqm5/2qldikWAABMlaqr4mEn+yVCla7JqQxFGZta/JF8cOv/GfqlA/vWBlYh7A==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-alpha.13.tgz","fileCount":10,"unpackedSize":479394,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJelzpnCRA9TVsSAnZWagAAhWkP/iThenIrGdKDlsRFNYkT\nLaSmNmHVcNOrzOhNXr/SU1DWPPTY2n8FcQt1ZyRQ5tEkNJbhfYmqI43oiAup\ns288GltGfU0rW72nm5BaKuQ1IfM6YCd1WpOgnr+kGih7jIPhlLrGcqQqufGA\nSWjHEWRtHzpKSKEMlJ7eJAlFKjrrCAxG7fm+51RUgT8E7U9W6pFrA9AZLXvS\nULXfQ/UezPIrY2rQCgKIYnjOI92ekquWzs+5DdxDMAH+ox+jYq0CeMVI9FK5\npvgDbPLcfnCJCzJ/KYhZpWQBBE4MUB6eFq4rwmeztnwygow5HEwl79MHDheR\nqk+rxfO+2EvbFUHTab8TnQw2uWY70dlOlVXaxyqi2onBemdcTQiLn+F10549\nQC3y/jtDe0A+ccHiJdVV+An4sEdpPVW2UvJilEVw/P7g5NwBg44MummkuzQs\ncoTitXoCsEfQ4f/uQvS4TUC8jI8wua7uZaw+qpIG6gY54SiFVo7nFgcgqFVY\n8nXkdgEtaQVtFDdItAzkriO8qChuKp3AfKo+CybICud7WMn28PfPDSLOqavK\nOVrtkfZMjpg9l1mUpxEYsNM2CtncUvnFMjU44O62la/Dnfzia4dVlT+SXURq\nph8inn+JicwISTBQiANdMVADUMYv1canjkhoCDgaRFacJ26hg+wIpyZSqgG1\nsYLj\r\n=huph\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGOs1AtUtz/f2os6iQLvERTcxA1XrlAEx75031qZqSWAAiEA/iGmRJ9fnZ4FRPocExj6Y2bBZ6oxOaEJr+urYa/WAY8="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-alpha.13_1586969190856_0.44971144818557973"},"_hasShrinkwrap":false},"3.0.0-beta.1":{"name":"@vue/compiler-core","version":"3.0.0-beta.1","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-beta.1","@babel/parser":"^7.8.6","@babel/types":"^7.8.6","estree-walker":"^0.8.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-beta.1","dist":{"shasum":"77017e0a98b808da3834327bcf8857e4b89363ef","integrity":"sha512-mlHfX/+3qH+GAuMbGFvye0Jn2/H9IwbmX6oqbpLErM241xAVbpqniFDiJCywrfjeUDKMfDuNs1i6lGnDBH715g==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-beta.1.tgz","fileCount":10,"unpackedSize":479390,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJemLXHCRA9TVsSAnZWagAAA30P/iOQCO8PPGOEVX3HGBq0\nXd1N6Jc5QON3HCry7e+F1gY7xuWce65m5moyae3OxwtW5q2Oi/1oMafax1Tg\nqJAYY76N5ukDfj2PyNZMKm8kpJZBKQYqfR/J8kDOfCe1jtNbQuxaQtEQJeSC\nXxpaSdhp2HqYOUfXI+7MMdkQ9AHTPY9RUrSXvO3m1qNNE+2BmSxyNRcKgMvp\nW5qSDDg0yYP5strEnpOy0+XZUhA/0AfTSPyMAGWOo3BqedcS8TRuftv5y8LK\nTDKXuxXqUR0ug01VW+gugmgbZhxqqdHpdbIh9egfXj2lVYWbq3yZOkTpBYNo\noCmHutCE+p81KI+HLVgELtuO2Vg3QZQaPg+bBY/IfSD6LrmrquEPFt5BlTKX\nhNF9PhmIXzHHNqDiT3KKLPnvoEEcCmVCetoBxTld/QHZ7I5sSubUxusPzQBT\nXoJhimhtmK6hVofrfHlJUS9ZibV6Aq33iBqkQzkbHPzpvwdYiXedebJuroAS\nc49U0E9LbvT22NDkiyCnYrxpIwDgwRkBbRNPti+v8O7q9coo64TmX21wD0r8\nQKnkckjzCOXWNziYLCPKESqtRtL5rddb47HK85dOYl/1BCvnegTeLXXVDdbw\nPQx8Q7JtFIA9r0W2z5GdBWhgnI1gS3cTTvWRfGyl1U+WJ6qxJlCBLyaulNwG\n3g9q\r\n=eKiW\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDcG6qrt7OJxPBp0AJtHvpaZxBUjQYBECiF+YTwceoIFgIgdjmt0kk12F+dAQ/xdUnBuUxkf0Y/qTC8UeWpjJhmnnk="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-beta.1_1587066310513_0.2676023486746002"},"_hasShrinkwrap":false},"3.0.0-beta.2":{"name":"@vue/compiler-core","version":"3.0.0-beta.2","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-beta.2","@babel/parser":"^7.8.6","@babel/types":"^7.8.6","estree-walker":"^0.8.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-beta.2","dist":{"shasum":"ac8f14856cd874cb22d89181e8c3bddf810b8261","integrity":"sha512-/c3ePWU9T7xwn0J/YRlxCxnxqphNVlcXisnI6aMoK3pjvQFXOMD6tfrHUtepCrQLNdKlhxNjqe3Q625Z64Z0kQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-beta.2.tgz","fileCount":10,"unpackedSize":479390,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJemcSwCRA9TVsSAnZWagAAaxgP/0Zk7uz18rVKuC3RpxCx\n0/jLMqcrBpymKj8MWDRtLoZnt+tPFX9gBv1BZIc2AxPfmD+MzvaEivKniJ4N\nkic9iddIGsDKC0+UqDAzebSITP6S7lfOY+C7mtPTfj5qN0YzZCNmLSEd8qwb\nxvWRtWZHcl3wkWM9n+JEFoo9O2H6yrnMoZdg63bI5Rc7U/J8vJWn836BOBdP\nnQ4XLS7JYc6ObIkiLlBNR4/VoUQBGdH3V44W/xZgrWIpiFKoMzBZJS/JBinj\nA3h9g/Odl2PECtOi/CMyMqF5GSckxKEsxBz/nYQOmL21GjhBX8XYsA/pv/JA\ns/vYSIziuamYe9TT1qEEd9fO38U830DNz9wXDhwmvhfDYfq6gN8xV1GBznNs\nRglQpfJtF2XVPHbnxoLMfOmuP3cVEYln6dT4nXMnkM+j6DwVxH86KGIJArMT\nCGvRo3c1C+qwMIFYQIpkQJ7TGDj4GZwvJHbx3dmiiW0g2D9iFnMKvv7Bxvgg\n7fs6uepA82D9mJX8l2lR21bw6f7bYGq7ly1VldbFfvBL9oH1AjYkuwuv+G5R\nKef7Tq6xM9ObpbI1znz0mzqVs0torrkGz23amnxp4pTfs5oXdrkqluW246H2\nl5b7I6W1Y1clPMAvrFf16ALFXST7Bv5JacsQtbRa3XDMQghJ/Y8DxGtCTqp+\nEQSj\r\n=StN3\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDlJI3rdgubWqcGW8KwcvlCHBXVaF7amXEd6H1YttpEwQIgZVhmjXY6GySyJHIrQvgPuqFQivz4pUmvME2g9aInAqo="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-beta.2_1587135664237_0.37633523553982795"},"_hasShrinkwrap":false},"3.0.0-beta.3":{"name":"@vue/compiler-core","version":"3.0.0-beta.3","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-beta.3","@babel/parser":"^7.8.6","@babel/types":"^7.8.6","estree-walker":"^0.8.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-beta.3","dist":{"shasum":"e9cbd695d6bc07e475b80c5e47ae9261475582dd","integrity":"sha512-r8AFbzQN3IuLbOEKa8y4EDYrbrBUiHh3kX3UHw3YDfBPDG2NryeAMtonden3Nvs7i3QFTCPzrWRfb/bjWqgAzQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-beta.3.tgz","fileCount":10,"unpackedSize":479390,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeng1vCRA9TVsSAnZWagAAwokQAJSJB4q3P9pMtjeE0owl\niuep9+rUZuoheFjFiu7rXdk6dvK/7UzOV8OptrlskoXtLLVlJnahz4QuzhrU\npHyCpH6fY0PlXCqq9tIyg58MxvdSggQPZDmehxAg1IBqZbtydWahCmF29EBv\nIW/taly+MDsVzRTBjRz2ZTqFMJf9plCHK6bXqDSP5D8+hTReWj3AbPehgdib\nETX2kFcnmEI/jHFCo39iaKNJkUdtMuGKin/y5bIJlB9zfLMs2p6yFekP5jDf\nauNmLMMwfoeuZd/4VmPn9q1q+8M0hkx+SOV83zaytE6f3PjgTbZthFiwATtQ\nVjxOZ2CUJ+C2sSKXzUFzQnB5K5ifxz+O6mQYkQuULP4noTpIXq/NB9Ep3HjR\ntNjGBw+f7z0ruWohMtTF6y9VZxjOI9KsMwZh4ICkQLFBhR9yBNVdzE8a1Wdv\nnQRu1fH25GnBfid5HZZ2mJKWS2EnHjH5a1IVTFgsbIfvbKaWCN8/KJVRACmF\nA1+HO7H3GWtLnYJ0S8fTWCS+HQiLCj5X9sdZZJ0PniRzNxF+92yPC9Puf6vq\npcbpMSoqGcnbIviIQv6NeO+joM4p/Zrant6xR5y3zCFSZQBP52V3H+DCuWZe\nBm5JjdKQ/+mAE/dq3pvQixLbY57EeChj6qGoq3SYco3xWasmX7cYhj3Itb+U\neRgt\r\n=FY18\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDQ5IdbJLaO99/SpUwCsnSSMy9kvRuNuWvHTE8sxSv/6AiEAkzyr9DwLjIh0dNNYnOs8piiuYio2sNIJeQhFk3QZby0="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-beta.3_1587416430813_0.6931985210531595"},"_hasShrinkwrap":false},"3.0.0-beta.4":{"name":"@vue/compiler-core","version":"3.0.0-beta.4","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-beta.4","@babel/parser":"^7.8.6","@babel/types":"^7.8.6","estree-walker":"^0.8.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-beta.4","dist":{"shasum":"25cb620f3b813c80c020bbffbf44dc1fa5cb3ad2","integrity":"sha512-9BQu2BqF2kUDWEfaE60Zm6EqBgS5fg5IwKLdk6WZ1k162jg7cfFklhopD+/7LY1TT9kIZ0PmRBAPrNl+8gwrzg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-beta.4.tgz","fileCount":10,"unpackedSize":480283,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeo0oICRA9TVsSAnZWagAAEFYP/1kOBc+kuR4oxas8rII1\nfTaBk/OfWSex2RpgzCHKhn845zR3ZZxiuAF5d0MNK1479ly4VgrfT0JWmowG\nXXlk6R0pULYpiabPV3/jfn3A4gkZh1tUYUFwZdrW0NFDPXXe3+34I+s/d8wU\nK6QWpydOma4vFrIMSlzsRIfaKPO+BeXrh1hyAPZpob+/umpjqZxRSJPw2qRJ\nfGvAr71smplYZoO37iKa7Pmc4/eHaD3UuPxuSkDWq81b7DTI3TOCUP1H2GoQ\nk2C2bE5A8+Uz147xlx17e/eIfpxwqAgWg8bqOke4Dv+tjKQuCq36MzAEjkfc\nEd1jvI77MHhU1Y2r085TSybwrcfLXO+KYi6MOT13ieqyWA7ERoW0Ncif/Nzh\n+rmbegdl+RFgR3qIuRIv/i5ywupNLx5D6bJNkxf76dFP0Slpm8duLYVDhKm8\niknZReLHEalLVVPUI53KKYUusjH2v4CHSvkQf0H0FpobevG/WaIEgJJkFooZ\nj7BF36C61MGIRF7d4vPkYynNxPyJukpxDwSpZWTYk5VCzeydZcyWA2Knd8zu\n5vNPmgoBWznwS2Hy/vCchaRTTZIMPnJB0YhJEp8KrOCJkMu6n7d9dcHyvQcv\nDptqvbwdE6ape5MRanJyzf17j0xZsQSTCgBJwI0ExekeRiYRnUza3YgcgbIQ\nBxIY\r\n=Yv72\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDbqmLFj1EodkPXI/skZSS8skYKcZpcsfIwxrgtYnj/DwIhAKWw9pgy2nzEsKbA1ZmkNUTU5/3qRk9L7Mf6O4l43MJl"}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-beta.4_1587759623880_0.1956134868006043"},"_hasShrinkwrap":false},"3.0.0-beta.5":{"name":"@vue/compiler-core","version":"3.0.0-beta.5","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-beta.5","@babel/parser":"^7.8.6","@babel/types":"^7.8.6","estree-walker":"^0.8.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-beta.5","dist":{"shasum":"5678d80876e96ae5585df1f830ffd171d4920125","integrity":"sha512-8j61FHZ+CoFy4Fdzdxz3g7sTLG/YbqvqPFC8o+IKSCAbtznQ9GHvakT7bQf/umBhSxAEKYXZQpWuLvoEY527bQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-beta.5.tgz","fileCount":10,"unpackedSize":473545,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeqzMOCRA9TVsSAnZWagAAdBcP/1WIqkELP09t3+CwFrCl\nIRhkZhXStSdM3i3PvduvBzz3lpyFmd4CQn8QsXMJi2Sux1Aj8MNPSU4UzLna\nHqCt9HgOD6j/eaxh2ycd0D1fVttLoKCsXlCgRgjHPYZdVdDLYxTgWQ3zApqH\nv7MjlyRwDT1QbDGkt040aYUQxPhCtpnGdoopJwCDM5IMx5k70l2V1B3mjsBZ\nLAZ8TiI8o0JTEJU1vCl+KxiwSUSjwKyyjCALrs9UU0e2GnBq8yA8JPiCpi1u\nrOv6Yd/4yN636GXVppSbP4/6Rh2rpJistzraObiLu+1w1gLKRScsr6S0YChB\nRRl/SJMIb+Ttd6PE0CeXxHm6UyQwDU3gxUo0LZ6bX6W971N26+EbkN1XJex0\nYpTEBvYzBcpPM5UFkzWsEZIpeNwVtiTfz85uPKQS7vrmBPrxirKf/KZYyTgG\n3tC/UCGSnkVBM9tky3OoELsavXlMndJQc0p+o3saDnugfjENH00TP0E71Vd0\n0Rdmlk/lNYVtoybYaclGaWNuGqwGZWuMvBcce4KOSR5yVVGNGEM/smGYaciY\ndCK2EPF0FuBUGXGen93mHT3f3O2FY4KCPqVXTEY8COop8rrNu7TzZbbRC8bW\n7tPBUH76jZ9u9VVJfBV+DQpLKGZ3Ag2xo5Id67iJ8LbYednh3xgqDa4EFcjt\nYVYK\r\n=HoId\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDKA2cCHCLI7NBVJ0J5aZpRkN7/690+yujFxrVa31yVXAiEA4VW2R6hH2uyhDA5HopgOjQsiM5meLTMAwW6OcKP4MSk="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-beta.5_1588278029885_0.24592845581241152"},"_hasShrinkwrap":false},"3.0.0-beta.6":{"name":"@vue/compiler-core","version":"3.0.0-beta.6","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-beta.6","@babel/parser":"^7.8.6","@babel/types":"^7.8.6","estree-walker":"^0.8.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-beta.6","dist":{"shasum":"5b6374b577db55f43910e7b5bd19d956560b8a4a","integrity":"sha512-TrUBUZ4HeQaP1SEPjFTQzIBgPSrgNKpQolR0/p2dyp8ek4HoVZ7zzsetHWG051IB4Pp60X6DIvVdiQKQqoispg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-beta.6.tgz","fileCount":10,"unpackedSize":474772,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJerKk5CRA9TVsSAnZWagAArIcP/3u8g4QffkAHUmApLsRO\nOUpTdChWltnkuTsYa1JiQmtQwT4gfY0zjttuRyAOyS1ynUtAQV4MHGvxjEkV\nb6Hi7R2TXoTBUC3h+Ef0Q0IXe2sbo7Gwdun3cHoBBbxa1bPZY1XL4Oycq7SB\n4ouSGOLxlLvD+L7IiD2Xlm82VuYQkUkBvp/tbRLqf1ZNgsG/KnE3fmug9tBI\n5VK/GhOeVCCvTfftP9MS6pU5hitUUEQ1CgVvKj7RfAzOL7BiDRbHikPYbgOp\nfPoqL1uI1rUjNkc+9qxv0XrFA/9DKM84zQJzS0yUUMB85GPcWsNMBPGTAhr/\nXUb4RmStrW6tLZb0GA0qaf7FWgtlr/YAwQDGYuOlpF5ajgbPDo26dlPVkDi/\nShYbq/fy44gSidzBxQxAdXuUWO1/i1yZb/kWO2iuPAoyM9dXd/V+oTzUP5Dl\nqyBZ+V9Mlx8pdA2R8cEM/XUPAA6bo+pYbOvuooJSWUSwskouPbsJWmtHFjbk\nnp07hFxAYrjqXgSNDnQDca2I3jlsIDWkhIOIehVmhfk6E6+P3dZRiyVPPui0\neTECelRxNpsZK/Sh9a3iHIUf04s8+JDTFOaXYwDxMIlcl3znORtI5fBPdfuJ\nJ1mSPyDx1UxMdF3N1N6L4PqXuYTc+5Qf/jVyFBvd7Z3RI0oFDbG73Rht9zzd\nTDE1\r\n=SSL2\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDDKvw/aW0+v2/YZwUitDj4yQde4aWPg9IqVuCUkx7b1gIhAJoHu7WgJZyg48HQfuaT7bW7VkJoGA7CvF2Kj7JdGowv"}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-beta.6_1588373816951_0.13827257935373183"},"_hasShrinkwrap":false},"3.0.0-beta.7":{"name":"@vue/compiler-core","version":"3.0.0-beta.7","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-beta.7","@babel/parser":"^7.8.6","@babel/types":"^7.8.6","estree-walker":"^0.8.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-beta.7","dist":{"shasum":"22767e988d941605ed21e14325e41b479f1ba97b","integrity":"sha512-JDVuGzWfNdVveNambLLU7+jR+l3yRiu8TwhOLkAoaK8iAgA4J5kW/o4LYBmZgyGegpzotT7zHg8/CfsLiCNG/w==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-beta.7.tgz","fileCount":10,"unpackedSize":474772,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJereDMCRA9TVsSAnZWagAA65AQAIStebMtPwVk1zpyjcjZ\nAi3EL7trmw+t6f2PcrDaNMRQQd2yEegXgbymD4Y5K9bn/DpdaAzn0ZqUSHsh\nTi5lH9AX+UZl0rlaqqg+jPSYMdo2YB1E5VVubBmv7Zdz9Dr8MDYhRgcRD1jq\nVYYlQtD5UhoZkYwuniOmdQDmgvsGs351hY83XlRa1ZoRxqOQIiSNPFeYyMQs\nKQB7rlMN0cuojrgCTclNJWMw1Tl+oN+ag2mBt4zVjfnWYQbE8rhnDu3saPLT\nqaV+LcZhyvhXBhQnwFhlhjpTim8Ij7pDWXFkXMaoKtAQ62J0PP4CEh2YAhEC\ngqfAeeOTLAX3IpZxron4TxdZf8TdLi/BfkpTRdVsUXNvZMrpwUO3Hr0fBbsb\nxL+ty15RDawRiIGvx3RjAwY0H8Kp5b2dQIU+j0n3evxDOM3h1Ji9H35jZmhq\npdZZFiq18/qjUQzX32ep82zo9ngS286D6KI6Dx80mrSY0emNqf/WruXjph36\nDDb6EG38XKH1/GgXn0emsJuliScm+QHXvEvbxQVyjKLVh8v06m703B48DW8q\nwAYXZ7UXghcCPOcC1fDUxiGn4yXh2S+tk9H86GQYNr7HLb8JiLIaCrBMebfS\nkidZLDa7IeR9P3z1GN8AmXI+3WwWHSMWzPcg3B72lW+QdJKUWovtMh6icKg/\nUUPI\r\n=y3D8\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCppJr88vHAwDGOg9WWwb+GyPbAPt1BGDUr+zg3wpdmmwIgQgXFeY9/87HcqtJ6AE838i+hoWgkfzSVMenVdXorcAs="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-beta.7_1588453580157_0.8157076582509586"},"_hasShrinkwrap":false},"3.0.0-beta.8":{"name":"@vue/compiler-core","version":"3.0.0-beta.8","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-beta.8","@babel/parser":"^7.8.6","@babel/types":"^7.8.6","estree-walker":"^0.8.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-beta.8","dist":{"shasum":"1f9d711f7faafdb13ece6e5cf3f61da52a8c1557","integrity":"sha512-KGUJdqHZi1Nl1t3eZkUDzkllI7JSOErpOs6fpxJI7TswFPErCQVf5vnJkvwEjUkDRp9258ZHUa8X4Fwg7FiQXg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-beta.8.tgz","fileCount":10,"unpackedSize":474772,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJesCt3CRA9TVsSAnZWagAAeU4P/joTxnsVDg+9JyfoLjxz\nOKNCh9qfMuSVMXe2gXpysKc3oVJlGpyrEyLTz9pKVlThhUA1Fyzk7M6O8llQ\nwi6tJxkQ9r941beXnGoHsd+flQxflPpCtBW8XpU4DOvZJwRfu0DiA/5niprn\nuzxz5LoRF5QZi+Ux+6t0JeVOCbPakv1v/RaKxfX1VIhh6aSZh12Gu4QsdtLB\n34YnfGnbVlQXONXJUW7ctuOdGuBWgbozDMkjWj5JUqNdl2Ou5U+KLQWwdp/g\nfpW5RwvKza/JVEXSL+Sk8tVy/NNjloK2uveKFFLKjVkSX9RSLaeMx/0kyGFj\ns5H+q/HQb1WdA+bO+gGanoy7zEmV8Zt2KNA2pcak9pWAAzr5esSMC73DH70C\ngHbNAm3FlO9aHVzmhv1ywljIp8Xf5mDqDrRS9oW0+rdSfaVU3i+SyDY6BPOc\n+oRsG9/JC+/fymyApk2zgeiNPolZ39y/pgYRmM0Tn5sfaeh5uWtb4YO+DSLu\nblehrUxqsfjhE//L42OxQtphYOGp1hMF+o8e2dcQNQHtj3iquuyolyLDekiV\nWf8zmLedy/hT8m9vTdT/t0LY9v0eXLgbvG7e72cqSenjh5CxAxvEzzfS3pEQ\nbiOV4GQ/erXl67Uxcw5Progf+ZOn9krCFg0Wq7bRT/MBnP490NiaEzr4AtWx\n9W2O\r\n=Ka9T\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFxMwibt1MkAei/IQpSaXe7CbteS2ZC0aXg+p29DwcHJAiAdqBUPTwIvG+KJa2pCyUbp0yFAk27gPmPyCgRk1+jExA=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-beta.8_1588603766715_0.7744360439020357"},"_hasShrinkwrap":false},"3.0.0-beta.9":{"name":"@vue/compiler-core","version":"3.0.0-beta.9","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-beta.9","@babel/parser":"^7.8.6","@babel/types":"^7.8.6","estree-walker":"^0.8.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-beta.9","dist":{"shasum":"4ecf5012d9fc5757337ad7bffcc9758e133c16a2","integrity":"sha512-9wSyjY4n4+XySezEt8j+fe+UCht+HyqIT98lafqcZ/c7GVNNz87zej0VNR/tO1agwSdPZjApRv/kes7lcKs88w==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-beta.9.tgz","fileCount":10,"unpackedSize":474806,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJesIXGCRA9TVsSAnZWagAARRwP/1Lru+IQeeO23qQo1qTG\nkJE1yUeTAT4XtPN7UR+rmpbMe1aDxmbXnW9+kCiqh7zPzIUTLI6Uk1aawt8i\nog26erMNW0EW8dKLp4xlw7/Cp6q+eKaoQ13+9PMxsn01aflHqnv0qmCpzLwJ\n5uImoZnO6E6Gd6Wp8NONv6IXgJkGU/pOEwZUUTdOMlmqhAeFcR7wPGIDm5sG\nC9Db4E71813Ba4yxCXSrGOJJAQftBfdO/i8i5IfocoCPvtzEwJUU5asYx6aH\nEV7xXfOy74PD+f5cCE3Y4wGJFII+JCT+2pjc8vEyRO8JxC2pEjOByV6j/prA\n7b8+m7vUgmoEW+iYUfTp5vNXp24p+bbA+vl6WCMmsThgzOFGHUgF0w+c1wRq\nFz6fiRqr8tRPNRUjqbRbc5n81TrD8+GPfBPpVTA7s6eyP1ievhwsM9b0Z5k7\nj7CINTb7tJztbjbF8js28i7u/gH171/vBFZLPsnfgRusfwpjf58U4HJOxJwd\nK3pSi7W2pzdHjdMD2JoGphJnnWVyOoeHnX++SIONWpRvHvRlTeQEkuuG+w80\nTwrEUffkOSfbc832+W1HfW4BsNod7EbMMBjrtKq4/Lr84SZ3XRq0HGc2+pLj\nroNcSxAEgeZxldqanKS+FpItD95SiwqdDr2yBycnfSo6C3sdjmtijzPRtj7Z\nPcLh\r\n=w3sQ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCID2hCSuvDUjqBCAX7wuG32AsXt2Gp430FlmEloBuTyFPAiEA3YAs69pnmrc1DOCwnSBbDteSLAM4cHRawTYUe5smF1g="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-beta.9_1588626885820_0.8357645630899857"},"_hasShrinkwrap":false},"3.0.0-beta.10":{"name":"@vue/compiler-core","version":"3.0.0-beta.10","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-beta.10","@babel/parser":"^7.8.6","@babel/types":"^7.8.6","estree-walker":"^0.8.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-beta.10","dist":{"shasum":"42b62871d36839c794fb6650c322a4c517a2c813","integrity":"sha512-GX5D9a0mjTUzZkd1PTDbETQlP0zcDb4k8wnMsYr1ZW/HXHn+PeS131FWSXz7kV4hVFiwOgxLfN+GEXseZXrxrA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-beta.10.tgz","fileCount":10,"unpackedSize":478769,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJetCdyCRA9TVsSAnZWagAAzU8P/RqmTDzVfxa/lcn6lQDf\nZ0kyR/ULxQls155tANdoHAdChPARJLFb3i2gSnGBrAAHcf40y5zsKeNztKVF\ngKPEaRfmr07VwMsw5IS+wWRnhck0WBgwCRTnvUhLzzOjVEFgO08hv8CMPxLF\nuPzl/fsYKmcoJqZbtO79dO+DkNnrSkDGhsYMAFA/pJG/XHWt+ElWh4oAbqDp\ngAQKNUFCSCeFIu/2wE9aSxO/MAWes7Ja0rmxNHmKClejOSBvXfllSLpA/lFY\nP8qJEG/INPgkxE5EytgW5CLAxrvRNnG2V1V5Ot7rjvvIDosmEN4aPQD5Gl5C\nUhxk+KWw2ItCjA4HJXW5uRtxYboNvuwDrp0uMG5JwD0IJepvIF0TLWXW4gON\nLAhZM8u0IYI/Izwzglexn7IXlB8PJ4Mt7gMXeMC3x/46o9ogYBwKj1Dxtygm\nWjqhe3iPzaBdH65q0dQvis1aw8ha7A9d5Pouu6m1x04McLYnZKMz/sLqOF+D\npPv1Sg3W0diKKq1m6xC1fiJrG06Kse4ztVHYxGRKV/vlkMFi7jerF+uSNTNk\nbMvVC3P0vfFMKe7a/SFFCAUff/Nk4gX1YdLB+mh+u69Q8OxisdQEZpEkIN0H\nOseX1OsuyinLD8/3QYPbeV0GGvEZ8SQWl4266piiSxNHg8ke1LuPk23OgACR\nzBQX\r\n=rT3l\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIE5rh7+QYXDyB8fg0SCJ25X1OPbK+PkkvbDIGGNxdoqfAiEAk0VAG6Kvdqr0GjIrTWgn35g3SulHBM44Yz9ifzIZneA="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-beta.10_1588864881748_0.7721804822837774"},"_hasShrinkwrap":false},"3.0.0-beta.11":{"name":"@vue/compiler-core","version":"3.0.0-beta.11","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-beta.11","@babel/parser":"^7.8.6","@babel/types":"^7.8.6","estree-walker":"^0.8.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-beta.11","dist":{"shasum":"9dff9c5fee727ecbd883b9ee6f66a355db439808","integrity":"sha512-B6G0fuQKFdFhKgNYPOOVndI2ja+Y4JN/P6/wclDshcA6aS+216cEuoL3zaeBU0rgfesiDRLz9PHc7fms5YS9Xg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-beta.11.tgz","fileCount":10,"unpackedSize":478769,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeuZimCRA9TVsSAnZWagAArsAP+wdgrsCl90BgvYK3r717\nf5Skt1NosqsrGC8lpyzWn6ybG1g7RoK1HErXFUbjDv4KpxuXzuzSxCXPpE1k\nBwnzI36hBAnBYyMq6bHjvzGuiuf3K0RpQz1SYKBvSZBOm42hAKr+u9vuROOF\nEkM1PgRtOS8nKj9851Rf7PwilSguzI40nJ3wrfsSAlu6u4xdInEH1tllondZ\nCANn6G9JfUaLUhvSTy5Hh+54EB2bfEkQPKjVb5T/V1SPM2ha/t760IHP0m50\njly9H/dd2m34hBpN2MiFzEvIZtjzGRDpQuVuu9RlQAUP7gZngA0DKQsQDBRE\nkr153CBTMXxzZ0VdFDpRF/OiNi4a4cbbHC6O2m3vlOygJt61fV6uJ6cHimqR\nhaf1zR76OOcFWKbbKkaH6QeGf8+m8/AMr5Ea2j/UBpOiXz6e7oOJoLF/ZO76\nfdX43C/QV2Sr2rc+6wgU80Hn7OSU2MWM4qnnI6v6gme7QNSJohI85f4kEV9N\npBU+8JILDz76orpEV1YgC1nueFsl3Aax9yHAZYk+c0BL+NwyROMIRWKUjTYj\nwAHpi/EL/RlnoFacqJk8U9jqEg1ynnGNfZpLJC7mpIHgl9E+rUeTNPhufp1j\nNfd6vKHF28e69yWOSRpfvWuC3jyd4Z8oPYHS5f+1zja06e9Wk8KlR6EB9BAn\nt3Bl\r\n=tmGe\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFdo4WWzqjAXLUJdk8BLeYyHDCcph6Xx0QEdDzo9Thg1AiAlljguEG0HyotWqN2lKdm9CCSzNmYyFNVFH+Oogq8cDw=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-beta.11_1589221541549_0.6727653061838772"},"_hasShrinkwrap":false},"3.0.0-beta.12":{"name":"@vue/compiler-core","version":"3.0.0-beta.12","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-beta.12","@babel/parser":"^7.8.6","@babel/types":"^7.8.6","estree-walker":"^0.8.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-beta.12","dist":{"shasum":"1d9bfeeedd7fb9fd8181e762b8c42568e9caf69c","integrity":"sha512-+UjGiEo/RLx7yaAUfSuhZCvXypV85CKgVERXvtL/yOLd+3Y37Z7d5Qwnsej3S4NPvhvHNUFplhU1P1LOucw0pg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-beta.12.tgz","fileCount":10,"unpackedSize":478769,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeua0KCRA9TVsSAnZWagAAk4UP/1AWTQyQqmaBMViBzPpz\nOQpkN9d4AG5Hqm/hSYiAxb2BWJNaqHnmv7+S5tvO2Vip4XPDBGMrTnpy6neT\nl742j0OA9KDHEnsekxv8fpotl5q8u/Fv0qqf48EIxdfYY4GMJcIH88d7nOjr\nxp//01mysRiy9ucAa++3cCGt4DxczAqpkgQSf44t63oe8TQMfJZi7+Fcu7DM\nmlRMZjzYs6+qBpji/qqhKM2oneP+liswfB9lhNFgXJa3C7+FfsmnnHEv7PEh\n4vIyjCxhbkVmS7hOXD7emazNLuPWrohLwbogi5ZfH/d8A29fBvt4iqAwVGrU\nzItsnpGfNpemsjKWEei1P0TKkycsbn2fE/JOHTaoM5DsIBGWcAAMf3kYP6W7\nnIeVl3ql+u8gKaV8feO5nHtNrF3jKmboKDHKiOk1TbRhLwaKJzAb61lUgvFh\nB/6NFkdHQTZKlPKM+FoEelYaS3yn7ppIcoyFXOKVHF+OXWG/tDvBEndWkRYo\n7A5UlGD19BS38ZZMUK9wZL/2cchR11UJILCEOSiQ1CrBuQCM5o5X4bWEFOuX\nPy2VDVQuYOV7WNiA5N9gIyJ0wbl4iOb3Bq1enM3t7srn7aWxmqLpjR5g3YUZ\n1yvtQH7y1Y/cgbqATLIJzLNAS4wbcitqB/Wr7j0TzvLxoQBUuXdpQJUxCdRU\nZx17\r\n=I2sp\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICa4PDPvBGFUkRtkviS2/CZvUuP6+rK101eiCUVgdtHQAiEA5AhyP6ccqhQ8cFC5ZkPaqZfbuu1mcXUwycgSuwZnnBI="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-beta.12_1589226762239_0.27746778489469737"},"_hasShrinkwrap":false},"3.0.0-beta.13":{"name":"@vue/compiler-core","version":"3.0.0-beta.13","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-beta.13","@babel/parser":"^7.8.6","@babel/types":"^7.8.6","estree-walker":"^0.8.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-beta.13","dist":{"shasum":"032e030860fa3bf83857d7098554d6b89f9fc9f2","integrity":"sha512-OK4Lq12zeCaaYiPMcG7/QaMFgznxFu7+ai1JK6/iwkKFXX5DwgDDfF+JQ6Rf+gA2hZDrgaZIrWT4tvpRHG59Kw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-beta.13.tgz","fileCount":10,"unpackedSize":480220,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJewJkuCRA9TVsSAnZWagAAkgUQAJg/e9f4ixQSgNgya2Wm\nere1+eb0eHefZZPGWvsRKLImjASBxo89vKTu9SDyDlo5TIn387MpHdW8nv53\nfnRQdz7VPqhjoIovMV1R1UHBAcFbpNPRYSB5b/e0k8yBAX+Ji2Sa8beJYkBA\nziXUSgmy3XkfT1WykYYxgk45XHhpcmyI5eXWKWQvudIHn8kugFa8x/91nHjJ\n9cqHcYzDbxcA12kuoWc4UKC8kfYL9AzMXS3Kfv6+8IxxB3f7NDxgPfzu+ZKq\n8abc1rPhxYXS7wwohZDIliCggiZYVAwmlapT6w8W45DHftDBbXjWCDUwkWgf\ndz7DFO3dW71LtCBvTalN7cHIIPbgawSybS0haKxucIBs0NcAghgU+xn2sSOy\nDBPwMhC1gQUD3jtEX96m05V+GvUOwlqihD7qKCTffyWejiKSqvzeNw/KOCW4\nJjsTMNilA6lW4wQUKJ7PRBSwxiaoORVHPoyKEeyjiy0x6TbjMmBbxdGYxK2h\njX6cDHhHrW2s6H2yQf/M/8ibYhrvqvrqRsshl5iB4jKwimGiu1GaWt83E2Sx\nzEXloUTR3APwNOUGOt7UF4ql4P+ywixMdCrUWlAbadyLEC0eNEJHX30iP2wc\nSWWZ3AVa2pQFzjNJ+JTJxzvzOjS0dyFErCpxHVRi/BZ3vFS9gBwsBEhl/lnc\nkOzm\r\n=AdhT\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDGDIa9SG6n6ogw/KegIKQECag7Aavhx7XuIq3dT6PyqQIgQwDMyDKm3BuzsvVZ0g1sT9SYfOTNvyIU763dtv4l/T0="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-beta.13_1589680430272_0.886897367843744"},"_hasShrinkwrap":false},"3.0.0-beta.14":{"name":"@vue/compiler-core","version":"3.0.0-beta.14","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-beta.14","@babel/parser":"^7.8.6","@babel/types":"^7.8.6","estree-walker":"^0.8.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-beta.14","dist":{"shasum":"69019b5c3da8335e6d83f81b37648caf120dbacd","integrity":"sha512-VZarslk2r0E8V9Iuu24LPOWuomWV8KgTp3Pmie6Ys+LnIk+G/hme9BwC2jZgmqgF+adwcfmUC5BTi/KbhRVeIw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-beta.14.tgz","fileCount":10,"unpackedSize":488818,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJewtcHCRA9TVsSAnZWagAAr/gP+QDEgBlqJmRjQXFoKOpQ\nn+H77MBh03XoLUrIDkCWSWJwrjW8vE5T1X0CegpEQwNNnQy4ISNnwEM92DX0\niSyDNa9tZnyUh/Ez50YyaB+bz0dKowd71dsccjcfk6kvqA1CW6dBuYa1o4FJ\n5mO+gs57Y+14xvm7KT4xvRXwarB8suJY12WHI5TajpWoPPFH9qE4fc737D1R\n/NlaQFFEhUqdKHBmhz/7e82Dk7ImfjWgble00TZXCAaPq5vatpjMfrM5C4IP\nniRYzihY0DUeCfzNomWbCqcUt3i4dMxA5vyyV+1Rk7HdPdrg2ydZi8Qlbafe\n9Tvm68Cwjqdg30IcyZI0vuHdRg/SsDnReSf6dAqb4tKUhgEOWf3JkvnjhxT7\nokLwx5S/MhtnmvxCFW0ANKZ1Eo8vWAYc4r+H/ZprNp1lTY5AXDxlih2f0LXt\nsr0XbkAlYqDJsJ0dBGk7Z2OptLIhCNgg2yrbXgsQ4OHaAM4WaTF6IlZrCXbt\nuOL1hey7Tcgh2AK7cQZZg1XJYrrCC6mzgUefspbZwVPdaRIxZSPCkAH2ri8+\nL02ukt+1ykYkA0raJ/vMd8IsO12sn5eKgEMXnALThErnOnT5Q/Ueju/qjZ60\n/bp96oHovyeWqpoaiCJw7dpQCcQqtjLBu56zUPJ9LQ6xVj67ZKsPet7djdqV\nSslp\r\n=8/f7\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCtOF5UNxFC8MO+yeSZCm5D0eRogcfYFE4QZiHi/M7jBwIgbr0O1KjXZpgrq1vZ6vVIzHu+eUSEu1EKvMGXKUJyfw8="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-beta.14_1589827335374_0.4466910620301465"},"_hasShrinkwrap":false},"3.0.0-beta.15":{"name":"@vue/compiler-core","version":"3.0.0-beta.15","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-beta.15","@babel/parser":"^7.8.6","@babel/types":"^7.8.6","estree-walker":"^0.8.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-beta.15","dist":{"shasum":"8710a8e3ba15ba1a8b62bd17609d26bd27fdcc45","integrity":"sha512-NLNW7tAMHl8ybRgTPTIWLsi8aXHbFngY2x95eEHAdxhNasTY5NsgmQBBH9TBAUQEn6Wo8ybmuvQoNzgcw979Zg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-beta.15.tgz","fileCount":10,"unpackedSize":492863,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe4/0HCRA9TVsSAnZWagAA4nMP/25zKJM38jfx7iqh2Tge\nnRc8cuX6wkJh25jfnvOtRveuJ+qzd340guEqXiyNePI5wlcbFbwj8+ABtw2s\nCB2/Plvf9I4mkEXMqRKUEYR5+Ps6NzdA8HTdyBkPVAdxOc/Wk3q3b5t9uP+y\ncVfhoLY5cQQNnMTdy0ECowQennFLstq0wJErShUplaxggJzhFSroaJSkKMGz\nEi/4J046nQFWdwmrPJWK04Lu/ZO8Pjx5mzbO/3tJNgtUAleULlp8ZLERyRU8\nuXQhHQH3cD9IUT3baKHYfNcXYDmgcr7Ub7y+kZ6k4GbQo74qqqYzXG9lB7Gs\nAuZvP7EE5u9ATN9PX6cfIn/RlGpCiIOSNCzJPNQdg1S0n9h/cikTW31SvUnq\na4KHGjGu+ikDFckrMWOZFeqdIVMaBRpC5OXaH+D/Gr9s0cSlpeNlPT8pVYjY\n9M3PsIt5Hw1obIYeMMZ5lCvb3KiOGwTpQjqwLACwRVkR+p8ogGeSSggcTZqK\nSBjZbX0Fx0lhLzwFz5NWL+c3eX1Ab7tvDRBG3UtAj1u+D3EcWfC7mv7bnbxm\n1bY3OGdjlpOpj0QuSpVgX4NsXX6Y2kByQrKLug4GzN0yfHjFqyDcmIcfCncg\nEosRAmzi32+46z/RinVvXP3tKq0pbCi9o7FH63sZgPDfNVkHWzUgUePu8Jfq\nN3gK\r\n=Oj31\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCyMgOErtg74tTOB0vG6TxTd64h9pANxjEuYp69PifqawIgU7dEF/srk3uqqsU2HrTwPTxhGkZn+w4l8UrKAUr1GBo="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-beta.15_1591999750834_0.7111666379174757"},"_hasShrinkwrap":false},"3.0.0-beta.16":{"name":"@vue/compiler-core","version":"3.0.0-beta.16","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-beta.16","@babel/parser":"^7.8.6","@babel/types":"^7.8.6","estree-walker":"^0.8.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-beta.16","dist":{"shasum":"3021064a1290869dcf44c6a9ae8a2fc537ad05d6","integrity":"sha512-VheMwTReuptHLWGNiFFRXYk8bvESwxWB/X/Si8Gz3XitxR/d8bNqEdGBE1HchXggb2oFrtz/Qd8aNeLDk4MUcA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-beta.16.tgz","fileCount":10,"unpackedSize":494566,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe+myOCRA9TVsSAnZWagAAc20P/3RbfrRfaGfsnNVZ56J3\nMU2CzXM6s2FNtxsy9qoUcH1O8ACrQ2ouPZsFQYGzGauBlWlBmFDmkv63et6R\npNHZAN57iAU2C1ewxpeeOVwxllcSFO11gKb2Xw29chxaFnVlgMPJIAR1dcZs\nI6RvAXzloS9dcaknYLMztgVI0pIz0/Jq2lX0Usk/AdiLzz6d5IfgGYv/cUz5\naIgCJRmjEIigwNpoE6OvqSgsa5FnquKll+rqW08ZPJ1Pz8mBxWi5rYIfmOBT\nGpJqul7o0S3q6D8YAyug0SN72EwiErNJIj8FSZaRWxeZkLnioI25+VrF2QMk\nuKaP/T1FkIq4XA6lHX5zDIw9jw7KoocEZQRjByI603eEO9FZg2GZpx7KuBCg\noMt5j0XqBascKtecwkZwWl4uGX4D5n6tdZht6BAUrNCui4NfE/XfHPFGrJax\nkqMQ62Dkfqvud0Nnw/BHWCSNLotrM6xyjlNQejz+f4m0gUqF4Ewrzb0ynyA8\nSYIvQvgdvlOE/k95ARib2NzI0HNvzLunAmGJL7YMPUH3tXOMMHcT+6tpI1vc\nvz1DQO6Dc6KChbH4wQtlzyg9uiFb/iqC1YxSV9w1JkhK2dMQrchmQhYz0DLB\nr7Qm9FZqTlyu19EqBVUlEQ6/6bBnYyd06Wch+7ZnXiQ7CaGWSMEF33bDIhgP\nNk5M\r\n=GG9x\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAYQwfrdRxcK85MMMQNjpY2SLHLsuVqkQrdAsZ/VwHqtAiEAswPBFe1mhyAjWpsHwOzsMLoalQIogLEItOlePKj9Aoc="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-beta.16_1593470094228_0.736294654217531"},"_hasShrinkwrap":false},"3.0.0-beta.17":{"name":"@vue/compiler-core","version":"3.0.0-beta.17","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-beta.17","@babel/parser":"^7.8.6","@babel/types":"^7.8.6","estree-walker":"^0.8.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-beta.17","dist":{"shasum":"92d75f5ae7a03c51694f439dc96939bde9a7074e","integrity":"sha512-UHv7YFUremfSXf3CAeEoRZOX+n26IZQxFRwREw55spoMRjjpNIH+sSLQz3pwgTnClm90GlzRMzOFYTOQrzAnfQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-beta.17.tgz","fileCount":10,"unpackedSize":494566,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe+2OQCRA9TVsSAnZWagAAkkgP/1fe9hXzTRvwC5NNYrIM\nj8YzZU/lnJ8nhOrgWgS0dsEWGwTg6MMVw7oLAx6h5ZUKePP8BpDXYbfsL8ns\nrQmlwkZ5N0iHZdZ7Xfw+XJDh1ihBZ2PAD17sBNF/sIhMS4GMG7/9p5KX4Trv\nQeTJIpVISgTLad6V7x2BPzPKUx81R8zcetVNeLLiz2gfTQMCrTNU5vXn3o3z\nJIMgspJpZJ4/EeFAnVwNVtBOgw+0wNnmDnch63d7ptjWt7jSkQbIox960NKw\nJNXsj0Pw7hUtZyOtOJIFj1MlwgWIyHZdjohSnqp8a3HoXkctgpR1/Hkdmh5D\n90tr/3kuZPQGa4JrCzpog5/gKH9CtFoJgfafOGJkQjs7SUdbBNGz56cO3NH/\nMbUZ1oU53+SI5W7PFAPoTRNbowjMVBlWlC2YZcxZxKdqQP0DIdpNCNqONsDx\nOal+WEF1yPvY6myxXDhEtyDtOJNXFHwVrFCCUgQjG2QyWMYY9EvKcS9hHE03\nkOOQezmmEPB4N1Yg5++IBp+jtZvodTedMOEGLiUx5NEj95c2BnjyNp1jrI1f\ntixbIq1Xh1xpCGvleROtFR1SlvWcgS/S8+clmCGuLzpyLijyfsI9ES+I6Jj0\njzm5yMVJRhOKN7CjQ4EJ5y/GOoEqOn3wi+O2S8tl7K5EuMR5lyZ8C3H86vN+\nED5b\r\n=JdKf\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCR59mF1hT3YY61HaBA5UnncpOwZEosjRK/aQ82smtIxgIhANgVlgXY6UGGBJlVRS1gSL8JecqGI3ndbq971bfYgmVw"}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-beta.17_1593533327822_0.26720958316906906"},"_hasShrinkwrap":false},"3.0.0-beta.18":{"name":"@vue/compiler-core","version":"3.0.0-beta.18","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-beta.18","@babel/parser":"^7.8.6","@babel/types":"^7.8.6","estree-walker":"^0.8.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-beta.18","dist":{"shasum":"52cf3e4f1f627230e9affb9da22a408a624e7e50","integrity":"sha512-3JSSCs11lYuNdfyT5DVB06OeWlT/aAK8JKHLmG8OsXkT0flVSc19mtnqi+EaFhW3rT63qT0fjJfTfU0Wn1PN9Q==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-beta.18.tgz","fileCount":10,"unpackedSize":494566,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe/TMWCRA9TVsSAnZWagAAGkgP/00CJJAZrXWQSxK4kPIq\nNgsCtx2JeD+AKyDnqQgQVnvD5nF+R5kwCQcdoYncbhi4dpzApuoNN2ay0DV1\njZcSOu4iSeG4e13dkM3nKHZAH3emGPZxAI0LQoAk2MQnz5zTZFVVBu5ee6r0\nztDcM91javG/Ro6v4MH6VnkhNi1yDo6639OjarYtaJ3F+iVTEpd03Ri4OgFl\nkm2r5NM+wAJlnSYz7QbzXzcoMTlBbZE4boyR+2ObCgBWfXt6igUSnBhB1rdk\n98HUmtLVzSCIZyBaUXvv+PSNGXs651ez2WR2yw/Vx0HGOk//1EEfEwlpDunM\nt9ENcrkaddcGfHNiGcbQEQqDkAC1piE1SnorvTmRGo4VK1svuDg+zed/aHzc\n8eAWUfFnvOa5s+Ra5FxwaYbTYevzVufKOUYEyuuThoyAqvOvbn/pMF1HsAru\no/ZCgARELHrGi4ne6i/VRyegjD8x8UoCKUNAJRsH+PBqjZXFrVFngL+siSdl\nL/wCowAfRV8k49qYtFjaNAdVuY57wnh0p6T4mM8PC0bQhsAutPck8x3ECIgY\nsH1jiZPtdU5P4jpqhCM429MHs9k5RdGW16+U4M7VvFRrQxMU8nKXEEf6lL1U\nn3ZNxLT7yCs3trFRVhUgUSaZjGnlUKMr2Z5o+00+C0h1QokR8k1eLm6+y69i\nqv2w\r\n=QyHh\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIA5yxwQofezUEnnKQHuEbM/EgH57VWJmLuFdPsO27iUdAiA9xaceYPOZSrQnBIu7tGthouhey8+xIyXPA81XBkWzXw=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-beta.18_1593651989690_0.8266582819765476"},"_hasShrinkwrap":false},"3.0.0-beta.19":{"name":"@vue/compiler-core","version":"3.0.0-beta.19","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-beta.19","@babel/parser":"^7.8.6","@babel/types":"^7.8.6","estree-walker":"^0.8.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-beta.19","dist":{"shasum":"54dc70e29048e95876b349bd628c79fe57a4e2cf","integrity":"sha512-GWOJGDn3Ci/dJfiIkE1lBNXYrWhCe+j8tcTGVctriBF0d7ciWZ1G4r65SidYgwrvv9QpbroR5YVSv2XnOEwqHQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-beta.19.tgz","fileCount":10,"unpackedSize":494572,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfBID3CRA9TVsSAnZWagAA0hEP/iQoz2a6ak+fHGgE7X0M\nKq/YXvbFy9tIiS1Mly+0ZpB8K4iFXRUz0ESlM50Kh+uFskguN9VFkYQIMTQW\nXoNj+/2MLlfLTUNyC5+OQZKDJTZt29EO7V3Dx+o0XJ2weKo2D7HBusuVYFmw\nWX0eNAnOOS2uF0oNw5ydURxuCsngZfFnUZ9t941JQx1W003UwsglGX2WfVnh\nQ3WCfxb2eOLShfFXyLOnSAMjGtkMgsynrp1/EpcfebVjlC83JJh41Fg86pR0\nRaoSFuSXCYOHvbUCWB6BkFODkKvInIWVi08px1v/rDYdJjyoRzk3LgSKzQGq\ng8oRlXgkxa8bYdnLCYkfUDIi68zaEgPdx6yHXXci4qQue4zoby5eqnfgQxA9\nWFFGvhvtxDlnvXRnpIrk387eTOCzz90hKiR53ZKKRyxn066KdjlxqxRUiAGt\nmIRqBlydqZNkGLgpFCU5m5eoTRAaCAzacPgUwj1VvyBxaNNzOiSZD2d0oAuD\nuS3OobZylDHmyCecnw+wUw81JYTsErPiCvmJtiAaxKZsPrNm7BDEsVM2ALdV\nNxM0xy6NJNDYiAlKvOeew7QEiXhTo6Q0hhMuAUBnVAc4xxx4s5SCnPXrnu1w\n6eQmxTACr9cqGdlNigRqQVTsPELWjVp/HrRNO5sAL3V1E5e85MPEA7vP52Oi\n589x\r\n=5c76\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCm47RIIj0ReUaNiq1ICLY+kVfDiL+7GxrCkQKyEi3qKgIhAP2BW32L5dGXdh5nKZmmhkThq+VZtBuV1DWrxkN8AhjH"}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-beta.19_1594130679096_0.44967601679549785"},"_hasShrinkwrap":false},"3.0.0-beta.20":{"name":"@vue/compiler-core","version":"3.0.0-beta.20","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-beta.20","@babel/parser":"^7.8.6","@babel/types":"^7.8.6","estree-walker":"^0.8.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-beta.20","dist":{"shasum":"66c085e23d5420088074bec73291fbd8151caff3","integrity":"sha512-ZMMMD4GMZXrwJFBzdn3v+VcrrGofqrP7gfJ5ie/3p2sIEVAfsI0qwIb/DCezWt/Cm3viMJiTpv4SINPGK4xM8Q==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-beta.20.tgz","fileCount":10,"unpackedSize":495912,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfBfgtCRA9TVsSAnZWagAA+wEP/iCl39CCiOWohJUv8F9G\nqCSuANTon+a2qUpzX4uWeHZFRVwOFKoTCGLj6GWbo7Sf89Lp7RagClCHwqep\nYGv0fwJ2OxfijCPnKGFnlBl1nDZtZ9hgEDw7iddakKO5WHq359zw+/3fBC3Y\nWIG+zLDwRxB/rWVc6ONPWN5oooX8aubEybN02i/M47xJl2oDdICHcZQsP1cZ\nPV0oqPnD1p825lnZvl45aUrpz9/c/zCeCWjcxvH8rT64wUC449wkykm8idlU\nFS0Cn52PYe+wLTgWZM9rc5MUCDG1Q3REm/9R16g9xk+M4dbnc1qIlww6w3aa\nB+50vy6pcg/sBbhdDOKw0GCVCaHr1FHRwbattqMmZUy/1ceTw6mv3QwXrgxB\nzA42yPxmzogN9P373lmIJSSnrt16xI+UOraBkiMGB9S+Qqw9i/SyL4yjeNll\nhyLTJVXyosnN2B3k832EI4dZgY6ngCz5JYoSgZgZ0I2DRrPGzH4atFEGgfvQ\nKKZ7CbUv+G2YlW8ztrbXS0AeKgke7ELagI2t5cA9KA8QD2V8p2+8gk2rCW0O\ncBk2YBAZzaCD5B1YiukC8Xr3NHd0/HOCo8jFGru4NF/GNJeam2kFhBeDUOXf\nmJcpjBDOmO1GfS/EGNAdsszM/Jp2XA/iq2PW7cSb84j6YnRxDEomVT/RI06W\n5b7D\r\n=Ek3c\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIH9yifjtkWacaqWZ+5EeWqlP36QweByzsyJv8MRt3B0sAiEA+6VdypM4N+TemhPXvX5FX5vTEb5G5kQw8k/Fv2w2ckY="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-beta.20_1594226733066_0.85246663025107"},"_hasShrinkwrap":false},"3.0.0-beta.21":{"name":"@vue/compiler-core","version":"3.0.0-beta.21","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-beta.21","@babel/parser":"^7.10.4","@babel/types":"^7.10.4","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-beta.21","dist":{"shasum":"818b1a27d640663de01fef3a12ba53cd90cbd946","integrity":"sha512-+V3KymdckkMmcVFOY+JKUM4q/4WteJndjQgFtQztboKCeMc4ZGdiOmkwS1ZMtqfGhoE7wf7BPQRJ47bZGneS/g==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-beta.21.tgz","fileCount":10,"unpackedSize":498328,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfDiEUCRA9TVsSAnZWagAAnogQAJtQIaW0Ukwcw3go0LnV\nuSkSTrAfOBD5wXgYlaU35kUfbgBzywhODtNPlfKpbgPy3WIPSdNZBIGDazoo\ngSvTSUfAqB26Q3CsJ3dtiXtBb/guutdDN5okyBuGHjQVpBVQX+pprO5VwlJe\n3s43CunkC7mbUJt6meES8fDUnL9tb5gEVP7Qxg10yIuT65kRxcvuhwKXgXxK\nSXqhZv3jiS8ruEVL1krhxBqLiiOWV5bumFITgpB3iTrGf4OBaJcaHly+86oe\nQlnO2dc12VftTpKeWb2ZVb5aIxYMKIGsHl2h47VeFGEtJW+q3vzQS0arg9AU\npTufyiSGk6PhTJpDZZMaojbg3sl7VKn1lDHWz9FQgC8GxJ/sCthPuVdp1IdG\nonsoiJAMx5w281txQgZE5DM0KkMk7Yep5DCHEmV633J0dX0YxE2lt3Wmsco2\nlxqOU519FwvsZyi3b4sWZ7kYbWbbstBXPNztLLSzrWoRPEbSaatmIeecrQoo\nkFj42mAVKYE5jAXJ0VYva74UM4fdnTlHZDCsMDvLrYdxTMGfxApk43pdqlEm\nPZpwfzVzLOsTdcsG+QAxZ5TI3p2RNkmnQotl4FMdkErQxIBkOKj7iUOni2ja\n0YzwSwwfIlYzwM900B4tv3xp+5YSy2vKqshn6S6PR+xXNZF1Zh+AW4A3K1Tb\ne2vE\r\n=mf4c\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC+XSII0NGWR3Of1jzh8sLyd3NgjJ7KCNZUZWVoA/CLYwIgLEzUK+kIjoctBb17jCx3AL085C4vtAXptuT9A51NJKc="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-beta.21_1594761492283_0.998316380935037"},"_hasShrinkwrap":false},"3.0.0-beta.22":{"name":"@vue/compiler-core","version":"3.0.0-beta.22","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-beta.22","@babel/parser":"^7.10.4","@babel/types":"^7.10.4","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-beta.22","dist":{"shasum":"d49acac2125d5e54fcf6958402ad449e2587c540","integrity":"sha512-i/e965dQbJ4EGkX53a/aBO//IjgG5Rl9LOoRh91ZmPxi44WSG+tu+mvq+y7lRl5HoxkjGWo8GVErFYSRQnSLPA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-beta.22.tgz","fileCount":10,"unpackedSize":499885,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfDzJICRA9TVsSAnZWagAAXjIP/2pPJJK/lXcmrmoUYKuH\nVFe0a1qgoL6MGDvAvy7SFde5661FDdaz0QOHWgNYtmeRO7N96IbgB592yF/u\ndQbPb88t9jK2CapX9+Im2dqxAnKUnXQv2ZVEVgpculEpDTtQGtfhsuvKONuW\nDIDsDU0m6GZqSEXkizBU+sm1JMfcu98A5QF+EXMYvXw13Pd7ieIK48vTw6Ws\nlIrHY/4EWm/ayWPDUjNjC6x6mmCKf9avBdmop4cjq620+SxaI505k/xmR6Zz\nWFXKQZZ+pDMvSJlQjSKHLR5DNV5bwNEdvamob5oGXHvObOioN6X1P5wGHZN9\nFYEJouZR9vPRxbuqQT5SPMEsXjnJPiNymt9chuAsyh6nGgdBmjVGqJd0JPuS\nSKK9Y3YkqLYib3LQkdFMk55cghSh7bhkHvvaR8wf8RfM/3dQif4UY+Ma+o/4\nK1qKXrPfQYxeGPTRc5dES66S2ZbZSHwvY+PCWfrOSm0SRL5SyG3Minwohv5F\nkrJVHPgfsvtxPIOb8X4doFsh2O0DrQXUI8IEUtaAsHJ+4ndUStsr2sPXXazd\nO5Cpl9E0XbeY6rbjTC7F9uT1wZAQ8NUddBKS3m2JPRhVKMacaUX99vWe8E7v\nzJNWPZL7VFTiq1FCn8qKn/Y1Az6wzFql8OAtNoTXSVsKDWO0Xnz2IROET631\ngOAM\r\n=aZ2I\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC/QxbRdJqWiB8CTad0TOIico8/a4izO5B/EMT7f0u69AIhAOyslmgd5yyfzfTHs+I/rlB+XFpoFdq0uKXd2/2cTPog"}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-beta.22_1594831431587_0.29165253867823715"},"_hasShrinkwrap":false},"3.0.0-beta.23":{"name":"@vue/compiler-core","version":"3.0.0-beta.23","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-beta.23","@babel/parser":"^7.10.4","@babel/types":"^7.10.4","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-beta.23","dist":{"shasum":"2956bff7c144d8f08f6fbc5aa9cb081262f0ab28","integrity":"sha512-ozpDWK7rpj1KWQRQIFz04P2AthDf+CCgv08aD2UA/BrrVlo42qskw/qDluFcq0t/dIPMgiN1PtUmGsgHyMQSZg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-beta.23.tgz","fileCount":10,"unpackedSize":501628,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfEIT8CRA9TVsSAnZWagAAAicQAI5aBUQz/ASmJHq/HUXs\n87qsqdgqNZHuf2jKK1R6gGAtBrdis0p6Khempl1M6xR0iPOiLTDUJdJIWa4B\nm66I2inzx5/1ifTC51cgjs4xREx6zOFeSJUanC+09g4hqIegOU6LMAKTkSNo\nkuta95Bb27V2+AGfQhU6UeoO+15C+Otumy0XA22P2OGxBsdWEWGdIWS6M6Lr\nJNbkuc1QrDxqFCsf7o/7KdMS6fc0lmgvhHUf2ty+0NtTzr8F37t1DsAKeXuf\ngcqc9ni3nRnvskcZEj+ScRFbhzk2UZ+IeJpf5jFah2nViWwumh46jQJPVY2l\nGlLOa35ryaFtWCOV3wpghV2RnCPVOuZhFHg89hw/iDbkshXpwPYvgaZ0g2Ya\n9tdy0J8SakEi00Y7DhzE/yK0HOqoJ8SxN0CwQo7IW+pOjbKI8xA/mlbO+SD4\n8Dy3ODWpUDQ5ss0ksRw9NsCGq9oloLEHEUYT14TJBnSeVsDJsPos3jeUFr7j\nsc9YseXmPPwU3nMKVWWWP1XGwHQjk/EkH8/F6fBBgwymK1CWyHDEeSpGRWS5\nMyE3SaLZTiZLFnQgWPLWubN3Us9Bqbjx4q8TgawJg+OPuYhU/17oKOj9EVhL\nVx9N69RdRmEUp/NYQfnhcYRgxMhB5JVquaY6lbUBExyUUyCDBNlm7jp3MaCT\nVf66\r\n=1WCY\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCvhUqGnKXm/xBrh/IrTPIrGIZxKbge0T9cuE62YeGuXwIhALmadL03hyHkA0GDBJE3LJ13oJgQYJBl/mAMBG7eU2X+"}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-beta.23_1594918140023_0.937442425522754"},"_hasShrinkwrap":false},"3.0.0-beta.24":{"name":"@vue/compiler-core","version":"3.0.0-beta.24","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-beta.24","@babel/parser":"^7.10.4","@babel/types":"^7.10.4","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-beta.24","dist":{"shasum":"7b62a24a9b6bb0d98c1e22149ba4cc67bd676d6a","integrity":"sha512-hBPMU/8NtxkrL2utPzCdsB3Jebe1gUR0ijl5nUyE0iGejt+ONq9pBX68dktFzcrJxbf/n41wcN1tI2iFC3osvA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-beta.24.tgz","fileCount":10,"unpackedSize":501628,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfEJO8CRA9TVsSAnZWagAAGs0QAJujuQ2u+wZak7/ik+QF\nqlOe49xDT5fp1Wc9ewfwcfPDWLrDK9tlwLALl3aOuluS15Wv8g/KpgBWGkho\nyiDByfH0iRVH0g/5m8dDTb9pdn61DkAX+lLI0r+a3tLmRrjQbTeW1q9OGHA8\nQsidS+IfB1aOdh1UfwDM6Azs0SzYn96GMutWJBgqQx1OwDMysvNRCndG+KI5\ni8uyW06DgrNTAInEaqivI4g4ezsJGtA0JEiDIQhtSJrlBh4nHhlXiH/wCrCY\n9lX3zKKH/uKVk72uu1uW7JsmiAx2Z/rCqq0nKKekkwjDkvsGhMUaW12nZWF4\nwOZ00FdlHw9yYbVvfmPLIGQllnSCWSpyBPRRSDKDaXBH7ZgOiYhXc/YhlYWb\nDfyWCwmMRX9+sZPewK2eTzH2hI0u0egfMeHeNjztJElVgn5m2RdchcLI+an6\nCruFG+5umNOMQ/ZkCFBF0BwbeoyNKRdvTT/1yDgcvJEUexC1+mV00KsbfqV3\nJX/H3gnciL4fZ4xHByYHJl2cCDkV+fQu2i9BQkyKx2+4P/e8g1wzeaqgsXKL\nbz6gyke9k+xja5BnxCuy+w6MvjtHef/YkXHXLq6vcGI9AAmqSrlN7vOCt1pX\nZsHLinYxtY1gmXpECoU+mxvur3xpckbk3kUBJf0l+sscpAHUOlOPIHTrdyRI\noE5J\r\n=7DxM\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDv1eVArOAVrTgHYBlSMccG1aF5PwrY7A8W1HHKAC7jZAiAX7gi6Aojg1UEgx9SSu+u1djObIwh6XErmLb6yFpKAfw=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-beta.24_1594921916443_0.4468570645638217"},"_hasShrinkwrap":false},"3.0.0-rc.1":{"name":"@vue/compiler-core","version":"3.0.0-rc.1","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-rc.1","@babel/parser":"^7.10.4","@babel/types":"^7.10.4","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-rc.1","dist":{"shasum":"66459f085b07408ddff0868199e2ceb7ddf8845a","integrity":"sha512-5GcHJuoLnji0fxaCIntCZOmkbEemcIbknh/OFh2yYWbQ+Yzv5HwI7OA8Z1uLs7nKEKkVpbdFDtF68Zkf/BXnfw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-rc.1.tgz","fileCount":10,"unpackedSize":501636,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfEfxNCRA9TVsSAnZWagAArGEP/j9nDagpm2LtBw9IaDZR\n4K2FUxIuPA8Xr9aBuSvo1cVreeXXCnbKvcXn9NGHLULRC6Q5QXWngBKBWVzu\nahF3F5ZuVj8LK4EsgJaAJ/F51piuiQCsu0X32doToP5aMBbjli33Sp+n7gyq\nRo6L+FLL24Cu61pwbOCyMVKCi3fhP+qenDPY8u4kS1jFv1ojTQTnFK05t+Rb\nOJfsCg/scL4hU/bkUsog/B/e/sPbERtaeWcaqbCtJOS80UCwWqOuxgK9cqlX\nSHjuEnYZCcOq8YpjxyLp0ZncSXwmPqWtIazk4Yt8KmSXcChKfh/G+TpUpc5A\npH3Q1yO39jisd5/0fw7wzgtpu9AKPaJcMHLRcsarnM6mWlPSStZmsIAKnSpJ\n0ye8MHeF0iw0wNYMmkr2H4eBzo3I39vEB24xM+FeIBPl3+jEOhamJm+mubez\nImD1o3AjMaP7T0K95Bo2kKHZ2Lm40vMFHsYCWMHTGP1f52xbL/P3n3pq5Z0f\nxKc9z/bOXLZ56EtL9RqymeVDO6dD5ydh16JRRXlbmRZd/KgBjpm4DKf2kU+1\nE8cecl/6FpGCWOnRc/OxyJdSzIvaTNF3hwfcPsqbLEQmbJaEfvBGzNDFC/ot\nQqdopIVNarsHY36lDubI6FIxGua8nh86BaylVSfQiUf8og65ec/HQhXhpgdx\nb6RO\r\n=5N3R\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCV8icVvPuT5L+YwwtKKfLk9tsmnk2+IJIFeGKwuMtmfAIhALq5DTBqHnwl7MOlOoYuNYnEnUfdPYeZ6tAIztN3nwkK"}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-rc.1_1595014221050_0.35254749835442967"},"_hasShrinkwrap":false},"3.0.0-rc.2":{"name":"@vue/compiler-core","version":"3.0.0-rc.2","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-rc.2","@babel/parser":"^7.10.4","@babel/types":"^7.10.4","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-rc.2","dist":{"shasum":"6005b793ac12d2d053590871faa04a26997ba2eb","integrity":"sha512-FPPNTd20Y8U5RWyXHWOC22gpSnaFz8V2zDq+f1AQ6xTTRD09qFw7wJ8T50mnVgeXgYbACMnD+RXOAAwYfB6ijQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-rc.2.tgz","fileCount":10,"unpackedSize":501813,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfFJZ/CRA9TVsSAnZWagAAgycP/1u1YSU8z0Iv0xrQVNWm\nID18yCuicXmIra4pdsOXEb+WiCSfGP/uSIBSAAYzCsO0NkF67uS0xWvVoTlx\nf+3kY6aCr83ix8FhNO/x6CZ0M6yckR1RQNome4XH/tZsdRNDkJRY0NdBuIZu\ngB7ziKgdb/ND8UliJf2/ZBjLprKxWIpsp5z5bnntwF3mTZSzHn3BNg+Yrn3z\nPsEOEj77EtRh2MuoQ4bT2p3lOaC+yMMGe9CTteoji0pF9kKtIzrTI52ypRfu\nu4usOmVg8OHinUUGk/HZXvdAR2Y4fWR8uWJTkoXoRaJKh4jh/RuMxfcLELbp\nmjcn8xwjh6zdWxkgUPzL9yhb1wTlelejcrEnyQZAQ4hPtFiOh6hxnnj+TmrS\nq/cDwY8q9Qp5sCg6HjrZjP6b+LCBaenPv6InRWecMOZylwrWJ573IbazXTl+\n8ns0X1KchDIN2tuaZfTESAK5BeXx9vZvRVb51U6Vfn/SdaX20IIfs4MgeeQq\nufyuc0VNhGwgf3HbKC/UPh4s2gBQyDcLX2ZF25pEREhj12G7KSJSD7AZt9Ak\nG3GXU2HqlE9BizNiS8ClMBm48sbpSbMC7H2rCm9Ew8eeW8fFWdzD0w6HGg9+\nwakpkSIw7e71q39tZMAmCOwIkdo4cPiAjy8hVPHEZ8Najtmp/DaT83Qf1tOZ\nNan/\r\n=TNoD\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIF0BKHYRxcnBwWJOQJDgtcaE9ce+cPJYRMm9jF+L7qYdAiEA6ntT6eDF64ZLZCxXy7JkljyVeG/Tp8Q6P4q/5rqY9hg="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-rc.2_1595184766806_0.11211201121523384"},"_hasShrinkwrap":false},"3.0.0-rc.3":{"name":"@vue/compiler-core","version":"3.0.0-rc.3","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-rc.3","@babel/parser":"^7.10.4","estree-walker":"^2.0.1","source-map":"^0.6.1"},"devDependencies":{"@babel/types":"^7.10.4"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-rc.3","dist":{"shasum":"42eae19b581620971609a0728e61e2a0067d109a","integrity":"sha512-bxFz8kY9Vw2LF+cNh/PQxlF/YQiuNNVKca08HD9FMfeKpNY11YpJhk0aKPUDzsJj5Ub7o9DECp/TAATroAjFug==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-rc.3.tgz","fileCount":10,"unpackedSize":505711,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfF0GiCRA9TVsSAnZWagAAGw4P/RIB/y/Pa+CFeIwQ6n2Q\nrf6HeTtzsPRb/xB0bCKQNeqEGtvwYY2HzsRbNUp9HRGd97/QRl3n3S6zyQQh\n9INRmdGTgjW3BQt8bI7sSTX2O2qmpYwCbq7LHvmwgVCUPh8gUIA44YRGmQCt\nWqwNetOLg5kkoOt+SgDid5wDIILwqZKsdVsj0TbDvDtKkL+9cBbY5+e37BZS\ntGrq+1cUwJpJdxFeCDfuP6zm/pAp/rYBr2h2U5Ih6GSPQmUt6j+HxVvaxsFf\nCuN99tf6D/xwI9ydNWS8tvywNWSD/vZFrIWbKhVjSwh3izlgrV/RCjiLcjnb\npM/PO8UtheiDOZ6LHnchQpDeuqFdKaPuNRWK779SvrW15Q7prnnkakWK/HqP\nRsImBWgtO0IFsJvWUTaiS4ePmU0D1V6IyrYC123mXt0UUxoPl2LbLU4YmdV+\nYbnIlkT5FKAlfiY1rAOWYD1Rg4kJe4c9vODhsEh/YrmP2y2cOai1RzguBgoK\nhII3FxFdAl8Sg4t12p3bCuxEJ65dyE1i0tdc4SAFAQx/aorT55Yt0vV8r7IA\neQrZfBRePWGBOPbwVWbC8iseNSLOc2m7W6MUkOB84aUzmb7BzTGVd/Mi8eIO\nCXzKvuvgp3CdwA+4LE3fS4RMFZJxBAtiFX1PKeNcNvhhp5hRhaZ9dlNx5fam\nawNl\r\n=plt4\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBU3yfYabv6dZgba2+r2luTExCbdFZwyf2ltZy62YL0MAiEAxe3r3TxMSN0PbGejFIiH6nJeYk1PLFILxBI3X1ypKsk="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-rc.3_1595359650518_0.04064033268104672"},"_hasShrinkwrap":false},"3.0.0-rc.4":{"name":"@vue/compiler-core","version":"3.0.0-rc.4","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-rc.4","@babel/parser":"^7.10.4","@babel/types":"^7.10.4","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-rc.4","dist":{"shasum":"2fe7c9e010d6c66f1f191c8a6fbd4e9c4d87d126","integrity":"sha512-0SZKcUTBYI+v9JN9cCjeJvu/jglw7N+l0g3KspjAHLsA8mXZn5XM2j8v22uR3ChoJmxTFjAyuQfFYcomJpqXRw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-rc.4.tgz","fileCount":10,"unpackedSize":505684,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfF0TBCRA9TVsSAnZWagAAq5oP/3rk+NtnqEJGmzuOIiaN\nn9Z6D6AZDMvEJIrBpLSU6burDBPa2LdpOeRMDPea7XLtv7Ju7ZrafW02jAjn\nhz8grYYN1t0zy7phstzgVfUI6zYQDGkpL7US0b38VL7jIUenWV4LKGcf4frn\nhoz2paCiSyGirRKrM7jObLy/SrG21pnie2nZdtxsMXHESWxlYgg4ELO1qI4l\nOOqrsKjAGhw13rZUrmk50z6fGxIuHIv6NrCsbHTyStXlCuAXQ6tr2RDH12a2\nYANJ2Q7H6nGML+B6jiv8U8CaB5Dw0fTIfFJ9uohnFDEJaTMYn/qDzrSUVEDu\nTvoFHtMNr5pAAtxoobewnaggCAGx1PBp/aENu76CyuzD/So+MX5PRlZlH+71\n65OPT3rFXn3IaUMswXriMB4hWvikn1PAgzGW/7f3t+MFHvbKTDNh4rypAhTJ\n+u5YCmz5p9kEr5vOXMDNwsF455crS9yHLFvBdw5jvUKNfge4fVwpcINuRcgR\n/M/czCSWbCYTqgGJYKqfnJYi4TqaN2RKgjrzZbHkupCpopLzfUwcTg0iXTaR\nMeTSJjOOk5cHTdL1aeU9YEBIDQJTAYHwstJvfwGRD+KVqpYSbX5pKApj42yx\nurvECESNjPaGCjA4s3kHmR4f+fjdMY7+cTXoj0a/eqhb87Dxeyj3CStOovbN\nUPFe\r\n=p7T9\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDOVkAaG73w4dnpt556QAmXmpKnqIvDjlTlDYYscpg5BAIhALqAEoPWpYnmZNoIBusOFJQLg7s4dKsThxdHTqAcJYo3"}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-rc.4_1595360449129_0.14054594522478014"},"_hasShrinkwrap":false},"3.0.0-rc.5":{"name":"@vue/compiler-core","version":"3.0.0-rc.5","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-rc.5","@babel/parser":"^7.10.4","@babel/types":"^7.10.4","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-rc.5","dist":{"shasum":"dd4f1816fcae34a81bc60e584f97993cad284d54","integrity":"sha512-dNz5AObEYg0Oglw3emIsBhTAOVfObrfxDaAzR0UTRDDq+Ohfr6KTSaVQAH88Ym+oa08ZlLZBFc6ARe9doAOIxg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-rc.5.tgz","fileCount":10,"unpackedSize":508251,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfIJuxCRA9TVsSAnZWagAAi8YQAJa/1rqq18R0J91YZpkB\ndIhZUD4ABb+wqeS2RAtOI9rhOoQNLkcmlHASo0ESJiKT9+vLWIzwUyK+3S9w\nCPv6Z3eCTpcsFDMvmc3po6nPqaUJ6afcLbVKbvG7VR8/ypdKuwGsMJGT89lL\nP3E1DvvQrs+FV/bf/DEez5a4SltOuLg6SPOz1QKHvck45FQNokz59vLac3ew\ny3YllVbCiP+9DFq1JlrP6hEX+jXB8JD5gAvD5cLGJLHbJYejleai2XffkmWw\niwtofYmw3xyKO9LSSpANwitjliZbDgJtDqQp8AlvDT1YsDl3dQuDXcIHLuDm\n5jOfpuYxXPP3WYXMSb+QlYTShB/nk52kohbD95BWrwXiAhz9cjPbh0PNcrqY\n17FA3wXK0ILm/0Ubs46dp63kF7kNAnBAKKxZRSX7wVeck67Z5UX5QGIByJYS\n2VrZJ9i8VYMz1PBLs9dtsT6pw7Vf2PmAn+URWpMcqkn4WoCNxHch9PQB1VJB\n6bNfbTkkt/sHdpmr5Eaid89pOpR2H7ad/P//bkcsquThbDRa63WzgcqFyHMC\niYM9R2RhUGr+WwwlSTRi8RyVLtrbYoimppYTlqFxUHTm6lf4WP1ItyptPk/3\nxzR5FSejlRE066q8fSiL4GnmPC7gbXA3aoI46WtZN0IA91QOV9baNON5IzN2\nsVdO\r\n=lclJ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDepiZkiFHKWekcsbnk07wvdzyLyljJG6JTDxXd8Fsi7QIhAMmhiIzUMYybWqCDwEANkiZxejpkvHlD3kKxtjWdRVsi"}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-rc.5_1595972529297_0.21988552364493597"},"_hasShrinkwrap":false},"3.0.0-rc.6":{"name":"@vue/compiler-core","version":"3.0.0-rc.6","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-rc.6","@babel/parser":"^7.10.4","@babel/types":"^7.10.4","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-rc.6","dist":{"shasum":"d5bae6ba028068aa54706a5c9c1e8e34a296b4ce","integrity":"sha512-ZECV6eMIO+cY1aMQoPMZvkS1Bjv5tfeYrcd/qE4YdsjMUtId6N9EO3xob9FUo4fL4SZt2woHmGkc8x4nKu9+NQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-rc.6.tgz","fileCount":10,"unpackedSize":514814,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfPaUMCRA9TVsSAnZWagAAbosQAJCYCcg+UbXZ2t+BtrN/\n+eH5wzcUvZ+ka7PKDqSuFZxBTte41bTv9Thue1bR6ltBEbFM9BW5zh94Tnr2\n/gkM8C9I42g5rdFwi/J0777Yr0lrCiG/qy24zCahNeB/iPLB8FKAqr9RZ/sL\npfihjWfcqDW9gnCnVWc/xZYirig0MsKyZ/8+hM7qSJDVGimgcr1NVk2szMPn\nCqB+3ayo0JyUIWdBFJ1SI2BuAzkR34F0Iiy1LFHBsP1nKcJ3gkP76vaydFN4\nYHT9NDimj2q0pEUj9Uw+7DyuzvbHpnkLOkHkSRol9asR/ziFsK9wNtWRu6s9\nYbnNNLEDszzRv3UCf41/olyBbL5imK5PcbGKrurQpEUNNLewnUBpjA6buk3F\nX/BtjseO7F818SNcyTqh7qiiF4AVnCI6FwnovknXav3EY3nAZiqsggtRsGIj\nybMmr/3w+uxexCzvqvDLtv1Gd58XnjKWf55eLgF1+e20BPfpYG+1XO9/yRJT\nyVI95v66YFDv6Gv+53PriPBmj1+rYOI+ttCuS7gVowV4hyQotSzVHjfqEiD6\npNvA4GyePPhDNvfpKqf3hOLCofNS2G+mQfEppitPivy0w8KQktdaSbs2nwbm\nbuupkxXOG7scufheadLWaMgEaU3dEDXER8Rn6fLaiADUGadFq2slPLS/xRDB\nxyNk\r\n=Yu64\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDiFega8eazD+biUH6e/PMu4WP2GptX3WdLD+O52ga7nAIgNJhm9yyQBygfRnC2iFBvL02vtVcQUGnymv1AE2z7GhI="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-rc.6_1597875467606_0.8802903632384391"},"_hasShrinkwrap":false},"3.0.0-rc.7":{"name":"@vue/compiler-core","version":"3.0.0-rc.7","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-rc.7","@babel/parser":"^7.10.4","@babel/types":"^7.10.4","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-rc.7","dist":{"shasum":"119f669ee59c96124c280a6e94187f3bad09ea8a","integrity":"sha512-bzk7uGKPEAKC4XHnHvmMUui9MASOVK7e4xgDz6oOBWqo1mnvqk1YnNZzY+0XMaCr4PFOFqHw739JmzJb6SBqUg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-rc.7.tgz","fileCount":10,"unpackedSize":515987,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfQA61CRA9TVsSAnZWagAAOUMP/in2a0fw/KDyFoPLbkCP\nkEKTD24ThvyD7715Pjv24Saj2Px95qfpnpTVluTxcakxOXMhufpUW7BQAMlj\nfAhilBn96fa+D9VR60x1OwZl2G/ju6KttSXycXDHoQvcK5lFtWmsSzyDiUxj\n7eAIs1/wr9BLZ96/5Xxz9zeWHO2I4rwItFQ53l6OgKYguHSb+1aNaKzYKgqh\nAmwP//dvX6nKrnasrzu7X0CBfp5vFLE3hSWQhzwp2g6sSHS7Gj32fwEX0CTj\nENyJfNWiOZ0B1g0WL2JKEbt5M4Ovxc2sPaiff40WWOmIv0BKA+B9eiGjHBN9\nE3BhMZOrbJbELHXCjF7gdr0AOCzoE6oYy/bbDDyhRgfnoihlzP0HnBBb7rSn\nKFwhuk7OGB/lH7PpTcsrV6/Kh1WcOXGXNLE1nW0W9NykGGSfzABgcvtIj2Yu\nfx8xa5g9gr4tUJhdpYBScf02Sf2AfFW/vjhOFNCSi4uQGNHa83w36CUnmWiP\nNLqhnqRmydpeiTerPvVze+X1QZq4lheb1enJVupAQCa+/2fnc52ZtCGRctHs\nNW6FYQJdT9hL6sHDkFGTnf3nySKIdCvh1PbsUULlrc3P5CM72OKYhFkpN+6n\neDqPV+mh7jfAqoTPbJTFN4cKR0ZjCX6t5KWTtFyZy1xXAzVGBxx9X5jGdX+N\n7YnV\r\n=APko\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCrU9tp7M4HFbCvHfZNtUzs4711E3QoEyLxCL42buxZfgIhAJMZWBu2JvWEtbhjX7OGnlcnKH0TaVpTZi+SP3Wdqa4V"}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-rc.7_1598033589381_0.9246601481267431"},"_hasShrinkwrap":false},"3.0.0-rc.8":{"name":"@vue/compiler-core","version":"3.0.0-rc.8","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-rc.8","@babel/parser":"^7.10.4","@babel/types":"^7.10.4","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-rc.8","dist":{"shasum":"c8a630b440d03a1790d34b3c5a7b3c86caa8a84e","integrity":"sha512-67sHKlKhrBhxF72gJc8PkJeAA1iZ4x1krVDuS2yOvS44Gj+fNHu8Y25mThLu+eq2rXCUrrbbmZge9ND6VuyFUA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-rc.8.tgz","fileCount":10,"unpackedSize":515987,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfRSDdCRA9TVsSAnZWagAAMIoQAIEzEuDzRZx977Vnx6fL\nUJECFS9os3DWsTmIvdCU2F0+/oweHZ+JhnhdRVrBiV9US2r6euEYgiSN+af0\nEpaJGB5n0JW81dVA6SGaEFkAU29spEQ+6Ri4BVAaFW2ud/4ReUnnJP01BkVC\nDpL9k7IdN0cYwkGuJHgeVAbspctgbsRE1uAMEFiFRkzrQIHez8QG5NRWcotv\nPNJUrHUqzkSGnPaXYgqETRQL7E+tdBmAsb/WlTO6fWv5hdIWnSiId74Ez8Rt\nNxrCt6sDzyhZDzHWBsnOlICHdkTqiXCLTgLq/2vvZmIqpJwlYmlLAEkHkwRl\ncUldU26VILZqI3YVy0aNx6jh2A/fKsOxWjL6f79Mt5Qj2hqqDRozsyGvn5xJ\n2fZKRvQrwpMVNePvqvp7JnyFAMkHk/uuKUJXWv+fhAtjsnK+tNDOe8BHmtOx\ngA4ua4S9kNEOI/795dJ8JgtXp82o97Ea7f06+aGSwUCXsv5M4lqJweKWnpRG\nopKaRIO6wW53Ml1rFB28dRTlF5F+sSWUJgPS/p6PROV8iRRBMdF3EqVItxpa\nmiD76boeZWFo16LHfZlBP+/gGM3wB9w5hVudhzaSeaiZJOkcjj88ZT5al5OO\ntM22BYGbdz6xUjrbiwOTJ0QziMP325Fj2uzkYtahXtXfkzkyUH/Hk2Oer5vh\nIPKN\r\n=e+dD\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDrTvIOZW6wKf99PrgjBcGwdnfXatOkPXFRqTcjZdAMFAiEA639lusOPd3xTMbko4+sFljgGbMXd1q8U/8MY1SVPqCk="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-rc.8_1598365916904_0.909608434108574"},"_hasShrinkwrap":false},"3.0.0-rc.9":{"name":"@vue/compiler-core","version":"3.0.0-rc.9","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-rc.9","@babel/parser":"^7.10.4","@babel/types":"^7.10.4","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-rc.9","dist":{"shasum":"f2baef360dec3630a230a056dde1e76c9c7bb5f5","integrity":"sha512-/Ns7KGT5P0wh4JTM91drBmNIiBlKrCFUqIE2vk8dmaVvqEJf1mqympz1CDZpikghCQC6hKu3tYKxA7qtcMRazw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-rc.9.tgz","fileCount":10,"unpackedSize":515987,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfRuBjCRA9TVsSAnZWagAA6mQP/1CoGZlNpO8uJuRdQnOV\nfe5Moq7WEFGMvsnG9eWFgsbjsdb74bHmRLoSD4wHcUjOcGUuaY1DaBWLPGpi\nkvdVNJKW5pQpKfgJ4TmZ2EzGWTFqSEmxXs2xuKXkeix3YGCp7ujzJ4gOkCmI\nX6OVclACOHF8SR3CzlI5Z/tfVCWK/yzXOFQFIlD8J7j3SnlK6/uU7jN17NGd\nwVQsY3hHNZH9I3B0dBRjdHBcXgn8fSnOhn7mdxnVR1Y8YTu+Sl9rEQTsN2Zu\nx33mcwR4yfQxuIpqXWAwYNpeOob8XIXcA35Tyvn2ipNtPUl7DjdE3N2hDfPl\nrPEnfsGMm+/xeuX5Z5Kzis1pF0opOljEpoAH5QUuyuOygwM3UOFDKbbWaEZg\nyKv3zSWPDrjRl9jSI20ejjGc4ZkGAxfqsIU6p+oXl+SaiCRL/AFjXppkSBCV\n/qkKsDF51hAqYqNGz3Aq3htQd8tYuIu/fKZEjecAZ/jbJHHmP4vgQBg4OjMd\nw2DQtU5Yv6C3aWJQONO9lRYdM37zDVWjt2SrVNbvmtcq12MMbMBhIoLn8Jkr\n4XsQFEq8rCyWGqxzEUED2xo58mHGqjFaRFZsFoN1YhwUllKp+qMZC8oa71Dx\n49Wo1pCCOhQQoby6WBHLhBuw+6UmUBn9L/75w6cwnzGTxxx9d/uO4fdZP/Hz\nzuSh\r\n=iGOp\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDRTcJBvPW/0bH+8sTDQzLHgM9Y5FS77gdAkMedj6PgbwIhAOHlpfqiY38okjJ2XUCroOWUM9/V2sZRxHJVTdOoECJR"}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-rc.9_1598480482848_0.37221620065043703"},"_hasShrinkwrap":false},"3.0.0-rc.10":{"name":"@vue/compiler-core","version":"3.0.0-rc.10","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-rc.10","@babel/parser":"^7.10.4","@babel/types":"^7.10.4","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-rc.10","dist":{"shasum":"a76f713fb0462429ec0ec10a472fff1f539c5772","integrity":"sha512-kQzHzRsM0NPAWHeqSTb2J4VsHhjRkGeLTsGzeMnW+sojgTnS3T94KacwvYgVS4qeZAKiDq0bMNZoJWrHVQ3T8g==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-rc.10.tgz","fileCount":10,"unpackedSize":516611,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfT8tWCRA9TVsSAnZWagAArVUP/1qzA+aDe74e4cnyXT9D\nx7OyZecKTwUUn0m9kWQehgTTNSdpX+YzwfD9bsC8TLSBuXQ01DNUAftqTJN2\nOefpmwvK6oNsVr19BGF965N97C4gZKoazaNvKxFW5LTVn1Apsc28MDMRe8yO\nvvTu4t5Vucd7TaYl6xid9cl88cmJiARitlKSOyNwTALmxCGyhSYEwn6sscoQ\nVhdS6lYFe8yyxoG1q02N/Jst4zAiilzL0oLt+3DxgamOqvL6tVJdb4ykQmeI\nSPEoHRwR0JGU7BbkaHA+gKR7Vtm+iQluP/g6mz3T35PpCQ7ClHRZEE0mJldV\nEesJKqbmDDQ98kzSNdprc6Yb3lSXgjqewtiyYI1QOgWO635iuJIsqBBLUWFn\nffAR5hGhK7pC6h+AxH7ZUDVrkefwgxadLOEOU/9+iGiqj6HUtJFd1JJVc/1p\nFTTXbf+vltcBWjSo6gyS8PRyunbkoZLCpsJxlEMKiKkS5jf7t9u59w5dQirO\naf5ROTarsMUMCG5yPD83eiNQbxWLRW5wR+qqcsjP0MfsthLrFpzqfqaRuzJX\ncOWV7kSKmxp+5KG9WlPQvA3CfckRNzzVLeaGASi/7HKGIjfKb4woHD2l0Q+P\nn6YQ4dWPi690zrgdiVTbB9r2R75GSrvflWlelescZZWiyV0QHQxFNWd9Td81\n1zXe\r\n=Pmay\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFmr3Yy68pzN8JyCDHA9eli9bGrxE+rFP9OADkHx93CtAiA3xGpN1B9X6jBCRBkCLrC2fkxtuaq0SzMxOwPc50t2lA=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-rc.10_1599064918119_0.02862212148982146"},"_hasShrinkwrap":false},"3.0.0-rc.11":{"name":"@vue/compiler-core","version":"3.0.0-rc.11","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-rc.11","@babel/parser":"^7.11.5","@babel/types":"^7.11.5","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-rc.11","dist":{"shasum":"4fb60aeab0b8e560fe4e587b02a546a5ad575754","integrity":"sha512-mt4hiJG7BiKo5nbDAZ6Yd9yim2hBIorB5wVWD9bfM5rPbzpwnKp/f8MRlCvLuIjgf43xPbSW6AZ5awrgV1NDsg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-rc.11.tgz","fileCount":10,"unpackedSize":516613,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfYPbCCRA9TVsSAnZWagAAKAoQAI1z0DK7ci/6xFN+NvDq\nZhDML1bjANYEyn5PiMEMCd4hkFNSxLdtnbluFxz00Z1Aicgz22XdnXSv2pdu\nxGdHb9v+8GgxZN+Soalv9HG9BnL6Ja8UwOWNusw1Cxxz2CvliIsh0Th6yVC7\n28jiwRY4tIKz0c8NY7YQQYcZrtViU3zMXWfmFDHwsevdbDrYNdZE4tyoQcHX\nh3a+NmzOlnb5XUtR8ymP80DY/wCSJgMi8MhPG2c0bfocAEh73QxPS9cZGJXm\niG0q9vZjNIKshi2w/itZgLs4kpqhdaCrPWRKNT1pNs2F1kdKqswqwVOBUGCT\nTshLjuyQTjg3nEPKYQK+n0xPpBbrFPzz5wXAmvOynSg7Yt/0tWR1oIn4138K\nVZpDk/8Iv7ybiaZZh9uwKnSNZplprQoy7P1OSiNJVJbcqvb9ua+0Nh2hXpPh\nR6M/Olukm34HFEQb492S9Klfmcu2f3TKulKZOocH972qZUZ4I/DHDwH+399D\nBmPgogCq9h7BosmN89VkfrLyvwLOAMFgF4SzaRLb36Kynjp5c3qff2dM2trn\nMR/zHxvtxCHel1rw0Q6Dyy2HY80WVon0phA54j6bUF27MC4cm2mNU3S7e0Kk\nYSJlDoGk/K9FTmVOlAuzqNQ3tHQbO0zKSJ+LqrIUGfEBS97Amy+FQmZbJPhb\nXGdx\r\n=RVH+\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICfoiIRw4bewlDZuJ4m0VD87iHGaH01jTPuGeIDTQhD4AiEAm+pF7SoU7SSOR9FKSdsldntvYKHFDsGwujqFWmAQ95E="}]},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-rc.11_1600190146159_0.31979113358974076"},"_hasShrinkwrap":false},"3.0.0-rc.12":{"name":"@vue/compiler-core","version":"3.0.0-rc.12","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-rc.12","@babel/parser":"^7.11.5","@babel/types":"^7.11.5","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-rc.12","dist":{"shasum":"eb26ff2f7e0eb8b362606228b2dda59c0c914f63","integrity":"sha512-TuOmPb5SXgK9qD/AAmy46j80CyKThiBppcgNIJTax1ZWLEtCU8JejXOJqXFcqDUrBJPy7WVtZWRjMsiZBjIlrQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-rc.12.tgz","fileCount":10,"unpackedSize":516613,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfYlBcCRA9TVsSAnZWagAAFgkP/1IzSsDbpnMDQEMjc+np\nZ2Qhm0dvSVWDYV6rPD0WC95ew7Ctlo1JANcENLvnXWfuU/UPaoRYHuz0EYVn\ne9W+yTJ/6xG5/Cmmw0dx9aUoOHVWTbuRKJP+WadXF0sljWbg/1MLrZJaOWLv\nWTkzEdegtONsosakrBXIrGPYN/vGYgwvmzOXEDL3pkzyQvUMDflPFuQTbuY4\nh3Cyg97BnNkBJhjBC4zOnQhuto+Cb+IIU4cp9VxUYLU3sHJi0klmcIzYNIv0\nYopGoshM/+4jZiNvfR7hs0yhQRe6ugnYQVdmsrBa922CHl0X85RcRu98ra1A\nOCKdwwEsjjaPO7F1uoZgVkQNrY3sZjlMCouHFYldKGQDmwItxT+EwY/JUboG\nn4Fmxeec1p3RV6LiPDC79U9Gp9NGxTXUBTMYmxZbUXrGOeGk310LNz5S//to\nYYPgSY/epxE8RKAHqcgOE3EPCPLF4woGt8zguAW2pkeRYAcFH15MFoGrAfHK\na7spR+Z7wfyAlGeSk8dn0ZDLEGYxOLXj6oTSUwpeKDSgHXCoBlDESpDLl62I\n+LHbYmoLxIMPylFbyMkckI5n3Ce2xMgpD6S/kKTCkBV9Aa79uCD43ata1fD4\nCPAfACtxLnwEs/SC7Ck008MRklkIwdr32cbpwZrXjqykbD/Od0Nk0XfF7cSO\nmXpR\r\n=BGb4\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICisDAP1SymrpytjucOSYebSjIW3vLBrVMcOHEGFc3CsAiA8Xk7s+eQ18xd1ZA+vFA91RLUjxMlXU5KYu6WaUF3s/A=="}]},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-rc.12_1600278619849_0.8594947393503298"},"_hasShrinkwrap":false},"3.0.0-rc.13":{"name":"@vue/compiler-core","version":"3.0.0-rc.13","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0-rc.13","@babel/parser":"^7.11.5","@babel/types":"^7.11.5","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0-rc.13","dist":{"shasum":"bec6812c4ce9e9b41210deaf8d05652feb50f1e5","integrity":"sha512-bVtg7iilAE8uq+WvR4JN+vtzQWX+yjKHNG5Un0ar6M9WbphydGY9C0y1whKjRbKn/7U+evUh1MJ2hV2q3GBrSQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0-rc.13.tgz","fileCount":10,"unpackedSize":516613,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfZEgYCRA9TVsSAnZWagAA4zIP/jK0Zi5qk2ceX2kjsGH0\nHKwKPrrZuVdPgsmTJDGPRqx7PIRRpGzA3AivvQ/jSXkCizMUkT11hErIGu9u\n6PY+z2X8wlNRKuAIt82zZxTdslliurGNN/vqxTz3KepMY9xkUfom7kMIRrt6\n0yME3eSxrLvyJVXw1IVkOUpjTPox9NuV89YPjc570i5lwa7a65wNbbMkZpXz\nL5CCZsJzWQh8L72lSuUiIa3+QQS6TBF7dZdWBXvfJaWUb8REKtZkDCQ6TSeh\n8Zpj1kJJ8eFFYU0++iCxL27HHZWVQzUiy1RvxtLBhMrVPJ/yQpFPxYq+UeEP\nWCC/WsiZWFUxvwhrKkC0uKXGEIpWFtyq7sGENngOWZEVNp/nXvWVdFg51kTl\nslKnL7i4UTyOxE6ZVPKlx6ck6cgVzA4ulJKweaCj4HUKbjIkas2LnegyTw7/\n8nAJKGfoIX4AfRlYDBd3sosQIAR++6bUfCMFfMyGD1LyXqgvp68A14FWGkCh\n0Fyr0NrQVJyt95CNgUCdVQtZBtvuGJ3GShoVF1SIhlXqGScjzzVJfICr8Q5i\n868MNNdJ0/zKznsJMIcL5ltOvCfIUevQa6UMTUz9tO7j6/O2qtU7gjko6M12\nYzKn+3NIwK+UEdR5XlkNn45d1c2/8v7OJsA9H3KStG7F7ZXtTG2hRCRt/Nza\nRCFa\r\n=x/+k\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCID+7XqI5HWo526SCVdO+l951rWpHSuTDJS3s9TWKeWTMAiEAmYJ6Ck71S764NtiO1LUa8vsW96vluJxsdZHU3+Ij9HM="}]},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0-rc.13_1600407575862_0.8104322726386142"},"_hasShrinkwrap":false},"3.0.0":{"name":"@vue/compiler-core","version":"3.0.0","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.0","@babel/parser":"^7.11.5","@babel/types":"^7.11.5","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.0","dist":{"shasum":"25e4f079cf6c39f83bad23700f814c619105a0f2","integrity":"sha512-XqPC7vdv4rFE77S71oCHmT1K4Ks3WE2Gi6Lr4B5wn0Idmp+NyQQBUHsCNieMDRiEpgtJrw+yOHslrsV0AfAsfQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.0.tgz","fileCount":10,"unpackedSize":516601,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfZNIJCRA9TVsSAnZWagAA4t8P/3bcStmnNwgo0Om/7hxT\n+/LoRfulmWmnSYllqpYEDxQJN72rkrSQRxBoJ6NPKF5kzQ6g6tvOBuz2M+Ri\nqziHvPksxDXW+PlrXIN5UDcubGKZw05YiwF3wGgEXzjJ9sXpEU+qgmQWaNxa\njt0BPTrP1bx2DjbeP9T/QwjBY0rKPCuiGGl0wZ868fjnTfCqQyGMbedyvfOs\nehSOOQr+ppPi3qRitfgPo+KS/zxUWMl9tAyDdQRtAGpbN6iey1v//1l2JfE4\nGNPKSpYUJ82OHMfVuNqA03HxurfkVMb6HgDpqPkPe5abUeMlTHZIogUAK9Eq\nLMFwoTUEFUUAyO/Au57yqxQQyjkXlfZJh1+/ovMDx0kaaOn7SeW46RC6e6TY\nzS0aZ33ROJagIkNRXVq03YdGsEsZZB998oKDb6LBAA5qH0fcmMq4RpA9lE2m\n8Qy/fMt7HuBjdaQJtUEBrDIlg4hjtGPxiMgRAwq9og/I8FPgUQwBrGlVPl4t\n+VLGsDqVVZ3WwmWtZ0T6Pti3Vj5ptsIONVxcT5LfWzSe3MXN+zqti9OiNxLL\nbw1D2qqvrI2MngOVt/i5bRm+S+X3pvrhWZ03ljKFhofEGPB2kvy7yuq+w66Z\nfZ955HTOJfCACWnEM0dmCaUkPFC2I6nlHeMG6NPrFBL+OwlOPlKU4KN7cTOB\nVGlC\r\n=Au2a\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDFlDcuPvN+n99i7sMMj/UYosuX0qxZF9j4WrEDe0WJwQIgJjazgUl2hHJStZJGRydzHr9p9wtU3FRQ7a8mxgyyn94="}]},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.0_1600442889111_0.7556840286147861"},"_hasShrinkwrap":false},"3.0.1":{"name":"@vue/compiler-core","version":"3.0.1","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.1","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.1","dist":{"shasum":"3ce57531078c6220be7ea458e41e4bab3522015b","integrity":"sha512-BbQQj9YVNaNWEPnP4PiFKgW8QSGB3dcPSKCtekx1586m4VA1z8hHNLQnzeygtV8BM4oU6yriiWmOIYghbJHwFw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.1.tgz","fileCount":10,"unpackedSize":518383,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfiHrHCRA9TVsSAnZWagAA7YoP/3z4JwnCL53gYb9upWvb\nLm9aN/IAROQoyr0gYvBJ4W+VbGpum6X8yd4gxUKiqw10a0lub7jn8I772SBh\niHtr8+YNrC1hwcKvoTzFfh+oJkvIcQaSU9y0rwpP8tVHAt2xOn1f48ihgBTv\nhQZPKWXRHZenQBGbBY18QjJBpsnztYpjF4MhrIc2a1Wl8kRY5zSSiV8zgqAn\n/poRC1jyDko7XX0teb1AL2GX0HgFG6Hgwye2YNNMO9I26i3Cce3D2aQMYYZ2\n3CShe3eHiSGVfU78v6vLHz5BkNrOLQd7fyg4mkVPPNGtkk5kcImVylqPHbe1\nkYwgbV45x7jXvbl5O+L/sbS6enotEEVhB1Z/uOc9dfD1cTuV6B5UbIfCw437\nbuK9M4sXOZ4d9iE/+jqprpmJ9ZFm/4ChsaUxGIso2KXw8rVxK1dha4yYfmp7\nGKvJf35Wn62d7yQ/qpQY4FYkwdG2YM8BJo0GBGS6252GdwUv1FCb3SZ0Tvb8\nMbglywNuuwl3kOUDIH1JiIiklZ+H7HEHq8mGeT51+xp80aa88lccOKOZN/kc\nAHQPG5YqtJAHxe1xFFbYxqJzI5/jfYYq2weGIv6N6T0nx+ny+JXAgaAHjT5R\nDIC7jh6W6fsDOFXCrtIplBWlRevVpB2sibINfcyZ1c6dE5uRpMBjWdelcUgh\nnC/w\r\n=U0mv\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDWzSH6RpMeKEg6f3BD46EXGkfmomWn4SelRBNKggJk9QIhAOkWamaR9I8HMpRp1r2kjoNEKJaIsTfr7qmK8I7VVSme"}]},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.1_1602779846653_0.1544219104034774"},"_hasShrinkwrap":false},"3.0.2":{"name":"@vue/compiler-core","version":"3.0.2","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.2","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.2","dist":{"shasum":"7790b7a1fcbba5ace4d81a70ce59096fa5c95734","integrity":"sha512-GOlEMTlC/OdzBkKaKOniYErbkjoKxkBOmulxGmMR10I2JJX6TvXd/peaO/kla2xhpliV/M6Z4TLJp0yjAvRIAw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.2.tgz","fileCount":10,"unpackedSize":519386,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfj0dwCRA9TVsSAnZWagAAnRoP/AknFzjl7LDPHH5a/2DY\ndi48PqOt3M1fXxKVSHBFE2bsZYVqhK3Z82ByLKejkdrGwrph6d2jDxedL9n9\n0WkVP0dyXk2pFPOoRScJ0NXuaTjrzNl3iBIPQhgEq8q1IYGVzqbUjke6SzXI\nhxBI+xJ5H1ie6Mtjm3sPut69jAsGXcw3ogE8c5zntMEW8z85BwYbl12icNLS\nEFDkJhZWFUxmB916rxF30rx+7xVmXCvj793KsfqROjfM9AtP/ks1BkFo0Qxm\nS7iytP7hOgAIouUKbfR/pZgAeJKkPiVynrxCVi6upPb4/HTzEHzlbxzthOO2\nCNlylpfy+tzMtxaPo+q5+nlEfHEfcckuc9u/xr084yTt3RtOZbQf5oVle8lD\nze1b5RpQUR0R494Ih+CaoaVQqIv6w0GRUBLriNdnM2uxUgZMuFSy/sRpEJI5\naxOk6x78H9W7Plyakt6rdVHTEezbNYdV8rqSZQvAOxbmMmLLVICFrshBYkJr\n2EaoPIqqBC9j7YJ41vMYgE0jWpfNRhQcLCRXNO0qn5twsV2qJQuiK6vPdUq3\nCJqDB3PfyH2O9gIXlENsQNfzW6w5U1asB46oR8Bw6QVQieMM0/AjBiJEiTIV\nI78/blar3MIXxx3ek20SbQGJX5+Uw2AyWu4d34Usc1+fobo6ULZj+0OLoVu9\nic19\r\n=bmVJ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCpeON71WHDKUH+moCZqlqAfyrCCyREaltj8UL1i89DbQIhAIbmXvJ94E1CMnHWnQww6g4e/HqoCstImm+1N++nAE7b"}]},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.2_1603225456179_0.6164166119718484"},"_hasShrinkwrap":false},"3.0.3":{"name":"@vue/compiler-core","version":"3.0.3","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.3","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"readmeFilename":"README.md","readme":"# @vue/compiler-core\n","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.3","dist":{"shasum":"dbb4d5eb91f294038f0bed170a1c25f59f7dc74f","integrity":"sha512-iWlRT8RYLmz7zkg84pTOriNUzjH7XACWN++ImFkskWXWeev29IKi7p76T9jKDaMZoPiGcUZ0k9wayuASWVxOwg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.3.tgz","fileCount":10,"unpackedSize":553882,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfvoNZCRA9TVsSAnZWagAAvrQQAJ+m0QXW1e7zNJoF+WrG\n6e6LockfV4TF7QE/vUItWmF3N7ObyPWV3/1Q0ICB/eQbLnVU8EShiGHSFhD7\noX6xeY8NKD2/jeqtvAMcBdKx3EFP++v1IzOogPb60xwm5jptLRzyGs7ugv7G\nDkaBTyANmJQ6ELTfJNP+xf5FbfN7aG3ROsChg7U8KH924faI9ArTqKuQXV9/\n+s7rM+YjAUwYjLI/ZIalkoRbQenNslOTlxbNJcWQh5OcBzi63IF2FyipLC0K\n7ZALU/fl3RpTpQNqRepH+Fep4Dfiig9r2VZpgNoicnuX9q6faSdZDmx9LKbx\nan3S/RHO87nF7sJb50NHYFteYJbYovRgTovFTN7F0K9UMTkpGMEaUANUA6zr\naI+FVuPCM7qlVJTdev8dPKjje1Xe2rulUabWCRBZIXfnRfVfJ1VaNhlMbTGF\n3HwZvgJph8wpPw6awSMat6tqW4dM75nGUSUSJF6unGhwin5ln2aL+kBp6KJ3\ntxtHBHKfecvrxmvbrTG2smpFkszGzMXSqU/2e7bRtIwFbtZDgxgP1gTgFPWw\nVaDs9vk8f6+Nv6ayWec6xMoReeWpNlpqUZpFVQQJMPZ0fQifMpzhzAM70C01\nRdE0NvOJh2C+5WNplJPxuy/17QhUqoVKwEDI8KyZ7nk9cdn7mcIy7JHxbQKf\n1eQi\r\n=joVw\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDUb6iStEYp7CElWtkWMktSu0rgsrRBWiYE9reX23iHEAiA2wwrEifXWXoefRTzHURmdaqAHLP0IQI7Avdk+vj2tnw=="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.3_1606320985306_0.6107637127005068"},"_hasShrinkwrap":false},"3.0.4":{"name":"@vue/compiler-core","version":"3.0.4","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.4","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.4","dist":{"shasum":"0122aca6eada4cb28b39ed930af917444755e330","integrity":"sha512-snpMICsbWTZqBFnPB03qr4DtiSxVYfDF3DvbDSkN9Z9NTM8Chl8E/lYhKBSsvauq91DAWAh8PU3lr9vrLyQsug==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.4.tgz","fileCount":10,"unpackedSize":545451,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfyBP0CRA9TVsSAnZWagAAOoAP/2Sqf3SDxWYbThRQmS0r\njiH9ilY5bsHnq6ZR6XYz4R8w/++Ign3xR59HPgVjg/gVBpOnoSLLu5C0oEEx\nkATgcVsqARIwRGPGMjaA3NbxYcdBJYkbAQy1Hn6cEFgLyAaqEr0nVnOlCXX3\nCS/7Ccy8QBWGaCoVeWLBSrPeNJyhE4EXNsBplM6bLj1x/xtt+kD1rIYWJqRw\n/zsBBZHFQo2V+FUSDuMuu5YKxDpc3ORgrUCwHAcOLZu10awZYJzA2RufWEth\nxLRI+qdH3+BVH73WS19a5NJvq2clsIhskr2/A6rT9cDIbqXBGquJ9UqQxo7o\ntSZApyW7tEepS7dInqSJaiRn3MGlKFUIBtwiZ4tFVH10nWb/aizKcKXgVEx0\nL906cTFFrX0KQQ8aQNd9pcclzrGhQf/yl/5Fw9IdoqaZYIDP5cu7caQlACUb\nJVg6/7lUEcXkY56QyhO13zmtzU8eOxIDYfY8E9TAIDNKzMckP31WLGD42apk\nQhmzMCgpRJP9EbdzHNL8htK8ra/Hh/2bqDbW1FcpPEO3G0p2ypKNmrmpXog2\nT+2VRbSeSd1ljBB47ixG2wYGK2oueiX9dCfAGZKYoSxpNg6fDPc/4oWIVN0q\nBC66/ckhQr5A2gjaMgYJrBsPLzcwytK0RYRzMR56RUt3+gcQLFB4x9Dcb1bo\nPODt\r\n=EznY\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDgxtZdbnWdHGwTD5yOPS8ay/oYm+hmJFa5m5cGFq5gkAiAz3KcU2+DF6LuhrS1ytXpdnggcIEUUYPTZPcZ10Cw/EQ=="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.4_1606947827805_0.5275612074595728"},"_hasShrinkwrap":false},"3.0.5":{"name":"@vue/compiler-core","version":"3.0.5","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.5","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.5","dist":{"shasum":"a6e54cabe9536e74c6513acd2649f311af1d43ac","integrity":"sha512-iFXwk2gmU/GGwN4hpBwDWWMLvpkIejf/AybcFtlQ5V1ur+5jwfBaV0Y1RXoR6ePfBPJixtKZ3PmN+M+HgMAtfQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.5.tgz","fileCount":10,"unpackedSize":545894,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf7OgWCRA9TVsSAnZWagAAla8P/jwmmgxT73iKxa/A8JVs\nJx4EYMnc8WN3BnsvY4wjqCriwKIPlCV3vrayBfS/z1JUa1abv/mYpJMu/qBy\nSg38OFCZSs5BJJjxpJbcp+htnvmyU5tVrQELIMHy4YWIoPFY68Rn7yOPyeWi\n2rUWMKcbUPw7xpWSHlIyvl8c4qeKPhe/eEkPlGhN/crFpqir1ViB0+UbT4JL\nvAAQo1qETEOxyggIzHU+Fmh8skf6w/pOUHTMvs2B4YeVOiliSKZyJoEP8oAc\n4ErWJaCOxGRuj52gyrY4K3dRUzOTLgyWtk6e90MUjLfs+o1vf8rh6jcRG243\nS4KE2PpB2NNmp+EXtFZ2pLr1PTxL6OR+2KXYUyCZhaChlyRwmZXxtCCjyN9E\nll3yo6LLrNognwF/Vr4OcnsUCTWu6bMDYypQsuxAewm5zXXXqiiJEsAmX3EQ\nrzz93BBFcwuPid9okXX9JSdMd9jg5nr/swmwRXFHqvAAtVGJnkZC841Ku6GH\nIxur6UZBnOfGjzdz/EzSNLu4P+hDntIdW9993VwImxopeDSG8DzuTzrXpHXM\nEPuHkjbWVapGnEyLzWJEIBlspxUdSf+xkUxojE3lDBg4OUuuKiBk/3qvMGWQ\nAHPfZtllEUrTENysLlJHcFtx52B8f383Qp4jSfpwNEI5ec8pEP4KC1Ym0nqh\nt/6/\r\n=QYXH\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBl+bzt3Sg9dOYRPY/C3pNYfuAsxzrEfNeTx2aYnFBBlAiEA4PHJaLY4mqmUuJ8ucrrzU8Acx+W776e+h4GnAvGnIrM="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.5_1609361430416_0.5753085936070776"},"_hasShrinkwrap":false},"3.0.6":{"name":"@vue/compiler-core","version":"3.0.6","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.6","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.6","dist":{"shasum":"265bbe0711a81ab4c1344f8294e22e2d08ca167d","integrity":"sha512-O7QzQ39DskOoPpEDWRvKwDX7Py9UNT7SvLHvBdIfckGA3OsAEBdiAtuYQNcVmUDeBajm+08v5wyvHWBbWgkilQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.6.tgz","fileCount":10,"unpackedSize":545409,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgNrTVCRA9TVsSAnZWagAAIjYP/1sGHqwjWzsA+nnV8HW6\nn2s2HGN7PK0xqE/tVIGILyiQlpHvIpPPZK1diV92DyCWWSbdbFtUY8u17g1o\nhpTLRZH1Ns4neoZAMPRKv7pmAehxXL6CLVtdpLedb+zDPgUIQ74HzRaN0fvi\nV6ZVUxz4onmELkTFZpPHZ0t18fr05bq6ozTW7vh08cPX1nARWKj9GMeclmbY\n14hYQrBl+3kWzlkeW9Y0KSLtajkbX+vOxi8cJt4pUzlnJvGuFtU/G8Ij0jDl\n4AvY3KB8TdSb3HE7NVA4tGpBSHETQg6JUbeHt/swHzscVl2a2ifcsd1/K5AT\nA8QZI2pOB1YdEvyLOvoMo7mp9+MfGlKx3RNVv7lekhQC5kbRADLOAgfsPYAT\n65llKX8xerWPOd5FiHSP+zr5xFdoxUuV+8kWBOdlxHRjGvhXsXIA2Vwu2pz2\nb3oE1d2jtqF8edxVvfcd4hnt/tioQkME7N/3iaJQcR9ELUXJLy4S7XHgw1wM\nt/1X5ZwW+2c5g5etSkOJoCSvNJsYztatwWrxt9I71/HZuzUv/pK1v1KskW11\nj8vThOhZogmIwwxnjkKcP/wVZdHOhLoCgKKaFMSfqdejnfENFHbDQHZQSScw\nvS/j4zoyoFFybpga3NAv295jpI+A4qukmWVnjuDv8K0vzolHnSYeQ2/i0Fps\nNufR\r\n=Tpkn\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCoawhazbuXM1DiYhwyMJ55X8cVHp3SznGm45m6LDPx3QIhAITsCAsHDknRdjwgGPKb6Iw+ompF3EhmJSqBx3sNntlY"}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.6_1614197972989_0.5919591299007705"},"_hasShrinkwrap":false},"3.0.7":{"name":"@vue/compiler-core","version":"3.0.7","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.7","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.7","dist":{"shasum":"421782a4c67cc3f2b7c30457ef446d74f8524f74","integrity":"sha512-JFohgBXoyUc3mdeI2WxlhjQZ5fakfemJkZHX8Gu/nFbEg3+lKVUZmNKWmmnp9aOzJQZKoj77LjmFxiP+P+7lMQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.7.tgz","fileCount":10,"unpackedSize":545409,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgPQ9jCRA9TVsSAnZWagAAP4UP/2KpOmyzrhNA/DVG+D9Z\n7zlMcWBwVdosUf57DmEu1KJOPrdK9FQXvTbaHUvIi8Nc7vrHvm7GxPDQow6a\nKa6TMXe/KXrvM+TndKVJSpyFBeV9PWoXVAX3CFzj2Uczwjqu+MgBeELJQ/66\nwAgTbQYWxrcSjo4E6MPCUZVZZrDtFRBc3/wdV7iz9uI3lZS4U8nysddsk33O\ndMUIIw3S66jqiy7UtlWFn7P6NuNR3dz0TfArTeaiKgWBPdjXiHUUUFOKoBHT\nuKCIUMrXmLiENAlC6quq/j9ORJoFVloaEdge07JI0Js7/wB6va70M7ZU3q1c\njv/44Iz0xvG446d/b8zWqrZlDdPAxwkcGrK7dasQ1UlUyM/LTVa7ifRkh/6v\nDykdOKNDIE/2/cx4c7cffXaHnTIoSCro2rkfvZWNF6kiFXkPQLUwCYnOa4zA\nexDGb+W97JJGzzIkJjTyjSC8gJ5wVvi4IvPT+E8xf71YaaFVGXOsOuxgztRl\nGYtyZd1wSF+u5qpnIDUzNaiB0TR6/pImkE4kArh/e0Ezn77HClGNhQE96wQE\nVmVlLoAqtW9xvOTWT7uHUURqaW204ba50picKnAZx22gZrGFRMVxe3VyFEYL\nN9KIcL0gj8053WQi7olyKkcFlgQTbbzWAlU6nCBlW3e39ro5LqZfbHCsQt0T\nkIc/\r\n=VTAw\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHUe/hTREyyQsiyXJtr8HGWT9OlObGUbgjhgCBc/4AsBAiAT77xzcQQ3tImKVfnX7udLWOYnF5gECQrnvkwkG21HDg=="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.7_1614614370839_0.08105315202638042"},"_hasShrinkwrap":false},"3.0.8":{"name":"@vue/compiler-core","version":"3.0.8","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.8","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.8","dist":{"shasum":"8e24a63877232f7c5d00e97201609da7de1a3191","integrity":"sha512-TFusP6wemgJPgmXyxHiYshtYci1PdAjX0bOSJqxPDXf2ykojRGq9RcTKj85b1fWyC9fnT5HK73OHe6rqZUa8vA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.8.tgz","fileCount":10,"unpackedSize":552372,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgXlOyCRA9TVsSAnZWagAASXIP/3JCKx6ORTIQo9tMza8L\ns042PEJgIqz4+aa+Av6MY3q7dQb8bS0h0WMgtnlkkE5z1xRp1yvIUcmy5KM6\n46WsXrRj33G8/7EwYL6eMEFdBNJq4ou2ymNbEbM/uis3sd4/KcG6miETCBP9\ntZjQug+sPpnHOtM4/JrGCSRg8OkOwMOsKjydqIkYwCH0Ndee/8G6/GTjBdxE\nTpIW7h8iB8nTcl8jOn2/70DCe6/IdO2jVZe5Uqb9BWCriovc+HNn7rMc3qst\nZA2Ar91xbNkeASBRr/+498AJsGTjCgPzBRVK17dH5Rbx5wNxcJBuoJwUeadk\nEGjwRg8sOG+vScUIV/d9LD3DBCT/yuTEPWk/giBalPwRw+InSJjk4548xf0f\nEJjPkbocKtNaha5mk50eZCR+lPsHYNDJncvgpnVZPa3ESzE941SvsIOao6yS\neZ3m0w1VBxlACU2Wm3tGJJFMpokkK17gOenKiX6fwm9ExF3Es634ua6z8B5V\nXc+c6PdZqNebQ+YJHCEyWpRWQ3VP1dIPIrnKwPXlT18EPX2gisGfpuuiIOez\nxOwMOtTK9G8OEY7Xgf1HEj+gfTD+Zy/yJUE51uRqQhuX/GhLUVWuKAz6MGWP\nQuntNf2qZ58pKJM+j5b6gEapXlPx0XQnw97rjFME1ZKi6hN7dFFf46kjNIz+\nHniG\r\n=gub8\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGy3A3/bOcdG6nn8xM1gBqDkKXnFdlx/4QeWALUci2VnAiEAz/uXO2mTwxzL5l6Rs8xfa5gc1/oPQP9hqHIgIwYV/lU="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.8_1616794546143_0.06234061712976047"},"_hasShrinkwrap":false},"3.0.9":{"name":"@vue/compiler-core","version":"3.0.9","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.9","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.9","dist":{"shasum":"ec7efa676889aee006fc43739ee4a67a952ac623","integrity":"sha512-bHAPwfVoLhGx8d6KV/OfGf/3gwpymVirgfmSyhgv5YuXDybLa6BwjSLvhNMAyDP+4q4pp0p6g248LuoOy5W6OA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.9.tgz","fileCount":10,"unpackedSize":555182,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgX0+GCRA9TVsSAnZWagAAUOQP/jsCaW9Iga0e5ZA5t51f\n0fXMVT5u4t6xfMs7FYaOiPPP1iTMWlQ7MUehCUYHUXGbkhkeQh5ANR/QnWAu\n5dn4m7mB8mV97ngaXCbsMttU60Q4mtQeCnzmY3RkcbUKtzMgJnYiQxtfZEtL\nDowokhdrxzaB4DVkU68FU7HKz5FrqcOg5fH2VQwQgAj0YXxeE2BhIodG+MrV\nDnOu/9tu4RsNcURafjq1rYYgsRH4PDHrgFaJLgo0jQ5NVKrsr0afYfgXo/Wb\nP/ttUdEBX62dPhi1gsdi3cYEqbZXKGVhV5Wsk5ix4L1oOSi5hBD/Nw5vHHPe\nf+RnK5WLkY76AY7odiVyMLu2zOFKMDLhFpPLj7Mj5LOPLIOOmFP9e1T+mCaF\nmW63+TSg7So52Y0EAmAAH6CpwWXcHvJOKfPQuoCq8pvF6+tITf6UjzC1IyPz\nPgIPhf9iGXM4dNkHxiLTxn9jfnzI+Sz5fOc018pqzLtaYWHNEcQU/aJUWoWm\niHC3p0Oc45BD0X8lg8CRqTxzUfEt40GkMCGpdBeG36O8hmTzS8VwbQjR634P\nVViVQgc3D4Hucz6aE0V6YklGSdU1baSOOXikIZ3KnH/mGA9rh1AgekqfqKCZ\n32dsLyhGD4j2bb7m9LVJ7L3do0uQ02s643r8TGH3E2cfSa4+CnhWUbJ88XoN\nwRCU\r\n=yq/n\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCtQ2sAxUEVNOcBnkKGpBBMaSGKnTleFgv9fett1GB5tQIgTM+r9FqfsYbTSxvoOdmdkDuF5ncTefG3J0q+oeeVhlA="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.9_1616859014095_0.3586220153664008"},"_hasShrinkwrap":false},"3.0.10":{"name":"@vue/compiler-core","version":"3.0.10","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.10","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.10","dist":{"shasum":"ced92120c6b9bab7b6c44dfe5e3e5cf2ea422531","integrity":"sha512-rayD+aODgX9CWgWv0cAI+whPLyMmtkWfNGsZpdpsaIloh8mY2hX8+SvE1Nn3755YhGWJ/7oaDEcNpOctGwZbsA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.10.tgz","fileCount":10,"unpackedSize":555807,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgY7zbCRA9TVsSAnZWagAAzuIQAIpJbQ8ZsBvcB74GdM2+\n7gg6TppbBVCKP8NxQ0RAPFiQ0WkXA67/0gr1Nm5bHZTEGtvDXP7Z11/O3Kp7\ngM8dZAIuV7I2bg4xuIo2kk9ce2Bvy3FakeKg6oWvwU+4nTJxiBgbSznpFlgf\nCr28lRHljV3xwDjiZJ2jzKJOjamHyUA9NijxD/ye+h+bgVQEH5s4uy7biWvF\npJwJYyXh6UYwkefDShSnozBGTM7u8wZBHM7LplCwqHxx2oPiawueDgfy4TB7\nFNnbS6uIMvxDeSPLOaalYNUczq5rlo0PTw1Zpg3MwVHxf4UK3GXGt7FtXKID\nORnSxhidCVB9Mdb7xh2MXZvXPwWeDXoFuqEoLFSPoH6Yv9IsmuQ/7viM8gOM\nu98RAwDJnJhlmv8QVNkNkIbBNoQ9vKYPVEijzE9pX3TfiMB7kMFhwGsEg8m5\nbWsRzzBcR8xssTKJ349LxrEcwlS0l5lNgB4o2ps37SOzUNzUmViEPYmAxNad\n2yQGEhX4cTLcOoAPcGzkYVZ0mSzJCssSykxEon172b3miJWe62mNcgj+Cb+r\nfo8qgvo9/B2VA0c/ZbQBHVuEEe5dn5WE8Xgl9z9zQ7imNFa7H0chvCNmQLaw\nxEFuD68FVvLVPFgCQ23IAKenPr7MrYuc/T9UcAINgoRUn/YeNP5E20tAq71X\n1lF6\r\n=lT/H\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCedYe+HvdK3j4Blz1duEphPbZQnuXzLZPlzQfKCvjqAQIgS5bVhRt2w8TOZolnNsd1VRkL02N2l6kKVkCIk3pnggc="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.10_1617149146833_0.12700021642172987"},"_hasShrinkwrap":false},"3.0.11":{"name":"@vue/compiler-core","version":"3.0.11","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.0.11","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.0.11","dist":{"shasum":"5ef579e46d7b336b8735228758d1c2c505aae69a","integrity":"sha512-6sFj6TBac1y2cWCvYCA8YzHJEbsVkX7zdRs/3yK/n1ilvRqcn983XvpBbnN3v4mZ1UiQycTvOiajJmOgN9EVgw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.0.11.tgz","fileCount":10,"unpackedSize":556183,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgZlzPCRA9TVsSAnZWagAAlEAP/iUuMCC4OkkWZ1NKk9Ch\nJtoPqR1lCSeEPPYY5lujigZm3/hL7ai1sqqi2+gN7rnnRkYN6IoPFgsodbmN\nf+R5HluO/znb0mpgbq6kfiO5ss2746qo2ZmLimHPuglF4oV0qJfB8+dK32Bn\nf6edprGVIm/E0Xk+CcRuaEAYA/aoMYENdaPaqjpnR4VyndMfvMKpLgPKsUUC\n8kr4vPXxPfWbBgUF88+A/rjUKmLb60sVM6lVCajrh0SphzQdFK6norWFCoxD\nfLLCT5PbTjwNwfRRC5D3O+CGgj/T0eHeT7T1mmcV+bjVEJhVK6f9/pICJDr0\ntdrgWthwnRaAv9e3iZQCn4hWTCOhLXxTqNBebIRSNhxpAcVHdqPRxHHqKFqx\nhPlIEBnedxFiz7s4cgeMFoLpCz4JnyehpE9EmBQnLhpCESRB18UGARUqVrcU\nsbves0zHKkScn5Tx4+K9q/4ljyknfrZLMwyQLrl/mj5YLQZHu7/n69YlKKEz\nF47nkf18LayxsTw3Qhz/sgJGQOZP7gXd2Lyq7oTnocXZk/MjyNZ7h5DiYYca\nTPG9nze+GYOrFafFXpyHzXuDPCAg1i+Xdy5HYsNjoGuXHHvIo2u+RadhFUOj\n20IKoLHBNSmc/oM+4sRbtl07+Yf8bxIKL2pcJHlIzFOO9DoLMSYbapu6fnSR\nZ3+T\r\n=uMFo\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGVlVztoi57AQ24R4bXOnsl4UKK8H5BcMjEi4jyMxKNgAiEA6d9OMXfSMhM6ebgMHJMmJ9nfyAkYq9HpqhjPBeGsL6Q="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.0.11_1617321167118_0.28665270145667465"},"_hasShrinkwrap":false},"3.1.0-beta.1":{"name":"@vue/compiler-core","version":"3.1.0-beta.1","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.1.0-beta.1","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"readmeFilename":"README.md","readme":"# @vue/compiler-core\n","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.1.0-beta.1","dist":{"shasum":"ba2d710560bdff7669fba9363a5b34bdaf20b7d8","integrity":"sha512-ENEzchFUo+BBDznujUOpEN3kCAVAR8rfIAyu0UDyu1pD6CQo72nFTuAqtewg5dBpxS1eFRHUp3XVXkzN7J8jhw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.1.0-beta.1.tgz","fileCount":10,"unpackedSize":609068,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJglvOECRA9TVsSAnZWagAAIPUP+wWwOnG6WMstlE0X/YJd\nPkjRREZE/njzeyQnKpF+zYkT57pPVMz011qT1YoFvNvAjpIYoWJK0gOOUGJo\nH61wY/6wDrlmAHfqgvSt+L/fFSstYDQGCBqiCqD4j/iPjX3o/ku3dbTfBC7f\ndGtMp+P1SwZS6VIXyKr9r9vMZ3xIw3nePl2y/ifbcLGDYjzhodDTX8kCX3hz\nipROxSy4JLwxc2M7pSTomEHX9/3AmRNXr9OyM4Ppao0qxTgNnbzABej0UwGy\n3yyn99P1qecCyRbZpnvqRllmfIiEcB+yhLiWyJdeZjMstm7+epIAP/2ARzSS\nnNRUAEdrHh0vQta3YCQoBqqc6nwV3J3ky29K0zxDSeD7kNgHHmqfgPu6+DR7\nLSi19DPYJ+yGk6PIhj0MZHiQd1vGZdA2vJPn376GVM9UqlZTEGnq7GV6xjfn\n4oz8g0eLXmokY28t7gQEM/M+3KceLwdLEnfSgtlL0qqG7w04hWCVM+pPIdD/\nJ4UPFx0GOgCBmZXmF9dtl4/FsR8LX7rQcutKq7Xbm+PWHGBrsQsGpdWN0vwU\nu7biQhz1YxrIECiLyGrRqd/rWAvsRIIxAArTpi9oa5GUySPNy4luYBeEs3Ba\nFvoAZmOJ6mT/xHklSaOai9nvxF4AOvhxTdfsT68hPi/prf4Q46n1IiRLrG/k\nV0j+\r\n=5CE9\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQChsIhs+hM1BzXC/hQ59efWZd/FE2q0wQkFU1Xh2uhLLAIgAy3KaBd1iO9kd6GyVbXymnXyTuraDRYZWCLEa60PvkU="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.1.0-beta.1_1620505476117_0.7291421442644213"},"_hasShrinkwrap":false},"3.1.0-beta.2":{"name":"@vue/compiler-core","version":"3.1.0-beta.2","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.1.0-beta.2","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"readmeFilename":"README.md","readme":"# @vue/compiler-core\n","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.1.0-beta.2","dist":{"shasum":"fa66626d621801676d11fd28e05ca43f88c67b2f","integrity":"sha512-HLd5kCiZojcbcu4+PqD22XKkmqvo3XuM7xRAst3y0KXMlmCnkHIK7Z5mmogPjf/xBBZllWl2CIy9+bR7wrdDSA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.1.0-beta.2.tgz","fileCount":10,"unpackedSize":609068,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJglvuiCRA9TVsSAnZWagAAv/IQAIcKI5sgrfLbX20Xd2Sw\nG62SGRDOPKpu1siCfGmLri4SjPwoZEuDILvifZ02ysSzWwBjM4XRaHeywA2X\nxPHrjE8CfzI6DKN/GCdz9p9+tG5HDvjDkFvq6KZRQacARuTFMNc79RAV+a/A\nzG+/+fNNBRcW6rVnQrd72RimymVRMsHtTymQV1dGn3oisKqRfm6v3Kh3FinO\nNcwxKl1EgsuDU6jl0s+gQP1SNGa+RQWOPjeY1Z/e5eFAfkv/2KhV+06kogGB\n1Jqb0uvA/J3EVw64nhrFPVYu2QDHYDyR0/fRr+7ofJgliMX9s0gQygnr8VOf\nVkSelumkSmZFN1dazpI3z8VYYPB914rK+K6TAL2BRbLuyIhE/6hEvLcrMGVb\nGHKpPLpJiuRqONhI3ArDa7xkMj1o26YTz5773gZigt9P5uk+d1cGJjfoQj1E\nLFtb+bK1OyY58x4E5RFSaZX7uglciS+yOYrP8J4lqBFriyDXzRGl6RxFLojv\nF2RpMh9XUQeEis/egDkFiwttj4g0SZOhLWewrKiXqOR7z7UYIfASL4zOSjO9\nZLJJLBjxhwqSO7wzcEXMp418E7ZRFQ18MoZPlWNJFomuaLoCECs44so79ReK\nDWpqtNRJqCUVW6z6kvdP3JM4+Aivr9OpQkywGPbzYrllbaYdRAojygeKFRQR\n7xhY\r\n=i7yQ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGhaRFz2FIx/ofrCQdSyTjl2xYnd9R4iDqHDwIyhMxjLAiARWYRussO1Zzaa/RibvFsubbblHBy3j3XEQow6w2yfZQ=="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.1.0-beta.2_1620507554177_0.6578947663887482"},"_hasShrinkwrap":false},"3.1.0-beta.3":{"name":"@vue/compiler-core","version":"3.1.0-beta.3","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.1.0-beta.3","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"readmeFilename":"README.md","readme":"# @vue/compiler-core\n","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.1.0-beta.3","dist":{"shasum":"87fdac4c56f2a9a4182d930c70fc77f1efd8db45","integrity":"sha512-4oviMm56Bk/PWDDqOx0DM5RsYMkMGmP54iK9cC8tG4vUTU2YagR4Suh7TJhidy1+SlBVGgujPwiOHtR8ehN1yQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.1.0-beta.3.tgz","fileCount":10,"unpackedSize":610706,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgnEqCCRA9TVsSAnZWagAALcYP+gPoGskGiexBcwcJfr/X\nt0tsbB9UjlOYKOkoN0Epm44W8kFa1cLg+HZW1HPNP/sziyeZRHYi4JLkuUVP\nQftKmSnZkMM96r7axUqWt8Q2IL18MNH/EkoBtmIuHHhSy+Srs3KC4Cr/SfkB\nkDZ/Vc9O9/csYRAqhxtgPmbp2PJsfmjuubyX0tcelOndOS0to/p9zqi6ltme\nOvOW1ntslDhv4aAfn5lxwXF1bHF74b0ajYPGJKUbdeC+IJOuaPNgg9iid8h3\nzGsdL25s4472nG3nBXuEPUI3j+MWVDUKo8K6uHvBSbXg5RkGrxXGhhG2gJOM\n8ujasRodHC+8IrIoQsjjDSxKcIemIV/l+UI179o4Uoisl2k4VehPeAftDbL8\nNgTi7iw8vVRvQQ4B2uwy4XabYgEvqUqZHZOxvtPyVyLAvI+2nFiegOcYLjED\ndNsZOxj7fIOBhVIA+mCvJy59AQU0QNUu+i4+9gwb8Ifvw4YozJKsB0+SYlgm\nHTLn2h6KRtt2q6vXO+GlhbBk630rszD/tz4fmoEijgR6NVAw3p89hLJICVR4\nWUIR7AB29EhT+5r6hnSaaLoP6l+iJp1CAZ5rRrgeIa0Spg9T4s4iOrEcvIa3\ndPDCWDhSB60xtWZnZxEcMdjhj1BR090Ire3VJAGw5PxXZdyVbZBSS8noXS2A\nw4S5\r\n=/n9c\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAqvmZbhfuoH+2j1qzR7likWLUQ/5A7hJ1BhPUWenqPrAiEAu4gaYHdBZhew7WsYjnJShiS/BHLgUzz7UIwgCQUIhGA="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.1.0-beta.3_1620855425912_0.8126419188326783"},"_hasShrinkwrap":false},"3.1.0-beta.4":{"name":"@vue/compiler-core","version":"3.1.0-beta.4","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.1.0-beta.4","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"readmeFilename":"README.md","readme":"# @vue/compiler-core\n","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.1.0-beta.4","dist":{"shasum":"ed8b7dd3d2a42688283875de13c500099fe5d612","integrity":"sha512-ukGe7aVKkzD3lDAGeiCPJutY0+FH0JEVglVRY9pm3oAYkX3gdOfrfUCZKx2Vm0IGHci7oyfnIigT3yVTEvcBRg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.1.0-beta.4.tgz","fileCount":10,"unpackedSize":612902,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgrDPgCRA9TVsSAnZWagAA6CgQAJk1gxhkfLPKPOYDg8mN\nr+Q18V57sA27TnNrSNTsmgDYtc2bp0KtE0HM5H5hqa99UyvvyWO/eU2f7yA7\nD1+zHkYSEklimVcgnWIwohQ6EO9yfr3T2OWeoJD+HWzurJXUOCu0g4/o6MSg\n4CwqUVwOkIn7/pSUpv10j/rpmYuUlKSElHlhdH/5DuJNsE7RedJ9D12Sc5+e\npEz7oxIXmfy3RSw1bzl3BOvXBLOP5oqxFUK9boRZppK014gBkVTLHQ56wlNW\nWlnXNYRa4C+IgCt5CCrVslMNXsMgoudJoVPA2Ud8K4UTrrWkVuqtEUdkq4zl\nWGQW287XWIlHZecdWj1tTnpUO5TN2Mmw791bpE5YE9GXomrS4/FY7dAq0IKa\n3S23L0QrYyYandAF4UgXA8nUVGfTnA1/+fYSJAL0PaRNEztbR2CYLEw3JabB\nsheahcFQTs7AswbZRpmT94PTustLKkL8ZmS/f/GpFJmo0rL4cpWw1sdsbi/l\nw2H2L6vRow2BaaeYQr+g7XEMFurrTGM6coxQ35fF3wvQEHA6se9EWVtoqV0s\nasr0Zmr7zSb9PmTnrMppqQBTnTOj0Ff5u8aTVQbKFhHh4EKVh+44vnwBq2U2\niDLTikiiYDf9PXg13jY1WhxRCYqPdWwcxWkUnvj8GM2om9kalcUHo5VOSJM7\nF6X8\r\n=tFGq\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFVXjETmoelwhCbJGdVTdrUbsPbAaznaCh+QYHL+8W5wAiAV8ydjlAuhFaU0jrdKE9a3Nhno0uSInWEThTU1k+ynig=="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.1.0-beta.4_1621898207383_0.16272238844492826"},"_hasShrinkwrap":false},"3.1.0-beta.5":{"name":"@vue/compiler-core","version":"3.1.0-beta.5","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.1.0-beta.5","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"readmeFilename":"README.md","readme":"# @vue/compiler-core\n","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.1.0-beta.5","dist":{"shasum":"e99427a810d1f1603d58ba5e213f83e2c54688c6","integrity":"sha512-pL6XvPUvZLsGd6wHxZ+KXBEc8oOiKZKCuQ+DGBU2HWSvSP0YrIVA2y1fc/8NP7dFvBq3Eqr79oIPDIQHbmVDIw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.1.0-beta.5.tgz","fileCount":10,"unpackedSize":612902,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgrqpfCRA9TVsSAnZWagAAX4AP/1eCDXgMXdF2DSGFlZX0\n5/0+2PbKlRJwID3LA0AbVkRlPqugOuP3D0k6uo5PXVONtXXEFngNenOBjdnL\nEioh51Z5eeCUxe5vWSNMfM9rwg1Y29dfjzktOA2VFRkNQ26+P1ZcDD/Kusa3\nmBht4yvFrZ7q6rENSHBT55SqGBDmqLboxScKZZDoBeB+ZUMPlveZbPeYlBFN\nmC7VCVNqmp4rEhYhRxzsyrLfkVCJ9AoPZmVtVORQpZpiVTUbyp+tzdrFHwSn\nYJkkX5ztBb5vFrtKT9sJ939/YgBqN77v58d5uO4dFHPZtTk5ex88hHtB1QNx\nPntebAta7Sw8ss/XNbS5d7TcDWA7XWVLRQQ6z+b8yWVr2RWh0Sra+oO6a6+P\nBaCgKEDmtU6pLBAWzujYQEwmiisAN7KFeX3xLt+ajO1DjCQS7PoAthG3eI2X\nA7N4R0hhtew4QQf3i1Q+I5bLGDyK2EuKmA4Px7Mdjz617IPXO7RwHJKTuTC5\nEPUZ/hhwKU4tEHLkXFQI6G9a/QyL/WMKOhmyPPIiT+kv/5D4wAM5imTBg+/t\nuVDIFypPjnsJcI/zlmJ/hWRhRiOMxZKEDhyuVS46HLZeUKc0WNY24ED+NBON\nlkr1RB3KjDEqDkkjiG8YDkjEx1c/rznJdJR+MjUUNhBrP2m94YyWJcXyM+fD\n63K2\r\n=2psD\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC1EV6bLJQUdO/qHARnld2ceonuKpZreZwxTZy8sERw3QIhAPF8AmEdUZIW+j+b4nDjcjcLrIqOvu7iSg/kAkB0Un/V"}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.1.0-beta.5_1622059614770_0.599775464862959"},"_hasShrinkwrap":false},"3.1.0-beta.6":{"name":"@vue/compiler-core","version":"3.1.0-beta.6","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.1.0-beta.6","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"readmeFilename":"README.md","readme":"# @vue/compiler-core\n","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.1.0-beta.6","dist":{"shasum":"19238d596dfb70bd03c62aaefab2022a22264593","integrity":"sha512-8HgII0+tgOvSLtw8DFgI0Maobk8bsPygtzfgH/erb5NLUX73YI1xx91pGtUxLIZvJsVjnF3X4viW+aJqMcFhyg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.1.0-beta.6.tgz","fileCount":10,"unpackedSize":613511,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgsVmSCRA9TVsSAnZWagAAj7AP/RSTMfe49bgITJRKyJnv\nMQKELs+ma+2+LKwVNdquE8AfmYTTBEmtrIRgZ4Z5RwMptfiWMRRAgkt1S8Mj\nh6hl2vOeC2gTz9Nxm5GP5I0hM6KCxXl8vngUYpMLbPQ0XtRjsh8VzT9NoZ3B\nrywzXXyTIus7OhxFvCsKqD0n7MsxXVx//IApTsMVovFc5/OCbZbOFCCde68F\nhh+PrhGX7TRW0BH1NR798gihWWd/w2nkd8ubyUKfdxnDa7Bq789VQkNd72Xu\nQKSsOkBqUC47EVS5AIMqpdB8gDpsZDIDtpwDKjvQT3tUhco2egfEXm1nGbNM\nPuJEbzXQjHRD1uQ/RQawo046b2kKKTahAhiZtJzV8UEP79PRR1TYD46R5ZTf\niKR/+k3OYOx+txtEYdTMsNVscLwR6lsKvezDbh1JpypdF2AGAczgKwVB79cW\neNvSBbEWQS6S77wKSLAM1oiUlHf/iOoB8EwrFGuyP2Kz6O36qX1OtrIkftBo\n0MDx4XDqInsUgFq++yhXoBHG04x4VBYyRBMu2nOoKDCjQoOiGytPW5Iyvv40\n+Fy8u91wni/zJfhEGvxRxfuwAV/LHBxPx1tHB+7ymyer57icfnxZ2CIJoUjw\nCmxdQ9+FyfFc5xLnMmj4ebVGh9Mu8DW9j+rANeSP45eiNtDkjYK8X6/57Iqm\nQ+CD\r\n=mAtN\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC8NJwTvfCQxuHp1Gx3+XeoxaM3PgmxAZPQidcaLW7/QQIge9Z4OsHlegC+3pO5Gv9C7FY4n3fDHZbUYBqr7z7dI2o="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.1.0-beta.6_1622235538392_0.1356910474862767"},"_hasShrinkwrap":false},"3.1.0-beta.7":{"name":"@vue/compiler-core","version":"3.1.0-beta.7","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.1.0-beta.7","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"readmeFilename":"README.md","readme":"# @vue/compiler-core\n","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.1.0-beta.7","dist":{"shasum":"a72d3298193b50616be3957d6d9c8573d81367be","integrity":"sha512-P1QQdK4lKuySGEOoLu6vhajMKVguLyR7Oc5Rqio0JPRKpdBNO6CWrD52S+kkkAssbE+rilr0Rf1ar58SqWS01Q==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.1.0-beta.7.tgz","fileCount":10,"unpackedSize":613561,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgt+ZKCRA9TVsSAnZWagAAbTIQAIwZ5J2083XGYxVC6OtD\nhH66kTMI4TJIAnZEQL4Z9AvsLa0kV/44hLsAGYhl5N65yuH6KfOCFFJRJUlJ\nMq8WVSlui7SqAfxDQVi9r0nKnZ3SVXoqLanP9YG0Po10MAyf1Vdz5k9ExUMm\nLlJHjt8Fseu6aODyvOxvlPx7jd95geP8gud05wv3yHuejLl9edCcDY2r7F/B\nAlyqNo14TAS3gL/xbb+LP5bEL2f0r0Be01wBfAIZnCN21QcXptJxeAcp9Wr4\nvkkGO4FEpWb7w8U5FzouO/nofyjRKWL9wbJd26Lx1WXT2300MFmXaRQ3Munn\nb9NfqtKDT8sxqbcbohlBq5i7is/aiGJObgKfZEATMfuVD14l0szTxHCMZfSP\nvze5PkJhgwpQBMCsHhSJ54dkdprUd/75eIJfDPaj3A+Ws9XonFZfHBDM6+zU\nuRQEs+nOGoEQZj33i+UvapkLH2pa6PASUFhIwsLyt4Lmt0Bw+Lgy5RGMUBSQ\nti9mZZ+2Rm2jY1BvRwcInwTEwy2fcKjyOqbIU132JEg5E8ABceSfR9ME6L1V\nZ6VOM3nqA7refu3AV4BTKu5dyo8BC//6ILxh/NEqdIIN67D75Ne1zQwCVkBU\nJ0zYdKWB0xUhLKp4iQXPoVi4cCatAb/JK4edHfO9hdRQ2DY5MWEcKx7ot7cP\nQj8C\r\n=KdmR\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHtPZ6cO9Mpky3KjSoSaqeOyjlYLDmajkbU8fJC4mfNJAiBULoBfEGxOM/0PPlfLw5N88dsIRDdV96s03JgO42xzqg=="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.1.0-beta.7_1622664778141_0.59013393350639"},"_hasShrinkwrap":false},"3.1.0":{"name":"@vue/compiler-core","version":"3.1.0","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.1.0","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.1.0","dist":{"shasum":"5a79db95f57a12445fe1a55a40f34f75e2cb9ea1","integrity":"sha512-fj1yKsjpKpmKXMCUO1uoY1CUcU6g4tiEiqwxSZMlJOEXWhCl6Dwa+tLprIC3r6IdPx4R1HrZK3iuqO98r8ENDQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.1.0.tgz","fileCount":10,"unpackedSize":613547,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgvkuTCRA9TVsSAnZWagAAl0QP/3LQdgnj9b8qGjMX349n\nEUnoxtuPq/vtFtkjUv3+CIhiaaMLVq1rJG3oMknX+xQRi9wrKbNgfbrQZeDj\nrABIgH2NzTqO6akRqVtVwXftrAfsB62r/GII58FIaA5HcdzeJxbKxJGCUehF\n3YYLcJTmVCVqgslJxuAiXYN97rosC2nuEW64X8QQ4GPZCCcBEJUJK1fT8Dg6\nOq4Bn1NrIb6zeMs0/6d6t20qH95PnO0L4chtp/anmCwJdccXFm+YKCnNPTLf\nLwpIfY2aMhuAe9mZrL4ZQB+afWgXLwA+4j/SUD0UElKhUEkS2ioRv+QkNmWd\n5PFJOp1jEt6wwn6SsXE91y2n9KUMwMbZmiJDNEalLLS0WVW2iXijWM9LIDYr\nRQQm7aaJFOz05Ses2q58QxiVIPW5L5/xTwo+hmV701OZYJ1y+0ttoN1tMI8q\n7bNIVJtYmnVF2HqQY4PsYwhJaTTbfwf5km293SLc529l0QAZGygGExQjggzM\nkTiEHnOQKLt25Fa44FeJIc0CwebTZR6XQn4dMnxu585I1HzquG1g/mYLfHoO\nWDlYYZq9BFh4UgveRNK16WLSn6FmKya3zc+/q/2eZIG/gEXOHdYHhyc7SfZP\nAqHot7m5vA1GRLuqpvhuhdAAxYwDT97OeXtUfrgKV0/iXNZx01tATVwwP7j+\nOAj5\r\n=UfTx\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBLwa8riHgLRMW3RNNylS0eARcK0+Dsc7HaG9TKrcFlTAiB4PRhImotM8lovhkZViwJwyhaheqbY/QC34SlkJ9FkuQ=="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.1.0_1623083923745_0.8795866130889851"},"_hasShrinkwrap":false},"3.1.1":{"name":"@vue/compiler-core","version":"3.1.1","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.1.1","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.1.1","dist":{"shasum":"4f2c5d70eabd454675714cc8bd2b97f6a8efb196","integrity":"sha512-Z1RO3T6AEtAUFf2EqqovFm3ohAeTvFzRtB0qUENW2nEerJfdlk13/LS1a0EgsqlzxmYfR/S/S/gW9PLbFZZxkA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.1.1.tgz","fileCount":10,"unpackedSize":613547,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgvoEQCRA9TVsSAnZWagAA7igP+gIs5v0agpSl6ixRjMAW\nA+V+a0QXq8Nfo5TQPnuSGt3hACDL2ICbiKAiVI+xbfeea685hiPHAW6TshyX\nfJTzCnJ9QJN0gEUXJ9T52BmFcAUwqe35Ga+XVyUkmqP3rZ47o2MWbCcFYTwj\nK5BAs30k6bAUjPh1T+hFLnA7C5KbvE2lJw1rHn2sWjX0mVqYdS7zXA2GAU05\n8kjjxyTXq+gH2bfReFajET6UhffglyT1X56vf0BMLd8XZEVIzMCLBExc+fRp\nrWoqMf856+VEayTuAQQsLcF9Ui8oS1o4nK0TV3suI2ikHprw02cRjn/UNG2f\nIQ39myr59wCNSvO7YCi0gzmbM+dmabpXUrBedcudp7xZLj+grBWfwMKoYtNZ\n0+egjfYONWVy1xKPxAlQLoeAY0G7n4f6ha/MkHMdoMSDsQhMpPEFX5gADN98\nqdP1HaDkTwY1Yh4ic39FTsQ4zADHZ8w4HLTOgAQSK6FJh2/V+Kvoi1/xCNEF\nbVPaYbRfE+xS1WfLh9LqH571JjDPuh38sNvj+WMUL2nJUE0j2BPrJ27JLjBX\nKs7XBekrGNk0hzz3VHzWrfnwXeeBHhz6XjDq05fZBWzTp8tzTUPHLVH9nvKP\n45qyUjzefH8uGejLjz6zyHbkCDFklQjydA9WUrTEEHmI+FS5fRJAdRPOQZUK\nk7xf\r\n=fll6\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICSqdTqHh7rqzZp0Ev1yl7sYzXvzMYQb6yzTpKmoLFn0AiEAgNRQqunHQ/5hG+37H+GKWztXZoG4ymST2nUJtACAK7A="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.1.1_1623097615998_0.12967845501422026"},"_hasShrinkwrap":false},"3.1.2":{"name":"@vue/compiler-core","version":"3.1.2","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.1.2","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.1.2","dist":{"shasum":"31ab1d88e1706a5c7a545faeeb64c31bd0101db0","integrity":"sha512-nHmq7vLjq/XM2IMbZUcKWoH5sPXa2uR/nIKZtjbK5F3TcbnYE/zKsrSUR9WZJ03unlwotNBX1OyxVt9HbWD7/Q==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.1.2.tgz","fileCount":10,"unpackedSize":622565,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg0ir1CRA9TVsSAnZWagAAbmYQAJb2bXqZw/EHMSdtwlX6\n80pnx8BSNjf5lvoaashYFu6sglbX67/986PD1/+HkUZXRuPkY87sDwUx7PRi\nsUrqCQlYC4z3ipNR5/GyKevneCQ4oBCAsRYkNA7IHrxcUizWG/JfuXvgs2i+\nZWoEXO1JUSySXcj1SNAPj8V0A4rKtWFahrqiGtnUpSqQl73PDlbbfjZuvkzH\ndwOXfXCN47XTJ3Knc0dDLr06rmH845tS8SyGoFkwW8p309uPInWTT2UO0OGh\n00VcCl8zr6Cz5NOJz21jx7k966t/7nmJ4+v0Ae//xhcy1bs/z/68ONpN4jJp\nbrOI2QCeCROhwfNEihz7WpvQm+jDsxSfZycwxrHS1BI2uPQxrZPmW3gQtY88\nmU+4ojw9+Ch1E4SSVLKvJLmcnw8D4+eSzPx6ofvMq+XiHP72nwQYE0zPRqx8\n8z3MRbOgyf3GIHNK57wldSAJH5bf+w3m66rFqfAjjj9woBuHcm+AeW6w2Vd1\nf8XzjNILS4fEOljhAleGDClmftrEyCBfLST/GmKXVrHzq8Qt+uy6awZAh8fM\npvzxvnDgjTEC2Bvx/TWKJonJc26qxBD5fp3JnMv7M0b3AxWlCNBXhs6PLAmH\nQ5oMp6CMMS1Ouel3iXUlXONxsRtEsVgz6pjAcZbW2Yv9yca+zdweDRda4neD\nutSE\r\n=Irof\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCF9pMipZtbP+jhkRvxi1IL5aEPzVgxkY48Q1kqmnbPwgIgMVR2ksDOa9eqgqU4u09b1aSu1a0AGpN6UOi8S/pXXdM="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.1.2_1624386292392_0.9761653744939753"},"_hasShrinkwrap":false},"3.1.3":{"name":"@vue/compiler-core","version":"3.1.3","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.1.3","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.1.3","dist":{"shasum":"cd9587aa1fda533b1bdf752689e281efccfb7062","integrity":"sha512-I58MDtVa8AYEIa3waLO6/89JdmgpkDAEcL3Vrmlsbnt07KZ5sIGLqaXjzGrOT57j9s8ty0WTYlLQq2rWUVYGCg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.1.3.tgz","fileCount":10,"unpackedSize":623101,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg3k+ICRA9TVsSAnZWagAAKDoQAJ4gD9DgixskA/cEx7OR\nU1m+1eoIHbW3G37FdwMrNb4yUyOsvnrQojwR/xDIiJ7wDdUaqgkbamVOW1Zu\nmWkJiud3V4ROWSO1ntU/DSYqy+xV1KYdm+/Km3/Q+ZOHMFhOp5wh13mNaWsm\nix9pdOMw0QQ6C3KN6hIKmb7SpwOpE1sSc6oqLLbgk19zNwj8XZs8cm+1H6yf\nrd7JxKq/uJKDlIX2bFFvzmO3reB24jkFe4Kvt9dnA9PpdI7c0U5aq5bOEgV9\nxI7VgGUHq1N7NNK59yEBDkdG7C0g/2GVNXpN5sEW3LcqbEwdREPnnywIJ51+\nb3/SOvHd9+xB3V4YoBai5Y4fcC8HHGWda0bYBDj4FbG4Lu8J9UZ7r0rjk+Xv\nWbD1oXYl5GwjqHNxtNwZWkQB0BdOWXjj8sgDxbePcA6XuVsnxXOdAz0ScVEv\ntaNZO0ldDrLvGL5Nrymvuo7uytZ+N+3rbLSCE8ggleX21IJODjC+pRoNPMud\n8zR5WtT7/fV+nrOq2W3MF4tPuJ4ua67aH+gKaqFj9SuXZfXEQ5vrURYXVYVn\n8CJOzqomWobGjM4MP7ZylYG8gvkRwEoUtpa92D3BtxhqP+8YPQhAy5Oc/3lC\nCNqltUjJTsd2tZVlaXX6nX1arqFtNZp8WLWwKBP/QNFHA2Ydq2yAArNyILf/\nLMtJ\r\n=e1J5\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCAeW4zP0HbTYAmJNyBtwTUXqbDn6/HxwnVrLJk3L9yTwIhAPxiBYAdlFIN6r1k6HfasdFsiZTEIYsMNEVx5Adk5pN4"}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.1.3_1625182088251_0.927063541346447"},"_hasShrinkwrap":false},"3.1.4":{"name":"@vue/compiler-core","version":"3.1.4","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.1.4","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.1.4","dist":{"shasum":"a3a74cf52e8f01af386d364ac8a099cbeb260424","integrity":"sha512-TnUz+1z0y74O/A4YKAbzsdUfamyHV73MihrEfvettWpm9bQKVoZd1nEmR1cGN9LsXWlwAvVQBetBlWdOjmQO5Q==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.1.4.tgz","fileCount":10,"unpackedSize":623251,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg3wigCRA9TVsSAnZWagAACDQP/iLr6YVIsUHeVuDCFXKz\nSclivOLFm8JhVWLjmUzHB4Jjm1AFrCGaabqMBrA3lpv7SDgVsCvVod9v1xRe\nOObt0cmfljgeSod2QTPruNILIuIU1InfslZqijOurA6IuUhGr2zXZefQDHBY\nfd+sW7PHxipBVdmcfNvkgpl8ADk7r+wj8+7YX3Qvu0HM6hYzEDqlYr7uUT/n\njNWcwAFwoX1zzi+UXwp5hRnZWT2/NteqS6e05ZiywjN85in0UyS4Os2jXpQr\n5U5PwlzWqsWwzHCjy0d0fJSxfMBiSqTsOfLH7W2v1DkbSiHIOhIS2H5gmnmd\ncXV5CXXjY7kP8YzEiJUpAnsov6edtaSIQRdxP8UTBG/vyVlPVO+ND54RipOk\n+3A8lnejV0zyro44e2Jo+FAuN3iIpBoXTLaIzgFQ//97zlTTaNgQQZTrPWSh\n4zkIqPLpQRkB759z0PBPbPOE7N6j9wQyJWdjTIAogNUtFaUKjl2GTpPGpJgu\n2ioVFx6SQJJZyolM3UepmMwnyuOB0ODGL93IaFbzGakRthdyiteE4jigB7eL\nPEAkv+sPXeIf1Wm2MmznmCI71K2wpDjKI623FPKzNBBKcJJpC/COdRBoTUIm\nVihSMSxyn+1rQ2jFnw3LICwpUgIx25ncCokxAMT3x+6F6t0eK/IBsmwjxiya\n6ABT\r\n=fqK6\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCxUeefKjHO8fvnk34RXTK2YLy6NsJIYz5TXhP7flOngAIhAID+R5UWZz5A7cDwu9ZCz0t6CbtRL5bzirZzRuyrL6yY"}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.1.4_1625229472183_0.42687179967676103"},"_hasShrinkwrap":false},"3.1.5":{"name":"@vue/compiler-core","version":"3.1.5","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.1.5","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.1.5","dist":{"shasum":"298f905b6065d6d81ff63756f98c60876b393c87","integrity":"sha512-TXBhFinoBaXKDykJzY26UEuQU1K07FOp/0Ie+OXySqqk0bS0ZO7Xvl7UmiTUPYcLrWbxWBR7Bs/y55AI0MNc2Q==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.1.5.tgz","fileCount":10,"unpackedSize":626623,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg8bXrCRA9TVsSAnZWagAAYgoQAIIQbW+m5fMrJZWtxS8s\nj0xuC3XEyk8tm7HVkfxiwmgvDwINvlmCRBzRDE6dQA6r3hTXS8dufytLK/FI\n7UD5oK0V3gzY275KHzKkhbLhChjyBrKXZ5EhDiUlg63rPHy1Qv/N+4AgL1lv\n9CWzA/bdGkFmvZxsbnMote7uhpk61XIHp6cedpMTaUJnp5rsNyOTMb8z4XY4\nqIBlZrglrhBrY/x1qiy/CpOFhmzou9En6J3Whch4XLzQ+yj0YNgjQU1eRn2a\n+dTCL8jYewattV3JZ0ubwbdMJpl/edB7H8VueWcazjPLSHY53+sBkGH7JdEC\ncZJBHGF1gy/6/DMv8R0e/vtqWzclnABCn/qVTJe3VYEfYYc64MhHLPhJ40b+\nPKbcl0VZaxrunX6yhplHzv51E4yKxr3AO3VisfQpvoeZhc3fGMi14Wfw7i6Y\n1N3/wUj7FJ6Vzg16FdXOab3cR5VLL5Qjeq61kRk8w73RNjC1GBYTJKN+ZI+t\nOfeE8HbCzNgI6xG7e1JwGF4FVscdVXSLvG6OGnhujjE+6RX1J/6MG14MNarn\nkC0Io0li2aF7yTpxoOm+okSGwC7tmkyvVBe7kpkrxUjdG5DovD13rkJGAM1Y\nTuuHpV9GBh6Jxb0iRlSA75GP2kzAmrfMhusPUwM9NqqAorSobpEhtHRpcBKp\nPP8K\r\n=8auZ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAXEN/mbQvSiCVSkK53B515L9aLheptaoPV85lGGAPNiAiEAkHcV0qcobbha00pFf4k1rEU2sywETWBs+fksy2W7SOA="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.1.5_1626453483191_0.26751637187879607"},"_hasShrinkwrap":false},"3.2.0-beta.1":{"name":"@vue/compiler-core","version":"3.2.0-beta.1","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.0-beta.1","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"readmeFilename":"README.md","readme":"# @vue/compiler-core\n","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.0-beta.1","dist":{"shasum":"13c436dd12ea624ac710467f9b07797b640bada3","integrity":"sha512-IkiOlJMn10ke8k7Np/OhkTqvhzsVcbLSTZBM0pgiSWRgo7HExji5W+sNUoLao7+Q3UwkkBaVMEZEBOUaU6AThQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.0-beta.1.tgz","fileCount":10,"unpackedSize":663807,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg8dN3CRA9TVsSAnZWagAArTkP/0tZBWznOcOZ29/JwyQK\nkTmO98hnj3MMLNAQc4kW1sZmlRSs/d/BL5pAwWAMPSgv7OrWvLG+VcaNLoNt\nNDuWAHcU1eStL8AD5d5HWtCIjo+VQ95t3Jar7FkynpT9MUtVx4vzDEW4ao4V\nWNyyWV9VAeReKAv7CiLsGMcDCYxh1Xr+BEFLr6cXvdyh3VRMVqnewpmLJWZG\nuifvlgEpXZNLLZWZRbdHUjQZY4MAxaHyO4422GjNM1AyMdS9LDn/gs0NEuWB\n+ZuFPUB2ef/RmBB5Ar4cGZN002akM+5AfQjjdiG+T8M2IX3mjgjbA7GSYUyR\nbkZIEOum/0bXByTQw0jy+pTOtBTBA6XqVvCHFiolpL0NAQTFzQh4dDb7guAS\n/yptpP1TL9W6PwVgAoLxGybaUGYQMN9nlBcrj3+xelxyKoDcxxXN7DtJSLhe\nXf2bn2mVGl7LWRuoeYDwJ7hQAPUt0Oe/5MzRVF+m24ysw+s5OapH5tYX4B1m\nEaah4MM0Nbn+bRpJcTtfMSwjP4sSo2lBF2cz8OYHtPSr4eEygL6tzQxtyibZ\n7wuoh+CzTLOFIeLbSuDyKO7Jnuywloh3BvOwJSmmr+/ET7ET30VAdrK5uYtA\n3c8fJowXmNDmtoZYlOkMsAz8sXtunqJN8HJ8sXUPP7bJGb//it4+PoNmFHNF\nTZAd\r\n=4piq\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBdaZn22kFmBW1aahkT6AWUQVu4STuoLG/83m0ELSFGBAiB0hOrSx8Zlrt3sjjmHQKPrqKJ0MYzta56Z1Qsiu/du6w=="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.0-beta.1_1626461047537_0.95350244472053"},"_hasShrinkwrap":false},"3.2.0-beta.2":{"name":"@vue/compiler-core","version":"3.2.0-beta.2","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.0-beta.2","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"readmeFilename":"README.md","readme":"# @vue/compiler-core\n","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.0-beta.2","dist":{"shasum":"2bb29fb48acf1bae78575c07c8eb32e6bd98b274","integrity":"sha512-AOzxqOYlWrQqCQ35JA8he4dCOUmBamLh3ILpr+h66d9SZNaN61H4TZbDYz3NckfPlkNxtOEZjPVRnJtqQO+hUQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.0-beta.2.tgz","fileCount":10,"unpackedSize":664440,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg9gyZCRA9TVsSAnZWagAAViUP/1GbXTwRU6eP7j708fK4\nkCtnpFWq4fYNMUpNRFZ9jFyPkNolmhfIUFbVMtLGPU8lrCdZH3MN6oXMA4J2\n8YF9oHfRAomzchgnMo5/6Y28p5Cl5ZRYsPHwGw+ZCEpqdCt/qDYoYghYFH+z\nxHxqK3Yi5iXxBijpVEF4n0VvAYPQZ9s9RYsB9xlSpmGyFYUAs6hJe1At68eW\nxoUqQB/e97GZ5mPFfPo7zaGIXOEOY7YLZm/fc5el8L6ymkMsE7Hq2vnSAPg0\nBMC7usQnRq/oiH2zsOXAAr3iN/VgBylOllDpMysbf03Ll1CEBfdDTK6k6bic\nAy4/tTdCMZu78ICGHdCAdj2Jlyq62XtK+NuHVTdR42Co034idjbdQNT4s+ya\nDs5giLzd4O93PzVVkZI/29JA0mA8G8u2KHSWcdvmHdpkQ8+SQ3HX8y1zCnWV\n3UHj1c7wpHnSIrtDSaOSG9JvCHb/wry5x4Ae/NzddIFQG+ZNVZpVHaC1rH5Y\nCjpFH7jx+AqxLxvDd1XKLeriC7ilL9JQkY+a6NLBFE2BKfsOQegC0y9oi6dK\nONXbCrytelmk27Gyp9snE6cC+wB7ntqRp7W040kgf3Chi/fT+bu8MAXlcTe4\njRfQhUNsn7EFOo1PGaULcCssus3wYPPeWKgkDFd7DTqIM5IWPzOrPzoUySzN\nHRzd\r\n=Zchh\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCfWCFA6SYZDm1VdE5jswXrpJXHidLhY+miQHvGUJMGIQIgCfUo/6p6xTilMP9xhhFTFG3Kwl45fGbkgYJ6kqcB/DI="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.0-beta.2_1626737817039_0.5799641889636398"},"_hasShrinkwrap":false},"3.2.0-beta.3":{"name":"@vue/compiler-core","version":"3.2.0-beta.3","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.0-beta.3","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"readmeFilename":"README.md","readme":"# @vue/compiler-core\n","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.0-beta.3","dist":{"shasum":"3a10628c6bb4d4b5df28bcdb6522a6c7702fc152","integrity":"sha512-Uyu7xT3z3D8+1ZWDuFtoMoRIPj665Vp7BlULi4TuthXTteKtDy8rygqCV2TAuKJS6APY96NZxRyWd3wlO2qDOw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.0-beta.3.tgz","fileCount":10,"unpackedSize":664440,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg90RZCRA9TVsSAnZWagAAfq0P/AsVcRhZ3cw2JC6HJQdF\n+SZOurvLUNMLGeFBCh7CAsstyo47G63AO83f9POGgFzJbRbBNJKv4oZvxufE\ncbV2WAGR8GCRH5iAKjV6LElDCQqUOXMgKS5g4Engmmprk0pxrKCYzaL/ZrBu\nxCNuMucBYzsOMqXXxgdHfaprYUSZP6DlV/zCXacqYqByIuJM5xu7rFdrbHzx\n0JdN8PJVghKPrdaMeoCAvQplCYPlomXCUtde7qReAjo3Kgp1GLCJ3bMMH8Vd\nO7ThfHp7zY0muuE9p5q0jJMz3xnEt12eU6UFwKF3uOPGUsnBzqqcTAGRUk12\n0OWeTZc3HAm+nvgaRUlx7kT/QI/PVLos8HJZa8N44+C5HMfaX4X1EE0SuFyH\nh2fLqbhlVYEkrNMOPS9RVCEj155hNPXvFgamg4WNVcvl1aMIFPd++AEkPt79\n8FZZEk2CikMhyeysZICTWuci6cL3lC0on0V8aMeixatx93Xr90ZE0vIuYWnP\nT1F2i/1cvkGkYFM0sSJAF7nnVGhFAXwUckxBKlVU6L4eishYtJUNg2FrZSMH\nOls2KPbJx2/VB8InfkGCDC1GPtW6j+mZm2bvcYIqtEiO2JFa1z/xNcp4YJ82\nhw7ZCGKmjTIKQCTpfHC4QyDEH9cQYzsRK2JU2fykb0mSALSct0FGLNIqwvtS\n/TWu\r\n=VBDy\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD9goZGXVx9KTHIl5ctY2MQMvWof13F9JczRyr8C9zELQIgAOKR2WijlYMNBAsyutmYxLe6HTLPWy8Y0lm0rEwkq6c="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.0-beta.3_1626817625098_0.07150817443978119"},"_hasShrinkwrap":false},"3.2.0-beta.4":{"name":"@vue/compiler-core","version":"3.2.0-beta.4","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.0-beta.4","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"readmeFilename":"README.md","readme":"# @vue/compiler-core\n","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.0-beta.4","dist":{"shasum":"5cc738e4ba6e63cf859d5f1e136b60f1b55ccb46","integrity":"sha512-AStaT3fehyb0SYYjiRCxrxyI8lFyzE2Hg8CB8Hf6SM05lONUCileI9Gu3Z8Z+iyho/HL9Z2JhZs47VPpR4z0iA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.0-beta.4.tgz","fileCount":10,"unpackedSize":664440,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg+JRKCRA9TVsSAnZWagAAGOsQAIZmOVGCH9hZlYAcMsdZ\nU47IMacBPu7BLxqQnZ35YH24auchP2QKWqmL9YTF4cuzjDJFG41cX9rkEii3\n2Fy5ByfoOXcign6oYzMq8KzagWIonmwaInGPvzN9Xy/DLc4nQOwfINTLEg0R\nt4YA+Ten8OGvMVvLj03+UB+p5TRQW9HHGlga6T/FG2hJZHl1JwLTY10l6ca8\nBlxA0o3yqK7VoQ/tvVpn6knzhojnEbIi/eiY5RUDX/XmxyBs66eZ7D1apYXY\nU8Kzn46TTa58YVb0fNyhUna4HPsMPVG3d7LMuLpiSQRdY9AQfMPyLGM7r4or\nZQCUetd1A3bgqhTxr9DkPoa0QOs1EUQ3r4F1aLF9lRvufnNEG2Xixw+pCETL\nd4GovcW0j1tVU1E0sPbbwxeCb5wHNIcRMg4w4HCcrPL/czuekCC8shjjXrUb\nfXV8rsyfVlTsFvwBUe3axzKJTUM9XzyvwN7SAVzWOE1Cs1fTa5+dCIlNFgex\n4hKft6xUoVgUfqeKoptapU3+ZbTmTyAlHBPK5qe3cPEzM5BAvHBgwdsuXlmI\nc5OvHlgp06X7OQEiAgPFJb5rAKvfuUhNTQe901koNoV6k3/4f2g162iS3tjK\nX+i07zRdJwbjXZnFbNCGoH/TgOVlLjh40P2vkIidxstip4hS5We05k38jrGl\n/TuL\r\n=ruVc\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIA61MMla9zK3FW0FS6c2xqShLUPPjH8vhfCtnSQqT8lBAiBNEAbyqKtXdGjByQWf/w+my2awoDvM+q9/TYBP5QxjFw=="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.0-beta.4_1626903626668_0.9211036358004623"},"_hasShrinkwrap":false},"3.2.0-beta.5":{"name":"@vue/compiler-core","version":"3.2.0-beta.5","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.0-beta.5","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.0-beta.5","dist":{"shasum":"6f331c5c1befd7a102f861de19ee08d1da43d41e","integrity":"sha512-EjOvdpTcPEWgsNufn0qI9lbEiX3kztuKwxUR3YSGUKyB8gmyowP9/Z4uBziawR/Rd3AdDF9RarURd/bpmsQg7w==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.0-beta.5.tgz","fileCount":10,"unpackedSize":664440,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg+yIvCRA9TVsSAnZWagAA3ukP/ifKHQRkYClL67k+M04L\nl+BoSz8P1gzjFT8HCP3/YP0EGo9Y77lac/DJoFZo2y48avm9VlZYYp7MSRHO\naTOUtAe0aZDp+MeunZ/PIzfOpeza5T0gqmJqaqrR2dTcleojD50I2MdgM4nc\n2MPJk7dBT97ZS2Sd64/OIEnSlMa99grxxg+R2MXwV/Po7mUM/HMpg06tEFyP\n1QrHYLkdCuAU2OvZ1VwQq0APoouSZIAKcncCBKkhUU2mtaPGGZEeZ5mkLlJB\ndd+MCK5NNBA0G9+NKspxlLmiCWiFVlDq7jNdLvjdbmAECZXJluTUkCGvZZtL\n6gCs/neofxAupAXNU7S5SF1QD0iMC1ntvk+/Kblkwy6OXkf8PDVZDNt2G19L\ngUhqRRyCjFCs3ilLmS3I4L9uIGmy0kP3LmPclK4mTwVcc7YbE+3Ed0crSph5\nqdWSJx3x4IiWCM2iJB1GFkXI3H8ULPZeuy4/Gv3J6m7FHA50uRMjsWy6D2cO\nsA95e8Mdn08Es/xXrVHdzI4/SAWxaimJCCf0qKAM5tgU7/9igLmlqqhv7lnR\nvkWDhJjoXDWxFvRdvvs6XBWR+ar/Ktz/NXdD5LbE5fCAkWkQpqvLk9o/wVmv\nlEDAYTWA/iRmrFht6un0uPIGY3/Y6/mzV0ziLCUmPLQmu57FpKX5og2t7ky0\nlz1G\r\n=Q/F/\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBpio/v0yDefT67D3b2d2gJ5jZkYAUZlUhDWs6Cy5CJnAiEApplh1ymNhNnKR9pcGYD4Z0Cxg49N/Qk8WgoKwwPIzA4="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.0-beta.5_1627071023220_0.09108065441143598"},"_hasShrinkwrap":false},"3.2.0-beta.6":{"name":"@vue/compiler-core","version":"3.2.0-beta.6","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.0-beta.6","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"readmeFilename":"README.md","readme":"# @vue/compiler-core\n","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.0-beta.6","dist":{"shasum":"d518e106839f27b38b0f9e0e2b0ce795d68e8eb7","integrity":"sha512-oiICBlip8ry3ihWq98bcCgsK50YDq+lHJlJ0OAtI+14lyhhgqx3HQQytQi3luakr+8OFcsTzs5k1ejcbRkunbQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.0-beta.6.tgz","fileCount":10,"unpackedSize":664440,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhAI8DCRA9TVsSAnZWagAAInYP/21JSmSfJwZddsr9KZ0k\ncDazFYHQOOAd+CLNl+7gMZDdJtVhbDkIBsiK5wZVDX6syQGy5VgBCmP7MKhX\nAYMQQv0+6Xqw8ZznPQH2/IsjVUYoFWPUTJI7Pv7vtNklxcYqM8XR6/WYiUGJ\nR2yA8N7RZwnl4J4qdCy6yTtBAofo7Bcd2u0uYKmBNee8ROvS1AdFZ+shmKnH\ncQEbukyudgrbcfLdaIbi47U9gCVT4VI7zhMQX0YR0BEU1eMoGljXpQGrSLnn\nh69bb89Y3zvi3m3fZ9OjWsO5AK5otvkh3Tfnakuq1CqzWHrn4iU/PfRT1lDk\nGNHahCASF/pKfRD/ilcLUNhMjqG3+NW2rlYu01+Qew19x3sSp2DT0I2HQeeX\ni207WVIZmh2vWN6JivFW8CenAw0KUxnOPTwW9B8gxWTweYGv5h6ZclPBpUs/\ntsdtUOBBLsa8kJYjGpnp4NM9UE5M7wKkwzDoorYHogrJ57JDDxpRXdMy/a/q\nXMjak6m679jcygK9o5S4WD1WfV63KSTY/Bew8eYbwgbGdJAE9YCD8755AlWO\nAYYQ/GgIZY2+MZk30XGdbyehgRKuFNduW4HReWFDV++oVnNtjPo+WhaXNlNB\n/EmLmDabGK3OX9ZAnRKNsIwpOanNBufKZ9oNzOCkBifiSZ9w5+1uMXtJdvxK\nUGWv\r\n=GDV4\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICrW/ML0riiKPGDTlKsLDQu3Ue5hC2y3NMwaXgqCHUAeAiB3slSHqdZYoqKlENNO5fopvJ7PokK806U0m8IILX0NIA=="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.0-beta.6_1627426563226_0.4645926178994415"},"_hasShrinkwrap":false},"3.2.0-beta.7":{"name":"@vue/compiler-core","version":"3.2.0-beta.7","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.0-beta.7","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"readmeFilename":"README.md","readme":"# @vue/compiler-core\n","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.0-beta.7","dist":{"shasum":"bb551e99e207c3e694bd6b283cb5a2a2aae7f521","integrity":"sha512-JoL8pskBqYDcw3Yf6Bm/TUz4ZIRIkT7VzMzk0chBwpxHima9roZZA2bn5M/JznZryh9JNfrpm1DdDKmsdrRVSQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.0-beta.7.tgz","fileCount":10,"unpackedSize":664440,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhAuObCRA9TVsSAnZWagAAn+sQAKQA3kW7ftquSUhIB0h7\nM+4vhub+U8JwivsBWnBiFXlBpg6a9E5YzL5giUqWdZIJfauIaLzk1ErRqxZ8\nTSzPIIuFYjVUdIrnAtWU5rjkxl80cpp8fN6+f2hLDqpMKaCFbFal1+M5ndT+\nN8CZKOVwOq0gwQUa/Q9o/4Pfjq1X7xrJA62Kj/p8eNwDrX/U6+axcIoIB292\nCJTMt2x0WzahSDE6oWMZ/a+dHGZOO72xka9AD3bufRo+Mx2Gz7kycv4CoZFv\nJxy5NKTMT+cHymxSVMiic4LEa8q5LyFhRiOKbiGVvijYEtKSN19zU8P7HbWw\nkBo2Cykx5gx18Q8ZvEFYwXXx03IXaNcWE5WhHXu4ecnooXpksOeqYIAR+Cry\nklSP9JEZ1f8HpBx27wWPlFnqCCJd/BtuUjEjRSl+24hUWr5I5ubOnYsEdRqS\ncGKnRAuil1x5zYPZcZ3/CZKFuL59UDp4M4yxaiE03yFNJFxgu41iXazwPaJw\ntvmm2eAbT08RUZKzJaa8AaokTDnIGGR5SGYNr4t0U2bgbbSONV2AaS+qQgzt\nRGOS1x615sdDOXd3aRslyefTtTpj8GjygIX+/LQRNt+9FvdDF0Wkupa2e91+\ns3qkICYRiS9jDS3rjM/v97IVvu1ldhqKgb3VxQ5OcBkWklD4CmCeWieE4ZNT\nO04J\r\n=JVSy\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIB+guQ+DHgnxSeSiRcFE92Z71LWoiu3QrxhrUu8jGXtDAiBNKnX2GZQNSZH54CG7aEpCAXrOsQn8UGLVgHdWnfRdiQ=="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.0-beta.7_1627579291787_0.025597341320339417"},"_hasShrinkwrap":false},"3.2.0-beta.8":{"name":"@vue/compiler-core","version":"3.2.0-beta.8","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.0-beta.8","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"readmeFilename":"README.md","readme":"# @vue/compiler-core\n","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.0-beta.8","dist":{"shasum":"0f16d457e6f7169496fe67c80660a6e3d93bd5e6","integrity":"sha512-nVJk+DMl0tY9e4FLKcxyWQEtnLwHhW9K3rq15oqNhnRGP/mk2zN1y/BDAC7hQv1MxU3RX4X8fUOw0EbzVl/vDA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.0-beta.8.tgz","fileCount":10,"unpackedSize":664016,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhDfodCRA9TVsSAnZWagAAPo8P/00g+a+Ddxb0ikpEvG82\nJG6qgQNnZZB57tttbzvBwi58Wfxt6tcAYQOhx9mAS65Zaz1T28prqnXP9YyE\nIKzkynEs6SvoVR3Cz2wMji6kOyYEpaZHP0N5WR0mMKTBi9dwldxuP8Tvu18E\nseYmKOCljdun6REjHaaNHMlN1gsUTLJa9UDzjK9GUV3bYvSHPwxZXbaJOoX8\n9iD/6sEPsrUVkAIBM62eaRVwlL0AdWZgqUaqdTgVkK6FetHIDBWo2uRtvUqa\nUJqyzE1snPtE0zA8+g1/DQCWaF+NUbunEuvQhisIFm7E56SnEWlhFeJtxgOv\nZ1DveMU5Hf+P0L0WTaBH8pX/rIzPMK/UrhbowEnCowSkXMPXi2LEpCa7Xv5h\naj9jkaQws2R0NriAybp/HVF2D1XxGDT1ekEo36guplDD7V5jftfnKzAJI6Uy\n0r4DXQlDKI3imMKRIsxeMhOoC7K7Yb/+2YiDV8lPUIHiDzU5fYa7BJGheKE9\n4GCNQTVW5NbC7eZvfJltWo9zf6pshfBiYvdGbB9/ev0qeru/HbRRzyLTBFQ8\nFU0xMfbd9Esq+YUfL43nEvtg2iIFCvtFTvoo67hjTv3z4xP/HgP1mXd8RCVv\n4mZBKsY9MHL5Ck6LnJywDHSwe38yZbzYCRSkCCPcDA+J16nwsg7BqcDn93GJ\n3Ftz\r\n=5QR2\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQChLE84BKAY2qpIbGcIzNLKHv1b1QXlFM7PUHwqT8guYQIgFsg0ALMqWIFpmp8lNRQk/O5XPQXSWukduPGzqgKFwMk="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.0-beta.8_1628305949055_0.7529248499430798"},"_hasShrinkwrap":false},"3.2.0":{"name":"@vue/compiler-core","version":"3.2.0","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.0","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.0","dist":{"shasum":"cd06283615dfb228b5e6f2aabcf30dadc0f9dfe5","integrity":"sha512-+kfA4pisto26tcEh9Naf/qrizplYWnkBLHu3fX5Yu0c47RVBteVG3dHENFczl3Egwra+5NP5f3YuOgxK1ZMbNQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.0.tgz","fileCount":10,"unpackedSize":664002,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhEYdaCRA9TVsSAnZWagAAqGoP/jjlt9dV7r5H8ggk6EUF\n/Hg1Z6kF4Lyv6cNEPK09Nc1Uzr8EWF6aw0vhQQWJGYG6RVDT16EujgoZnOdI\ncBjwmL8DL9jc1favqXIsRGGWU0jmMFnZnDoV7EPK3MkmKFsMYA4PhJmUIzQD\nLqiROKs5RmuY8Pm+lbDW/iGRKM+wUC8oNZ9LyuExKkLdQfD6uQS7PTQgwZf5\nGYsSItVjz3XTKiz1Y1qfmKnwoAzPVKmWb18j2Ephn0Zvw72Q771d3ELMTqbu\ntFWz/RyreNiG20AFoIs/d4AQgIZWQUkpncNycdaJjPLax7AhdMGJXpvP3BJ5\ntuD4pW/sUNPn3/bPvaYlDnSZhJlosmObMsYYLYzv2MWaDgTl33UVu/uT2h6z\nntGcv4PoP57InMSCLeynyFv/ZxxuSFBZPFaRD9nAhc6KvhBgFKBomDFGMqqv\nMNzitpsIgJMKmhDXra6uCSOQ26ICP+DYIK68DaD2Vkz7kZsKdrogHP2tPA36\nP2y/weFU6feXY4wsiRHai9oX7MegIuwgxyZLsEKWKczbo42Xtd80i1tqOXXd\nMuomFR2H9jygLskPjUYU0eciSmdYiDtrcikBseYVQoulot7/lnzS+byCFjpJ\nkasWyzayhGsR1ggFUFUvoRoKnvMaS5JBbCapHDWvZ3nABSckeCkSdGp3UP2f\nwNWG\r\n=PzCn\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC8eh/yYOKfFtv4fmZpF6y2fpLr+QxCFIR82hk+mR/IvwIhAMFFvovYoQUP7AvZjBsbThYjYjBAfezmql7bYl9XDC0v"}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.0_1628538714738_0.9063240344716923"},"_hasShrinkwrap":false},"3.2.1":{"name":"@vue/compiler-core","version":"3.2.1","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.1","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.1","dist":{"shasum":"8e13232f7aef8e308fb2d4a10571a5640257064b","integrity":"sha512-UEJf2ZGww5wGVdrWIXIZo04KdJFGPmI2bHRUsBZ3AdyCAqJ5ykRXKOBn1OR1hvA2YzimudOEyHM+DpbBv91Kww==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.1.tgz","fileCount":10,"unpackedSize":664002,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhEZBDCRA9TVsSAnZWagAApNEP/2TEUWnM++gkQRb6eREz\n1g80vaWJYJdaGhN7DrPfCsi8geI+xuZJUuxNFR3KYQj85CgmgWIkCIzMIh+K\n3Riue/OcwRL0a74SzIAqRHYu/ndYMmiPiN2TfNoQhv+SJp7OBAbFnFgnwRzG\nsx8gQw7nevms9hDZITSMmPZZxddwd3fI4SfalVVMngoEaBrpRaVBgE1BYNNp\nhH5p9O04L1/E2g2QuLM2lTvbKQUWX1z5uiG8obfiwVcx2NKucHWcWFC/FR97\na1QabNg7TllGOFcGb/5/CrNR+UooQqqZRf8kcy27GNSC7heR8MQcSp/CYbdl\nm/S1J5/lpmYWWep1trWXTgntz+PyXIG9kfGvEf6dVQ00gK16PiY/vX9MYkil\nad7Js2R7otoCWPGsejqPgp7QC0bNQ9C180a0z7EN/28al/zEOBmUNdNnKgwv\nX3OYT70qoMtsYPhnyids1OvOb8D6x5pHLLSvhdFjcE2utx+EdKbs7EZA9/6q\nX/GgxmKGpnlNUrzRFke5emGKUavtMV9qxRjMbdVDsRuK/o4GjvptV+rdymVs\n8RZBE4V5zvl13s+VG5+NzxH3EQ866tV2Hm7F59O5hMKw5wHUf2NBwJ+kHZ16\ni/CCif+c7VBgcrYbtS/BEWM8Gm0iy0Yu5v3iV8jgNf5okuU7nXvpU7gG8qhK\njlti\r\n=tBqO\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGhfA8n0lyNkBkfsMSWpTMzMqLMpKp5eHr9bOM/fqffbAiBSzZD3Qxjq09K0cNm+YL/aLZk2dlT0OedWO8uQ/KhVIQ=="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.1_1628540994889_0.30345853613249485"},"_hasShrinkwrap":false},"3.2.2":{"name":"@vue/compiler-core","version":"3.2.2","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.2","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.2","dist":{"shasum":"8d3e29f129579ed9b14f48af735fd8d95f248504","integrity":"sha512-QhCI0ZU5nAR0LMcLgzW3v75374tIrHGp8XG5CzJS7Nsy+iuignbE4MZ2XJfh5TGIrtpuzfWA4eTIfukZf/cRdg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.2.tgz","fileCount":10,"unpackedSize":664002,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhE+9qCRA9TVsSAnZWagAAj38P/jfW3e4zlbEQ67r1XzjC\nVe2JV4M3JIaq3bGt+Zdh62HLiJZ28f1vDG7WHWlemn8zWMG/qZ3mqDBIdAVn\n6r9OWGt/Zm+8bnc/wSFPfm7J8XcelTiQyYhkZjJs+pWck0rhs8w4BEcbZJ4H\n381pLqAljIc3nf+uPSUVAbb5j+Oe8aYTkTj3VX7t5NlG0phnzB17RUX5ykih\nkCgXz4mvgw4V1I5fFtQ7hHSyy9NXayjnZxTjzA+mcH13JLJkU1QxFP3uwhVB\nVg/wJfF+B5q+DcHak+ygjx2k1OgheFS/n6dPo8IyQCXyPA4PRVghqsSRKvOR\nlDfNXfQiPPW8OPidHiAJ3td2uAZ4X0ZuvIMzyzbNfLpR5/ABsPfjEFy7AkUM\nJ2rlc+FwpuDOAM5Rx23Yo8xQ4QrIsoAdfAalPpF0GGGGVd6iDpaqDTqwxhBr\n13uoqjwIJpYhqWvl9CQutmqBwkscN7jbcAiiDos4FzzXNDPtD1qq6b8OHTaO\nHNHAMz1NNcUiUfKHqegokWx2azvI0BAzUjLB2PjT/RL4FbPsL/kBMY7wnqc5\nlQKbnjGJbxlmyQGc+bXCGGTDK8QG244SI5GHAKJBY3KGNhlH3tn/j3fuLh9m\n6hzyxqf886qllg/SvYZy11wji9XHosp90X8r7pkTB6hSD5VVYSsKd7vvBhEe\nQjMb\r\n=rAt6\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDR/TNr9B0mrAetJBrZHoNxjbmdCdGzk5NeRnBFmg2DjQIgYBfKQPu+pHTA8jnXe1jxsoO+Pypfc4sbrFn+Vp95qTc="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.2_1628696426555_0.11004054891074655"},"_hasShrinkwrap":false},"3.2.3":{"name":"@vue/compiler-core","version":"3.2.3","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.3","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.3","dist":{"shasum":"96aa6692ad3819127f9f6256757f67f1c400ceb4","integrity":"sha512-qQpACs40hClYqghS209OBh6NDArKPrS5emWMOH/hzDy0KtOV7Kfyy2ILWRfamIsygq8mg+xHcqtVXOjr21WvQw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.3.tgz","fileCount":10,"unpackedSize":664875,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhGuXdCRA9TVsSAnZWagAA04AP/0Sa7ydMfyaGbFYJKKym\n1a3tQzo9zZrW89NgB0MdzQAigEE2u0LfA2R85a2tfyonRBY9dnSXq3Hwyjve\nO2/XK+l66X5ZzLStUhuF8mcoXNDlyzvRx3Iti1Q+3/pOBBlwotk5nriia3Rk\nllhN4LZsuPF46bc75KHerZOIx3OSrFsQsf6uyry1Oi7hgYqDrAs6wo7w1vWo\n06aGeP3g7HzL5jG42UUUon0zJumu++Jp0KZsE4qMhND2YMAL+fUsJ5g3Ic7r\n1KeD6VqxSLUFn54wt0OzqHpOCyZKwx6fFS3pgC2LhJaUcoJjMo8TPCJFGe4t\n5kwG1la6aDG32HEWQKeUiYYSoa8b0efezCYLalCiLWn75yARRaDa4k6UJI64\nKW9BZoJJHCy/RmkFy+C7tCGyycFPDwC2o4f5MfRonWJ4PCNAPTQVnzi8h5Ww\nBlDD4y9oQcBDNYsNasia+l0g4SQ4vSHhasfDHOttrbvx9JwjY/tt+UrwHFNj\nCArj7a+pHkGI3Lr91BDv8gNX29Q20w7+4e6eeCZje3E1cmQaDAVRbonqfMzk\nxtx2DMj06PdjZlvXKs1NKiCs4OB/1BnyjNxf+EeF+kX6O6X16efL2juf+q7c\nWdI8OkHBqM5PGnxWlAHlbcmmHoXYTJE1a5F7m2zHM2DoL8GMXCe/0TH1Ay0B\nxP+7\r\n=CEl1\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGHRm8AUHiQ77j2ngTjMWkhpc+y7u0IejhATF7CoBp6/AiEA6sOjhhA63fLkJFe3agRcnZuGTQUPrYKXp9ET9DRiYEU="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.3_1629152733206_0.26123366216671795"},"_hasShrinkwrap":false},"3.2.4":{"name":"@vue/compiler-core","version":"3.2.4","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.4","@babel/parser":"^7.12.0","@babel/types":"^7.12.0","estree-walker":"^2.0.1","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.4","dist":{"shasum":"a98d295771998c1e8dccc4ee3d52feb14b02aea9","integrity":"sha512-c8NuQq7mUXXxA4iqD5VUKpyVeklK53+DMbojYMyZ0VPPrb0BUWrZWFiqSDT+MFDv0f6Hv3QuLiHWb1BWMXBbrw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.4.tgz","fileCount":10,"unpackedSize":664875,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhG+NLCRA9TVsSAnZWagAAeqUQAJm1uj0ao3NlFSDpV0bB\n7ED3SatNoEs3tdKTpW9GTVMj7YLd/EIg4axpqEV2ANZMufwescetrPw6lIH4\nrFb/SKfqtD2xrFYNxK5FCKAclLHSJbntlZpGXlUKqx/Xq+zCHYN3cPv3DIIa\nIuiY1/ER2yuFyNSbuAw2sUKn7Rn4YUDawZVHcm3p/uSKXGvJGBc0wFoE2+Q8\n7Q9Kobj/2kzo2omdPB2GJGMNhN6LeBgbUKKyiFIOXbm1AgWAZD6HHtvHipcL\ngL3oAA+dAXyi7ljQ0oVThxHclusTZjOc/Zpn7MKPN/fwarMl2zCWxIiqIsui\nP39IbwKQ3E+2nOcCaOFUaGATkCSq2D6CKRWf0MqB6jFo27NPJfc4ZhDTBlPy\neM47gjs3uK2QIvRWWPHnLq1K5ud2bbUYdwd4VyOMb500KRIDIWJu+CnL0eDL\n6GFXgbB5T0+WkiHqrGlhTY0iOdpR/08du7cdBMwecBO612agFP9O+rb+k2P9\nC5dMHNWkTTLVi+n1tWUlUVq6BM5mCR1wii+2W9Wg4mXMfn1wkWdEKTm8cNaF\nmB3OkO6rYtD6jfTQ1x7q0kFOfqmfYTZqrJcJ2ubVgFlNtdiLwVE2T1Td2l5n\nI54iueIR8y6EJ0u+D1A1hJv0Atfnn9EE0z+l7p5F/e9wk64wycTyYcRgYpv7\nup0w\r\n=AIM0\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDF0HZho+5+dxQ07+Z3EiLwYcCgA61uBTHJnk6GSeYVzAIhAL65agU9j4q5rlBrHwjxyqhJe9r9ms/vM5PUh19LzezQ"}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.4_1629217611349_0.3245309218901218"},"_hasShrinkwrap":false},"3.2.5":{"name":"@vue/compiler-core","version":"3.2.5","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.5","@babel/parser":"^7.15.0","@babel/types":"^7.15.0","estree-walker":"^2.0.2","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.5","dist":{"shasum":"82fd33f6e53bf9a361d99609725483dc1be12d4b","integrity":"sha512-mv7lfWtnswl5AaR/dTJWCjbZ5v/UNnlpaPo9VQzDfG2VJxlRxByPW/lVxGCj9l+bYLXRIjTkpYdNT2OGpFtZGw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.5.tgz","fileCount":10,"unpackedSize":677323,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhJRYwCRA9TVsSAnZWagAAKyEP/irKZ2snHf2vlN1DUHuG\nb4qdNecoTOAySashM2ecJz+or27XEwirwId+Loqq+UqRkbUC6nZdoSRth7xb\na6UMrJLDI8Ho/QoOZ+la3e4315PXkP6+Y0Sk0ctHFr3Sj3mwvYZWgUfNToLo\nnQBXE7zgnER1ET8tHwM3dYYEpAd73lUvV5B0V5+iRW9cS8Iu+0qG3TvnyfGo\n+MXiOZk4opU0QOmnRoJEWbuPPw7PIl1Rve7IcqxbxDeBrhGTYpEHAKn+KucV\nYPVp6Lew2HPGLQ4CEVHZZaP/u1VayxeIW6n6nKFXcsjc1NTRmhQU4PLpLdyO\nhwaJHZbI3WlSJSDqLZq1RkHQCPJKtSZVWm2Y33YK2fLKMw1QRio+s7vXYeHm\n/P60Jdg5FZ7RwVpbpXTngC6vFAMSpNOWLDlVKgiK5LoKSdSc+Io/pB/zQD58\ngk/HYOW8+LvZCYqtSwKmO8E7sgglvgPDP5QowP10YVJHP2NeX4cwHvs/gn0G\ndw3KAz2/lvMwPFmM919niHY7c7Nnuk6gqSXAUOzn7jjWknBaGHy9rbEUF+Yn\npHE00Rwy2r75R4+aD6QJEsipGtaRqIWhNWwMRgc8IMJrc1jd0Le3nFZKsGra\n2pfTB07N32AUz6yB0bcl3e8nk5jYROCTRE5JYvHg0Mlf9uhuCoBeHNGoX/jk\n9K+1\r\n=Kkik\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIC6oB6T3t+qe9i/Vi0utzKyCv6M+xv0NvSvBXfLir4lJAiBqarpetnYfbqX89OuhnxeGe8BMfwQKInGAF2B8BzPoww=="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.5_1629820464064_0.18646551093848562"},"_hasShrinkwrap":false},"3.2.6":{"name":"@vue/compiler-core","version":"3.2.6","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.6","@babel/parser":"^7.15.0","@babel/types":"^7.15.0","estree-walker":"^2.0.2","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.6","dist":{"shasum":"7162bb0670273f04566af0d353009187ab577915","integrity":"sha512-vbwnz7+OhtLO5p5i630fTuQCL+MlUpEMTKHuX+RfetQ+3pFCkItt2JUH+9yMaBG2Hkz6av+T9mwN/acvtIwpbw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.6.tgz","fileCount":10,"unpackedSize":674356,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhJSRHCRA9TVsSAnZWagAAMJ4QAKF6/Xv3sjPzrhX27aJ5\nPoh0qglNdsHttzYY83qhLGa9XmgbS8J/QH+31UbCEzh/WkyejHK2Mfc8PzEl\nlWnwqZZOzvVRxMob5i8Ay3yFk9NTziu7uwbBIsYLuVnxPvQEj/kZ3dIHMSn3\n0wWSEPB8NKRv9JEEnXlTQTAwPJokN/LY9jXM3GUbW4EXMlCsTmZV+04vkWYJ\n7/9ofXzargZVnUBMqBIXsaq6vBkPxtoEh7I4NmQGjsfFLf5VbHxh96OqDurh\nfn8gTM3UyIHO89pU543hDtArIFuljuN2OYar4xtseajYCevE2Aqq36EFfRjy\nb4A3gh0G1uNE6jVQI9qqqqh2Pam8xCFIZ5LfMij978NBX8JGvW5O6Hq3WpAL\nqo0gvXesabgrooXwJVk3SL8nvhK5tH8l0CLbtRbM76SIbUM+1dUgW6iKUAeR\nuqPMqUSUYsqmgFl/SlKdW/5hsEOhg5IFBiUiPWG1fXLcUIaJL/9tN4iISDnq\nY7mq2PQmpTDpbMuA84LNgVESoycN+4roXeyUKuqqfuyYExQlTBFnar0oCMrX\npdunOrsofwSCpfSYHXzYw3noGc6otyZuEWRXtvgq0CZCLa3IWlXnJCoh0EON\nMvHTPjMGVpVH3XXOXNRWevMMGeSjaIYLfiPEF5Ejo/ToTN9I40rnMlLW7UZn\nXIMF\r\n=12Z5\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFWNMR4JOKmrpbmBqEJB5oRul2wi54GfQS4zgftNvDAeAiEA5bXRfI/dhZCPqzILUXVkkViEPb4YrmB+j+mo0YGZMNU="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.6_1629824071409_0.48594023955332477"},"_hasShrinkwrap":false},"3.2.7":{"name":"@vue/compiler-core","version":"3.2.7","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.7","@babel/parser":"^7.15.0","@babel/types":"^7.15.0","estree-walker":"^2.0.2","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.7","dist":{"shasum":"a7f1f87d4fae8c78d95a3d3df81bde663427deb8","integrity":"sha512-OcWy72QNTkcNYtZIb927pRx2cRujrlDWsAx7ejWDnRzwo83gIyF8NeTrMv/7wbnHoeA+Gga9AK4Wo9PlCzhuLg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.7.tgz","fileCount":10,"unpackedSize":673852,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhL/kdCRA9TVsSAnZWagAA3d8QAKSysGw/tDKh5Ft4TU0d\nxoYF2ok9R2Ab9gDhV+9SfYTCorz44CeuspJvhNghhY3crUPePmkCtpT8TubA\nmLedUNyuHvWduWJ38v6r8R/sI71AdbyfRKoYUkyxrVU3TTXmLvsoEiJKg0tS\nCAgU1+vCpz+UiZxmBIgPxW20raRCyOZ+yIrOdApLuBwAwr+axXAvakoIAW3T\nd8cS54lOpBOj04KuETF/ARLa+rT3Qr2ONJ9kc0ZF9YYwxUaaWR5Q9eKouEYz\nwMjYrYDxAy0GzWhlZbtQ4OvjxX8TJTEIdKthNkz86cxZrntAvlpf4Z163Xzz\nqG9+NZAu/lSZRssXJ/8hFDL+/sSsJhZqupJgq3nFvHfS4IoN1j/AiASWAHc7\njZLaDHHMmcp0P74yJRcSbbHuLYOcHeeg/x7ixznBz7HjynIxvhqL3A1C7A5o\nS1tuig6Px2Do9teMZ4TRr6fbRsGPXfDqdNutB7RLNkfBzfZMBP59Msb33xel\n6J6mKjSpshcn4atlh0iIm+KSdoT3LHCxh53r+ckKuREea5hStj7U2eWwRhFU\noNDxuQA1zwyXuzefcKdbg6z17z2uJ+zk1xupvd2n6T4FTo1CbiLkJ5DMlg/V\nJHBCngTrOuMGjcJcthIoyvYNiO2AsOgZuInrZoxNe8EXsPpg57sh3Uw8X3lc\njlRM\r\n=igeI\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEIRGQKgF/+6Kdvhn/Fl2eFIrJKxSREumCJAe6g8XIHeAiBX5H2NL1YFsiIPr96c1TABDANhPgZyw0o8curwkjMTPw=="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.7_1630533917712_0.6370695185852535"},"_hasShrinkwrap":false},"3.2.8":{"name":"@vue/compiler-core","version":"3.2.8","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.8","@babel/parser":"^7.15.0","@babel/types":"^7.15.0","estree-walker":"^2.0.2","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.8","dist":{"shasum":"13b2386bdb03455c9f6c6af2f3468561a5ae5b1d","integrity":"sha512-Sx8qJ030+QM/NakUrkQuUGCeDEb+0d0AgFOl5W4qRvR6e+YgLnW2ew0jREf4T1hak9Fdk8Edl67StECHrhEuew==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.8.tgz","fileCount":10,"unpackedSize":675816,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhMRwICRA9TVsSAnZWagAAvHUP+wTHCDCbCK2FrU1mJoVr\nrdty58TzD6B8KU7PguhFAwibGRs/lrtBDwqdXsvskIwPQZiq95+HAO7jza+A\nwm4aUA4vSILXh8LDtpnCfB3YEbLJktOS5e4XEOO+++Y7UCiB6AoVgLNPXsJk\nD1zld5GfKETLmE3l+U5RGmRzfYdBxx8+8BQbx5VEXGXhsJtPRNGpr6d2bKpg\nJx8t+8fw0FtK+q+KAsmsM6cp9ij5YoM+45RGS2ePk0g0dB9WjKd7Uoxwfj+0\nIpOwFD/DNY0SUG1k3gJBlwtb2QqRGL9Mor6Fw/ZCk3a5guOoLwXfZoR0npf5\nY2XoU38fkNRoTg/YMaBa4GNgZ4G5ijVbr1BcdcSV5XI6fdHZdPYtIUUnKBmk\ngtSYeBJB4F05BvlSLy2jbcCbSzFd1M00+Np33B8O4QaeyvZK3Jz4lO5EhlXt\ngKWoJSxOyD8euTaiUTj5hopcYhQnZfuJ0/2CtmoSqPwj9XRt8TgOlL/Sx2Ox\nTN4BtkVnk6Deh8/0H5ht8YZrGdtWa0ETJdr5D+/yKZSBDCiraUzN5KQg6c2j\ngCFN57/vDkRwq+Z6lrz+yqkotmz/3A/YwpYyLmFZ2b6U/eU8YBWMPn4rwVg6\nsQ1MK0zDSGjCUlZMkS+mrgFGFB8JrqVB+xFnvzUQhBAE07jJA+X7hulO2O42\nWCLt\r\n=o+xb\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD09IBwpi3SkX4cALpMBHhYqILRGcJbA4wBFxVqI99jggIgWr/BtNzvXZS6BzJm3xmXy/w1WSUuAHfypGE5IzdKnTU="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.8_1630608392020_0.22506342021898962"},"_hasShrinkwrap":false},"3.2.9":{"name":"@vue/compiler-core","version":"3.2.9","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.9","@babel/parser":"^7.15.0","@babel/types":"^7.15.0","estree-walker":"^2.0.2","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.9","dist":{"shasum":"874d04d3e4de98f3a60769db7fa47e041bfca490","integrity":"sha512-smi76K+pg1LeltWSLoOI9GqXdH1oK13sd+SrO/XTdyfvf2dOQn5zE0o+C4B4Wj9M8Jd66Z5dEfGEldvcOutixQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.9.tgz","fileCount":10,"unpackedSize":676080,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhNUOCCRA9TVsSAnZWagAAlbAQAKIsFvjct1ws6hHjcZWo\nSsWb21J1m5UbASTD/HjV+mhLm3LGB5XiTvzED/8eByDI8KnpbQX01njxdQPr\n4SjT19XAg5KY2CR0P8y2dVJBZJSvEmy26bt9Us4rXPq0ouVwR5qX0e8Gikfe\nyoOj+RD/bj5P6bkO7Xw53RXIZYldzyFTzCArXXs3CjR9CpFl+lPEWTE16RdK\nodhgK9Md+2au2xBw7V7GjnXvd2rwSQ9Y4pG/E4/P3HzS1z2pvHypf7gn99E9\nWwyAj2pgLTvWw7IXoJEIlPmZ0NNSXLnGOl1IaY+ehRp/oW5iyiUBV5TKKQSH\nz47/ksXisfkjEK/XKVA58hRhy2qi4PsjtDauZeS81JqIUR+8MMBeKZCbOs+o\ngiJDVj4F92LlSsH0lLB2YaVB1/BvVuP1qruLH4zsLa3NZ3iJ0+ALb1Lyy94L\ney9sW1xbP8fCmOHx+cM/5Y+mU2UrIligUjOHmx+QMNeF937RYJM8WesFrYQ0\n/fnBFVmI5Odyxko6hd4oYrhi/Me33MS/IT7uJ9cbeK9NVABIJj7L/Da1Vtsc\nryOnP7l6fOaEuY6bbaIRX0Y2Qno3U6ALWI2M6wP5RM9jSCoTT66toSTk8OOh\nKbCMeR+1xAmDfmED7EPN9MjqNqgp27mFQgrhsHjN2i7QVb+RDpbrA6QT6s4o\nzcm/\r\n=L2Sy\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHcq98Xi8J8tGbLH8a24e0YKZpLt4CrOjacOaNe50rk7AiEAwfVArU8S1L+YSuLWP2KE4r341pJJouIvMtYs2UWFxno="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.9_1630880642777_0.9587306406115272"},"_hasShrinkwrap":false},"3.2.10":{"name":"@vue/compiler-core","version":"3.2.10","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.10","@babel/parser":"^7.15.0","@babel/types":"^7.15.0","estree-walker":"^2.0.2","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.10","dist":{"shasum":"3388b0feac0ec98135f9cf123a2eaae65708b7e8","integrity":"sha512-KKFxveRE0zm9Je7vlutHOF59JRytUROYBXDuoOpiDOId7kVQWdeIzc1TondASsXUgzDjbYrWkRHXiHAzKFfsHA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.10.tgz","fileCount":10,"unpackedSize":688075,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhN8l5CRA9TVsSAnZWagAAj2sP/3ZoNqYqiK1POYgr9Sqb\naSYBDk7wPwiMh29V1AnRmjzUhWr3ZoJMAACvvTGD0PYHObbjRHJIdL5a5a5x\n76gmMoCRApibcmntn9SAL1rYCGw9xUArQiyU0O0nodl0a/3jiQj3M27AfECW\naHQQEicJs7v7ctIPRvZNIEHdsWNfZys5LIWIL1F6T5TpkT63xv0dYGNCQ1jp\nJwHg8DEhPEdaO0Za98mIIJs1e+pXiCOpp4lLVrWkCQmRM11yl9ak9R1/IdjK\nn1nufTDJOumRsNp34xVOd0vyQxQ56fQtEF2pVI+xkJMZIgWtgTfwnuU8qQkx\n1dt3I4eR5+mL9rufgkAKbR4WFBJhQmqNjfX9pylRlwzlVcgu1iH22EgRDwPY\nmKzfDCeXTFEii/VvU/gULNzftl5IxSYfMaHueR11ubRjXtCZf8MYzdyD+FXs\nJhSBvrPEwGIYkZqYt+LT2GT1r2MmWvHEhs/h5p5SF+/b3aidJ4u1gVPG0dJa\nwSKTEWqWxi2p+V7NHOwNGR6JkHuMuvJpMAIj+IGqsl9hIjLWUN25P2jVmo3t\ng1YuIFI51T/BPdq2ezW4Pc2haex8+RqBf76S5CmUOMg6BbMscHpN98kXDDsO\nDwf3Z2SpfWZjGDzg6782cURc+ZkWK3T7KfSeeIoj1QpW/40UiRmDt3Cjx9r3\nAIz1\r\n=9rt5\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEgwKbXsVsOxwpPaWywy+fWaj+9BXelUWkoM99RizgqFAiEAm9rq9iTkrPGw0hwzvgg7EAH8LzsKcHV7DICtc73/c4o="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.10_1631046008966_0.4580876506399565"},"_hasShrinkwrap":false},"3.2.11":{"name":"@vue/compiler-core","version":"3.2.11","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.11","@babel/parser":"^7.15.0","@babel/types":"^7.15.0","estree-walker":"^2.0.2","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.11","dist":{"shasum":"10af3777dba303ee7aae668029f131cb90391bee","integrity":"sha512-bcbsLx5XyQg8WDDEGwmpX0BfEfv82wIs9fWFelpyVhNRGMaABvUTalYINyfhVT+jOqNaD4JBhJiVKd/8TmsHWg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.11.tgz","fileCount":10,"unpackedSize":688075,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhOUAHCRA9TVsSAnZWagAAC+4P/i/2CtRMgC7h5s9fLGFn\nqfeuQBhsDUFMTo0OghgU32Oo+iE2jlXylSdSZdAeGHEUF4/OHvqwatIfgO9/\nE6VBw4q06OXRfyEwNnjpj2hR5l+QWsy7llUH09UxVyIH/R+GbTq1CgzH00Rd\n0Jn40esqfu3LitypuuVTFawi61eDvawzZVrhM0fbTkA9lNnoMpUzud2R9uoo\nxSZm7oDM5UbG7NXqPNwoYsmZLgGV+tP9Af6nGXoCnSdS7ryt7Y0V+TZUJoto\nt9+OCbRM3pN2Q3G7rDkWmHcK61FWugVUP+9N3bg38WEKZH5pouJmw2+dKbJq\nUNs4mjgOWkmnE3sj68+bK8oJcpziH1zXE9cOU1yrjVYx0fsHrJNt5/S3073E\nBSTHNIqja3lFmYZoAY/rqfRbu5YpiTs05nLeedxEJxeV+zgi+wnJGZFhd1t0\nZoIUHclj0qCcXiLCThrwEZ39T4aQabo+gKF8dbpVrbi2d/hXbhuH7o5+Ai0i\njyT8VuLlwde9kZRBYte+5D8vUAruCaYRtjcqte5uIbXkgUxE5Oi+vYf4j7fh\n8lc7Mp+uxwH8BeVUWUPb6zHqWgLAhj2gVvOqivtE45bi7dFG9O5swN6bj7iV\nXbCw5NFUgwe2vAufhdEl8YdEjTBbeBUwsat2GRTNWQgx4Uy4WsIRVEGjW+kF\nRh7v\r\n=wA8J\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAu0lcnB469NSIfwfE6DwhU2UHeUYySVgFXT3Vz2svWDAiAWEtKxlTI6f/hO1rdqAPaev1VQyUunKLj+uVJIZ9MHRA=="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.11_1631141895223_0.7738786379925582"},"_hasShrinkwrap":false},"3.2.12":{"name":"@vue/compiler-core","version":"3.2.12","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.12","@babel/parser":"^7.15.0","@babel/types":"^7.15.0","estree-walker":"^2.0.2","source-map":"^0.6.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.12","dist":{"shasum":"23998d6986a45e1ab0424130cc0ad00e33da1101","integrity":"sha512-IGJ0JmrAaAl5KBBegPAKkoXvsfDFgN/h7K1t/+0MxqpZF1fTDVUOp3tG7q9gWa7fwzGEaIsPhjtT5C3qztdLKg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.12.tgz","fileCount":10,"unpackedSize":688707,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD/nPPbY3GxdkkKBM5GsAuEdv+yXb+/DnKE0Wx33oLL8QIhALzcdM4GDme4jSa4ou/ctuIJnMClF1ouoNTth8gbnpap"}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.12_1631890527241_0.22108145712785632"},"_hasShrinkwrap":false},"3.2.13":{"name":"@vue/compiler-core","version":"3.2.13","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.13","@babel/parser":"^7.15.0","estree-walker":"^2.0.2","source-map":"^0.6.1"},"devDependencies":{"@babel/types":"^7.15.0"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.13","dist":{"shasum":"901268088b98a53c43be0f02bfa0e3a389ad6bf4","integrity":"sha512-H8MUuKVCfAT6C0vth/+1LAriKnM+RTFo/5MoFycwRPwworTvkpWq/EuGoIXdLBblo8Y2/bNsOmIBEEoOtrb/bQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.13.tgz","fileCount":10,"unpackedSize":693266,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDwVj8ppcRAI9R3e8TqoqqshOp+tu6oKPsb4TJWVWGZIgIhANa/ze1CXG00VmLC6iqAbvT055rnvKm8ltQ6YXSWOFb7"}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.13_1632248574586_0.7024828303655561"},"_hasShrinkwrap":false},"3.2.14":{"name":"@vue/compiler-core","version":"3.2.14","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.14","@babel/parser":"^7.15.0","estree-walker":"^2.0.2","source-map":"^0.6.1"},"devDependencies":{"@babel/types":"^7.15.0"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.14","dist":{"shasum":"093bf572ee2a6c7edeb3a15b1301b910375ee4fc","integrity":"sha512-dPxxBthVMBvUKDP/ppaQa+Lod6gUbpEJUov10Uwl/sRI8qHcMLK7CJocCd7Ic1BbjgLGISJ4KTw+JRgSdkOFQg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.14.tgz","fileCount":10,"unpackedSize":692964,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCnTuVN9BgMKdsxrYhfzkY3RvxthW8Cws0A93/Y9mjCzAIgPLgmAE0RhioiUtWlVFvYGKoStRvo0kjPtPig2ZL710o="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.14_1632350218334_0.9040661101899854"},"_hasShrinkwrap":false},"3.2.15":{"name":"@vue/compiler-core","version":"3.2.15","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.15","@babel/parser":"^7.15.0","estree-walker":"^2.0.2","source-map":"^0.6.1"},"devDependencies":{"@babel/types":"^7.15.0"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.15","dist":{"shasum":"06f9da09c941ec9ea63599dbea6a910bcae7bd9d","integrity":"sha512-z3Ks1+NSl8fxRkBC1NtlBxM/+b/tqcqMNlUCoFlEGW9qDs/uZP1BUag8c7NdmOKZh0GUgXowQcdUcgERxK0E+w==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.15.tgz","fileCount":10,"unpackedSize":692962,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICZaoE5PgvlkVynTtMkOiZrfPNcT3tOEW+QLziNKmKi+AiBuy7Xpa4YJwIVQolMRPAQp/NZ3m2Ag3xSNmnSYWnOa6w=="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.15_1632404940482_0.47458685310754967"},"_hasShrinkwrap":false},"3.2.16":{"name":"@vue/compiler-core","version":"3.2.16","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.16","@babel/parser":"^7.15.0","estree-walker":"^2.0.2","source-map":"^0.6.1"},"devDependencies":{"@babel/types":"^7.15.0"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.16","dist":{"shasum":"aa1c475e5183f24ca93de1bb009b77e63cd189ab","integrity":"sha512-60LD3f1GpMtoCPWKP7HacFxv97/EUY8m4WNqfFYmfaILVGO0icojdOCYOfgGFiYC+kgk1MOVdiI4vrWci0CnhQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.16.tgz","fileCount":10,"unpackedSize":693472,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCEbSvym/AenGhtWlKlEgBr9mNS2qlUiTqIYiI+peJnmAIhAMNqkTEb/0DA+y/xe6fNhDJDBJyi6kURX53Yru5gv7Fr"}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.16_1632406623547_0.23008842272870322"},"_hasShrinkwrap":false},"3.2.17":{"name":"@vue/compiler-core","version":"3.2.17","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.17","@babel/parser":"^7.15.0","estree-walker":"^2.0.2","source-map":"^0.6.1"},"devDependencies":{"@babel/types":"^7.15.0"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.17","dist":{"shasum":"86538a91c7426fa9b95330d5079fc07861deb637","integrity":"sha512-2+RTRj8cOnCQ/yzu21q784BqaVtCs4Iym4BMwGAghGmtmC8PnHTnH42q9mlnw+cNhl9A3LsxeFzswLaJUjH/vA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.17.tgz","fileCount":10,"unpackedSize":693024,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDI8QGsQio60pctnVqdwdA0IRO+t4cPT7DWgiR6TYBQ1AiEAoAjFcldxb2lIrBwDynbMdIHhsmSKKGjLkBxnpRoZ76w="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.17_1632501792300_0.965442261625711"},"_hasShrinkwrap":false},"3.2.18":{"name":"@vue/compiler-core","version":"3.2.18","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.18","@babel/parser":"^7.15.0","estree-walker":"^2.0.2","source-map":"^0.6.1"},"devDependencies":{"@babel/types":"^7.15.0"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.18","dist":{"shasum":"239f8ed2e8a95e87f6a6235a4798d8d29e5b4dd8","integrity":"sha512-zNKVUx2gN/46xjKy+fNRB3+PJVO2WoGUUdpQo9w5GylWj8vs/r7pMuzQralP8J02YDp6YgJ61v1Yjq7nW5xK6Q==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.18.tgz","fileCount":10,"unpackedSize":693024,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIErXFAaCn70dzRZ7ymTRZtYRSNCzDhTcQ2veOBWHralnAiBrqtDR62s1aCbQ04US3C4yrDbFCup7ZpeySobJ+4Ij5w=="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.18_1632513918371_0.6995690256876184"},"_hasShrinkwrap":false},"3.2.19":{"name":"@vue/compiler-core","version":"3.2.19","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.19","@babel/parser":"^7.15.0","estree-walker":"^2.0.2","source-map":"^0.6.1"},"devDependencies":{"@babel/types":"^7.15.0"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.19","dist":{"shasum":"b537dd377ce51fdb64e9b30ebfbff7cd70a64cb9","integrity":"sha512-8dOPX0YOtaXol0Zf2cfLQ4NU/yHYl2H7DCKsLEZ7gdvPK6ZSEwGLJ7IdghhY2YEshEpC5RB9QKdC5I07z8Dtjg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.19.tgz","fileCount":10,"unpackedSize":693152,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD4KU+uRsDJ9IlcmI0N2HO5vrhFF7w3MkuHsJQiJidSrAIhAKTavSlb1X1hiu1evwCMiO5eJwZc8ZOJbmW9JZ30bZuC"}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.19_1632596301280_0.38930816287248904"},"_hasShrinkwrap":false},"3.2.20":{"name":"@vue/compiler-core","version":"3.2.20","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.20","@babel/parser":"^7.15.0","estree-walker":"^2.0.2","source-map":"^0.6.1"},"devDependencies":{"@babel/types":"^7.15.0"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.20","dist":{"shasum":"af5a3c5237818835b0d0be837eb5885a8d21c160","integrity":"sha512-vcEXlKXoPwBXFP5aUTHN9GTZaDfwCofa9Yu9bbW2C5O/QSa9Esdt7OG4+0RRd3EHEMxUvEdj4RZrd/KpQeiJbA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.20.tgz","fileCount":10,"unpackedSize":694060,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIG7tpTBPjDe9/YlEgmYROoNw6AEXt1RwrcAY7Qdxb5fkAiEAkdGdFjx7SXRDkwZDlB4H7ZUH9XaGCq+SMyY6gwclqBk="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.20_1633712512559_0.46552458454920775"},"_hasShrinkwrap":false},"3.2.21":{"name":"@vue/compiler-core","version":"3.2.21","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.21","@babel/parser":"^7.15.0","estree-walker":"^2.0.2","source-map":"^0.6.1"},"devDependencies":{"@babel/types":"^7.15.0"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.21","dist":{"shasum":"26566c32b2ad838199d471ef5df620a83846f24e","integrity":"sha512-NhhiQZNG71KNq1h5pMW/fAXdTF7lJRaSI7LDm2edhHXVz1ROMICo8SreUmQnSf4Fet0UPBVqJ988eF4+936iDQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.21.tgz","fileCount":10,"unpackedSize":694108,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDYWmS/eoacvx2ZhKTwvLZGcjd9E3S2o3pu7S33hQDKjAiBt4KmANMokpkwnCbygk4luTmvC3d84b07PFHjicGmCsQ=="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.21_1635834916115_0.37575123147590284"},"_hasShrinkwrap":false},"3.2.22":{"name":"@vue/compiler-core","version":"3.2.22","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.22","@babel/parser":"^7.15.0","estree-walker":"^2.0.2","source-map":"^0.6.1"},"devDependencies":{"@babel/types":"^7.15.0"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.22","dist":{"shasum":"5e3d3b983cc7f430ddbc6a8773c872dcf410dc89","integrity":"sha512-uAkovrVeTcjzpiM4ECmVaMrv/bjdgAaLzvjcGqQPBEyUrcqsCgccT9fHJ/+hWVGhyMahmBwLqcn4guULNx7sdw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.22.tgz","fileCount":10,"unpackedSize":694081,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDTPD+6k651cuzGhsuQ3Z61I/29TZtt+rujBjdAaifaIAIhAPYWznD9pq6GXs/7IBrb3vsZ0irJyTBNLSi6HsXsh0Dy"}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.22_1636947907047_0.6826437849004654"},"_hasShrinkwrap":false},"3.2.23":{"name":"@vue/compiler-core","version":"3.2.23","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.23","@babel/parser":"^7.15.0","estree-walker":"^2.0.2","source-map":"^0.6.1"},"devDependencies":{"@babel/types":"^7.15.0"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.23","dist":{"shasum":"ef1769fbf313306b47c858735a9300aa2a20f104","integrity":"sha512-4ZhiI/orx+7EJ1B+0zjgvXMV2uRN+XBfG06UN2sJfND9rH5gtEQT3QmO4erum1o6Irl7y754W8/KSaDJh4EUQg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.23.tgz","fileCount":10,"unpackedSize":694081,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhoH/NCRA9TVsSAnZWagAAR2IP/3K7Quhr7+VZ8zREYWO1\nkqdFaK23Ch8g+czeyxhhtW3xLV+aChW5EJlP+9OX94THwHv2oVqMa0iSfG6m\nrv8UyeVlVjD/8RsY9pNWldE+9Z1DIFopBh7bQqtLCEJvpvve7SmYR+pybT2y\nJgfv0QDbEkp42JQXt+1h2mChUo02cmtXlzPo2wzBGLg6fPlk9mpJxfuCBbW1\n5uWy5FOLVXAjfzN7ujk7PP7A1kWppricgfpSgCNp2rG8MPyCVKBkYyPYEZ3A\nimBIcj7a7Vx21juSKpmyIKO9T65Dsjj3K2pTULkTrPU/Is7+2WAgm8qF/iuC\nOiqGTYqd3bxJcJtcb3AmaiSN9Bd+ZjMkGfEMFiK6iZk3SiAy1GAVa1tkiMmZ\nO9bj81PEi/j8EFLQNQDdQerkya64tITutpYgzRgLEdmzsN/uGzihZG7BL7Kx\n6BIDc6jxkr4uJEAcmIuVT6X1QRrilnJLNGP7ordeCDIKMMFKMKZIcG6pSt4t\nuvDdrvho9IawwqDAOAR+J+zlh5Mg3SrfHCH/t+CwWkPE6ezJBrWebwM2Fkhf\nP2r7Broj5uB+myokNmwcI7PgsEh/LDMIJVt9+mMGO+JQ7lRTEfYravwe1BoC\nAkhG0K+28BbJbu16/zRExd7jsNqloeYC+AJUfFX7yNj4Dw45SAVxFwjbPTmG\n4PaL\r\n=sR3s\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBQCEl5Lg50NjIfOi20syNOwlu5hJ75L4JX5fU3YDWmWAiEAr/EmYY8LZpOYHY5fX+PEjBk4x9HeFEu3TqlnAB4HnPo="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.23_1637908429606_0.2215344614506256"},"_hasShrinkwrap":false},"3.2.24":{"name":"@vue/compiler-core","version":"3.2.24","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.24","@babel/parser":"^7.15.0","estree-walker":"^2.0.2","source-map":"^0.6.1"},"devDependencies":{"@babel/types":"^7.15.0"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.24","dist":{"shasum":"cadcda0e026e7f1cd453ce87160be51a5f313fe0","integrity":"sha512-A0SxB2HAggKzP57LDin5gfgWOTwFyGCtQ5MTMNBADnfQYALWnYuC8kMI0DhRSplGTWRvn9Z2DAnG8f35BnojuA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.24.tgz","fileCount":10,"unpackedSize":690859,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhrdHQCRA9TVsSAnZWagAAQ5IQAJS+H25YO+C7szu0LHmW\nXbZrnXaR7x7lUgAW/T37iCync3Ews72Egp+p4sb/ZMYkvI/c0rDxPPbM6ts6\nsvildAktBdPSxEDfZHmSo8XTdG4+gnJ+PW5/lUuYO/1DtF69/P4eeVFIUsO9\nLvsQSylKXmMXQy6fkU8S2f+zADQ80j5ulUtIVHVodjT2PZVpA2pob/PtRLhm\nqkD86YX93sU9Y+A8DY1teN0PzLfrfpz187Ne8nInZYH80b3tJqIshBRjaP6p\nnJ1G5bXjyprKvNMfDbkN+L/Qg7+FtZqsu/YChD2DXhbdWzfWrpPnfCZcca9Q\ngbBYAAK40cwg6DbLxOYbZwDuFGE2cMJHJqES11fbrkn6SiGpXzokCKUhoKo+\n5rgNju/C/mLsaVgok1Z3fBf07J6+FfU97jrqFLijnox1kshbl1VUVMBIqhUp\neNubzxddoF2GlAs1A1dNcp4A71YALjms98bJ1/TyjorVTrw1/6uQgmBBVBa2\niiLvLjR+UsPYK6bPkBGB76V8vJduEoZcdUTmkt+8gGeRNuKB0WWpHPAExBOa\n1SIQClI3Rss9qsaQXrYk02+lmtT4yTQoO1pJ8CoKP9Q4lLcuE2IzAFxPMZvt\nV95bTxuuF8CXTDOvxLrvnKfmv4nbVmc7hvV1d/iEmrU2dc+gVihkCYOV+yJ1\ne4ba\r\n=yJr5\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFm3BtcACNrmLKDTX79kmB6PkuFYJ6fA+GjfEsBENpo+AiEA0s4STQm0dbzuowpK3258H1KdIyVZQwA9jf2uKJ/ckWY="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.24_1638781392645_0.8391862356605193"},"_hasShrinkwrap":false},"3.2.25":{"name":"@vue/compiler-core","version":"3.2.25","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.25","@babel/parser":"^7.16.4","estree-walker":"^2.0.2","source-map":"^0.6.1"},"devDependencies":{"@babel/types":"^7.16.0"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.25","dist":{"shasum":"3fa88debc97a89a513e1d9b771e0802b9a006734","integrity":"sha512-FlffKezIqztTCTyG0klkYRwhdyL6b1PTTCIerPb4p2R9qQaczccTX5g9ysi9w6tpLQ48a1WiXnFDJhWD7XoqwA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.25.tgz","fileCount":10,"unpackedSize":692177,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhtXi7CRA9TVsSAnZWagAA/2gQAKNXiwy2RAqDkAWmFUst\nhsLV/KXOqtlI0kGQypZXCA2bQ/zFiWa78hPIpkwphi3pPo0S1uSZ29otgoZY\n3n7/BxFiqTgmWoFBQMClsVhfNXAszS5JJTykRdsVdizypaNbWJWCRMcZxi71\nZ6km9Rlo/HE5W5ozTTNCS/SEKDROz9nGGr+sVc0sS0AV5CV3WFV+fD0NnWS9\neANm0BRJju8SCUbOKRUmJxSAHWrBjylVpnZtVlTBABcSQH6LYce33BRVLAkl\nv82ekU2+f5yErrIjAMahhZy7N4lh0HhVp3NmpBxAAuoA7AZxzkz75szFhSOx\noDv3e+PdN26KbQXLCkfOt4KktqgZ/2mTqfjt/A9NOXLivl6PzyNrH87shZmj\nCeX0jSs6wuVNDGXfd5lCxOJrV5nRTG2puBWZjM58rpzUX7fV+V1EZYMW4KTT\nio5T04ivge1h2MzrlJAkcSiN4lfb7jjCsuz86uzweVA/cIT9kyrnrF6+B+3W\nhkyx1yt9ZYTecORPMrn9li4/3GQS958i2N5uLwEWrJtoTFsDQFVNn4L3qgUs\nM34IUjKj1NLzxMuRDbHQjdvI/qYgZATPJLn6VxMhEuFOcwfTzLMguEp7wkj0\nvw6kOLbEyYcDHwV/bNvqrBTVyMp1uL+NAkjsRNlTFnFdW4hJwDzbQKODk1oP\nVUM2\r\n=M3/O\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAzjkA2YIjjgknx3gd7aFVOiqi6eOf2dXRXkw95VCEtdAiEA4EsSzjQwui976rQ5UcA6AXrHdaDImHAP5J9jI8L4Big="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.25_1639282875179_0.2725783849221466"},"_hasShrinkwrap":false},"3.2.26":{"name":"@vue/compiler-core","version":"3.2.26","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.26","@babel/parser":"^7.16.4","estree-walker":"^2.0.2","source-map":"^0.6.1"},"devDependencies":{"@babel/types":"^7.16.0"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.26","dist":{"shasum":"9ab92ae624da51f7b6064f4679c2d4564f437cc8","integrity":"sha512-N5XNBobZbaASdzY9Lga2D9Lul5vdCIOXvUMd6ThcN8zgqQhPKfCV+wfAJNNJKQkSHudnYRO2gEB+lp0iN3g2Tw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.26.tgz","fileCount":10,"unpackedSize":692177,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhtZ7CCRA9TVsSAnZWagAA8p8P/3nV3+VdbWjXrPWhXI4o\n3AoGm7ycBmUvvdB3fecLfh6hlHtj8hPy85MFeJeaRwpvRG7osQZQwK9Ee27q\nKDSb4brtmGSdE9/f3Jis9LnHibeKyETitR0l/wXHaZlmANZgoGHrr+1XV8L4\nj4lZbd/gcccU1fNxY7OG8kBLNin/IG/FgBqc8ZXBHS6Oofyovqs6L3QF/H5R\n2CVSc9nP4PtIGBFKM4ueD5Zw4O7PLEqI8lK9GbOqbxwGCDNhuBQfSpyPVRkx\nZ4uM0TOu1c4FWm8B0JKqc0IAAXNIFiikW3vA2XG+Gebjozham2xQSv2XU97u\njE9mON2ASi2Sq5cKPPcCkj25OVzCso+Fb3wV8uf9nPeLNyrJRIUjjR2Ov+I4\nLoXXv5kA4mTc6mFLAAGF/707PSAPCeG3uDSEgs7ox1DhgKsQJS8BZc+H7uiY\nfOJPS+nzhkJjg9lUdRao1tSqFd+PHPWadaIQS7Eu39Y82u7QiA3fvQxhCDVj\nbJWWDt+iRJPVEm7jmJU8RBcMrbhD8vhX4qGzHJHEeWoMeIpDFAPmjgF4MDlJ\nc0SYzowiL0L+NhIWV27JxfzoJU9ryK0I9ARY1bx18nn5QENusaIN4jJQPI3z\nHCZni4tcD1ZkBCx98wzJ5YqcRR+pabWtSVu11eMqJUsQ/2A5W0DqJZxc4CnC\n0Xo0\r\n=UIW4\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDpvS7t31kxW5sATMGiKgItvpAgFJ3w0nC+UyeCXmxf2AIgahrU3ZYk31PVHbJoF3SWMWkpR4kHIgXnsTq03pmFPT8="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.26_1639292610470_0.6386040088609508"},"_hasShrinkwrap":false},"3.2.27":{"name":"@vue/compiler-core","version":"3.2.27","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.27","@babel/parser":"^7.16.4","estree-walker":"^2.0.2","source-map":"^0.6.1"},"devDependencies":{"@babel/types":"^7.16.0"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.27","dist":{"shasum":"01bd5e5071f58f43e4184ba7fa810226799a5383","integrity":"sha512-JyxAglSM/pb9paG5ZNuKrf5IUpzLzQA3khjWGF9oESELCLQlt6O3YyPMR2A69wIpYWrf5mScZ8YY8TJKOI/1kQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.27.tgz","fileCount":10,"unpackedSize":692177,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh5CbTCRA9TVsSAnZWagAAD3UP/33Yyx/4QJ5xzWhH02X6\np7B1qEfOBDxE6X+Yyz0U98QG+vYCTZcFLvU0BqHaziNwQdKJrcMttChBEEh3\n3Ci+7lf6rRBpFrB7djEBMADyL16BTYeyusBuPP94/SOAUFrnPHFZpaEuYE+S\nyjFinvtMrU+1emk24SmiWiWQ4ev0x1ofQrdZeBzkCTUPKjllq/8H+0TvNm4y\nUM6V1PitfpFCyATBdRPjTZyZ/5bhkSzuelG+Ax9hryqjbkIdmYXRe0h6aCHy\n/aCTzxR2uQjRPYBCKdGlQ5DRe+pwewHmYbLGNvj0A8GQXlw+mJmWEGEBKTqu\nPmj7AThGBDcG4NqtsJgHfKeb7rZexrXsvLgsA6qlL9WbtMK6jX6MyjkD2aXU\nDAXdZAHng3aqsN03MF9PvG+V3rDGURo7nLaDwkaCVt1z/lxL03zW98fU5CCd\nvUDcA0L4Td+pMFPF1kiSlbcz2roXDboXCLwi2YVd4Hy+q6v/LJ3gfGcu0ZUQ\n09UIc8Gsu0dr8rH0E1qSMvXKIoXXKmF+OsiiPljGkgrZtvctIpx6ctB3Hos6\naHA88j7FL/SXLbLZ35F5Aw0EivNb/d7KEG3JnG+QCJb6PIpv9EE4I8LL3ihS\nCVktLgJlab4SVyexDf3TrIweDWKUfo6sTr0nNHDdnv4v/YD7SZpgIEZdz6l5\nmFsy\r\n=OQrx\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDO5v6CIQy3k2i9umvwlJMWpavIb2YQa5NJII1kBJO3bgIhAInZ9+dYQsZscZbu7DOFmNw9AQ+32b77OjnRQwRW7t1s"}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.27_1642342099404_0.9407304662716036"},"_hasShrinkwrap":false},"3.2.28":{"name":"@vue/compiler-core","version":"3.2.28","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/core.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/core/issues"},"homepage":"https://github.com/vuejs/core/tree/main/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.28","@babel/parser":"^7.16.4","estree-walker":"^2.0.2","source-map":"^0.6.1"},"devDependencies":{"@babel/types":"^7.16.0"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.28","dist":{"shasum":"7f6aa4b167f0ae0413f3c36e507c898db06e8fe8","integrity":"sha512-mQpfEjmHVxmWKaup0HL6tLMv2HqjjJu7XT4/q0IoUXYXC4xKG8lIVn5YChJqxBTLPuQjzas7u7i9L4PAWJZRtA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.28.tgz","fileCount":10,"unpackedSize":692192,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh6muSCRA9TVsSAnZWagAA7QAQAKAnPOLPhptZfDqxkqxD\nwLu7bzA3V9SYUJSgDu8peoEIlBoYF9bd7w58vaSMtoz3B2t342qhOWsYWlEa\nYojLzE0V61KH+6jBxbfu/Y5EAPdgmzj71CPc1GEqTtgayU2QXd9Yy/zc3X6Q\nwrsQ52aM6Jkxt+5M3PjolwhnwwFJCxrVd1erjzXmOGHRPO3+ywe6qWEVD9Qt\nhpVLa8qiy47cClegdzMdzBoE8h8q2UZXVcjm5lSYtICvbshlNq+by439NCAV\nyuXKIGpVNin+i4yPNdB0cCqp2nzW9sWLPAPDjlKDhjisoRBH3MyIq7E8HOqI\nzdKxP1gpzXRthcViY5e/H7uxiaTQiOQMx4suc4hlboNP7awkhb1yv0lWjYMG\nLvCM0ANozYl91czGJ4ymDiWJviRPxdR29skhqeHI+A8RJBStSRUKHCUMmvr5\nSpTxe9LPbdEli9iXReerad/g9g8mNeOIH9uDPTxmgiuVuHVSy0xs5jyy35zS\nZCqOaz+Qp0uMf6Fp4wc21fVUKhdEsivLMjjpmHlj+hlPrvNV5F946eSkV9Cl\necA/R20/ma/YBogWUMZz1kslbY27J4l1Knf5fOVVqQHBiDlBcS+bZtS1QXws\n9tavTCHu87kcCoT3ojDhYoJg4QsGXFKyRCe84nixfPwGGsx9LkV3uge1dFlt\nyoD+\r\n=t1qL\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAOPzocfmU3463sb52pWcgf1Ic8amAt3DoRkBlU4Rf1/AiA/kpjh76SC/0APQm9R//G5Fk3Y25Ef1i9x1uoEwehGbw=="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.28_1642752914617_0.8041712309926026"},"_hasShrinkwrap":false},"3.2.29":{"name":"@vue/compiler-core","version":"3.2.29","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/core.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/core/issues"},"homepage":"https://github.com/vuejs/core/tree/main/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.29","@babel/parser":"^7.16.4","estree-walker":"^2.0.2","source-map":"^0.6.1"},"devDependencies":{"@babel/types":"^7.16.0"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.29","dist":{"shasum":"b06097ab8ff0493177c68c5ea5b63d379a061097","integrity":"sha512-RePZ/J4Ub3sb7atQw6V6Rez+/5LCRHGFlSetT3N4VMrejqJnNPXKUt5AVm/9F5MJriy2w/VudEIvgscCfCWqxw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.29.tgz","fileCount":10,"unpackedSize":692192,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh7V/xCRA9TVsSAnZWagAAw1sP/0LbclJxt66daZUeVfXo\npMU38ShL2J0EOKxKq9TNmsR1R58rPd4SZR7xWkGtPXfEVD8OPqWOegmXxMRo\nvVCqxtLaWLROYYr0uskxUTIuf1YB4Chi/p9wj3E/GeVtM7qeqSmp1MhUDmVH\ndtRmugQaEYpBE8PtJTheyzMO2kM5LjmEIJQUX0qYda+sFhutrp1kFRqoOrCz\nvwLDOfYWxNsQkurYgBhYyMWW+TKVuiAhYaXxO/sE4dcYQ2U52YDF9syOoOo/\n+blq9RAjnIcixobFXaQx39oSJwTemN2Pir9sqTQJwcjcq+dI/KDFx0rMVaJZ\nGzaZP7NSP9G/euifzWAgYgCzPO7fQ+eM4RD02986dIrSQWTDTHuJe8XN07q3\n7CA364gcqR2Soxt+LHGH9FR18x+0iWmmLYgUgx+7s2DXHuehITDqufO1FjRG\nPO8o9QQiNImh/GPgMC8luCLON7wtSedxJC17WRdPXJNUW9x8BMwQBL/Y0QOz\ncuSwp8KDtASP05/NcrSDhWesS8dFm66QgxtJj53APqR+AGp839F7a7oGGQym\nLglgm2Z9D/IoUCLx7DOdO9jNhvR8qtITRtfM4Yys8+q6ivHIP0nZWB14ZQ6a\neCSc6DU7SxZEBAidamshylctGBZHQn99t4RDkxsa0eiBQ0iNnzOOHzV+A/3S\nNTN6\r\n=6UUq\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDlvnHhGGXM3cz3xO2WsTCNNqv38k0Zln7oov4C8cl1jQIhALRYrhOMWAA3b1vtvVn049ll0N/WjOWvvPxJhjPaN2jZ"}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.29_1642946544962_0.5896142571286427"},"_hasShrinkwrap":false},"3.2.30":{"name":"@vue/compiler-core","version":"3.2.30","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/core.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/core/issues"},"homepage":"https://github.com/vuejs/core/tree/main/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.30","@babel/parser":"^7.16.4","estree-walker":"^2.0.2","source-map":"^0.6.1"},"devDependencies":{"@babel/types":"^7.16.0"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.30","dist":{"shasum":"6c5b362490930e72de8d033270a145e3830ae5c4","integrity":"sha512-64fq1KfcR+k3Vlw+IsBM2VhV5B+2IP3YxvKU8LWCDLrkmlXtbf2eMK6+0IwX5KP41D0f1gzryIiXR7P8cB9O5Q==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.30.tgz","fileCount":10,"unpackedSize":692786,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJiALjeCRA9TVsSAnZWagAA3ggQAICir1H57iU4mhx2VYig\n8zpaVehIXJ0VMm1yct/Ebpm4bGfHA3V8ORscZesESDo+QlF7X9T1QN6ZzXih\n9nP+AtFOSDCn/bOCc/6yLXSyIcyKobXcSY5Zg7qNeJ8ugDtDg0robbIRIkvW\nRrmrQtud8TZ7PN/FkSFh9MO5T2Bcqh8Kn86En//MKYW3+hA6ujgCUJbrLu14\np4htBqP35vEb+cy5KcRdmCAtoDoz5N7AU/Ure+Qm68SdzU08OZZLDuyLrQRW\nTllo5MujEfwquTmVD34WK6kQuu3EcnP36HLM/LXFk6Ejm6RdbGBQhRug2VL5\nZLJJXn9YQQUCm6bRk5eb9XWteP8ZQyNWV84rlnDROAfjnLLNWaSMv3Cvunsl\nuWkyd2pupC2Z5/7Z8soGV8CPBWznQP8M+gEO4qF0i3qnEw4lmyn04d+Gg5dD\nSSi5Dm8r61XeAYTQNHu/fZGI3i7e84f3EEnTONPVIPAjiKxJg37I0fQhktgZ\nFbSLjDY1grd+nBBaHCqX1rfvZgE1IvOHPR9rBrLTaiMd46yvAP+UTLppxb5V\nJw0zqSXJHcPQW9IAITifBqZc1rwKhaltyssskiBXKtkK/MMc0MYnwVpk/tu3\nyK/hGUQ2YbxjkzimIkLKLqu5xiBA2YqWQo98PYOdCDYNiHPxUDkF4wqTcbMv\nARNX\r\n=Tgj/\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAXF21k4sPYcwx6XNG/pV5/YwM0meslKEMU4ZFckjOY4AiEA0mmDwplX9T1ijU2mP2o93I+Qg+qjwCNnpSzz98V67u0="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.30_1644214494530_0.6967213885862908"},"_hasShrinkwrap":false},"3.2.31":{"name":"@vue/compiler-core","version":"3.2.31","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/core.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/core/issues"},"homepage":"https://github.com/vuejs/core/tree/main/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.31","@babel/parser":"^7.16.4","estree-walker":"^2.0.2","source-map":"^0.6.1"},"devDependencies":{"@babel/types":"^7.16.0"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.31","dist":{"shasum":"d38f06c2cf845742403b523ab4596a3fda152e89","integrity":"sha512-aKno00qoA4o+V/kR6i/pE+aP+esng5siNAVQ422TkBNM6qA4veXiZbSe8OTXHXquEi/f6Akc+nLfB4JGfe4/WQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.31.tgz","fileCount":10,"unpackedSize":692786,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJiB3LSCRA9TVsSAnZWagAA4JYQAJlByPHtn/hN+qG/7BhY\nYa7tJ2csHNkswbZPCgowVhN6zb4QUA+/Lk1BTQfZmSBfOptz5DwBdaHnt9F3\nnqYxzOwcfruYeibninLtjXOCjIrb+95dW9WMK60/HWmbuC/D0ZndOzNxlflU\nyu2f43B+x+hYfqAnJSJbbWrU25KWHKbHrFPXpmyuxkeI+9Z/L/0UIrtpNMmt\n5rVGbOD67WJpCTi2FFj3gyRyRVtG8ozQLgsYDVOM1ADF7hBenwxXTDW3juDz\nlBV6uVKCNKfDqbG+XHActDyKpuQY+hTtKiRzQ8ZezhLulVWHyBrAZhzVxrWK\naRbjnjh2A4l3dfE5jesG1B1atWIZuxeNy0hPkTBfXdfMG/FOWwyOhxxJY+NW\ns1Rg9cZfCvpxuox6q3YTRoWrHvrQlCesmMke/WlJp1OoZsrA7qGVsl7mhl4q\ne9/GeG+szmgPk1brjqAAkHxj8hy5EZvBjZrUf0n/uvxk1jSmwKfkkchcmfxd\nTwvDDbXLFLQJqA6hqENv/WnylqoTdBjX8bdD7TPsnwyyr1Byu20UI+5xTbj2\noIbqzOBRtG0N9GhBgdKvaQcZ5O+1uyjJ0cne5x9zGok5MrFF5ooeapHgO/p4\njZGgcCKShBGfGl7SkYGNIwHVngX/s/T/ypBcya+8zOOOz/ynrTIZreFhZ3rL\n4MoQ\r\n=vvFb\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCY6kbapWH9Z3PswQvFFUgWNEM/0d9ij2dI2/7V1Y2H6AIgXJyiqjEnEFBuHBGv9iSnkUJ6SCbc5iLkAExcJiKy8BA="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.31_1644655313898_0.7937135020342998"},"_hasShrinkwrap":false},"3.2.32":{"name":"@vue/compiler-core","version":"3.2.32","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/core.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/core/issues"},"homepage":"https://github.com/vuejs/core/tree/main/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.32","@babel/parser":"^7.16.4","estree-walker":"^2.0.2","source-map":"^0.6.1"},"devDependencies":{"@babel/types":"^7.16.0"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.32","dist":{"shasum":"a0be08214c55ae48092b413d8b552c0573e3a883","integrity":"sha512-bRQ8Rkpm/aYFElDWtKkTPHeLnX5pEkNxhPUcqu5crEJIilZH0yeFu/qUAcV4VfSE2AudNPkQSOwMZofhnuutmA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.32.tgz","fileCount":10,"unpackedSize":692786,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEvVdD1eCfLtm2BncFkji4ONGCVO1l3lWyneJEoCXv5KAiAU+z/H8C75twDNsijmQSkNSyALPeOMRY6oRs7DyLvHBg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiVTNQACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpDTw/+II7I7qfNPyxu/pfF0hz63Lb6c0mr/uSBHvUsPtPjqyOyKmaM\r\neRCEErOguMxbwSVPh070c1pGJzWlLz6yzaJ9xU5Tx8OuzvGtVBnmbhNSBVM2\r\nKQtalamxQ+8tqEZgd10eP6TwzI+ggQjhm25kc37v3aLcCi80EMeEygRSqxpM\r\nh0O+uadnsqDHKIuhPi2tEtEmOegDwnArDHIl+C5h5xbmIj4NbLnzmAbStUKC\r\nfee3qUd7k6S6hqqkapy2ibu9s+z34dlJhlwtYJ/nAN12Yvaq8m7H5k3Ht3jT\r\nK9orbbD0V03eo17MxW8mNA7okU2L53poZV8N+eq8dxWwQJ7HpKGZ8FmPb98Q\r\nCnIp1GUm4yObeHgfK/OITUwXDO0y9vC7+KnPf4XNZycc302rtvQtivnlQ6LX\r\nNhe61dfszn/qzZb00I6DsWV3Zv0H46O8/EtH7BbE4mtNe50oSZxhF1DGv012\r\nZXM7oEmqmzBDqCIH4t7VedaC4+WEEh1crdc219NlSFM31OKnWtwPdBsC4I95\r\nthdE0vPo7BxYg0OEFJxeW73uopFXE4GPVaOhBo2oynVq4PbfWAPVgkQ8vOE0\r\nGjOKy43Zqq8jwc3Dxj6cAtbeQKHdIHqqpNIQLCsovFvHelAOhAfAxCZxcfLU\r\nWM7iI/pFQ5T6hAevqDN9VcD/meCi6q62I7Q=\r\n=V3wB\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.32_1649750864658_0.8847531826848998"},"_hasShrinkwrap":false},"3.2.33":{"name":"@vue/compiler-core","version":"3.2.33","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/core.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/core/issues"},"homepage":"https://github.com/vuejs/core/tree/main/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.33","@babel/parser":"^7.16.4","estree-walker":"^2.0.2","source-map":"^0.6.1"},"devDependencies":{"@babel/types":"^7.16.0"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.33","dist":{"shasum":"e915d59cce85898f5c5cfebe4c09e539278c3d59","integrity":"sha512-AAmr52ji3Zhk7IKIuigX2osWWsb2nQE5xsdFYjdnmtQ4gymmqXbjLvkSE174+fF3A3kstYrTgGkqgOEbsdLDpw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.33.tgz","fileCount":10,"unpackedSize":692786,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAJcf1QjhHKfL1c2z8QSVVn8Zw5ci1PbCUy7dN33oZ95AiB2LVV8euqpEzJ3Tj8XYpwC2o2J3VcetyZ1p28cDPNGdw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiV/QOACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmppHw/9H/yQxs5IJtQ52cZxf8AhaNgD+lg9E3BhG5WABa00auxeZrVo\r\nSIybxJ8+UaC4faPOKEH02t2Hbcuvmwe88OqwhVnGZrmihoA2t16GXmMKkjoT\r\ndtao475YnXC4DqVS5hfQCk7sQaW+hyy/xYsSXVmfoI6ke7r60NcGvxfDJapa\r\n7Rvn1VnjkzdayDN8PEPj3owWHGKqaAmjtQOADo9K4jLiCpeMELrEGtyzyCMM\r\nvB0EPHWti4Sju/elsiFwzqtt6ExHT29yOJaTX+CtC1wBFq6rUEopzQu0MXDz\r\n8LJr1reqOgJx7NgEFrxCHpmUnERKngJpAp1DrfjRAb1BN1g38tLUU/DU582L\r\nadqWYUW3S0ql8beGHViJV+F03ZpnnlG9q1FwCY7P4wSxHup7PY/2DhUsq6Ec\r\ncHhvJRsFY7P3vLcmys7h1FyUPcX8KJlc2gDXrsuDumIu2JSNOEJlcChclmHN\r\nW/ZSEKpbGnU/Rcm+8AYvtPOciDk+iX4k0XpRO5NzZ44FPUc/WBJWHZ0ZTV7c\r\nVwyaXYAhZocNyA6ivy8ClyUWnh9Z7oT1UKbYJk4BHl9F/JZWXcGdemmPKljY\r\n8w7n57YY7nMEPR06WevwCcVKAT8B2IMPzz6hfkeR5dqvoYT+mXF+aPONbWfG\r\nxdEvygDc15DtSETWO0hKLKV3IXc3iNoCSq0=\r\n=dh5W\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.33_1649931278071_0.16366249779400133"},"_hasShrinkwrap":false},"3.2.34-beta.1":{"name":"@vue/compiler-core","version":"3.2.34-beta.1","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/core.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/core/issues"},"homepage":"https://github.com/vuejs/core/tree/main/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.34-beta.1","@babel/parser":"^7.16.4","estree-walker":"^2.0.2","source-map":"^0.6.1"},"devDependencies":{"@babel/types":"^7.16.0"},"readmeFilename":"README.md","readme":"# @vue/compiler-core\n","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.34-beta.1","dist":{"shasum":"5294f0cfefa387779d5653fc16f6cb51db95136f","integrity":"sha512-OTGP9CNPMOXNChqGOYwxG7PDWwEps8giACqG7yBLWVmUWO2EsEw4cuK8mLzucOoAvKvWLLD1Ea/Ena1itn4mEA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.34-beta.1.tgz","fileCount":10,"unpackedSize":693253,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDTKBYQMAV4PQKA1mRgWrx9zsDO3eVT2Lb/xiCslqCRxwIhAOSVK5sPpZecEn5vgZ92kI7Nt5D0oo3aiwjRlHGKlHDT"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJigypgACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpTvBAAirkZVtFJPDTyUL+qrqW4bxpXKPvzRarY8xF/RWulkt6ELU+G\r\nQJYKHX9QOyhJBuUhyROVgQokF1sPpKZ7NSrci072Y3R17zpwGIY97AnZAN/Y\r\n27T+npaS4RSWMTzV2hfxvA6gzhPHWl17j7JuIebypJi478geaWv5f0GY5x4O\r\nIr0G/EvkTxjlCLBXDECU0MaK37pC1xvTGWe7rwZzdFmvwH03K+Dqjym1hvh8\r\nm0Ve2M6ysiKHlQOvpEkaYy+zUOP6JziWTnSjpC2aS4viyj/PT5K/PKPoMdSV\r\np8YK9gmh+2d6VpP6sz52tndOEFDMOowcbcvrkBbZFVhnlK9p83X++gdX96+D\r\nZDoLp4VhCt1E1i6q3vFjSYjpkUXw64vZCm5fGQHq9vbCuiPoqdU2uYfrsu33\r\nJw70uuhRodetr9T48xfk/HvijuqsinqN7fBqs2Js79h+2uH2VVE7KmpNWAly\r\n/DSqoN9DRH6HoktrHEjj7FRrEFtVWkNHn9lXXYv4oG7OrkUmSmo/iThyx6FP\r\njnNKHFjRPyRBPeQCcDIgg/wsSV7xJrNWAzFqjlyqliiylgj6SwqYvSFj+Ur/\r\n/9XHzmtHYIBFcv4tBP+0KMVqnhugFbX6FuT8DpXpgIHQTFZP/g+Poe2WJ5m/\r\nfN9dbMFjXBROnM8fv7hVSnAB8Ufnsmao2lE=\r\n=ECNc\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.34-beta.1_1652763231787_0.48618373527965764"},"_hasShrinkwrap":false},"3.2.34":{"name":"@vue/compiler-core","version":"3.2.34","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/core.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/core/issues"},"homepage":"https://github.com/vuejs/core/tree/main/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.34","@babel/parser":"^7.16.4","estree-walker":"^2.0.2","source-map":"^0.6.1"},"devDependencies":{"@babel/types":"^7.16.0"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.34","dist":{"shasum":"e28fe9d2b22dcb60274daea6df07e653d8a3ecbe","integrity":"sha512-Y53lv04ZhDfqflhk4yEgBZrCL1RipbxqmqJFfl1PRkjOzt0bvJpf1sCNN81QNfXohVwFGf+Hng2ztwLwOZgbuA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.34.tgz","fileCount":10,"unpackedSize":693476,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAkQj6Oghh4LP1Qc842VrxbWtznJtWpZWi7FXJJS25E4AiBX6vlTRgyA02zwOP1Fer/tVH+ZLsWsIx+rcbUs29l9Cw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJihcq8ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrWMA//Vb4dghaYIzbwVq4EpF0RTZwRUruO6mAS7MUr+qDB5bz97WFJ\r\nRTIapjwyTJH5Au80E5OIH1OAVL2lmeEO9u/6ACQTOlVlq70B5O98em9V/10s\r\n/0KJS2FzIcZ6JsqkdN+Cl+uLeB2decZaOLpMeA341mls9KKFvcinvcv5/yv8\r\nX7ggoK412wA1o45DS17paf3HpcqkaWa2qfTGxAihnvQUhJyvaU0Ml71/UFKB\r\n8xzOYadL7sG+vf+oMDvXQXrzV8EFffbowLo7PkKUEil4otTUs8xptEc/B0fQ\r\nz8Lz8UGe8cWHquLHuKUf2PG4Yo8gHzpcepgNrD7JE67oGRg8zTlidx/nafeE\r\nHboxy2UvPShRUdR8lp8NwB/FpnQJjQaboIYO0g0zlEPYrKF9jSI7tc2+vJTy\r\nxzxvfhmMtoKVqh+7WF227o8tj8qmEHH+RhLsoPKl0FkW5C83rRK64MvUEPsf\r\nr85kF73BdTYFAVGmpbUQP58CqyAt5+CJpQg5kM4tlQmfUKXyC76nPHKR+y75\r\nfdgavLBC4pPHvL7FKdDP36h6KGEFB+Ybtjp94YxNIgyGZz1+pfuVx8DfauMD\r\nTPPzo9vB9qxG/GXJBhmxsRXjD8S338zchMRg7zBDygsadzEwoyWp5c5vnE6A\r\nTP1cnEd7LpxZZeIrECijAlo4C6Griimmujc=\r\n=Eaij\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.34_1652935355928_0.16738727222158145"},"_hasShrinkwrap":false},"3.2.35":{"name":"@vue/compiler-core","version":"3.2.35","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/core.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/core/issues"},"homepage":"https://github.com/vuejs/core/tree/main/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.35","@babel/parser":"^7.16.4","estree-walker":"^2.0.2","source-map":"^0.6.1"},"devDependencies":{"@babel/types":"^7.16.0"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.35","dist":{"shasum":"f2fc01bd25d859a77b0d9ef5df28f657c1979070","integrity":"sha512-1Mtmh8ceVUoUsn/PME5oM+Dus648rCeV/fBaZ4ERLFbTHBJXj6QmDPrSn9mfEyPDXE0RYIwyJNn884NdWK+Yiw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.35.tgz","fileCount":10,"unpackedSize":693590,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDeS+p87p0fQYttSFw6raDDxCxcNNLgmX+AEiDWOu/BywIgGEIBBQZG5N4u5hua8cjEva6aFjst5oReVn6ZltPgD00="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJih8zrACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp93Q//R0LN1ybD/Y+8Ib63wPGA81LHGbnV1EeDEe0xGmaXXy1zRLhM\r\nkcH+J8DxK7a/voOXE4tchf92QJaqLz8JkovgLSv8N+UQ6/e4gmQZ8yuWNWvS\r\n4xOuPKFDybCdlzmnd5x1bEILFgoSR18vShlf3xY4hTGMgB1SYLD/YByeaRo+\r\nolFLNri8/iXB474bXEEQAe3/ImR1OV1zLLO9e7fsNvZr0gz1Wqs9TMhJNKuh\r\nF63JuANhcAyosNY4yN6De8wuQtumGbkrDRZfLQlLOVHUq883tCb8OOcMqKZu\r\nFLXmw8Sy+DShKnxdrfcwJzMRXr9bEgGa8WjKW+L2/YgOx2FwCp51XqM8ES3k\r\nS27NK+yubnc4SkBqXxuWWAdcHdi4ecuyNsNqZ4dfDK6Zrupq7dqwTYNJVBay\r\nTcu4xzndg1yyhBtY4kwu3Pq/7zFpi7rR0zj4DIF1GXwJWZZBnagmyZAyreps\r\nto4s3SeVG6I1M45igSjiObGQGw43ZaglN6qWTIUa0T2575BoNZSRc/K5xyXE\r\njv4vFUYxeOUMqIrB2DM1OcEOge17VBhsg1Y53SX1udDP0zM5X1iq/uQ0tX/U\r\nY1H0bBFbpuQhgbL9/LtE3XZK8eENT8vVObH3EIv3S6yWUAdIK4/rF4aM2XKo\r\ntzFQL2V6nGgufGNuSn4Wife+F3ewuv6JC+M=\r\n=N4kv\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.35_1653066987559_0.970221601421072"},"_hasShrinkwrap":false},"3.2.36":{"name":"@vue/compiler-core","version":"3.2.36","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/core.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/core/issues"},"homepage":"https://github.com/vuejs/core/tree/main/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.36","@babel/parser":"^7.16.4","estree-walker":"^2.0.2","source-map":"^0.6.1"},"devDependencies":{"@babel/types":"^7.16.0"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.36","dist":{"shasum":"2fa44595308c95610602df54dcb69063ba2c8383","integrity":"sha512-bbyZM5hvBicv0PW3KUfVi+x3ylHnfKG7DOn5wM+f2OztTzTjLEyBb/5yrarIYpmnGitVGbjZqDbODyW4iK8hqw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.36.tgz","fileCount":10,"unpackedSize":694838,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCXIlpCmNRtdfxBkcWawbfFxGqZdvcInlZZx4ScHK7oGQIhAKtDN9ortGaiu21Vife1AKa3doQViLNSYcAQTo3DSZn8"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiiuudACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoHFg/+OcZKUOEo9TbBqghhAU50VX1a8VWnt4pB75QnzfIjxpwUSwrJ\r\nfFKUP5nRZP1Dn104YjM5Xgum6F2kJaMtOo+a0niAmFFt41SWM+wFZhe46MYx\r\ns7KMDtlJ85aap0rTpsg/vzFDe7U8neG836G3qSiK8XfnS+PN1h6qP2fKWdva\r\ngwG5FIUxVvtsXcnxBGDO3FbmhfBLG8bRl2zcXBdqoMBmcMVPmBW5ki57968g\r\nUWxpW3JhUkQmwKxqjtkhbHLp7wyXtuoApQVJXTYzfDcRIlw7OnFxXqWtnew8\r\nwEyj1m6U+/ObfKVhoFaz9KHimD60GI6f9RMHMMluT8JAhWD4L2j1M6xwEtQL\r\n2SSUF4GFUcUfLuCAd0HlQd/3JC0tNRL0aWwwCJyq2DDFsamhWGOB73vZOu2L\r\nr8oMGsVSIhtzdQBRPKQqgru9srnSutbAFuFmjQjX8jsjd926q3eTPolcDKEe\r\nE+N/X4QmsSn3JPM8isuZlnT61FFCpS26AyGn+JX82tn7b5s8Xzumv1RzeT91\r\nM32gru4GYe14sOsgrAQ+Pyp/lgliQs4Ihx7iKXmOUiA78iiAXVj3yYMkj2tu\r\ntzYGBUEzXPKVA9tfK5y2yvhwfWQDqnJ5aitScETaqBprt3VHLscNvTGAvi07\r\nE3fcn7B0F9FImf/plRhfY2po8kOtQwFutMs=\r\n=AAMX\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.36_1653271453430_0.9070127189866699"},"_hasShrinkwrap":false},"3.2.37":{"name":"@vue/compiler-core","version":"3.2.37","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/core.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/core/issues"},"homepage":"https://github.com/vuejs/core/tree/main/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.37","@babel/parser":"^7.16.4","estree-walker":"^2.0.2","source-map":"^0.6.1"},"devDependencies":{"@babel/types":"^7.16.0"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.37","dist":{"shasum":"b3c42e04c0e0f2c496ff1784e543fbefe91e215a","integrity":"sha512-81KhEjo7YAOh0vQJoSmAD68wLfYqJvoiD4ulyedzF+OEk/bk6/hx3fTNVfuzugIIaTrOx4PGx6pAiBRe5e9Zmg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.37.tgz","fileCount":10,"unpackedSize":694838,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCyXHe5Ku0u2C27TKFxeDBhW3aYg51JRS47Ca/c9u5uVQIgCmqCm3IMh+p5wG02OuRO0qXIdwjQRicWkwuIte0OgeI="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJine40ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoHmg/+Lh/LaJvqThNBqpaZ9ErPIPvUsdok+fF/X+x32odB49IVS9D6\r\napAJX4S5FwNcsI0djqE8RJyw2NnMFcXiEK6SKG2ETlfQPkD+pt4Gzyf8BgXd\r\nd0341BzQz6cjH3zVI5xwUYNobQ+25w9agGSILhqtw5dVc45lNqrs3Nzse19Q\r\nOkWCqaR1aInNdy2lVLAwxO6TOjpnuxUMQ/Xi5iTOCfuPTxBLLNX7o/mGk4Gd\r\nhpJgSFWExOd7rthU0Wc9EvZIMzEH5R5P9Y7RN1j+ugqBgqrhdkSBIS3G9gRi\r\nJj+5ze79EHYuKfhVL9oykWvXoEVE1R3SFYa+7VTkKhrvShBv3w+5qytjNbhA\r\nHIMHN8QvQVzIZQg7wVcLAx/6C0ah21PtST5LhpV4qCRRLtY++t9KDhNlEbXY\r\nidzbUGSF8A68iAP8+ZwwDayrfOP6KgRjOwhoI9MDk7sYpyEbp/WGYf5C9r14\r\nsy3/dtJoc5QrWPSPpme5L0RULX3ov0Ggkalu07rj045+MAsydY9SZkUJUpOt\r\nF7H9IymAC/WA9bHuosmIXGmSKHSe4LHxdqK22dnd+S5+OgchRr8g1+khUJ4s\r\niHnpQzcN+plIqVFpStNn507c2vYV5dkd4BPDTYwpwf9QTYY5d2lnk6uGyVqc\r\nAs5YynG6MaSn66aUhMNYm6nQ6HUv4ji1kk4=\r\n=wgkA\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.37_1654517300249_0.6990518189220285"},"_hasShrinkwrap":false},"3.2.38":{"name":"@vue/compiler-core","version":"3.2.38","description":"@vue/compiler-core","main":"index.js","module":"dist/compiler-core.esm-bundler.js","types":"dist/compiler-core.d.ts","buildOptions":{"name":"VueCompilerCore","compat":true,"formats":["esm-bundler","cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/core.git","directory":"packages/compiler-core"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/core/issues"},"homepage":"https://github.com/vuejs/core/tree/main/packages/compiler-core#readme","dependencies":{"@vue/shared":"3.2.38","@babel/parser":"^7.16.4","estree-walker":"^2.0.2","source-map":"^0.6.1"},"devDependencies":{"@babel/types":"^7.16.0"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-core@3.2.38","dist":{"shasum":"0a2a7bffd2280ac19a96baf5301838a2cf1964d7","integrity":"sha512-/FsvnSu7Z+lkd/8KXMa4yYNUiqQrI22135gfsQYVGuh5tqEgOB0XqrUdb/KnCLa5+TmQLPwvyUnKMyCpu+SX3Q==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-core/compiler-core-3.2.38.tgz","fileCount":10,"unpackedSize":715064,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDsKPQqDaQJpXMwojakkgQ7ZTXf6tvF6VB4KgShDmnG/AIgbTYxfqFpVp/k1NCauhoOb6G7hsX86LoqEpPRt9o0mqQ="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjDcP6ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrTCg//XS9cYJqJY63weci6LoEheFOtFdABVcbWsqg4sdlgTI0RT4qx\r\nJwdKqoRHbtiVVbPFmaCCfg14e4KFSUi4UL1OlhB7TnY7fdJ6L32y/P3+4Mi7\r\nm/SWcmqmZ/pGgrfs5PqPtTgVhgmIGd2qPkSiwbQIrzotvy/LAJXGwRgnU/zY\r\nZ7rl0FYPDh1MVp5gdxN8j0JurbW0GSlminPGEGo97bvgnYaoaLVcDfIp6lpD\r\nmKYP50Fne6QP1ofFmWE0k3DX7EikT9FGy9F+wgHzNCrh+HIJnKOB7RxrJSjH\r\n8a3FpmgB8IEVxqPfbUbgs1vtUCIH5pW8kNU0wEp93ad+4RQWySdcwfkM7QrK\r\nr9lbtgHcPhL5Zod4LVU9eVxz9/48fCyvEK+cMa7Bkjq8UxK4igGawiaz0Taf\r\nX8KWfo4q9bMawfuznXLwUl4k0uBJTuBJAcbXbkw1NS3IxriL1TlOPGzgxnoi\r\nWaZdZ17T23EF+HyFwMv7xL/fPPWi+0ZBI2WJ/qvq6o4lyi3cxKSeSIV0GssI\r\npWxc4pEN+dznoDTGQu4r2YaEq9R1IywlWOy35TOR9QRwLrNAUmUZ6NMA902w\r\nbug9lbp59hojNhjYKLzkbO0SXOUIPlfSWXiQTk8DqkUx/wyZwOp1raTvA0rm\r\nVucJyZfDCUcJniI9Eqgu7t9a1bfakhCQWMw=\r\n=a516\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-core_3.2.38_1661846522683_0.6274225461824565"},"_hasShrinkwrap":false}},"time":{"created":"2019-12-20T18:15:33.111Z","3.0.0-alpha.0":"2019-12-20T18:15:33.401Z","modified":"2022-08-30T08:02:02.982Z","3.0.0-alpha.1":"2020-01-02T23:25:19.995Z","3.0.0-alpha.2":"2020-01-13T22:44:33.165Z","3.0.0-alpha.3":"2020-01-22T16:10:33.575Z","3.0.0-alpha.4":"2020-01-27T21:20:02.849Z","3.0.0-alpha.5":"2020-02-18T20:00:59.551Z","3.0.0-alpha.6":"2020-02-22T07:25:38.001Z","3.0.0-alpha.7":"2020-02-26T19:36:41.533Z","3.0.0-alpha.8":"2020-03-06T20:58:43.928Z","3.0.0-alpha.9":"2020-03-16T22:56:46.885Z","3.0.0-alpha.10":"2020-03-24T22:33:43.655Z","3.0.0-alpha.11":"2020-04-04T01:45:54.058Z","3.0.0-alpha.12":"2020-04-08T22:59:51.832Z","3.0.0-alpha.13":"2020-04-15T16:46:31.009Z","3.0.0-beta.1":"2020-04-16T19:45:10.661Z","3.0.0-beta.2":"2020-04-17T15:01:04.391Z","3.0.0-beta.3":"2020-04-20T21:00:30.924Z","3.0.0-beta.4":"2020-04-24T20:20:24.017Z","3.0.0-beta.5":"2020-04-30T20:20:30.089Z","3.0.0-beta.6":"2020-05-01T22:56:57.066Z","3.0.0-beta.7":"2020-05-02T21:06:20.290Z","3.0.0-beta.8":"2020-05-04T14:49:27.251Z","3.0.0-beta.9":"2020-05-04T21:14:45.968Z","3.0.0-beta.10":"2020-05-07T15:21:21.937Z","3.0.0-beta.11":"2020-05-11T18:25:41.681Z","3.0.0-beta.12":"2020-05-11T19:52:42.392Z","3.0.0-beta.13":"2020-05-17T01:53:50.471Z","3.0.0-beta.14":"2020-05-18T18:42:15.546Z","3.0.0-beta.15":"2020-06-12T22:09:10.971Z","3.0.0-beta.16":"2020-06-29T22:34:54.356Z","3.0.0-beta.17":"2020-06-30T16:08:47.955Z","3.0.0-beta.18":"2020-07-02T01:06:29.820Z","3.0.0-beta.19":"2020-07-07T14:04:39.295Z","3.0.0-beta.20":"2020-07-08T16:45:33.175Z","3.0.0-beta.21":"2020-07-14T21:18:12.512Z","3.0.0-beta.22":"2020-07-15T16:43:51.687Z","3.0.0-beta.23":"2020-07-16T16:49:00.221Z","3.0.0-beta.24":"2020-07-16T17:51:56.577Z","3.0.0-rc.1":"2020-07-17T19:30:21.207Z","3.0.0-rc.2":"2020-07-19T18:52:46.922Z","3.0.0-rc.3":"2020-07-21T19:27:30.695Z","3.0.0-rc.4":"2020-07-21T19:40:49.264Z","3.0.0-rc.5":"2020-07-28T21:42:09.414Z","3.0.0-rc.6":"2020-08-19T22:17:47.802Z","3.0.0-rc.7":"2020-08-21T18:13:09.491Z","3.0.0-rc.8":"2020-08-25T14:31:57.089Z","3.0.0-rc.9":"2020-08-26T22:21:22.983Z","3.0.0-rc.10":"2020-09-02T16:41:58.308Z","3.0.0-rc.11":"2020-09-15T17:15:46.277Z","3.0.0-rc.12":"2020-09-16T17:50:19.966Z","3.0.0-rc.13":"2020-09-18T05:39:35.984Z","3.0.0":"2020-09-18T15:28:09.324Z","3.0.1":"2020-10-15T16:37:26.818Z","3.0.2":"2020-10-20T20:24:16.328Z","3.0.3":"2020-11-25T16:16:25.537Z","3.0.4":"2020-12-02T22:23:47.913Z","3.0.5":"2020-12-30T20:50:30.600Z","3.0.6":"2021-02-24T20:19:33.136Z","3.0.7":"2021-03-01T15:59:30.966Z","3.0.8":"2021-03-26T21:35:46.387Z","3.0.9":"2021-03-27T15:30:14.262Z","3.0.10":"2021-03-31T00:05:46.954Z","3.0.11":"2021-04-01T23:52:47.249Z","3.1.0-beta.1":"2021-05-08T20:24:36.347Z","3.1.0-beta.2":"2021-05-08T20:59:14.384Z","3.1.0-beta.3":"2021-05-12T21:37:06.110Z","3.1.0-beta.4":"2021-05-24T23:16:47.624Z","3.1.0-beta.5":"2021-05-26T20:06:54.945Z","3.1.0-beta.6":"2021-05-28T20:58:58.614Z","3.1.0-beta.7":"2021-06-02T20:12:58.364Z","3.1.0":"2021-06-07T16:38:43.873Z","3.1.1":"2021-06-07T20:26:56.208Z","3.1.2":"2021-06-22T18:24:52.585Z","3.1.3":"2021-07-01T23:28:08.448Z","3.1.4":"2021-07-02T12:37:52.333Z","3.1.5":"2021-07-16T16:38:03.653Z","3.2.0-beta.1":"2021-07-16T18:44:07.758Z","3.2.0-beta.2":"2021-07-19T23:36:57.381Z","3.2.0-beta.3":"2021-07-20T21:47:05.270Z","3.2.0-beta.4":"2021-07-21T21:40:26.792Z","3.2.0-beta.5":"2021-07-23T20:10:23.429Z","3.2.0-beta.6":"2021-07-27T22:56:03.427Z","3.2.0-beta.7":"2021-07-29T17:21:31.982Z","3.2.0-beta.8":"2021-08-07T03:12:29.264Z","3.2.0":"2021-08-09T19:51:54.941Z","3.2.1":"2021-08-09T20:29:55.146Z","3.2.2":"2021-08-11T15:40:26.768Z","3.2.3":"2021-08-16T22:25:33.618Z","3.2.4":"2021-08-17T16:26:51.487Z","3.2.5":"2021-08-24T15:54:24.292Z","3.2.6":"2021-08-24T16:54:31.649Z","3.2.7":"2021-09-01T22:05:17.860Z","3.2.8":"2021-09-02T18:46:32.277Z","3.2.9":"2021-09-05T22:24:02.955Z","3.2.10":"2021-09-07T20:20:09.222Z","3.2.11":"2021-09-08T22:58:15.645Z","3.2.12":"2021-09-17T14:55:27.438Z","3.2.13":"2021-09-21T18:22:55.016Z","3.2.14":"2021-09-22T22:36:58.654Z","3.2.15":"2021-09-23T13:49:00.679Z","3.2.16":"2021-09-23T14:17:03.764Z","3.2.17":"2021-09-24T16:43:12.528Z","3.2.18":"2021-09-24T20:05:18.559Z","3.2.19":"2021-09-25T18:58:21.500Z","3.2.20":"2021-10-08T17:01:52.803Z","3.2.21":"2021-11-02T06:35:16.305Z","3.2.22":"2021-11-15T03:45:07.173Z","3.2.23":"2021-11-26T06:33:49.767Z","3.2.24":"2021-12-06T09:03:12.966Z","3.2.25":"2021-12-12T04:21:15.384Z","3.2.26":"2021-12-12T07:03:30.686Z","3.2.27":"2022-01-16T14:08:19.603Z","3.2.28":"2022-01-21T08:15:14.855Z","3.2.29":"2022-01-23T14:02:25.164Z","3.2.30":"2022-02-07T06:14:54.785Z","3.2.31":"2022-02-12T08:41:54.106Z","3.2.32":"2022-04-12T08:07:44.897Z","3.2.33":"2022-04-14T10:14:38.259Z","3.2.34-beta.1":"2022-05-17T04:53:51.971Z","3.2.34":"2022-05-19T04:42:36.110Z","3.2.35":"2022-05-20T17:16:27.957Z","3.2.36":"2022-05-23T02:04:13.847Z","3.2.37":"2022-06-06T12:08:20.437Z","3.2.38":"2022-08-30T08:02:02.905Z"},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"description":"@vue/compiler-core","homepage":"https://github.com/vuejs/core/tree/main/packages/compiler-core#readme","keywords":["vue"],"repository":{"type":"git","url":"git+https://github.com/vuejs/core.git","directory":"packages/compiler-core"},"author":{"name":"Evan You"},"bugs":{"url":"https://github.com/vuejs/core/issues"},"license":"MIT","readme":"# @vue/compiler-core\n","readmeFilename":"README.md"} \ No newline at end of file diff --git a/tests/testdata/npm/registry/@vue/compiler-dom/compiler-dom-3.2.38.tgz b/tests/testdata/npm/registry/@vue/compiler-dom/compiler-dom-3.2.38.tgz new file mode 100644 index 000000000..e3cd8a3a1 Binary files /dev/null and b/tests/testdata/npm/registry/@vue/compiler-dom/compiler-dom-3.2.38.tgz differ diff --git a/tests/testdata/npm/registry/@vue/compiler-dom/registry.json b/tests/testdata/npm/registry/@vue/compiler-dom/registry.json new file mode 100644 index 000000000..48dfe2360 --- /dev/null +++ b/tests/testdata/npm/registry/@vue/compiler-dom/registry.json @@ -0,0 +1 @@ +{"_id":"@vue/compiler-dom","_rev":"131-71f43f4c711a4058d697e17ad2c394d8","name":"@vue/compiler-dom","dist-tags":{"latest":"3.2.38","beta":"3.2.34-beta.1"},"versions":{"3.0.0-alpha.0":{"name":"@vue/compiler-dom","version":"3.0.0-alpha.0","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","cjs","global","esm"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue/issues"},"homepage":"https://github.com/vuejs/vue/tree/dev/packages/compiler-dom#readme","dependencies":{"@vue/compiler-core":"3.0.0-alpha.0"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-alpha.0","dist":{"shasum":"d54ed384b5b136ac166b1b48d5a89729c760e22e","integrity":"sha512-JJnigid6juCuudd9ZYTbxdUId5T2s2rM6ULYHrDHqxHjnfxxx+SdOZeBMcrNfZkmLa8wTSzo+aXe1+KYlvPOJw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-alpha.0.tgz","fileCount":14,"unpackedSize":507855,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd/RVzCRA9TVsSAnZWagAAMvAQAILkqXA0ZIn8rCzB8Ae6\nZjjUnl9+boLCpF6CeDO6sXcLjEU8SvlIu31ZlH2Jkz6KMeVvpCyVV9nxnj5K\npmaFKaKGg/hSnaKqf1UPXN7LIA9CBsojhta8YpA94wSCB9H8qF2izhp+t1CL\nSEsDW2i51PTK0LkP8e6HfLMxkuOq280mL6ERDWYQp8WMhqVhCQiT7uPbSqjf\nPla7SUrJ1laLFa/T8Fa+agOPtmW6ZrGqQ3Ov6gjQsQPpHKhzaIkfiNJ/N09/\n+Wcjw7iIC/o152PkBHw+T3Gzzqs3aBRn/yu+wYxrVGhDF2zUvUfsJt6CVYd9\nFOdtstpGgM4T0Zth83xbOhdPFNufnlfFJhS/tOq5l6naWt/JTML7ELQ7UoCs\nP6QF3BoteoQyn9N2NhYUmRlDuHC/VR/ajmIq1RRx89BDINhMYRcH9jaibYEj\niBXfd874eWLaq6kOzSo3gpqDjd9vCkdIjeMn1aRffOSc30UM9Amo3sJw4w1v\nUYpoxCCF9gmGu4cfTvcQJj8myIFuORIykPf4atXksGzAUjRh+ZUoid2mkaUB\n4a+ALtiHANl9C5g+o5cWfnmUsweLvjFIVaSgOIsLdPXBCwzokE1tZ5rReW7B\nKB9NrIiC2xXoSwqWuJ+ozh0ms/dKf/b8e0AgRlBgg9t+2a2uYstBjpDWS01w\nLLwU\r\n=oLj7\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFhgZO2XPasM80lOkAT1RRu7ppnIwAFm87sCh6PSJWphAiAyZvAbzMU8md1SttgiAZRBObUW2l6z9gkXMgSspeV/TQ=="}]},"maintainers":[{"name":"liximomo","email":"liximomo@gmail.com"},{"name":"soda","email":"haoqunjiang+npm@gmail.com"},{"name":"znck","email":"rahulkdn@gmail.com"},{"name":"yyx990803","email":"yyx990803@gmail.com"},{"name":"michalsnik","email":"msajnog93@gmail.com"},{"name":"chrisvfritz","email":"chrisvfritz@gmail.com"},{"name":"eddyerburgh","email":"edward.yerburgh@gmail.com"},{"name":"ktsn","email":"ktsn55@gmail.com"},{"name":"nickmessing","email":"dot.nick.dot.messing@gmail.com"},{"name":"akryum","email":"guillaume.b.chau@gmail.com"},{"name":"mysticatea","email":"public@mysticatea.dev"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-alpha.0_1576867186625_0.9324019260162302"},"_hasShrinkwrap":false},"3.0.0-alpha.1":{"name":"@vue/compiler-dom","version":"3.0.0-alpha.1","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","cjs","global","esm"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue/issues"},"homepage":"https://github.com/vuejs/vue/tree/dev/packages/compiler-dom#readme","dependencies":{"@vue/compiler-core":"3.0.0-alpha.1"},"readmeFilename":"README.md","readme":"# @vue/compiler-dom","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-alpha.1","dist":{"shasum":"c928dd61f42d0b90e7e9e9d1dd0e8094475a25fe","integrity":"sha512-3gEYW/G3FyQtpgARw/eVhfJPiUQchfRdpoRmkFZUDGpnqqw0fRr30u8Bm80JYajH5y3DgYOZbt6yIhy8enNPpw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-alpha.1.tgz","fileCount":14,"unpackedSize":509094,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeDnvnCRA9TVsSAnZWagAA2FwQAJFazfv8PEzYYnXQNHzQ\nt39mDz6t5Zjjbxjz8FFRmuffHyj49IyDUibGw/tezZeHMdzdNX/Rh0Jg8TbE\n7E1S4j+w7aM9t1ZQewW8whpMa/MCR6h0aRhQa3cIqd7zNMwjURDYp0+ZI5SU\nYX3wmya4HIDqLWdY9thLUn8QBSNUDFakBeYW1qO5zH/54qYkxjp+HeJiM6Ge\nY+5TB0s1KVg4ondOuZO5V3d/lWIlBaeOUvzgBeVEXEak0vO1qblw9cAIDdJ1\nK/2+OrlKatWRJiBlK0oTPeaFcBWqV9HjZ5u/4bGfpH29qhQA/7EATe9/kqhI\nYl1EW3nzdY8l6kr6VgtaU2t/QT//p6pmI32RWB00kDUBLP8R35eFENtoAiAP\nEcp2rHBoUuRJrcMEaU9rXeGOZzVvJbpRuAOl6QTHaMScqr3aDU26Cl4JElEp\nmRMIW21pMwVDMXVzSv1BhOvt1qmZlizj6f6050GnFLT2JqQaaXPfO7GTw9cB\nvFd4/Y7ilX4ZNO+QJSAQNdpw4PG9Isps8mHnNaoivy5poGyX6r8meNxdw60W\nDELAM4UIIVMB3R32uNOFBgcp6YLXR6poGAUWFbrwTyCgO8qio7jsS2i4J/qb\nPxeCSsxcGcjZBgzrBJfLlbMZ7xRBZHMmRufqnHXZIJkHuqjE9MCBWHE6CEAz\nxi+o\r\n=jM/P\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDoBtz7bCrgCu9+9Et5Tux6f/hjjLiEP1oGa6My2jbVQwIgVMGHrExtD3wRVTzhUtqOfKQeO5pv7NCnddoKGg0t5Iw="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-alpha.1_1578007527005_0.43172834672781635"},"_hasShrinkwrap":false},"3.0.0-alpha.2":{"name":"@vue/compiler-dom","version":"3.0.0-alpha.2","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","cjs","global","esm"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue/issues"},"homepage":"https://github.com/vuejs/vue/tree/dev/packages/compiler-dom#readme","dependencies":{"@vue/compiler-core":"3.0.0-alpha.2"},"readmeFilename":"README.md","readme":"# @vue/compiler-dom","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-alpha.2","dist":{"shasum":"76b0b77026e05831c8ca6aab9f90807843f45013","integrity":"sha512-BeKtdWi253njQy2SxvNH8iNdtnBctUIbjRbEOXC/2KDOPo6lwrgHNWjHxS43kX0aBM6qJa11w+jzfcCcpQ4yVQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-alpha.2.tgz","fileCount":14,"unpackedSize":510452,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeHPLXCRA9TVsSAnZWagAAhbwQAItSWj0stVGZ9cERxVcL\n2qtZ3e3CzRvEBKGxl/dvtp67em7ys9epmYAWFNIT1yziK50/d/14Kn9IBu8n\nyVq+dUUX/SKZMBxKoWq2rXwkfjPZHGrPFCr6zEDk76frG1ic5vV5MzieicRn\nwuhmBgkUThM5ciTGjiHXp7p0f/Lb8AOKN4Sx3DhQvVtRo9BPlyfzV//ufkFn\nPznn5RjjKEehc8m0Zr0lg1RY48/WlCr0HIkvK/TSZdkLrajd9DZ1aonhvoRe\nPGXxPxeZE4TnDQntnoBzNSmqnqmWBpu3W7tUtFY+9IHBbHPYHlE2QxZGMfca\nvDUpZfNkG6pdTtOhoCn0if49B1xcSU7ET9e3Np6Z4m13BDELBtQpD0bnF+ez\n3WpW1vFIEKKYrSn2xd/n+2JcHlXIT26ik9abPueOkFNgor2s3RXSJcSU3rvN\ndHmEcvmviylFxV0wocGX6/yFQb3nz/Aiyz3Cy5IFkSTfmLP9Evymp0YQ6O+8\nt3rWvU4pNGh/wsNj1EBOpIaRWQhwzgzfOYXb+8BGj9OKFmPE0eyBdsJBTb/E\nvRW3U/Rz9EuTVKhPdfmOprjKt1+VAC71XwQ5Jf5fVrQEuAB9RRC7m20FqgdW\n9z3zGLgWDOTF6mbfrNzPK0+9houwxn8SpQ2TZPvEYaoltogvqRmN4iP+GfLb\nSHLQ\r\n=n28h\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDqRvNczcTs2sz/px4om2VlfX/jsjlSqbzF+yxL5cwZJgIhAJDu1LTR2JpI0OjkhKudM3JG6CveXFDOIgshTY2OSMta"}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-alpha.2_1578955478844_0.4714449061618702"},"_hasShrinkwrap":false},"3.0.0-alpha.3":{"name":"@vue/compiler-dom","version":"3.0.0-alpha.3","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","cjs","global","esm"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue/issues"},"homepage":"https://github.com/vuejs/vue/tree/dev/packages/compiler-dom#readme","dependencies":{"@vue/compiler-core":"3.0.0-alpha.3"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-alpha.3","dist":{"shasum":"e4844edfddefefd9661ebce2666d865d49c77397","integrity":"sha512-m87mvZoYyE1HF3yNfl8qBxr6xqNeV4XSe/zneb+0tZNp5RyTTi9Kg8tnPZZ65HYBaX5huRxO66DAf1eb2O9Nfg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-alpha.3.tgz","fileCount":14,"unpackedSize":513018,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeKHP+CRA9TVsSAnZWagAAiJUP/0kKqW2+G7E2gbxDMiJR\nOJgK38EdT3r2V2gJX1F0ZA+/7c/2nEd2vwBvIjLOD+RxJdEHpjZB08mefNkA\nujmaiazduRhcgtGr+omefXVGF7/aSGWJp+Nua6ahQ6PQORhf4DV3t3Qy2973\nTKAsSx6zqhrX204MMMn3io1b0clSNgPFQiZZA3zf9XoFAQbbVK99ukx5hyNz\nqXJRQjKGPda0qMgyuYHWbIq5NuWf32I1OowlN4pvg65f6v7e8TTDNvCwzQec\nTJA6RmQOuWOgJ7qqWvzBjcYhEd3mhmzOu0mvLcCF/izt3j+oOT2p5cfnp+nH\nl4IWrrhQ4LbNfLeIUDIcy6meTKJnj84xT9+BLtK4cJOkSUREhWDWAhJCw2WR\nGExfSe69QenAmaTYJI6wns8emkOdHE5KUm8Qcap7SlpOPz32Pc7DWj3yFQao\nYaQZ6pKYem8ISflgo6lpJZ+JlzDaJDmBCvraAkEbVlM6UsnQUu6QZLCZj6AT\nVdtuaJTqY/yea6gqkbcudlrB02b5adQpnShPKmwsvon1Winxkx7EOJ7cq/nr\nFoF7I6qkTXuuvdzfX9/Ncd8M6vetjXEJtLjjp0nYkNNP6hK1+4SJIjvI/VcY\nwkpSRVv/PSJtue4ev1QnH/YwLIAdhBefgh/vc951zD5beLv8Dag1K2VjeYaK\n4RGR\r\n=K1Ps\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAtRhsZuwQlagq416XWPLyweAIbkcR3V4cuJjHKVIPFrAiEAwGbqwwBkMd7rPLsfwfPasog8tLz/4+AhZpMTtYNK9pE="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-alpha.3_1579709437754_0.4728134266532533"},"_hasShrinkwrap":false},"3.0.0-alpha.4":{"name":"@vue/compiler-dom","version":"3.0.0-alpha.4","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","cjs","global","esm"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue/issues"},"homepage":"https://github.com/vuejs/vue/tree/dev/packages/compiler-dom#readme","dependencies":{"@vue/compiler-core":"3.0.0-alpha.4"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-alpha.4","dist":{"shasum":"638141bb293f09692f005e8da46bdb64ac680fec","integrity":"sha512-QtDs/ezMMYcIX5gN9qijmTQE5YcOQH4TH/PKZUdToe0bjDQEhAaMiedKfTrLjR+OTxuHkFvayp4SzUzTiQ3CAQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-alpha.4.tgz","fileCount":14,"unpackedSize":513124,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeL1QNCRA9TVsSAnZWagAAVPEP/RDtHEFzQFaWvu0UERGd\n9Fc0jFL9er1KMzSu/RoHiD8+vtKo+QUmQLhNmThe1rYwkdGE+joy1Ran8q7z\njNNByINWEx7Lr8TqV3aAMf1+iF5VetCH0N/NvocsyUTFssMHU/X1NVI9ZrM9\n7bz0yMLhjlddb8ya8PrhiQ51A7ZaEepiY5NdbU/I4OwhXci1C0eyx0GP1G/n\nwUmzH6UdUU+MLLkYgFpwEy5F6/6yTxCzx2PlmkcajFlTaRNRqmDcT0mPUuHv\njHfGt9Nqpw6YTMTadzuT/0pBw1yn0N7PFwMnDFc+2FYsKYyWUv2ST9Qx6m2u\np0VzHUydAHo5ojIrsZv1bi6zhaSA8SYPxZvf3OaLTJ9absH2taTCR+v6oJd/\nrA+E1tBC0yAj3VzcXYZC1gRxO+bbsAtbWHoatQRJBQeakXHGouLPGU8Ma0iV\nXzORDG/gxYfiGBgcdj0ocAsRg1TZ1Pf4r7+nLnt9Lh9bNTzNzK8tJCHPNVtc\nNDKH8ANyv55FvoHU57dUg+DTg9iMAn0QFEf+wX4vMiRt8xMdzi135lJ4qB8u\n2Us7S4NWzUK2BK3xXz7HzqR1m2kFK7SMO5xtEdeMqNSl0pE3ryOlNqD+3POe\nmr5WCIukGilSDnf5ncLcPueRLLMpUcnfRQC3PAuQ+VgcWRRhTzmJiWueopoL\nMvzW\r\n=uOVd\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAgxq6vUQYijB1Q5fubc22DNasLEM9Qw/DTr6C77tUFuAiBTds9/ILTG04Pv480tIuQGBj/FTlbF+A6sxyu3cP1BQA=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-alpha.4_1580160013315_0.31686974268593704"},"_hasShrinkwrap":false},"3.0.0-alpha.5":{"name":"@vue/compiler-dom","version":"3.0.0-alpha.5","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","cjs","global","esm"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue/issues"},"homepage":"https://github.com/vuejs/vue/tree/dev/packages/compiler-dom#readme","dependencies":{"@vue/compiler-core":"3.0.0-alpha.5"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-alpha.5","dist":{"shasum":"9480b737fc11acc139adc0ddff780aaa5b23dea8","integrity":"sha512-7OnU9n29JIaPUrfV5WOiM6XZLHe7OyzfsmIWus9JXu/zIOU8XUao7vouV0HfKEIJkBsN/ylL6PWkDabRc/rvOw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-alpha.5.tgz","fileCount":14,"unpackedSize":584853,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeTEKACRA9TVsSAnZWagAAyg8QAIe/kLMhS2EH1bM7SqFy\nFJAlDbzz2XK9d1Nz0Arw/ynQGWt6YreEOCcBilTmHB3bPof5n6QQ5fWG/e1j\ngrXbWJhyIsWZei161yvvTNCWExHXzxFEjcp00DzZEN7RwXWsqyYLgmLWL139\nM3fuRn0iXh9ycPIRXWplIu2XMZWRfmkzgzV/79/KQAZwwXTbMRNPhB38bD99\nP6rK2hnv0OMrpVF+jBLsRd74+yH8hiK+urNfuDrh8++Zv92dXwzB8CpET780\nGBlC4jFhNPIpUng60n3EDj54NoliZedVIczyjCnw3Yz9IUQCdlMScKgoXpOj\n6YPZocgkc5A3754aP8OhCd3j2ZLCeCjIpSRvNUOb9Rqxs/84T0QNUyIO8Oqg\nyJTy6/BtaUQS9qM/PDYeA/fr+Aiuft4LnGVJS8G29TdhLToNsCA4uFpfsQtu\na5fuw1LQde1QLHNalIVJ7+oFI8+Q/pkkl2qU0lCp9wxt3kPw0I9l3Uycq5cJ\nE/0byWAxxEHLwXICsivZ9bo3rNkPG/9W76GZan9d8JSa/Drrl+D7xm7O2Y39\ne6jFqgZyTuOPYnJVRo5vEI891301Qkupgt5O18YwvxiC2XLbW/QzogAJS0zO\nCEJsZmE1rNoW3O4Le2bEzHkWG6qW0yaHW8gozkSx/HCPG0YTJBa930xNf7SW\nH6bc\r\n=p+H0\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDkV6AAxYaGaRCkNt2pu5lY3hLDJhciSBULrjiwd2EWvAiAWBabvLY1598XEw3kaQnvGpbsckDeV2pAJwr/NvDqBdQ=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-alpha.5_1582056063981_0.162154256848003"},"_hasShrinkwrap":false},"3.0.0-alpha.6":{"name":"@vue/compiler-dom","version":"3.0.0-alpha.6","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","cjs","global","esm"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue/issues"},"homepage":"https://github.com/vuejs/vue/tree/dev/packages/compiler-dom#readme","dependencies":{"@vue/compiler-core":"3.0.0-alpha.6"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-alpha.6","dist":{"shasum":"dba4ac5a622de651448e6ac1aa39f4644bad545d","integrity":"sha512-tfuGMD8UYsBHmo3zEkgEqetwmdfZd/DEJpRO5gUCYgEftd+Ma3AaGrqwDaHorsShjsztmoO8IyKXFPrk8oyDeg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-alpha.6.tgz","fileCount":14,"unpackedSize":590187,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeUNd2CRA9TVsSAnZWagAAdogP/2+hmeA2Y/IxMSxNa2z5\nZKykoNmqfuwJdr3fbJACicdny/2vnXAigJa1M5EQP+svEsJ786wQ0Fj46jbk\n6dZhuVY4xWlOuPtWaAsrgeXSRgvgts4KPTr7h9cPTpDx6M2J0tQrd8eO5Q5P\nmseULplZJZNHjKHkiD05UNSZvN0lpMrXcnDMb7L44wm4R2mmQHHh8QWuy2yQ\nFuBj9izSh/8N+Ey4MDHUeh7+myV87/JUBph1JqEnOg1VzeBQqw9ZETxienyB\nL5nJ72d7Fj0gCQsRqguioCy7j8VPedbyfYJdt091jdzF9kWbqJHKCgG9wH5x\nfduLvSWcKB75gv0RLb/9rtegMwgljDEaXWU6o+bakWzyrF+PMzxhlKR+yP/1\nDyuyt5W+Y/BdsIOhLbXHsAZjQmFPmC2c3vNaPEkuDtSOSl0Lj7OJlgAiDYbC\nvr7VM2xI4kiz/dsx0r4v/BQdZ4JYkKDbANMwDz7CjLqof/cDF0Mb3XiRgNt4\nh9BWQ562UD5LoEKk8Phh2uYy7z8wH6+jruk9vqstiB84PUMHU84kqHS5wpwk\nuAXhxqHB53KlrdcPPiXsMX/sI6gn1V3g3vR5MfFygI2kws8cXLzVgfZjX2+8\nRHj1t6/M888Bds5EzyJ8vBXhPDW/ESdBZZiQiNbGbbH07nfSiqfAJUIToXHs\nvrsu\r\n=83Ax\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDs5JrgOEPJONkN49GJgs6NG0gPCFyEgO/GAdwcWNgjAQIhAMyBBbavldmATfA/QMNANm39Wd8SS7D7wgwFnHSRl45N"}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-alpha.6_1582356342526_0.2961907176477274"},"_hasShrinkwrap":false},"3.0.0-alpha.7":{"name":"@vue/compiler-dom","version":"3.0.0-alpha.7","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","cjs","global","esm"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue/issues"},"homepage":"https://github.com/vuejs/vue/tree/dev/packages/compiler-dom#readme","dependencies":{"@vue/compiler-core":"3.0.0-alpha.7"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-alpha.7","dist":{"shasum":"ddd7f4c23e80ba67c5f40d0747cc5901ba0b6ee9","integrity":"sha512-NsC5CcbgiXuqxsAQwj7dkB082WMHL7KhQPnf/BtD0UO5OQ3ooptEOUYCW/bPHXjOcOxuCE0PL5xn4xxD9290zg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-alpha.7.tgz","fileCount":14,"unpackedSize":592741,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeVsjQCRA9TVsSAnZWagAAvW4P/iKz7U3om5pRKPGFshC9\nADr8P3W1fR70Fz6JWmkAPAx/g/It0KKvGs5AwUx99hci3zbZzGvBqILywPvJ\nrwDFpo516mvX+nhKvYV1pvPM18IkcdnaZspDSOYsOwGRbMyr9/onxwjnbMNq\nza12Agu8ppQK1ve0agpa/kH4mVPak5Rm4uudvtSTKroYHFlt3ymCXYVUZE6K\nQ5jv4C0PlT4K974wJ1ovZseUkf/GbzC/6wFbbotAmSUErjRywmaFiCgF8M74\n0NoWV44LUJA0YnYeUBib0B1pdVHe6VTqP5nOKC++oA9uifoWHTahJKnMM0mW\nYDYilBHXnDU4gsVvcRnJwwncehDJX/c+Qj/FSedgClsnByz3igvCWJ9ipu8K\nNNay33MXw3diecBe2mI/6OwvA+KGvE8Uq/xfv7dwrLMF5R/wBpJp2uQ9O8TT\nhsf0F9WvZH9Ns4HstW9wWFY5KyBjo1Rut+QxbnJleY61VmYrtjwhF+kInAM9\nRJH1/rmIqe0g5yEKWqpMZFB8Md0zwxEJVu1pJPzVn4g2lZ9B+J2dlXl+gu8Y\n9MSXh8H5h56Eh7umDe8OAmkLzJi+NMmosTZDRDX4iloJorOoBYlfzH7f8/ZZ\ndhom7xlBLfXNUxGkizxa5XVqHQer1hFlwvXdFk5OJjXDdX/P4P/1t8y1LZlw\nE594\r\n=TEI3\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIE9TjS9WlgwUarHevyqjCbwFgUie1h38vXoiph+CUxNZAiB7HZStnj3UxxC+SGsdrDl83tkfn8txvP1zRQADa/9gbg=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-alpha.7_1582745807844_0.22884681210717273"},"_hasShrinkwrap":false},"3.0.0-alpha.8":{"name":"@vue/compiler-dom","version":"3.0.0-alpha.8","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","cjs","global","esm"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-alpha.8","@vue/compiler-core":"3.0.0-alpha.8"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-alpha.8","dist":{"shasum":"82431ffaec5e889cd069954f4f5b90406f123108","integrity":"sha512-y/zGe9mIDIqm6l0xVKA0+AQ2iCQZoqt16JKViP6r4TEcF8FdB9cAGV4vC07fGv3HeI2FpaHL5j8KQ15k9BP+Gg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-alpha.8.tgz","fileCount":14,"unpackedSize":579225,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeYrmKCRA9TVsSAnZWagAAKykP/3eVLgFyvuqIOPdm3Nu0\nlFcTn096UmzZMc/HM1NRK2PMk27zYiRyGDjP69ji5emotMNVxfxNFqtc56A0\nO8e9cIWoqaYotvYHiK38mgYzQnY91se/jdibmmAmZc100AVlTIlnU9f266/b\nsU1N+GFTpa5w42H5MANUBh6sAJCWSaHqjKuIuS+HdDxP8OKXUtm2CamDRTNQ\nqZomU2RHc9NHkeEAMECDSbCL9A8l9dz1TrvPau4D8JEhy/0rt6BGY/Kr5n+O\nZw3CJ9GqRrNRpZVD73wEP08vwmZ6AJ8znx4LAosGmMHvey8OLpjDmb/pX9F5\nxcIEEIIve/LqvQYxykv/yGcncJ4QHwTrCmo6Ne6hMJ0WvUPAS0ExcevW40wn\ns6PaBUcWT4M9praiV7WWfSp0fdgYhcN/NZNYwZU9HalER9QbAwodc70xuLaj\neDT3xGVsTnZhcCGNkANaf8Wyr+O9SCxGoEXZLiL6O1a4AUnlKEhfQg4bySnl\nKQ/qMkVrT3CvoSvZk8EZEr1MTKSX9CLHSgsBg1WJ/Y3pNOcJBY1ZrE3EE79C\nViLRt9iHEOMzDRoS7BzZ9bBmJ2kR5ohLiywDZH2GVI0Up30eQThfFPB1eqXU\nPhqdJkXdst2dIePQA38ZiclRZ7fFBH7Nu5obXKOsFviPZ2GzoVSr7HjwYe/s\nm6N5\r\n=HCfw\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHhVnV2btiG6F/a4DY7pbu8ldOSvks2ylOK8P/+XefdvAiEAhIa4Zf8j0IVBzQJJGvKooxAIYossaCh9I+ZqK+rzHzI="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-alpha.8_1583528329990_0.3867970689514071"},"_hasShrinkwrap":false},"3.0.0-alpha.9":{"name":"@vue/compiler-dom","version":"3.0.0-alpha.9","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","cjs","global","esm"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-alpha.9","@vue/compiler-core":"3.0.0-alpha.9"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-alpha.9","dist":{"shasum":"cb93b9f25eaabaf084bcbae5518cd91565b09ba3","integrity":"sha512-LgYtgKTcjjRWX41EMpjAdcvNTM1mSvV6Z9iXcGQs348PzcbihboFvaVqOkK14f9R1d5WsnCaYvUNuIGSNV0Xig==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-alpha.9.tgz","fileCount":14,"unpackedSize":580083,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJecAQzCRA9TVsSAnZWagAAzWUP/RO6uA6kM7rI/ozCCvR9\n67LcL0tQ8UQC1maPcSdxcQF48/oW4i4DcKXCym7hDEIcS5lD3ZogrskeO6Vj\nLBzkYUgVNY13VkxZ9DgfgX5kydWt+YKDZwskZFN4d64j+gjv+iTGbzAtPucK\niRprMzka1B7W6ZXsm77wMs6Hp26ZagUe9htSUCuei2uPOqBZY26OhcKgf78Z\nZOYRZ9lVragnSHAar0SgM2o5HaAVPUtj39etDiSCdxAIe1vjqj9Ah2AzVKOC\nMaUJm1LcT8S7+DEuxJ9N1Fc/EQJkJbFYRQIJWKSe9u2+/TU1BA+R4k8Qe8Pu\nAl/GJzEurcEl+Mc861efXmqCiPYy6uOiHjfjdrh8HjwixRoE1e0yOJHfGi2F\nxsSxZGHFwXeScF+E0ZaB/isIxIATWZWmuBYdd5RjcwzZ/tL1Tz75Saw+ebSR\n6A54o+FRGpSzUedHVXe1vQZXfWEhrfbzp9xXEW84fouQhj8h1xuOeufFF0iR\nAiTJYUFW9WiOOSbmCjW3VLhNSedU5sRchGj+4JUVcvUpWAwukT5cYnpuYI4+\n9ypsXVI05D9JjKyXobnDoS4MDD05sg/c/fgS8NFkNNp2OITWAlztnyclyT1d\nBfcNFEd/0XODtgr6yMzTbZkLRWOaAawmfVo4NIqLokUdmrYGBle7Ydr5DyPf\n39u6\r\n=qnWv\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICE4qIFJAC3peoxu4vz7BzWmXX5ObLc/KdLI+ChmVn/1AiEApMvYj+jaqi4j5S0nbaEjVCNXz12LE1N/zDUM5d2EWeI="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-alpha.9_1584399410895_0.8445704220700507"},"_hasShrinkwrap":false},"3.0.0-alpha.10":{"name":"@vue/compiler-dom","version":"3.0.0-alpha.10","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","cjs","global","esm"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-alpha.10","@vue/compiler-core":"3.0.0-alpha.10"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-alpha.10","dist":{"shasum":"be9ec1d24d0c4d96d164f8e00a479bd88a45e55d","integrity":"sha512-hOasMBUsmqccY9Qyytqmrup4AnxQ6zBHT8tC9QpfdtygvxrFK2uNvNZlPoZay2hB13fJjZgRdCyxELM0zB4Hww==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-alpha.10.tgz","fileCount":14,"unpackedSize":580058,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeeorMCRA9TVsSAnZWagAAdmYP/jhV1rapkvGYM/uYf+V7\n2bsWdsYBYq4QgInNTahz1IassDWeBPmM6zUE9p9LV2mCl1otUDfVX1JNlFZB\nBB0TQk1NxsRL1txcICs/ONhU6Uoz6Aadv8+wv6vyJ/wI3NUlSbzklhqt/iDJ\npt+bJjddoBKi1BxoWX40FfI/3Ls7sSX7J/aG6Cn+VntsDIkaGaCHsLHw0RzG\nBfDJsc53qqt7BCfn/K9/kgcGhsTfJsNMR4MfQILCCXtzRfmNYFG2sSSkqyz0\nqLJRZiCrMAfNOuZsg4ole7XUB5jxJllVYSVni1Q81MXrwVGmHH1NyT39ITbg\neGo4SOXKZ5Hw3WJ2zW2JTCqNMAL+ErHvS43lhLNoV/1Tu40IexaeG+o5MMpk\nkC9JTddt9luD8vONXhFr2EX9Rr4TuTaZXZV5R0NwzEZNTIwZMAHlJbQ7shf4\ncNXFfDPDNitzamZ4jQESpQzLG81g+ktXSnU0Ltaoa506falZIom3Q+fL25V1\nbo0SNlzsDuNTjbrkyytNtznCYFIZ9CL5/gBFXgU+o3ek1y3jp4Q+C39QAtcP\nUoCD4wCHxgctI4vWRDo2eASIGtXavPnjRuEgEEsrsnXPz0ICUI5gTMhKqcRH\ndYjpiZkHwBqSDDFpgeCXOfxhFoa+1wp2BLzvDITYOlVJNKVjs7QQ64ak9EYS\ni5pw\r\n=lIuG\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEMCHz3FSlOEqIdMbOE6n/6UQ2+dYRItiNWF6KbmUKVyWjICIE4MMtHIsD+sR6QoaX3xLLLXVzFoRERO282WI9KylgSZ"}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-alpha.10_1585089227812_0.6596656708980126"},"_hasShrinkwrap":false},"3.0.0-alpha.11":{"name":"@vue/compiler-dom","version":"3.0.0-alpha.11","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","cjs","global","esm"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-alpha.11","@vue/compiler-core":"3.0.0-alpha.11"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-alpha.11","dist":{"shasum":"cc19b0cb56890e704606eb574b1b2d963e4fcc7b","integrity":"sha512-MxyMBbag78Jq17Lwt2sO/mqxzAP6HZC6Qbc6OrgoDE8ChhvidL3SmhXhmwGjMXaWjQ36trKaqMDcVMiuPdAHqQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-alpha.11.tgz","fileCount":14,"unpackedSize":583832,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeh+bXCRA9TVsSAnZWagAANaIP/2lALQWtgCUKhZczpSUa\nuzKd6Pp5OoEjo6XXe65759mGznhTloaJKBMi3JrMIvqBVi2C/+7Cj8KC2w19\nQj6lz+dYIPhPdM14BirDvVTGrqCuys2niB5cYmnsMwd75Bgw1p87aUEvky5T\nMeUQjQgGAA4uLp80gw292nYTlHPBMkVHiF4hpOoq9htZMhoCx2E6d/i8s9wU\nGkD1iVxgrAaumM4ggEoAYyC6iguOnNRzbIE06c5lSM9WnluHopWJuoPHLPes\nYkO7r2WinXqVaoseQBjaJSrHgBVs8RHyLYxnhNCp/TS+FmnJfSyeWA6FJR2k\nDe8Z24t6sOUA7zl5+9B47pjkuaFj0OfYAFhXHiNJyMKos7fqBDlLh0xRcd8+\n81xxKpKN0wd2ExDThTbX16TbbW6zKdvhTmOZ5+m+QujphZcTfYN4YZQv+Ier\n6znCcmyUSj5vZyQEj985AMHrA5Fq8UNTtcAJZWYV4XzlgOuyMaEZ+KJf3SPY\nTQjzCgrYdg8NBj7liZl55dw7/E4G4oBvEpcIV3gDn0SV/c6ek4t2xYVik33I\nYxoANMDg4v8m9dn3/c+/mxsdPs1lvaMqy7ZMSGA50emlabWOoO/FUVRZa5Ef\n6QIamzC63/v9Nl1+5bpfb2bl8WditZai0jU4De8LxadbzWsgU7v/PcoV4TZy\naBQc\r\n=OKlJ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGblnICnbkCru4fROZbY3yxEUJiAOapIfTngUsD4gvoUAiAx2CqB/2ay5UzSkFGw3o0lGcDpASb1boOmRnmuPelLeg=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-alpha.11_1585964758531_0.32536605961232024"},"_hasShrinkwrap":false},"3.0.0-alpha.12":{"name":"@vue/compiler-dom","version":"3.0.0-alpha.12","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","cjs","global","esm"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-alpha.12","@vue/compiler-core":"3.0.0-alpha.12"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-alpha.12","dist":{"shasum":"3f5b856007d5201c477540299bd89e0989e83543","integrity":"sha512-MpdGAFmS8Pc945Kgo0FbAQVObi+aTBGpDCz4f1UwBBR8z/TVgENTd8DXzksOnu82RrW1hV5Lbn3uUW/RuHFJlQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-alpha.12.tgz","fileCount":14,"unpackedSize":579863,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJejldtCRA9TVsSAnZWagAAyZEQAI3t9dHtWdoaXwcQelAh\nNg1aW3ZdYARAzl3IaL0jnBJ5cA+X1WXcZxNbtoQY/G2U9wiyki4rYj/C3QOE\n+YuccfZpmcAopSQPkvevC2AREPPcwHf+FNrAGiJKopfLPV08aVmf2NJIYMYj\nWKVsm7jQ8+K4x9BekCdyW0pm3h+A7ZBFbDSDwMOV44wPQuvy2lj54yJGS7Eb\n5paRKOUxKbfxb59zFm2/H1nwVqhVzIpWfOpxxugrv+OHE1RAu2Oa+nNkkX7k\nHdr4TUxxQFdSgEp1sCTZix8+eOga3Az6k7eGA0jfsonnhT6yWlPbw716T715\n+tbJ10nslSOpDjT7gw2+nVXQMsUkPjbT5sGyEsDE1xmKZEYbOef7XJRs2sq8\nggcdbMPTDnfGwrCQdGy3gZBQCtTkIsyuhNGU3Yeu3cow+c3umCXVQEXIAdfP\nndvBbyKHzz/FTC6Vce7jxpY4koBMUcpiH1yHdBVSHNboER7F4B+ShEhSr39b\nCRKl08mIxdkS5l8QqDUVz2as9Hd0aq7Ecr+I2EIBe+yuzfONhueroqH/STqy\nzPRPBMNzyMjjVvO1jgWuOeJRbagwGSnSWsxZ+Neps3Ul4+cqMKSQqT3+/l1h\n6g+Ere76sI73Urx3q0vTx72aOlIvYs5Uq2yHW0IM96ikKCCyd+Jb26lxDuHB\nWYzB\r\n=Aj+3\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDesyi8fvXIxqKxeEFOE63erI16HiTPmguIBXToF3/zzAIgPfp638orvnBUKFdMYdlpGI0gdjV6x6gQfwSXFbjITwc="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-alpha.12_1586386796748_0.16412797546942248"},"_hasShrinkwrap":false},"3.0.0-alpha.13":{"name":"@vue/compiler-dom","version":"3.0.0-alpha.13","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","cjs","global","esm"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-alpha.13","@vue/compiler-core":"3.0.0-alpha.13"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-alpha.13","dist":{"shasum":"b1930ebbe770dbed543dbe7ac88f2955719051f2","integrity":"sha512-g5FnVAx+HLUox3N+XHKIZTpMJeJu5Uj0JNf8X4s5Td5zFcWG+KJGUHz8qU9H0unrPc01uiT/VfhYErhFcRdVKg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-alpha.13.tgz","fileCount":14,"unpackedSize":579991,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJelzpsCRA9TVsSAnZWagAAzvEP/Rc/n3OTetIB5EiHSmjR\n6iBfEs+B6v7LwZ8faB6uiDISztWz5IDT9938E5i1yebG7LwLSjuNwKHQJvQa\nI2GwSQBv1SsWOGn1Nk7CZnpYxvvKC+4o/JNjS+2p4XEo2vVlaHiM1aEc7Y9t\n0Dr4gim6TnB4zCoVXoW4MZhoG9VX7yWWEIb9XpEo8FxCW+G7cQTM7P2QGVsX\nI9B8vQ20L/Ywv1se4DKDAeqXCCbCmLfVJfntIkhAlOkMmjnuW2y6khL7KgXZ\nWuiRh2km5Bl6da5rGGC2g/iNCt7SvtAE2aQwo332XcOnw2DwjzQONkAfYYLg\nfzFhweacrXeGljV0gyoVTbawfwJSC9P61HBAwTdgAyp272Bi5Lzx7CPrSz+V\n65a+AbN71hEfGeAGLrfuHrXzG0cLfMIoLkNZWA5rwICdAY20t/B6YwWP6fkw\nGewZdcjEixgUwVTOUqyuImW3VmABfwQLimxiVfzQc0BmQRTFlRQ+ybltE55/\nXybDAD1wG0eKy9gXnir/BDOupojUKkzBpPe4A7oasuUr3bemnBZhK5JR2uAI\nGwHFdafWR2f+iwGiqZZMUGJqVx3L9rf8aDqOK8i+BgkTCDtdUfrQ6HBmU5vf\naLrDUs8l25hDVolg3Eef+2nZKGo0+OVxcyEmuowo1AswxgoQUr8dPF2MQmTG\ng6Fr\r\n=hYnd\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFqhHnEKDwoPF6CSDKdG1hNcknTmiyFUJGF549ITW4ZMAiB0e0zQ5f8LrQG64FBkPE5UQbBIGsjro0WohUNghc2DUg=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-alpha.13_1586969195617_0.38319179026241534"},"_hasShrinkwrap":false},"3.0.0-beta.1":{"name":"@vue/compiler-dom","version":"3.0.0-beta.1","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","cjs","global","esm"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-beta.1","@vue/compiler-core":"3.0.0-beta.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-beta.1","dist":{"shasum":"eabd8279e5433214e613558561f59e05a01ef450","integrity":"sha512-Tp3Y2sT014B0Z3VpdWLwAv8o6kNPZOwFFMI2aAgIBmG3KWPGXUxm2LDRrNZWPoOPYPWYjRMBri1cNy3gA2MeCA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-beta.1.tgz","fileCount":14,"unpackedSize":579985,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJemLXNCRA9TVsSAnZWagAA7YAP/0ZUSl9zR8MdTzvKap/X\nUCP+MsWFO46fr8oYbxzX7Z2wIq41y1YZs9pS8e5HLWd+lBBfhXTAZQESyWvb\nbwgmduJfF9gQpkd+HQc12aQZ4u4+gXmopbepwKmpD760xUHvUUhtBMCYiUs6\nk/Kkq7zNq6tomAKoRc9Ct0gQy0tx7I30j/wM4frCjPxRa+DgRl7u8F1BLw3L\n1T0XivpMDdna8r2r4IaNoZVayYOD5b3g4cPvrYtijfkniOT6K8uoAdQeJuoO\nJ10Hnqlt0N/Ru1/MgxBBSVR2YFsWeR+rGYYVSbBD96stDmvaNR/Gxmb1g609\nVn/IDTOiND7VA77ySUwrB6jQfVl/fXRB+15eoUzYUuYNncUURExOuNDa8c27\n2Z3PTz5HzZDwYQFjxDipvg25ZjdPFxzxurcscnFqMgquJbgnF/ByqOaobXCv\nRFQsqDMYx2bjQT5/v5Tq7ALGSrr62PayKL5Wo0jiU8RMih3VJ2pTH1ND/iTr\nU1v9sZyHRAQTA5GRh3/Z2M6uLZ2rSzY5NWgOh4C+Tp6vsBrvgpKyQ++IUfbo\nVqYns0R+ztuRfwHQGn3O9ggGgSekmzyejPqQhou8srPAAEOIWhHfujvFb0pF\nBC7izzy1RdduNVF4izrHfc8Ml0I2rKh3B2vYt2H6JwFmRDtD2l7fpV2gH2ng\nrgXL\r\n=9J+n\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAkAdKABhgx60oCXGv/CAUzzgSBSiZK3ccCC5WQzAI/zAiBVUUZ3IAUJVQfXi7BVPan7X2WCpZi+UQwx4L1dhQ1TAA=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-beta.1_1587066314554_0.45228066641126285"},"_hasShrinkwrap":false},"3.0.0-beta.2":{"name":"@vue/compiler-dom","version":"3.0.0-beta.2","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","cjs","global","esm"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-beta.2","@vue/compiler-core":"3.0.0-beta.2"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-beta.2","dist":{"shasum":"344263f4e50258496bfdbd01a9a85a7b842e96de","integrity":"sha512-VZwvnsWPoi0/MR5CF5p5VhRGk3AkM9MQYt/pMaXDmbl09kWKVjQZubCRvpzuyjjm1QnV1yrSaqTZWDAIYbKYtw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-beta.2.tgz","fileCount":14,"unpackedSize":579985,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJemcS1CRA9TVsSAnZWagAAR4YQAIOV5i+l9L3RtdHKYpM4\nvRAe0Tuf/sC72PWPEqRPyDuh7qZrb5V9FsF8CzmN70nwE5grJFDgAoq1HXLP\nH6/b+av9AefsjIslR85gkUjuGLNyIz+HtJPRZ9AGOmsKfQUF7MIVPVF/brwj\nyhZNpuGN+coxvRme7awUWUazyXnguRuf56Y5Em5EqzvjKqqG+uIT5OsEBsUG\nwvZGpp/bEdG04UhqxcRXQhSQrz2S3oF4czVJ/q9EhvTpHWgj9iMAWpSgG0a5\n7od1nMZdM2+E35UXPxiRK1FO4v9GF04qrABMMglhZ0wPCX0+370QSbXK9PRu\nH3WgWxPlxRkkzCFBCweIoi6Hz8fj2agvT2sG5O65QKR6D1Tb6JBAb1B8c5iK\njYO8OnRmj00WAEW1W//NgWiXqRIdr51juhjLvOMJ9/FQaizlTMy085FhHdqB\n2dEAKmdG4AKfsNj+MDEWulKM8UPusNBNpEfjLFDNtmYqm2czL41iz3HJMhUr\n5hDYTKDNQA0v3lp2yeBtJrW1JjoJwscylsXIQ83+NRAE5p9XY938UCqNZrbb\nZ45lmVIC6FzHYY5R5NSnr2m5dkKfnvMW+n11Uh/mVRC75TexCQol7wcF2ZB+\nosVxP2U/voqqHSEYJnY4SM2rpFtMooV0Pp0s7NbtsenFAbX7BP6UeV5/IjYf\ne9dR\r\n=ptm4\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCID8CG/0ZgvZcyuzkyccnISAHBSiWNPZdlG1AYruoWZ+uAiAKxZt9jILM+vFSgl8FhNHrOcAJoh8u9sagE5qfR/TwkA=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-beta.2_1587135668633_0.269720275508599"},"_hasShrinkwrap":false},"3.0.0-beta.3":{"name":"@vue/compiler-dom","version":"3.0.0-beta.3","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-beta.3","@vue/compiler-core":"3.0.0-beta.3"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-beta.3","dist":{"shasum":"089d9ede865576a1b5bcf5d3272d546e04460f90","integrity":"sha512-1WimkkPN13ySLAlJl61WSo7xFeC3D8Nqkz35YIZIgksOOIr6W/Q3NfDxfM6bG5nTBWBmgb995oDZ8NNgq2frSg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-beta.3.tgz","fileCount":14,"unpackedSize":580038,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeng12CRA9TVsSAnZWagAAP9kP/1nOkZdMcjR5QwHXUWVa\nr2qTfx8l8hlEDVXqHFq031fZ7iZO7FjMCyy1g9/MVQS+vGJ3tss9POEjhWCn\nxnUjzWSv7OKlk2ez5OQka04dTDF030j8CX0mWbRXKlSUwVzBeUh25Zz2htdk\n318cmvWIRgrxW7wHdFEk94DpubxT1T6tWBTUCbqTJTceP8jWRvei0X6NzGa7\niMkIFhub+yc169A+nMzC4GhDfJ3KpOrCK/3JepHbgf+f0awblS+sxc7kSpFF\n64c6/KU+T6mw6RibJmgc7Z5uCGvjzcExTMF70UaniiVFLVRFLOPk9Ou6XZ9H\nwKLtXiPOBNmT9jppiVzi3smx0MQc3ZwVJGinGH1FBDHRZGqAxyuv97sxc7Mv\nxm1QvSFZd/xyuWj4uw26b2gD509wkndFmSkG/6OqNiaCHyqAaWLl57DjXaIW\nvnO70DoL3XrW+H5SOQcMgO0yRa6Ig4fmsojlXJV1kuxLrV2oIOZ6Oa/fBBTN\nXK/AZWMN8pjYasefkeRGW5o0UI4xYmgil0flfg/hRFwSk396KJPw5tPg0Qg3\nTnXpP/vS+n8HSD6WYcL/lxwzLTMRub4+xzFpkQwW4H8LnbUg6hx9B68/7+v9\nSo5xc359ybMH2AnBdsa1BU3XctEjt9Nzxc5wfIOw57UVprWsIRxt2Lv6ma27\nw12B\r\n=YOO4\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCXre1yaEL23Tdva4wgQd+cXnKneS5j6rdoqwD0+diXNQIgK2mrRTeSNJDVubDiD3wRTvwfJCfoWNHxOXtFj3lU7aE="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-beta.3_1587416437583_0.8867312184394114"},"_hasShrinkwrap":false},"3.0.0-beta.4":{"name":"@vue/compiler-dom","version":"3.0.0-beta.4","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-beta.4","@vue/compiler-core":"3.0.0-beta.4"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-beta.4","dist":{"shasum":"821569015c30376577e97c8833443a0be7f157c0","integrity":"sha512-/1ICCldaRuxdWhBSiYQpWYz2SwxW3bl4sDMuI0h8iUG+IGscDtOn94y8Pt6wqrGT4sWi4KvqQTDdJVx6uOTzqg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-beta.4.tgz","fileCount":14,"unpackedSize":580696,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeo0oMCRA9TVsSAnZWagAAZNAP/RmzHkEF44F6+EVO6B47\nENBD9shItVkbyipl+si8KRn7bbYyshRcLd2DQms0VGnJVOKe1KoIOdIbJSFU\nIfu/X3fOquKyPVjJd8q8X9fZvySmaNBfhXJY+MTw5NVVP3cog+iHNu4sO++K\nnG18M3fh0jruFEpJwMk1NuWSiD/NKP97VEvaPboWyTOaO/1efrayd6/4Tr70\nt/4SLLMV/sAzBruDbjc49XjENl97yoBIulCFRd4LYYfV2nJAm2Ws+xCvT6rn\nmAm0G9zjIGfQNwLXwh2UKQfhEUFUcHbSa4A2CBkT+Ylujv0NCTOxV9pWbDG+\nWnpHjAsh+xAsTGhhsS21mo111gd5uLu4TpwoUgZ1gXxiHV5M5oH3/k8sPQUm\nNfVsz2A4Yl9rYSPuPfy8nm8oYAJwF5qk8/3Fz8X3S0vyo/eaefTceWhnwPGu\nSGikO/MFGE6w/BixZX92Af4uulW9J94gPW1tqPKvl82qF7m6w7PLT444CkA1\nHRctCi4UBrDQo5drM8ogRXUAwdFpAdbYJ71YIUDGNZCdj9yxHVbWYMFd8ytM\nB8+Y/4nl8LJfMLHqrzxlN+M7+6N68KjY3Tm1J9Ut4mLnDDVEU9FBVJp5mlud\n6RPUmPJ+iaytbHxyaZuP89cxVWKoLifyIXO6mYc8VCZJ/jM9Y5zcoB9kDyHH\nL10g\r\n=LMRj\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC1E+9XkaKHId3tps7WzJHDz+4GkdCs2wkX6ozoolpZ3gIgD5zN5zv62gl5mniiGI56PtTxSoVx/0NvldOl6cyrbb8="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-beta.4_1587759628031_0.09038984695283658"},"_hasShrinkwrap":false},"3.0.0-beta.5":{"name":"@vue/compiler-dom","version":"3.0.0-beta.5","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-beta.5","@vue/compiler-core":"3.0.0-beta.5"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-beta.5","dist":{"shasum":"84ef01cd5052163f59276606fb37f3159e492d2e","integrity":"sha512-IUR+ITbYB8n+mCx5HXNb3EsvG7hlx7mqyliwlzBuhJR3QNcy3qeanspN6pcTwHqBJ/CTE+q98ttJs+RaEgepmQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-beta.5.tgz","fileCount":14,"unpackedSize":567123,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeqzMVCRA9TVsSAnZWagAAuZQP/j1efWPisbJznWOt1DN9\n9HLrxVOtNicrwPHWTHZeYGRu5Kyd6eldKXN5vgm4Pz3x8w7a6jVFpEgJqqRY\n81QBrlCgoYl+hCypwsoULwez568AxotH07MofHUdZM3uKqHFrnGvJdHUyZxh\n0N6jwZfuc2wMC45lkZlrF0mCzQedqXbZneFYvClaRjDXhYbyqVJBwWPkKUS/\nN/iuJXxDtbr48dFSlzJhONi9oUVOwsUwIB3cwOzumXBPO+hBo81WoX7+R0Tz\nOQQeza84g+qVrFDcWgXRTjYJAge3L2+zrmrn201YA6DqhkDG0nDrKfD8gH3r\n8elTTtokHT6ZZFqmVzA/DhqVKJJawXB/zjuy3df+ZHv7MWRH18jBng+Ohiqf\nM7/t05+riXYlZ8n0beHAEP2vOL9R5UbEh/sBAmT6Fci0pFJqm5hgwvluTq0g\niaqazrUmum6b1gtZAHi1tzQXgohq9N5PcpANGcX3/m9E8zBxfoQT3xZsLNWy\nBKMSlejoijPpWfvmnfXyGbXkoqimfXs6wqCmmMmApT8CqPfEkaW+wPDE001y\ngoWjtGTpkNoXfsUI6jmX6m2IS7MSqLbjh7fADeppS+am8zBIlB/hEjWMcIe+\nO1aDWnwTj4B9itvGoSf+/grp2/63iJ7Lxnrr2eE9Is+SPmkjA1Rh5OPnHZgf\n1It+\r\n=hrDO\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHFqkHIHS7WaS6zkCfXGqjuPtz8eKfIMjEM8SE8Nr6UpAiB7TrFcHRasozpSdt6jf8I69vp6qbCmzvgRQFr8vAulNQ=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-beta.5_1588278037350_0.6949044482950131"},"_hasShrinkwrap":false},"3.0.0-beta.6":{"name":"@vue/compiler-dom","version":"3.0.0-beta.6","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-beta.6","@vue/compiler-core":"3.0.0-beta.6"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-beta.6","dist":{"shasum":"80a85cd49570297c32425b364d026bc7185a11ee","integrity":"sha512-1pSE1LYHbDfuSpa6KEPgI92ltWzKJYIYZ99T1q7fsr5WYCTS/oXNQ3aCaNxJRpnnb8ib1GrjensGmm7Dr/M0vA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-beta.6.tgz","fileCount":14,"unpackedSize":568195,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJerKk+CRA9TVsSAnZWagAAQCkP/1mVP3NjtZi28uvFM2eT\nKXhiz+Mqj0nPmMPH7vjXSIVsdtBhFm4CIXCcq1G9emal0JG7Gffs2Njv4J58\nHLVUZHJsxHCNsVZgbIvz261G/jTelEICIANbTXbePLOFtmDNdNQUDN9fmADC\n6oq/8S4Xz/kK5TGZMnt9N0uK+/1NAHOYz3KHDxKaGah2eG501La6IGTnTXKQ\ne0CY/k44059MIwvXDt8t+hcjNKmQXn+5kjRxnoxBWus8QnF7yOmn9FBUthwj\n7AIYxnDrHaF/rOLwwaIZjxgU94kCIavg9aVSE5y319kkEa5BCCajWSgSKMCv\nd3v2Drd82zrZCtT21PymgS0N3ZC4pOiW6OGY0h79HTOn1arfFJsCk2oWc04V\nAnHTPLpdAA/0ZJa0unKw30iVnYxydfofGEgW31KYh1mGshV256TvzlR0sL0s\n70IhgKUEZD+g5kA4TbhnX1757uIaNbi9lSZ0v8EyX0NUZXjvki7Gbonls5Hc\n64XjwyQZN6YIkrsmAXMMwLzCVKRWwZ4oDwUfM66HgOZcvH626IVnnVa3CUKq\ncFSp0Ul/wMc7lFCd3YdlZzqtGdSk5+8DnWPxaq0aUSC5FA84J72QD2xmHL/9\nQ4I44IWE3l49bS7oQl+GjiUDU5TV3eUi0tTPRpqcPI7HV3H5RnIJPsDsYhKk\nNWJx\r\n=hwp7\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCRFeoozQrjYiRck2FB+I42w+1h2zVBxil+2gsrB2/z6QIgM7r3xyBOjxvOyYydfNliU06BIIVWjzzGdkORUGgt/sQ="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-beta.6_1588373822266_0.9248914505196515"},"_hasShrinkwrap":false},"3.0.0-beta.7":{"name":"@vue/compiler-dom","version":"3.0.0-beta.7","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-beta.7","@vue/compiler-core":"3.0.0-beta.7"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-beta.7","dist":{"shasum":"ba21ff6b7d8c7e2b7bbbbccd317cdcc16d31bff2","integrity":"sha512-uMJrYHUNkfdOM9MkYpsfK4+Yz9OPIfi8TEupond9+kwGmQZmVC/Gw86wdnM9lMZU/eXv1S5zoYNv8PH0w3ipEw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-beta.7.tgz","fileCount":14,"unpackedSize":568195,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJereDRCRA9TVsSAnZWagAA/fsQAJgs0YY5jPpuTaIkjO1L\nRXEpQw7t7f4POLaFZcq81jRIm0p7e6wcIMGMEClYz5+hAu5TO4SrIG2CASiH\n71bCKUuP309yrMDTqyASN6RYsvGWBozVqEhRxLniVqvaji+geiOpA8hVB+xI\nN8U7cSGJctXIfGnHyioBKBc1//sjBVWQyE0ZD/O/8dOhxpRryHdqlyfO8WOr\nd2EEjJ1LKdLU6PJswX4AqSpfHBDp9xz8HODnLrfpMcmsdhrJXDj3FoaYksfC\njWdnyA/DQtMnBCTy6J62DRLZdqwX/82vyRaImC5Zt3QBTtwsQtHOdFPpo66Y\nW9TDIpnjqVRHeqJj6QuOffDjhqhhUH7DDWoGpqO64ImBtUNsJszlIKHFzH+o\nQRROgOur5Hs/g5Lfoi4Ovh+7ZSXXJVQLfYTzEofrsH7IMfwhtknDTl5c3ga5\nb7w7zA/iUydOL04HMVGx53erDy4aNExFGsK+rAXYy8b8mvmJc39TB0oEAfgf\n4MPRf1yHPYyMQwRDc6IONpyt83SGuz/y4KVNtgZsPh77sdcvpaXjJnNjvXzu\nFIfVO1DJENi+4wCtV8Zo+OOuFIhTz/NpO2Xo70W1509QiOLdaAYtZPSGxwR8\nNGQCrkEGRgWrfXR/CE+gKB5ug1GM/yhf61x/moT2274u9CJ4RGN0XjytHAne\nohea\r\n=na9c\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGlv+lE2fJk0eZlI7AAIFjP02aVP2vz79cjRNVCooogNAiEAx+iQ0WxHHKqG37pCKs+E5MpiNStNumYlqumgrmZNTZY="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-beta.7_1588453584660_0.40874688021757"},"_hasShrinkwrap":false},"3.0.0-beta.8":{"name":"@vue/compiler-dom","version":"3.0.0-beta.8","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-beta.8","@vue/compiler-core":"3.0.0-beta.8"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-beta.8","dist":{"shasum":"a1c4070f3992d5ad2ecec7a63c800630e70980bc","integrity":"sha512-oOvC4ru+pg3hEdmnieIslfH6iE+cqAArr2XlJECgcJsk2Ss+SXMoK9vf/fcsGeIUlCgUhMuvY9iIEJml902F7g==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-beta.8.tgz","fileCount":14,"unpackedSize":568195,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJesCt/CRA9TVsSAnZWagAAgSIP/i69Mc0J7PMtDKtBHWOt\neQd1+R9PGqHCMgw7Rl47gqKkNXm8BZ4KEbVkyfDWEDNYzJGsxh3DQuI6rz2l\nsxVerusc99whU0+A7YgJyfdETFloAPXtXTGAd9dtaCi5R8ejCuXbjk6QGyc2\nCRrlf2y8+6kogYDCfauFFmj4M6gndPvFxQi8m8cgtT9pvzv++nN6jo2uHpzy\nxZfFDB9zlp8u69mNXe1PiPawUb4TlZ9I7ATV6CQKPdKeGDXBSXsy9iPGit0z\nEjBx/goGwwXSekj4qpcB8gqYbLG7ZVQDHspSA0zOskGqMMgX15Jrw23MAnfy\nVnkLUK8lRbLCTCGIRDNwvdPpmHwKcZVWCEwSqx5jDT4AEvEXPezwo4geHHNs\nJBl6Ued/Zma/f3SPHoTmNYL2zzjQd5qTWNd/efyjv0NCcPZoH3TXNHA17ymr\nRXbglCmbD9z8PeZVgInv5wvTMYtwJqYoOtQ/Y7iezx3Uh8ZI0hkPcJE0NC2i\niGQOLQnBo6aam8VusJ2nroJXB0UGnlPPOIwDwuRpmCQ9Ef2t9omPDWoVJbDp\nY5La96eeX/nUxjGPrWOZMbvgqm4RXMR/7SWlFKVoYg59NaKsZXeV9qF0xWhF\n3N9lv/1ptek8IBOCZ82s57K9CcJ0TeoTINBRSSQaxZtPaJg4nrKI4YfjI213\nqyeT\r\n=fX13\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCdLhAJaPuprAttJIsnfKTb0MocFkpQXfQBj0OGbanONgIhAJm7XQy+ivTTIrgZkt1ktqkyZZXHlDq5aSWLGqh9Tdks"}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-beta.8_1588603775362_0.46515095715882726"},"_hasShrinkwrap":false},"3.0.0-beta.9":{"name":"@vue/compiler-dom","version":"3.0.0-beta.9","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-beta.9","@vue/compiler-core":"3.0.0-beta.9"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-beta.9","dist":{"shasum":"ef4fd5cdcdceb37d67eccb70d28d09cecf0a3425","integrity":"sha512-KMWbE/O+177d8QSS46fyCYDipOw4RIoh9mo1s1CqBWQxHwNelOMU4NnHZ9TvpxBo+Dzyvzk9b9x/56KSKMcdJg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-beta.9.tgz","fileCount":14,"unpackedSize":569821,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJesIXLCRA9TVsSAnZWagAA9IUP/0VA2UMcL9rxNYqfuYfu\nHkrDuo69eWaKxcJPwgs3KPijN0Pe4cFUzZ/14YpnepsXbMH6dmn0kJiXbQEH\naOdigLX+ZXnNb/I3zsJHjgXYygXjSK1DoBA2FNrqkT9nR3ZDAyrrvi/3e9V2\n5TV94guihT+y42tVKFA15Zx/oZDz7y6eDgxqafG5GtWu1CJLn5zTb/FF7Xsv\nuool8LHA5FI8viYIBW8bB+3qsCgNqDbBeGxVg0ydcv/V6YgYoAxoCeGR34L4\nRvHWFzLbnO5EcMeHMw6AVAT7H8zqXCQdYAkmcDcXc4EI/leHVlZrsYwHaG8q\ndey4FSK1jWaGqvQUZKSJyHhzm2YHL7/LwcJyAPmgiCtZcIJXdBp6CyZOiXP4\nju3YJa8HD7JkW74f7bnEYE2G7UYnkosLrPIuCU1YKYpT0yz1TDuZg+/WHuvU\nR2rf/zMv14esJwsApmXYORgfDTGlpu+QbMY/Ruzm53IFVjkcyKJCl+YFJM6Y\nDieADIGQPMC6Qn8kEyP9r9FF1y/cSRFs3IjLS6eDKrbZBn88WDmC0OqFehjc\n4l4J02MTXUtdW1xXTzUBdmgM5JKflL2pRwghEM3cEL0IIHbt1cc1ZnYtROHK\nWCAfLOui74844RpTBgBCASt1VAMXvs0PTpk+rcDCtkKP43nGHDBCW+nD+Q+C\nJqbR\r\n=XmSH\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDpy+fB9cmEFMk7wINXlknz3YLJ+6FugTgtqmVIy6SX+QIhAKymaZYlcXhTvl/NvVIwfCJ/f/IYDdw+QCczfLEVQ3x1"}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-beta.9_1588626890963_0.9295335584647868"},"_hasShrinkwrap":false},"3.0.0-beta.10":{"name":"@vue/compiler-dom","version":"3.0.0-beta.10","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-beta.10","@vue/compiler-core":"3.0.0-beta.10"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-beta.10","dist":{"shasum":"5b35df447eb96cb7faed37b76a8a9aca71a87c67","integrity":"sha512-S1Qqc74Hc3BnHjORzWJvG4Fj5B4O8aqTF1Oyd+Px65CB6qkbAaqTLneYnM5by/78j8inmt4FCHOf48L+gzChRA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-beta.10.tgz","fileCount":14,"unpackedSize":571011,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJetCd2CRA9TVsSAnZWagAAvvgP/3qIEh8q70Y4IeJNV0Pf\nmt05Pb2yoBkuihJFUlyNWxrXwK+D0oTbn6A+Ifjyf94cnll/LKr4vX/0yIPx\n9P2fxm3PYJHbH8PeqG2MukwcVQY5moI/K1pgs6HfxVfvxzlHVhMDpLABLKFc\n1+dEgvT7UJzqeoROSouQAevYEq8DIUYwI2CBGzuuRRjt9BtiX7YuAOfbuVtj\ntVLnz+YrLFh3WbvxSZFwV971mwyF74vV4J6F2SLtQ81GhV8CQSCtQITpulat\nUFFw9nKeXnPPvX6lbH7mVTIPwqzN7Nt575HqPrvN8jHlBK71O63rRwtWeI2N\nJwwDnbrq8d/NdHeRkBUqbyB3rJrQDXbjRWUGsy7CGqqvBXnagEpAJxpOdHA0\n1fNe0j4SPoa5NkvAJpLMZF2PlJUkIUOs4y+ZcS3jJJAITsh/ISpJJzogwtHj\nNXST398YdBdPH4jgfTOmV5BhP/mIOO1nFFd+oypp4cQ70V2G3PBqRbc1M+Wb\nnzJji7INnCh+8uDYVwJKCXfpEshHXzpvvheXq3KPiXZf+bV8RVTnOqFYVuBZ\nwnpO1w5MciwsuSsjubjdxn03DrZAgxFVFDYUl1rcl8IYaiWFoTnF1Yati33U\nnocUv4D9MTMWK35zMmk1nlHWAE8JJZK1+iVhiD88k+xpGIziBOXOCX/PZGtT\nvc6j\r\n=5QpB\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFJMGFYOuNhR2IhYxnHNWfn5KzqN75Gesp+wIoxuDIAsAiEAuK+zIeu5Dp5GVgJJqb9QhmMXyLmyaa22rrChHEBswxM="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-beta.10_1588864886444_0.8857670471934709"},"_hasShrinkwrap":false},"3.0.0-beta.11":{"name":"@vue/compiler-dom","version":"3.0.0-beta.11","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-beta.11","@vue/compiler-core":"3.0.0-beta.11"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-beta.11","dist":{"shasum":"bfecccdeaa23df0fdb05c9c31aca0e601c2e8092","integrity":"sha512-ZSi/0kjVhuRmS3FedxrNHxs/TlrXQKXFPOyxPoFlihIBg7cKIZvi21kHw7N8GlRVgn95N8e+gy/kjpHHv1qQ8w==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-beta.11.tgz","fileCount":14,"unpackedSize":571011,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeuZivCRA9TVsSAnZWagAASVwP/j/LGF9VG28qAN2vreDh\nRErkZlMiWxut7EXt8/9Qx7ODwRCIZ11RYegblyRxhDrQ+usk6yk9LZ+o62+v\njIzTT0R+SfmaixjI2k72XJj3ZA47tysY9uQBDYH4pHTv02MUKzcN66wCw7pt\n2dGol3saQKOkFvV6shh0NbZk1Cd5RA0s1wrHPBKiqgsCe78kg3quJ8NKZsnu\nKoyT+otwh5D49kmI2EzHZshQOOauB6xCZgFk2XIa5LGq1PNSbZDPKN3r+TYf\nmE3tscxJ/prkbyEI1MTd0+zkieplidbHLsozFsLU7i0QXyQ/UrwL9dqNJW35\nRIHNwVkvsZaAXmLM00aZBg2iZ/kfhkmMyR0SN6beKadntedJB6/+QW0fMGMs\nM1XK8PgCa7a9gb+xLJzed7QGm2dz6Wbyl8WwXks97B5liHhIJk8FRO8kxzWl\n8TLtF1fCAQLT1py7BaGSlXOdLR85eUktTZoVhOm0UZHh2pvyYepiLFmQOVdB\nsYDvuQavXEmYQ8o6dzCgjNDCfw6GhwAJub59U2RDPF1Pu3gXumGetC7elqk9\nqWfBZ8BZfibtLYzZ0oeYTVEBoyzYxHdq/7EQXKY+h5pYL2V8ZEqwSn48mUkX\nyhTz765bQUgmoWls9jdWWTae7XiG6nD2HDTT+dymGSI6/zDgGFCHmI/jUjxC\nMnH4\r\n=2IX2\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCx/aFQd0znDSrhOGL11jizrZFmCEVl8M/DjPxOji0VLAIgSqICy8/3Zwnh58cChnVZbcxlJVTuZF4wVMjmRcLK7Wg="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-beta.11_1589221550985_0.9383941081051981"},"_hasShrinkwrap":false},"3.0.0-beta.12":{"name":"@vue/compiler-dom","version":"3.0.0-beta.12","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-beta.12","@vue/compiler-core":"3.0.0-beta.12"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-beta.12","dist":{"shasum":"f455898b96d421d71c808ca35b8349504a2f7ffd","integrity":"sha512-HEirNEGczvMep3suCZO91q/1x5wEO0y0MvZJ51HJL2UZBSUjBSp/8ilBVWpOoOYC6mYVoxEIm1Jv9AoSsOipzQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-beta.12.tgz","fileCount":14,"unpackedSize":571011,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeua0PCRA9TVsSAnZWagAAnOgP/0l79UFovf3M2K0cM2h5\nGpyf6Xq0ChRqPHzCi6gt98JW4WyzFlYPHdjXuO3BgsvFVPopyMHmaG9ZBEyd\nZFaiLtswuyPuB1Sq4fjuj/L1HRZaxfIIvFKv+r5Yi7sF3dlu13SkQUsD19E7\nH6uet2omNjo2vNA2uwMv9ta2FnlleT7mWpCpVzRC1BmSzgU0sBuao8D68CBW\nqEs1C6GJD3scI4qmJk7c6b2TJuOK6CeWKld7LgSIYG5EfnUomqZysJUdaDpg\nHBKCTK3cBH2w7UsLEcoPsZcn/tDfOJ9TMFq9zzjW1q//6UWQXhvTjqZgXP+O\n5RPkXzRDx5x3ylSa5L6h0bV2teYu0og5JiGfDm8TD3u6+zdn9WIrKZ2fnnSx\nZ3rmtL4BDk0V3If47joEQh6HF8XNqMzo30WCQXDW/Oq85AV7stm8rtkp1qUi\nynEqbCmbLQ/ONILbMAqp8pzhzX2a++1pdEnLa6/VMFzLUF+MO3uW+wV/AuXt\n9me6Z0NsugrvieBzeT287uwIxQOv5M+cCsSuCrgMMOqtDXMLqaXh7wTKJOXf\ntjX26nMNEmtoJ09LkWJNtKeXxO+OW4ZWpIP1A6OQVuSMRYkohuqn2uUtJT3i\n9VRkQh6+q4WUBvJ2xOSPlX+SIwW96Yy16R6H2j0hf7V2GD4zNT9eVlnsLDKa\nqOyg\r\n=NSot\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCktIlUbNXHe5LHNycZicM4GLch1LrPzEWAPAtYYC71FAIgL7pUZDJy89a3xKXzwyxOhmZT88vZ0723NkF5asyDQK0="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-beta.12_1589226767320_0.38656676751472685"},"_hasShrinkwrap":false},"3.0.0-beta.13":{"name":"@vue/compiler-dom","version":"3.0.0-beta.13","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-beta.13","@vue/compiler-core":"3.0.0-beta.13"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-beta.13","dist":{"shasum":"865561d33321093ae4de3f65a2e277a767c6f7f6","integrity":"sha512-8XEId6xa5T7S5uTFcKSDL60dTzz7/jiKqmznnnc8T4IBL3kbATGnFqtda3dCZwu5M6g2+0XGdjI7xLbAtf0l1Q==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-beta.13.tgz","fileCount":14,"unpackedSize":578889,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJewJkzCRA9TVsSAnZWagAADNcP/1Y8ydOKUBOOkZpmssBQ\nyAP32U5d31zT69VZKf37RK2WLjQu6Th8EQ1DJ7o4CmeAwoXN6up5Joab9CYL\nG6cMzkZOwH1Wf65+Nwy2/bpTGoFbLD8VfyPIg5DlyD/cj78MPjlYj0zt8qv3\nHcokP21aeHe5Xvs4uXQtPAUBZvdAoV9ZYtugGnHGcQ9mzrAsqw63ZNdCCskg\nIjMS9YB5lFl5Q0QTfDY7wavhGbRjXi15UOS1fSt/pRwM+HWr41YCt8zZ6qCS\n4QfLirm6IyphWsSvDzxbsrIMN8v5WjB6BEuxKgsTsXRMMFnPrT4sMt/bpRoC\nVqgGAiMT5FKa08g16xS7ah8K/ogQxxtBygmhbkYdvoM3YT75LiEmruzVdrpf\ni7WXQ7kVsX/qP3+HVe7wO+6wHRSmGsEBLtTPRh4XqZW4i+mwOb/3Olh19FFi\n8Fdvfxvf4IS64SKZlUm+ChripD6lAj1lwGP4TEbW/p1oI4W27veRV2eTbabl\nvmfNgIC307gSx/k6fwT6jQmZLK3fMuwCJ3EPU+keSF4O+1ViJH9AUQVbDFGK\n8syM5dzpncdBBw0c+bQXsbMYDpz/VFQWZ6T3PZRQl7SiKmdDzyyRgBQeQVbE\nuW1K86vfVKFsgg3KKA19GSUTfO/4SsFAocN/YNlqcEmKQuI1ASUE3pvcxPVA\n3mEc\r\n=35DK\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBDxSrsb7dJmOYJiB7wePKJ0nkzTtDQ37+z/I2balpGNAiAsv/OiEDRHxkyNQBKYbuQJ/LgOBNSp7HznXlRp1lhyCA=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-beta.13_1589680435095_0.2302453155049391"},"_hasShrinkwrap":false},"3.0.0-beta.14":{"name":"@vue/compiler-dom","version":"3.0.0-beta.14","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-beta.14","@vue/compiler-core":"3.0.0-beta.14"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-beta.14","dist":{"shasum":"2ea1c165e06e9630e687a7a5cbde4e8b20b064ac","integrity":"sha512-wZ2uWo4jvAGD5FPNZYMOxpKEDigLcoPvOGhIAv8H4B6ltDyW54Zfc4RrW5MopJqEcHDDZMpcgGcFN5Qa09sLOg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-beta.14.tgz","fileCount":14,"unpackedSize":584375,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJewtcMCRA9TVsSAnZWagAAC84P/j71YUr8qf5pWDT6dAUc\nx6wF+WO39FqB/69sznCtE/jm3vkGe3kNFYaKRFuXYCkbQUWiG7rtI7YNp84Y\nJ87/YVM0ryTII8Y8TADRwjkNojdSC3nvLZnJFky6oriaRI6FNCUjrin+yo8f\nkzlsVFEqbUZPbJfCT4cc3EK3qR/TgwoIL5ui+HUWXbBHs0q/KFIrWQ+NBdP+\noCn/JBjllf/++WmYpdNV4rbzrlLPF9VjpLp+XbQ5gaV+UFHAn6qLQFwOqOoP\nnQH4WoAXhMdTi2RvqTwQ8pzx+8kvlItwM60wzU9XCuera6xMoRZ9a/kH/leG\nfCg0sAk0K3xLzYXkFRTnhASnhZt0V/1fiwhWrNC/uzVcMcLc4hlPo+arS5QD\nhPE4AZ5xGXXgLIFwcuz9zqBhn4zryJbFtSKmaETyQijwb/+tLh2PN1g7xAM2\nODX4YW1NVFnTnWfYtxyKAqmAjPrgNppFuVDZgzYWhYFgmMGyn3cx/7pvLEIw\nVG7gf+ej0CZoipyKy7LGQ0pCD7k/O7kgkgvStN9dX0RkkQV82iZLe8SHLrpT\nZhwAAkOhG+vNwtIvcWxj0d5aCPgeMERMEjWFoPwcIo9I/COWS+RiE/R+CP9z\nziNWbyr/37cr37bu/oFVqOeYiE0os4TZiwQD5vTSV7H/UGv+XmelzG90/krd\nGlSK\r\n=hS9X\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDKCwCJGtlnJfuDbgh4/x1zDJ5D4XArLPhMeIi4z5x2RwIhAIibzsYri0zTHtkBm2mSNwzOtZFHk41G10tzij7Gfol8"}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-beta.14_1589827340087_0.5339316456022845"},"_hasShrinkwrap":false},"3.0.0-beta.15":{"name":"@vue/compiler-dom","version":"3.0.0-beta.15","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-beta.15","@vue/compiler-core":"3.0.0-beta.15"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-beta.15","dist":{"shasum":"ee6dc9ae1dabb5c5c257d7cc20c5f3e95d5e5f4f","integrity":"sha512-0qVaCosZ6XrkmlSOndGlNh33JQ2oao82uWxC/qw4QWBGm6a1DcKkZFIZFYLQWg5ZIcSrEQrR1VzUidBaZw9AIg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-beta.15.tgz","fileCount":14,"unpackedSize":581876,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe4/0LCRA9TVsSAnZWagAAdMcQAJg9AShu9ti1jzaAFOCJ\nLYpgqupJZ0VpSoFmaEY6kPPcEDbpgJ0rYps3ZN+xT4oLR9y5TYfNFjOtYx8N\nc76OMmQr0eqirMPSnsm83jDuJT+0WS02aZCpwThPvsm+z8CYcXcjytjC3QSQ\n1sJyP17+tqhwT5LZ0zrVwMeWgIfW9+Quott27r2fh2bC8nIAHDedxJclEuOz\nzJFUf6zMLr7AiRarPktkidqcuMOQp47s+xcsPM6nx0AXWL/Rlq2rkH+oAGUb\n4EK2f9WCsbzaypezdEk8rTLfh1kL7Z6T0uDW+c7Dop6HXx4Fc5cd6QRqhKyY\nM/F2R6Y4airSqomWRZNYCuOPC8Bt8IlBvc4zTynasduCgWf8qllJCpRStGE5\nVKLH7QHCcnw+ocgA+tNtJpi8ZB9DbA898sWfBbMJkwFb7FcdPb9N4WH64OVv\nEhBub9w3BP5t/G1VVx7eCHF/w6b5vU6nGN8NY6chPmtyGXn8nBGYiIActvHQ\n9HnBp6XI9qLfVAKbsWXm/JwXddNVsWDpaSXIF4tAwd96zIE1nKwuUe1kGxIu\nSNujU74I76wMqzLtD2W5xvjZbuFbnItNxNJxFgZhNyO+oEOEQAyL2mNvI07X\njtEt5FaMsigptbDTdqzMWSZnd2EVdyGsQkQCVQPptvc9EQioQMBWhouYR/fh\nL5C6\r\n=WQv6\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIB6IdAW2xthkN6jZf6uu6h+Fvq6Egbek1CiYjLhXyjqXAiBgVbwHvZZVG3O904G+PT4ntThL0HXyURXzrH6pNJxHMQ=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-beta.15_1591999755296_0.9222278745951777"},"_hasShrinkwrap":false},"3.0.0-beta.16":{"name":"@vue/compiler-dom","version":"3.0.0-beta.16","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-beta.16","@vue/compiler-core":"3.0.0-beta.16"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-beta.16","dist":{"shasum":"7adf6de4479e7fa4a7a763eed988721b85c790dd","integrity":"sha512-2tI3wYN6ntJ78WbMURZ6A4CMXpeRUb90AIQBvt/eHCAgmNz6M8QwJJdZ+XrgjLRzWB/NJlm0V+d5phcNTOIT5Q==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-beta.16.tgz","fileCount":14,"unpackedSize":583768,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe+mySCRA9TVsSAnZWagAAQqEQAJChiamX58I9GHgQnI+S\nFWXc9ZNXyForrochdCuE5Sckb8slu8vXemjUBJJHJ1dt0VZqBnN3/aG+tc7j\nhAUvmRCRsSJowGI4eNkzAAXnyvNCoGwUzR5RhLHLDQOvm/KQKOxDKYBvhxJ/\nI+nsfB/3AuSTtQvFI/7yMCGEq3w29QPrmWjfjjDUGLPOJ1v6F7pe76QkmPP3\nanIVfdS3FlpUmekpuXCnMGbPTwFaJy68sbhREo7itI6Bv0awR/QlGEc7NgHN\n3ajdZMESYvpMt2QN3gbt+eMkvnGnDVrvaoYO3CdCqFG1GCNPw9Jl1BPXjLqd\n+ezhEvDdiyYE13c5WYh68vsoNtvFtdCkr3iQkM0JwM+nvpC/x0UmGT8FedOM\nIgjvQ5LGw6pNjds4ArT5jVtmcS2cdmQCYdxomPIU8xEJt77WVs+7LKm5oew0\nbksti8eclzoAwZdEMmD5SubwiE1tL9bKTPhXwL0qCukIcWEBakHWx5Ba3Ig+\n4Pr6e8d+S1qCHyPcmS9viN5+Hzqm+FqBACUoTph1MaAhizq6C+sNIdQnyGa5\nFmaqxe99yE2zsYI6wruHjHPxQHneKaeSYh1RYQbkgj8nalUiz78Euou08O7f\na9VN0wFaJu6txVJ7EN9LR47F8LQVpZsosX8EVWRRdznoUFjigzFnPl6YrBhz\nelJI\r\n=9q9h\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCKsPNar/1xT1wM4RaxbI9KESfmwu71Aevt6Hri/Qp3DAIgAYaNm5fUKVv1iHlRf7rvHSaemObiTwXlr6swOS9vUiA="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-beta.16_1593470098311_0.24311399337304773"},"_hasShrinkwrap":false},"3.0.0-beta.17":{"name":"@vue/compiler-dom","version":"3.0.0-beta.17","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-beta.17","@vue/compiler-core":"3.0.0-beta.17"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-beta.17","dist":{"shasum":"fa19ad2391cd78dcae121cfbeacf6cc3ebd4ff20","integrity":"sha512-wj4egu6KzsJy1EG/MHgbEVfVH8oMIGoFqjwkbCyqE5G0uRPAPi0WYHY5lyjAU2gI7cfGxIcFx7UsWT5D9XH0/g==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-beta.17.tgz","fileCount":14,"unpackedSize":583768,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe+2OUCRA9TVsSAnZWagAAP2sQAKS7ItTly6KepbDl/rEG\nwmVDFg6cUPUQjobmSV12LRbCqw7CQ1xxjww3v9JltQrAo2k87oEstHHX1y9N\nu02P52GHNkGhBXNsLvyQkPpPGN5W8qYOLeNBNPR6OYWLi7XB9bhfLLkGTRF3\nT6OFCl5kmomXp5ViPnYHbkwZlRZbLwwXmV55r3wG1gb1bi9Hi/5jNfm1Ba4j\nnjGVZ4XZyYrLg1saFI/zSD02y2KMKNXHW+I+e/LPfbQuWTfBe18GAOcpJ2yy\nIwi0kkFP+KiNxM6DRyYUTec88hw6c8w0pVTXuwvgp2aMPbFidJ/dfUMxjWnM\n+oQBfkulT/Nhf0DS8/OseH73aobb1CJ2MSOtjAVe3rIqe6FyBMGrt9L4KTJ5\nKitSFNGg0wuONODTwby2gb0q/SaBJzLf1qVqdiB/oRqO8Nsg1trOmAE15bfr\nkD487rcLwUsKTNE0UpBiVo7CbFuKgWUUhAD5bKbJgE0x6Kt5Pt58CuyH8AgR\nVP5XHS7dGHlMUb8pT7mcVpL2m89uHKGOpQP7wqKM74hA7rwSKyZCOVrsEtAN\nE5NTdsSDmLFdt/5T/Zu2C4ezCmgnLLD1Z66bMNiQEyuX1PSM9OSSF8WtmKSV\nUV0e4PN1MRYq+JeZVaO9XQoqAjDu5Ij2IZT1AsZzhUwjRr3+xKXt983bMASy\nVMoF\r\n=K/Sf\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIApvBxSo27jQxHT6q3b191hm/6TvT3ESHosagDIH/7xNAiAAnIU6E8JPJOb+SA3YNX/TbPDRVOSEcQDGuK5MHRLCPA=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-beta.17_1593533331877_0.9398994752696894"},"_hasShrinkwrap":false},"3.0.0-beta.18":{"name":"@vue/compiler-dom","version":"3.0.0-beta.18","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-beta.18","@vue/compiler-core":"3.0.0-beta.18"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-beta.18","dist":{"shasum":"089b37c71850df28d2304e2d5034461af6065ddf","integrity":"sha512-vTfZNfn/bfGVJCdQwQN5xeBIaFCYPKp/NZCyMewh0wdju2ewzSmQIzG3gaSqEIxYor/FQmFkGuRRzWJJBmcoUQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-beta.18.tgz","fileCount":14,"unpackedSize":583768,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe/TMaCRA9TVsSAnZWagAAzXYP/j1ZOlRebTGxCAzGquSx\nMUpLaUdddbPrvxUbzKmCkFJJFoIR5S/cjvd9CmlzacdfFIz84q+RVoSYiDKE\nyo+ZsBrp1ChPgoH+vWJEKu2mnGkyjcLL76JyvYz75PCLREaJFpntnIKCnYsR\nuDNXliXD7kX/KSi8HGCvHl1GU6Scqm1wFc4vwRNGWoNrx6yQcSp/Tn+/UR67\nbSE5ya3x489yTZb3QUpUmLD+PmnLtj7PHc6CMJvK4VN07vr3qB4H540aqetT\ngQmXDAqG29J3Ll1bTw3n1r53JY7Z/TYZRtywgaAPzedzfk7cq/Ws7VRvbIMP\nyYaQ7MmqgX8PDL4ocp6BdmHZd9io4CRV0BRF65CCU/7DgqL18TihESrWJA/Z\nkoilRVq86kY7dz9zaeYV9GtnK9cfqJ8PMiliojtk+uzwgJ/q8YL3D2bxs7RI\nVpq12rsejQniakfhsUw9LpADMXcy6Opc3Hcbc7adpR9vnjVDi51wsW+Z/WV7\nT/LhHVSwOqeQkciFg27EAK0ucHcTpjUAoijV7SeMFBnfzUYqN1zgMxHPKLDA\ncY2RxzeJcfZC3zaa3iJq9KxxbhNBlBooGk3iyQ4KEEiRgv5n4Vd+LPXGXTAj\njzH4MQAeYbCsOZmyJKttA6j2Qf259gGiOezCu1NnlSO2TMtEDxYflFMF2S19\n8E/U\r\n=Ldxu\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCzqCFC74xg6AysWDetv0oepLnxt6Q0oX54jrbu5weblQIgPmM8hkEU2kXNoAx80jfaRzw5pVFSMhCvDnasXT0+pos="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-beta.18_1593651994533_0.0792463657861231"},"_hasShrinkwrap":false},"3.0.0-beta.19":{"name":"@vue/compiler-dom","version":"3.0.0-beta.19","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-beta.19","@vue/compiler-core":"3.0.0-beta.19"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-beta.19","dist":{"shasum":"441fa0fc24bf01cbed644f62b870f8b23c199585","integrity":"sha512-0OEKbtfmPwNoRE06TqOmg2xih/Sv+Hh10r7oZRLFQBYmf1+vW2E5UTCQaMCVKRQs3Tip3b0OaXzSvOp6tU4iHw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-beta.19.tgz","fileCount":14,"unpackedSize":583776,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfBIEACRA9TVsSAnZWagAAhzUP/iz7QnqXt+NjsmpcK7hu\nYpH6nmG9fzmnN3L1orK9ZwHUyVntxzcoelLNozHsi/5n8h2izYLsJQUARsvM\niWLEoWxWM+4r6XSUvBULMDcgv5GbccQQUawfnvxxaclRqbXqExB2lRXaS0e4\nYbpoRax6T6smlufGzlXL7U9TC3HTxg4pRbcxTfUmCAHCZsMuFG2LcdYcOQ6h\ne6Oud9S2podzBLQCuvc0bkZ19akyXB+B/jq+j0xVMFTx93IkKih7IZ5m8C5n\no4CTDJbhJV4lz7G5hQV8zxMCDBK4q50mIjdKFFmW6rMK3Cdc1SIrgU3AYxh+\nvlKA784KE6Z8F0Xz6LTqzZOPaVIJRycW+hhpMGBubAK6aqi54uUkY+lsmPwn\njjOWDtCZ54DAAe06Cebes7nQ/xDxTkECEN813jFUXYmOipXJqtArs5tWdPBM\nQjhfLtYx4E1UMke1YXGm0nxcQGT8Pj/2BOS8Y8Eqw3wUBeKfInYRDcZkrN06\n1ZOVdQXPg613FlMJGUdY7OqmeeZPpUDeUD9uoLMlERajfEI+6U/3bqTWKgs9\nQq8q/mEDuUGhzfOmHQYU2P4YdidaU6kjDieR0dGlYDC7QceVB/3c5zM2mhLW\nDiXATm5VzM/9JOslAM6fTNCUOa6sOsw5mO+TXiJ2rsAjYGeISxDC2JDpALmF\nZkT6\r\n=lKDy\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC2zUJXjfqqOunzQC3rRLV0GUSq3GMB5RlJEBUzf00JyAIhANfS2MBByivmqVe3SNgjsqL0dAwU375YRt/atA2SuGhf"}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-beta.19_1594130688396_0.9850534733298693"},"_hasShrinkwrap":false},"3.0.0-beta.20":{"name":"@vue/compiler-dom","version":"3.0.0-beta.20","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-beta.20","@vue/compiler-core":"3.0.0-beta.20"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-beta.20","dist":{"shasum":"9d305d566da28222db4a0f7cd349e3e603a42872","integrity":"sha512-vtkvL8OOcIMdZn8oLKTVRqKLcpRBivhR6xz2sS8mfRA+NNh+QDpBFip5Zjl//FD6mRvv2wiJoWWqe0MgXUChbg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-beta.20.tgz","fileCount":14,"unpackedSize":587672,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfBfgyCRA9TVsSAnZWagAAZDwP/278B9OyBzJZsTSJQTy3\nzLsB4yZoVKZV0ZF8mgLpwwyAD5Wl1pxmThCqIFTD47OhccMDSpdom2xupDUN\n6Z2CsW+cQKdiciZs7nBaRl/A92hzybpZig2fg5ICoftfGd6zppmfl3n+dEx8\np34k1fZkOmmWgfP75fqxaRZVBhpGfF7sYzPD6Y0tDtFVyZl4pYIcAvN3evSb\n2aA8PXLb6opTvKORkAxZ9cwR7OGEHOefhWCJ5inuP5AuNCfMSuZwJ1rf2Bm2\nzOn/+bPW1mZok5sPVA+IDFdI8tPF0bxQCkPPyQQFxsNgQWKM4pYXGsMBA87R\n0CBek2jTbZIGy0zTa+G4ZZb/K1JaWlGMBY56Hnxd+hdZQEqVknnTaVw16YEZ\nZNB5MdjMmmWCd1FEiM4UcrH5Gv0FmOebU/RvebGZZn+sadJzHxOlXYVC8YPs\nyX9VEPzV04rfHZ7vhVkJ5tCFf9QpnNBmLv/64VzgWp9tleMJTheaNHGJMxhl\nLpw+aiyT+31hWcO9O5U7tYqL25xUfsO9pHxg9wStbF9fKjvMA3KQv1mH6k7m\nPPrejt6AzjHp3yon6EbiNXJDzMP8peAAEEHyDhNyOc7e9dRuDhx7/Vuntq2l\nrT43ymi7KJ9Hfb/5lFWrDSCBR4F7p1NoWmwIwujgzUzO7AOrOcjHKl2keGG0\nFNhs\r\n=MfWj\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBOaymXt70UC6CgTrXF9Q6czXfJG0BnQaRHypWPhTvM5AiEA0ETNZvjqpcjjkkXwam6MMD25oHiexw11vGgUF2Yxc7c="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-beta.20_1594226737726_0.21933572632898746"},"_hasShrinkwrap":false},"3.0.0-beta.21":{"name":"@vue/compiler-dom","version":"3.0.0-beta.21","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-beta.21","@vue/compiler-core":"3.0.0-beta.21"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-beta.21","dist":{"shasum":"16140b976a083481a7f58577dbb5d7f70f487798","integrity":"sha512-NOw6uxAHXlSkVW8NkSplnOrNusVF9YRXuaS0DJW2++dtYw0kP6kYgOZmQ1liywl3Kf78BHXNLQqEdI7JDWkJ9g==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-beta.21.tgz","fileCount":14,"unpackedSize":592673,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfDiEZCRA9TVsSAnZWagAAwpgP/3l0jCCQVLjMZeNSLj0a\nSXU+cLeBEl2dZZvK3arw9DEtGVJi0oYZRdEAE2GqQ2lJSmPRrVbYUV561+MA\neLUFkT5U5rhkc+9OoCuSdSQ7RwGxcOJvYrC3ROsWGCmfo1KujBdpvl6iTahV\nPrkwSyFbRojBSOSd64sX6ysnO1D0y15vUpjj/IFYbSvM9NGHFT+mU6jB+WLP\n+bUxlIOP89diUd4P5P7m2vnsnIwz43FIoyoxoEHxfuS93baoBANmTcyr0stb\nvRj0BVjaPgBl0njRlXFkdUTmEixZ/Fj1/TNwDiGOVYHsmVRixRSvX9Hxul1A\n6Xc4U1CorA0Q+fPpmsoKrD9JpcYN5n3CJu+GWXtT01t24KirK/5Yr4XJvmw5\n3Khw7vpQJ1soMmghwZATE+YFogb54sdPmwQcJ0T2kowy5awOVs0UaC9Dgw+M\nDU3uWIbCZMJWQZh+3NHLy1wFLTqMVzJOvX6d9S3/TxxwYyXoKUWUTYy7B7bR\nngxQQwO/gXvPBaUdZ0SNxsPWAC0++vbS56QsSNdIcs9l0rFC1kwn4b2UowuH\nwNRoiORWC0a5J4xf9M5xx8um3QsPVqDNBFB4Ib631Ye8F/DXxfnuBBsakc43\nprToKBGFE0Ej4ivE6TZv6jGgfScK2z5rZyiCIDgOSM8mPK2g1zJQitIUt/Zy\n6UbP\r\n=LLTr\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD30Wy23wZZrWWuofZ+GQydAdlErqj+XJ4PESgG5QeqPQIhAM9RvEuyqUP+5PsoDUn8nQkmhpIjcPAgNAwPmt5TbWnd"}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-beta.21_1594761497227_0.8151260356101648"},"_hasShrinkwrap":false},"3.0.0-beta.22":{"name":"@vue/compiler-dom","version":"3.0.0-beta.22","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-beta.22","@vue/compiler-core":"3.0.0-beta.22"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-beta.22","dist":{"shasum":"d3eae4321767529ca73f93a1ddb378f53e5728b4","integrity":"sha512-kJCEeyaBbS+VjYNFEi3o2mnwS2rqdthpQ6TNigojXmGKEoA3UCOrn3IGR3iTSdo/3knaoA9/zwJ8LcxSXkZXMg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-beta.22.tgz","fileCount":14,"unpackedSize":593985,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfDzJNCRA9TVsSAnZWagAA2VUP/jAziDyN2a6eOZo8fwqw\nmoS7PJdEtkNhOBXOfECQ2CvjqpDlg6zb7n9DeqV3FyHlAwGIiUaZD8/2xqmm\nLYgd8etUzwv54+t93Hd7QeotBm9Xjdv417uyYh5y0jq7byO0LuPADdZzI8eb\nWSQdbMJR1PE/MrqfkUtUqr6mbiV/KTRz0cEMOaucQTIZvSLXEmxqsgjRrHdE\nzlvcnHeUQjX7PgzL7s4yW0iBi93/GYRhYDFny85bY/LX4Ck529/XC5ADF0FD\nCsII0TRlcXZDDL3Xx96cLrwzujxx+9WyL/olKW5AeaffVsWrPUc9BaxWWx84\n4LPXP43krVDqPayHnGC7U7R3Q6vuh3aJyfUX6XvhyboEC5cOarJhxUje1DPW\nGcn6tS1DdGMm727QgoT7ijks+P4pkynQj6xM/yCGkjrkYdyXdyNlYw3hjD50\nR8wEJH9ob41d/BMyBJPgMgcCbKJDLwXyI0FADMeVivRzdT/oOp5/cEaRG0nv\ncErsl9G0tG6QgunWr/nqWAn9pbtihxzJFPLHJy5adAiOEBKarSgeM/Pm3BUF\no4/hwCsZzoqpPjvM19jYOlxbSw61NzNwN9Y8fM3wl51hnkt0c20WqBoO9VdE\nb6cIAzo2nAjCITIYCeFFv0zLBWrIIw8eqs9WiuGF+sYf6KN+beTcQ2Nya2WD\nbgpu\r\n=05P3\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAEI/mGEUijwZS0bUtm62MyZUy7UvvAnCmpI8Sup/1nnAiEAkQYYgojPCfL9XC/hJ7byi3TqTYSkcEaA/wE06C7noTE="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-beta.22_1594831437213_0.4242072742961862"},"_hasShrinkwrap":false},"3.0.0-beta.23":{"name":"@vue/compiler-dom","version":"3.0.0-beta.23","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-beta.23","@vue/compiler-core":"3.0.0-beta.23"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-beta.23","dist":{"shasum":"ea21dff46245051ddcac6b3141be41ba1a85349e","integrity":"sha512-lyGDw245+B48M5MBUurKS5toPZRpw2yG9jGOvjdWHz+rIx87JhyU2+h1rmV7Agx6j3y11cy/TxDzWkOW+o4BBg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-beta.23.tgz","fileCount":14,"unpackedSize":595439,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfEIUCCRA9TVsSAnZWagAAEugQAIjInUz8MmgDnT5LAfE5\n4Y1/slqwX+B0VXYHs6awS5gQduzVogptVTk6uEPsCs5FLrz8iKHN5IfpYZ70\nD3BZIcFA5ZY3TMYRi1+d6m4SxN/N2BZ3Ayu+5ZaHTD3yCiD3YhrHlCE8ZhBk\n0vIFAhe3fQ4O2wARMM81bNOOb+hjgA7sOTrjBmauEnUb8IZmj4/upGlLDva9\nuV2WkLwOSeWK0SOPlJOrO/OMrGxFRTtKcDnLBnWoZ2ZmcwuM/ez8RkTOO2S0\npNnQWryNo1AUp0bH2TLKt/UmV6rtVWTUyrX+kCJXMdiQqlGELPsmaa6g0ERr\nvq4m3TV6s43VKKurt3+6RTqbbmpnhmfXNAX/djKl3c8KEIzJMXIaR/o4anKZ\nwrplJlClH9bhmRSmtZRFB60kpaegTdxiusxSSqdiK1DRHnMz7tdPGPCmI08e\nDh66+aiky8zctE2du7Usbtw+ISVdhyBReugyGzQcDKoW9aEO41Vcthz2brMz\n5eX7CRvhUnXvy5ugV9KNQwu5V5XX/+Fp91bGvAtR5JeTyeNuM5rhJLgx177H\nKokaU3NtDOX1XuTt8sMczLrHHR85r3IVtYyJScTitMTl4BmcPyN0UcePpP7i\nGxrAa8nlejYv/CC+Pelr7PsQf4TNrrun2h7Ef0TLkynlvuQWZpaxlnfyWf0K\nr3lj\r\n=fhGb\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDa0Hqf1i3xMYo8dyET9kMx+84S6jX5LD1iBGCT7PVbPgIhAPmhhA3fKbtl9NlF6wz+U1IFmDXzHG36LAeahPKSPNq7"}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-beta.23_1594918145601_0.8074952272252027"},"_hasShrinkwrap":false},"3.0.0-beta.24":{"name":"@vue/compiler-dom","version":"3.0.0-beta.24","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-beta.24","@vue/compiler-core":"3.0.0-beta.24"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-beta.24","dist":{"shasum":"287c1c80686824a56b6d8b246def9f7d86d534d3","integrity":"sha512-Nav5CqiOf4aIWnxJ+8+lSquAQccF1nRe7VzGrwigX8/pb0rMyNlRgxRRa+xnHJ+q5aNZEKlCHCxNQDKVzxP2Zw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-beta.24.tgz","fileCount":14,"unpackedSize":595454,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfEJPBCRA9TVsSAnZWagAAJKcP/izqKnXFNiaookRcY9Eq\npPLBAmKUN3O9+TRpZ8z9eOiEMrNKeBuOpdYkunaB0oK0+FzPhNfcHGmym//3\nr9zI+gNb6P7x0tx6VqpqgwBOpiUiKiHBMWuKwyS+uljWyMxV31iCE8oqsz89\nsZbAQwYWQXslIKNDVNGK1wqVQeus9sMwIYA+OoOcSTR0IccRAzAjp/Jubz5n\n5Eos3gMWHT7iO9yWK7Gb6PoAaXah/hpdG1aRdyEXnHRZCQx7eDGluzpumQAK\nern7vc5FspRZtXssfGNkESCiTwmmJsIiyCKpnbDTPc4lit8rQv7gLDcUIcZt\n581IqDrjtMVGA9clpArZZ6gr4ObfZ6O5/AijC2t7hCtNO8lLP3M/Sn7nT/9R\ny2MdBmcyHcuhsl3KShsbJZwnI9mK6HQf4urzGVkJzwN+sXBLnTuDZ0ptTZnj\nZQW7ys9tAfe5lejhz7s2z649+wl5zAFAKIfkLeiB7/LQZtPDiwNYXS+nJAp8\n0VD2fjKcsTGzvIbxg4U4W8HzJ6LBoOk3jYSVeIt1pP8Qg8w8SZF3NYGwdbq9\nlHxIwGw2bE4Ge9czkTZEb62PmRtxUdAMG7fFmGVCH2S2VtbrDZtXmHTGr2gV\nZ0pf+uoq2bR3pj9Lvbl9uG6Yj0XDd5ayZ0h5aR27UH4IgSyJfE0o0f8oHawL\n/9X1\r\n=QyZd\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDmC5hliyzJzO9D2lkn99ET4m0mPz2RTmcoDWLsThCnUAiEA9rf73wf1hzIBkkPW0ZB8a20mpYRmXU/UTZqyaazLy9o="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-beta.24_1594921921320_0.13609149110577845"},"_hasShrinkwrap":false},"3.0.0-rc.1":{"name":"@vue/compiler-dom","version":"3.0.0-rc.1","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-rc.1","@vue/compiler-core":"3.0.0-rc.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-rc.1","dist":{"shasum":"2d386624cb65094877ff615bfa5ed1484f11b978","integrity":"sha512-0Vs5eX5ed+0vkqNLlcQxaWzyK8EENwaa5dHlVwlH0aUQDuUQr+WIlTalHnLDWIqnTmRPHNjJ5nn1B4dqZt/6EQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-rc.1.tgz","fileCount":14,"unpackedSize":595409,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfEfxRCRA9TVsSAnZWagAAy18QAIt1HUKA+Ru/4oW1TdKp\nX6ABiULx0C71U6xVqwKFXn+zx5xvAldjo5cUtZab1+ih0KMa1r3z4K/vg0G5\nqQjZi2uI3sMCuDbuc1BAHxUYVaN9vATU7eK09zeej9TkOs8SD4SE/d/8TY+F\nLhLXdp2RrlC/l4YpC6wGhPDYvK8ellKKX942UqANdHb53ydAng5bnoXug3/o\nBWWLigmslWYQcu9Sy9cyLfIWzWqtEurnjLA+Vp/J4n25bhV6etQetbkR20Hp\n+N7l33Kj/Jv0tUgWbRl/B8iNBnVpojI0TdFH/q6IGUl7YwPg2XwK8udUhmHU\nTbwMx5onwFvaE79AxjlkyZPycXGbUZL+ofN+XKQm4M4TXn4Fscxk2/IpcvJ8\nh0HQFoLYhok7ITnhxn3urwI2RsrGGnM01EaYdzu0glHkYV6u3/Yo1UscArdM\nkxeLqxEzuZbQwN4JOxBzw/vxmrLNM2rvmVVWA6FiCoUTm5kfLBxQ639r5/Jp\nK+zccHTXw3YGiH6531U139QUqmdOHdU6AG/mZXS8bvTqNBEgRhHfhyLJFD6j\n0DCcNQ6hwL2zv6V2LarA+5q4Sft0FNg8+uKR2mO6+LZkxJ1qvVmfkCsu0kRY\nXvCIdro6PkQzeuBETDeFrEadgUUoYr4l4HOagfsC1B06J06Gu41yxj82z31V\nH3QW\r\n=g7D5\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDDnMCn9L2mZXCkMQbEniHN4qnA3vzoCs9qMoTwXkmdHwIgFZ7ZK3KzrOSndOrLCry1AySlH6aWhgGmxY6tCSr3kR8="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-rc.1_1595014225229_0.6229429071068544"},"_hasShrinkwrap":false},"3.0.0-rc.2":{"name":"@vue/compiler-dom","version":"3.0.0-rc.2","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-rc.2","@vue/compiler-core":"3.0.0-rc.2"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-rc.2","dist":{"shasum":"e56ea950d946ab316755fd1fcabfa627c6741ba3","integrity":"sha512-38iflPPoZtbPBBLDI9q2xP3MQAnUIQFs9aRwSMJqDI0PxEvB2J9O6o5bBtN7QIorL5KnxDO9LLz+RuCgmFIQVQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-rc.2.tgz","fileCount":14,"unpackedSize":595573,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfFJaDCRA9TVsSAnZWagAAhoAP/2SVm0Iyqow7Dp5Og1/I\nWsUS8nBlc6vmwV5Y38NKwI3zg6qVcPEOq1vOKhXheENC04VsVjmvPckvyvrc\nJ7PBbqCpb3trknGzwl/Q1OUaqG9lsytvZoQi6tyL7YjW2O+Ly0DaO4accnBx\n6sebeNaoItqDk0ApGm9hLie/yVCzLf78wdYPl4sjbQhVoS40K5g0XiAmlx3a\n8WZ2if7bOF4LsE1YdVl/JbpW07AKREeaGxoDixzzc2HETpdXlb0b8aKbFANn\nXyh1w4bJ93CBWk5wui5ZW0txHzCTsIigxAzV8dptLBe9MUEwsSs/1SyJogzN\njNqpbfPvekchk6F9laWgb4F5YaZVskWhw59K6zZGAijiH2MIaDt1MRM5ltOK\neL5VVhg+iHTenyKb0lnfGVk5X+6wFiAxSYd9Pez+ToHxEaAxy8JK8ygZU8h4\nA8BHlHjxFFhGBDLPfERtoisKIhCeUgcWciY5aWpKtxyfSqh6G9njf9xG//QP\nGavyKwzP1QN/qFVAHCi6NA1FWDx3W5uIAhCVQIIR6cCWXf1xfEhSjxKpFQ1e\n8ttlm5VECxE1hgFAKo++dINaImqsR3Z2demWfARmH2kv0oHShaVaKyC50Yy/\n6w6ZaZCiv1QFH42HRD0a/PBePKlhgTdRIWx5rVKTO5x0BMoyDCkxFkAPJRer\nzBVH\r\n=p+RM\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICnC/zEywlgKj6IW+3UxktyJ2VtkMMah4BMlxS+t7lJDAiAesxlUOIK0ObFXgGFCWuQGCyj8zX83sDvVpZrkFGFEyw=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-rc.2_1595184770710_0.42651914546385816"},"_hasShrinkwrap":false},"3.0.0-rc.3":{"name":"@vue/compiler-dom","version":"3.0.0-rc.3","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-rc.3","@vue/compiler-core":"3.0.0-rc.3"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-rc.3","dist":{"shasum":"f9abe6c74e540b09104caded8c27defd0013f206","integrity":"sha512-WDRjXy4Z2Vct4qlTNCAaBSRA8sBA1OSH/lxBLGvpVx39JNzME0RbuvgTlReCbqWgdDKfgSPxUJSgOdXUtyxUEQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-rc.3.tgz","fileCount":14,"unpackedSize":597250,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfF0GoCRA9TVsSAnZWagAAkoMP/0cZKReyLusu+ILtkDSw\nYBH3icKFw3D/J8d9zIxl+YjDBOK/q2VlXajKCAtSeBwBVHqa2Uf64h99M+S1\npXjhGxrq2hSKmOzoE/uTCIdR29F6kvdrPVKYYa+4scFj8Komuo0JhyobfqcC\nyqarNyYjAzIGADA8eCfNF5tPmYQNQgytFhmJsSafTHwLmRlc+OLGhMcZ33zz\n8AGUrhWCpRoT4uk0P1KYPwLdFcpDIwuYO267/GopwNWF36R/TgSHjM2o2Iy3\nOxYcQHds1GZk9yQzeSpNL/A3Y8+xPnzcJGOD2GHXQ1slN1FTra+oewYGkjGu\nV2GoJHppjnDgKWK63dhh1gKFz05vtzPH0txaFd9j8YeYhY2dBCAQ/V/rbVH3\nol4FjLaNXxfoL5cpqp5vNX5IQXb6HphdtAKZN2+hxMvLARt1AtVkn/+ctLSF\ndsafoLc5rLENHEXB3c0vH5oZ1TAq0nQqLmYCRFud61Ob356dVGjLs7Igzrbw\n0ACPRShAiIQtf1oUYl2F25gwEgfgt8nsR6nUXEBI9Y301aT2PzMpE48xNVsn\nYFGuSg0e7/7yePH91YJ99flCc8ABorqfjWsNGoqfWCfcdYWENx67Iq6YlgxJ\nsczMdJU3YYHyOY9/9gZCDl33Y6RSG2HjIZtJBdiM311DU01BqvFQZojK+20U\ntc+m\r\n=VesF\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICejvazSJQ1N0+/2QF5CQJpSjIZYRIZB/aEG6TA/3vOQAiEA08erg6d37dQEZI/cdNSGzLg8HcEtmWVxaKL23V9daNc="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-rc.3_1595359655787_0.7366279527266459"},"_hasShrinkwrap":false},"3.0.0-rc.4":{"name":"@vue/compiler-dom","version":"3.0.0-rc.4","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-rc.4","@vue/compiler-core":"3.0.0-rc.4"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-rc.4","dist":{"shasum":"3c6b56f8c99797b46cf7935ffb1e538a1a1174c7","integrity":"sha512-CZbPWlcQlLEa/IEXBxvIbs+OgCbONS3Auq/RXRff+zj440XNQ7j4vgd18+8suWaxObL5oBo0wg9BTUhP0oJgog==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-rc.4.tgz","fileCount":14,"unpackedSize":597250,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfF0TFCRA9TVsSAnZWagAAkJ0P/iYojnwf1vuyYqUeBAWr\nEvciBxeyktoTElL4e8LfHf80e84iCUEA6tMikshV8PNLZAEgxl8j4zFbQKeV\nmiOXb4viiVj229QcrF3IvqbOt0xme6YPPw8Zs2kvpEWCFa4SxasKDiuBxT2b\nICvRt0pYD1p04NmHsgMhWoT/cRntOgmOS2ndgZcZSH8r8hq+lQ4GrNjYFW6D\n5Ki7aSO/MAGLvznfOPhjySMY5Ql9Rsuy/mHIt6bObDVBM7AdhL5NHPJsvChA\nu5NLIQBSbJ9QC6AzIe+pEAJMG8O3+BLcOF4pDCprtIZ33Gl2xxmn+5kmLCGz\nRd8yEl/2+AT0aNYIfmI0NjD+ty3hMEYq3K8qe2XcCXX3O3ynNpH5D4GbRPNi\nIa5UYmIhuvGQ7fUDF2/qTbld8cJ40vSLvQN3W4+bB5xXiBd1cC5fWDiiFrT7\nCH3AhNCL/lxyazFCFJHnj/Ahv1rqFR3PxfRnJkpEYSk/I2kzum5lJZb5TqRJ\nXhOlo/EGu77MA+9hw5V2TetZHEB4ML45OEmRjAx5Goh6Ythmnxj/H2EEKw3L\nlmnUCJW7hluA5rcGfv4rciKRPKzVBgJj16FDhOQCAvpoKNnY66CvZW8zuCnn\nbemr3fOKxL37qsf7TvXlx/LWmXlIwz41uo0iyyYMNJBAKF3OoCzkWHDYBpql\nkxff\r\n=f+2x\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAZ7EEov2k8PPdVvKtv/leNcfb6Dne0AajEBvh6oypMzAiEArH/7ILvCn2f7OaHG+IkTf3/TDy4YSAuY+LMF0/ayVq0="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-rc.4_1595360453016_0.35248789615724085"},"_hasShrinkwrap":false},"3.0.0-rc.5":{"name":"@vue/compiler-dom","version":"3.0.0-rc.5","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-rc.5","@vue/compiler-core":"3.0.0-rc.5"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-rc.5","dist":{"shasum":"83905e8601123a3654b90fbd80708a16530ce21a","integrity":"sha512-z8n+R1GhFnWuKURLYxfVSEfP7nSNM91qteobxwys55fhlZZuReouMnUwgrn+ois/IL6RdFlT9H+n4+N6yLrdJA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-rc.5.tgz","fileCount":14,"unpackedSize":600002,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfIJu2CRA9TVsSAnZWagAA56IP/iFb936gcn2rKCs0Nu3Q\nkDaQGsMQDnDNWtTaUOfCfrW19osxEzGXJAjpJCUO38UuYVFd4OagEc5Vq5M0\nXtMBPY6xot/TH/tzIKEsGRqOwF00XgHuS7958Aoena3m7Mlhepp3/v5Kt6PD\niMYvlgbz0pCJBMzwRRyM7qFAzd9rf2ky6Ie0h+Qcb9TCxvFRI6MHUfoqZaxx\nGaFBY8Hdg/ylPgpORMx4yEVRqSJllpLeNhCXYT8Mll5RehYTtBltXY9xayGn\nvcjHYai7GrtjAl4qdSF4kOm46CUQ9IgBACNEscphFrbzPVuYk5U8IYe1Scag\nwAz/I6r1HdfBvC9I7lQMW30NOGigzoT6Zn1XWHXZD6je09jHrc+Zkgj09Uh7\nokZkDgRlKXscttISs8hk/GT/jqI445uTciq6hirwwnBlxpR1548TeZ0kKc9d\nEtcmYMDdeqNfiJKIWcx16+k0TIgYiRJY9PDiwzzT6bGvpoxTs8v7zR1E/DvE\nmBKkhtUcz/2b0CCjjEmT7ocqkSqx47T4d5N4KTTyl7BXxBApZ24hZks9491W\nKN7KzUK/B1Kz9PKikBUvB+ITqAVb1U8ymv6KdnO88ZVigvkSu6s+uZO4kFhR\njPzED29DDyTbjlwc/HxjB0t7PQJWHB9os6PeaTudL5lLDZDoq14mltIXuxs6\nEyVi\r\n=PnNv\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFHzl/R20ErMjwWqN1zLpuFIPcWBrHeuDDCaTwuTX6ujAiAIdzRDkECShTZ1WtCWXTUOiAkaGDMADAbp0MPrkN/tWw=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-rc.5_1595972533548_0.5833422005349653"},"_hasShrinkwrap":false},"3.0.0-rc.6":{"name":"@vue/compiler-dom","version":"3.0.0-rc.6","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-rc.6","@vue/compiler-core":"3.0.0-rc.6"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-rc.6","dist":{"shasum":"6d7adec707834ab75b2ab89d53f484e74eec7253","integrity":"sha512-ZlBvrH5FUPtMLKHib1yR0eLvVbjMarz/fWRD3MtDJiCpH5TTHo5I24HLaMhbjSB0nnwahwAbc/ni2538agmJkg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-rc.6.tgz","fileCount":14,"unpackedSize":604540,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfPaUQCRA9TVsSAnZWagAAoCoP/3zbgbxeAzkas2ZurZuT\nLsDA8cYGYSM6vAoK/1AbgkLlqlRpsW26tAOhFkx4pj8T3ag2az+MJcpyo15+\nzjdaijyeymOLKiwbHpGhtCgoHQkNIDCrhvb5KZx6z6WaXD5RsgBnmJYkfdTB\nBSmnw1XTPMtsDoyxvuIlMIiL7l2/mXAU2qiE+vl7BrAfDZT7t4ppgsqz9Q5A\nppaMtAK+3QuBZkkYemek8PbbJVXdkKbJ/nn57H+lNOky5aKd3Wgl9O7KZu5h\nRuza9yCD6NfEsCLO1Tw3bAmugoh6pKfG4B6RTS5b1sy/vj78e1QPEFAgWv+d\n+DmQelKiXd+cGSGFc34ZqM2qs4BSRc7a0WyNSFmkA8TKW3M7nH4tefVcZG1G\nVaaIkepaQgcmtq+B2vDNJvToBUy3L4UqvHHD8KSmZ+s9FP3SxDo19xrxuZFr\n0QHOEKX7xhd6CqE79p4sYjmLKs0/sZfDcvFdEKOqkzzLO1aM0WJK+XcSX6KU\njjbM60Dw4pbZ6VBiNTB5FU2SJxjBZETrybg5VP+HHMntdoX7+w+k4RAK+rOL\nkWtubmjGz9ip551W2Sj3cfhxzUJNKBFBPseVmMkcnhGC9uT8/soT4yM9RCpT\nMH0Rq9Rt44MIeG5HQ+GA4icKpyKLRsSxujYWCXzjaUDHZ7mqIatp1Zf5Ljbz\nEGAL\r\n=SmED\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDud9YsxlN9XSlt1Tn7wpZbYG2P8wgUUiJ/SXY7sr/9FAiEA2Ngr42M6fAG2tf682Uazz9yyxfWwCOjFNcsbxUxjGVg="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-rc.6_1597875472105_0.7904658110652654"},"_hasShrinkwrap":false},"3.0.0-rc.7":{"name":"@vue/compiler-dom","version":"3.0.0-rc.7","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-rc.7","@vue/compiler-core":"3.0.0-rc.7"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-rc.7","dist":{"shasum":"0e193767243485db314495e17d8fd56370b628e1","integrity":"sha512-wE8YmkN3ISodjijzG44YiRgbcb7skqdRbhoYgABGz8uHvNSMGPLrM80cRosgLoGlcgxDPxj0xaEAczBunJYV2g==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-rc.7.tgz","fileCount":14,"unpackedSize":606450,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfQA65CRA9TVsSAnZWagAA1DsP/iF2GxUWkV/4YnbAz9Bo\nvJHn5drj/WtWE1Y95xXkTeuQWf35BqiPpPylykTXI7WXqVDk1m5XAZitFH3W\nDHkn0db61jPjNM0eVYYXLT74zyU6FbwVmqei6h7uRT0yNaBdojep0eRQSMnF\nPCJkLMwS0udXZrkBSnV93EWB9TolsEp8iAe7+9eWDTzW9lKoG1r6ANcpjtgH\nU2tXQvL7JwBz9AKNFNvyFfRW2rI435eDni382I9B3oBthGl588RQBUcfftCs\nqSijvEuCvvFiiL42QpeJNs+EsworbkX77C4pf3YlTBrsEG4k6wdlFe9a/Np6\n7L/7fjUskgJ+5Yh3RwwKSqPW5InQOoO3MaY9Z66ZhkMExmhrS05Wp38JYtEZ\nnZ2VABfNRvorDRylr8Fv7aWaZPafgEylvFfkR+nHkaJBRVs2Euu6nzN0le+w\nmdvS7ZJ9N4lBb6MnpMq4ruVifLONftZ/1y7YZTnl7Y5tEul98Sq0wnofH8Fj\n+t+An3RYckH92i/V5l3a5vE3KyNearbaj+79IqvurdtHdaHNJzkDaul/asCZ\nvi+gptsFLFNoNjUgX6Qd+ZnG9+CFsH1BvU1oS3yKiE0hmf5cmDaeBVTV+0pm\n3Hu9P2WNqj6Qw92bv1ZXy4ZHOltq0efbgJrdsYfW3L0sI2Nfu6vfw4Mtas1r\nz97J\r\n=ajck\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDut1NljoOLMypdYdAthSsBmvBchqH5jxtv5l8jjUGfpAiAb2uOzkIoHQtsqn9vrMuEoYa5nyJINu946WCMYI11Wtw=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-rc.7_1598033593336_0.030251518463625615"},"_hasShrinkwrap":false},"3.0.0-rc.8":{"name":"@vue/compiler-dom","version":"3.0.0-rc.8","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-rc.8","@vue/compiler-core":"3.0.0-rc.8"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-rc.8","dist":{"shasum":"a4fd66356e1dbe7bf3f3e41f6034e682b7c22b3d","integrity":"sha512-xnYswIMWTu8ck5ZcyXrZBhB/gBXla5JpfdEkoPqjNNSXZn1w6N398KuB6UQtjSDjjIsZ7shs7/x5hgtnqTNBJQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-rc.8.tgz","fileCount":14,"unpackedSize":606450,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfRSDlCRA9TVsSAnZWagAAAZcQAJdpt65TVrIxbWGEZ49u\nkreq3elcBGjCw9GyV7lGVyYZrrebm4bAvzJzkxZsj7h8wT8ldKsPXgnFKD4U\n4g0N6fHuoGpdZEPpNEXen1fIEde0EnTmoG4HsDbdrdsYx6Rq2Cgi/MLfa6vg\nyol/ZTIaoucXk9Ea/x2W2m0doH3IHVXypDjziL/PBPc9FlOWrUA9HSKg5fkA\nH5jwLM0hz4Pc1PmP246xSQOlijfEwoYUdyy095bTSIhjpSIwtjApNqNE8gNj\nsfHsIWefNChQwoUyn4ft/WlbEpPBtZTDQkBLozCy7qmyzK7nAqMfJdOLMjOR\nyhX6novDOZ/wwf8M57I22yQBvWltbubbsaApIBLgVV/LA19jnrJe/iBxg6hA\nCWYhXA175Pa+qjR12n3JphLnMEUeZk8S8vG3GEJQb3Ciut88moAp4fHqKK4A\nS8Ujk47xUtpV9UC7p1m6KaAhrWYyk652uGReKZy4tPT90dJsoEc1ij4Gw/Ew\nIR8GunT784tJ1yRXS47xsb4a1waR0yjC70wxn03dAreaYC7ayOQQeincNUIa\nmjG4y03cx/bOQrgqmjhtm2F+4vy5mloscXfcpHP7qH9O7M1JbFge0HN35DhI\ng/NkQ4hAWsJAF+Rsc1yEwjy+vm7UyrVy/TtPsLm16Ck3uKr2EDJ+NtvgzaEN\nop06\r\n=u1G8\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCjHb6VrXbaasuJ2/dIlqZs7+7U19m5QlxIHThv0iSWmQIgVVEttisnm4FvYKkoVV98byzZDTnXxDV5cJ3/k8gxTtc="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-rc.8_1598365925310_0.691670902395368"},"_hasShrinkwrap":false},"3.0.0-rc.9":{"name":"@vue/compiler-dom","version":"3.0.0-rc.9","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-rc.9","@vue/compiler-core":"3.0.0-rc.9"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-rc.9","dist":{"shasum":"2a122181db498c0605213fe541af24ecb03ef27e","integrity":"sha512-0hCnrIxwp0TKVXKnGYFztM4LMUvFpfXW7YoEglvHqIfZsGkyKcnCYDx4FPk1frDM21xnrr5HgcHt42rlz8lDBA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-rc.9.tgz","fileCount":14,"unpackedSize":606450,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfRuBnCRA9TVsSAnZWagAA5BUP/2BTUbKDVkjoBR+35uh2\n4fFadYQnHBxWkV/Puel7zeBFdLPmOceREiQ5g66wCcNB6GOFg4hsCvgZ3kRY\nxe+rscMm2oRNZ+aUApqCFKnYOhhYBI/LxcL1pQS7IA8E6vTkqnKtYEvA80IE\nqP+QKdjTqaFvuzBPDmat4sVVv58ectDkUfWw0IQQ+5WLAkZ9hw/4mmqFLi3/\ngKk3+DvZB1DFKzFQD/vV7ox89Gv96JYT+z+dHEYiQYKsO+fiJzF88EFdiCmr\nFFJI0eWzOI3gYVP+KeHkmy7H2udUMXcTK8FFv8YPejT0TFv+dA/kap+Ca0HB\nLcupoYUyX8BmTbPTyRW6DMVfMa+R2Wc3Qq4UTgcZX19/jLSl4v5aeirUTp3A\nPSt5+YUlT4cydtTJoKD5bUhQctREm91EKgL93i0PGtBA4PkEDqa0x6oznSLV\nDYEgnze5/xx3uLBqDYY0J9abg8JAtslzqa7I/7cnmgzeEqc1hSGzSwwg5mXV\nDiCn9wqB0kNBfnYTK1/XKEqvCNr1/cgwRB8T8KcQWBVWr1+zuWP5toPTW/ea\nkpQcsSIMk0zzbw+J1emq4rMyQQVGHy7jJrDGlWNLbm9eHMNbVrx3bjMx0l5Q\nwDbgOPYbQI5MlxekaOts3/3oCMLNi3MN49ZxuN6QF8vOcRGfM5xWqpjVnDB2\nswll\r\n=QwwE\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGniQKt9seYXBxYvTSANQZ8nmYZ2PbPxGIfPpGbeOlAbAiBk1XciXuifHFM6gcrNARa8BpBsOKCjEbt30EbIIlufGw=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-rc.9_1598480487345_0.3094477060367684"},"_hasShrinkwrap":false},"3.0.0-rc.10":{"name":"@vue/compiler-dom","version":"3.0.0-rc.10","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-rc.10","@vue/compiler-core":"3.0.0-rc.10"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-rc.10","dist":{"shasum":"dd1380d1ee61170de76f9eb91e0d8ac7985f0ae0","integrity":"sha512-pqIUf5leZm0P9379utrRSVBMxhV8XaqJTEFFp5etCtbEa/H5ALs29EjFMtMcm9sQaVkZlKLu86mgIacbYB9Q3w==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-rc.10.tgz","fileCount":14,"unpackedSize":607065,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfT8tdCRA9TVsSAnZWagAA0LEP/0TR0rQQTEr6iQAr5Uio\nNMfwLVcWNDEyWA7LdFzlzfIQwrH1fR0iazfRaftt+mzyVSPPWfJCueagyeUM\nogoQKb7jXQLBS+YYp51RMsCJrBXuXc0Yyoq1vSyUX6PjDcJ6pC97CgSmr37s\n9Y67PxUthxXRGxkf+x891U2HtNvV2p/JNme1Krv8Q1HK0TqOfzGQSufTL/sD\nlCYqfX6ditfM7sHqkfUDKNpzr/xWZWQm9+gZiVfitvE2s08sMpAySGdN5Emf\n1hRCkuY0VqfjNWiDwGA+GFYO+qAPml2Oy8AlQIWCJYKu544QNbs5rmF7gT2W\nrZCQXmXdugA8/9dKVkoXvGW7fZx0XyUK7jbf+mlpGOY0N16Q1o6bFD+NW/BF\nfLPhcj8Qr/8noo0m25n7CTGLwES429FIh7IzV88se58lMgKvZNO57xP8H9RJ\nvKVukbT9URPiyOSPQZjGEfZwDezeDi/He/ASCKFoqZ77TUgbufMaCtHwXJXy\nlprjo5Lkoz6eWNLWFp6UwsMoK/nmmXAkpD32itvAhuznQSQwMtfoI4Ts1QST\nfK0THSZOLp+3jkDu+dfNGNET7oji0G3CNDzCC6hu1C4C1HkiAxx9kQwjuT6u\nqsAgDJRxFWF/FatpBLQK+GtL6GxYUwlfYqfsKxLlsBzXULQEAD1P4dn0kIIw\n+OQz\r\n=BfKQ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBclxTDT9Z9DtCu3QVFOK6cZJEXpv5euqV6CGe+jmtdrAiBTwbspUR6rdUr5XMqTaUIuHhk9VjlA5/tOCHtWXuDNlQ=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-rc.10_1599064924883_0.30811614053927094"},"_hasShrinkwrap":false},"3.0.0-rc.11":{"name":"@vue/compiler-dom","version":"3.0.0-rc.11","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-rc.11","@vue/compiler-core":"3.0.0-rc.11"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-rc.11","dist":{"shasum":"f991bba3d312e58b80927454e42d2e75adae186f","integrity":"sha512-bifgoi7/6E8F5ur9EC/7lFIXC1sUYXi9MzlOpj/VT8UVNN6Ww+2E0EImq4ZpDkZhXNkLfY7yIQIRkIE4SgcG0Q==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-rc.11.tgz","fileCount":14,"unpackedSize":606345,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfYPbHCRA9TVsSAnZWagAAqvwQAJ5A7OOpdrtdErtn+w9o\nHgo4Nlj06D56FBOqkx5fcGN4qVTp74ivwz8B3Cbh6gCouuT/g2L4a8aJAwtr\nwIPExCkKbXOj2TxXJD572hDlruCuAZpbSi2T+ZPRo9zTj120xGfrgzJBrUDB\nOzKeoxTAx8Pb5X77fWWLiEnxyomSAV0e04t2EmegZDKT/fG4PjjPoylsKqrm\nke7Csd3PCKLbP3LGHTw1OfbtKflg/E85q02xsMu71IcOa1rUxmg8XAqR1mh1\naEybfTITEad52WadwtXN+SLBiaelE7e7y9L5VnTaEJ9A14F9SLwWOM6EM/T4\nUltVsmgFvC8bIlnGezJp6jOMZkqCiEX9iJXzv8obVjge5Ku9Nd0rkWRjWCLJ\n5j3K10CmVbesOB/G0+mPjEO1KYXNFOBrvSJJzq9tjlCzlySfpZpbiZaKF54Q\nhpaevU4mJ+tDMvQ4KVQHrn0vZPvcl3RuUgFgcUlmJMb5s8a7Z2FJDYwp7UYq\n3uX4B8VdUAH1dh7EoPZ1jjXl0CMA3sr96yAS6eI645ESNO8TugyNLdb0a4L9\nexCajgRGh74g1fgyQhnVwaGZqvlW1cKwu9OIwA89Y5gOgV0G0jebM41UO7ft\nZSGzleb6OqzLYyXgI7yPXlkYHqcuemjS1a+WLEiAF8F78B7T6iTeUytyGhco\nkskK\r\n=xHQD\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDRaEdBB/Ib/KCTSBIYyzW8ZUJHxevvekGX/S/V0A1tiAiBA0zCbqwC4iW6bDDddnS5JcsVCJb2aZO5m0ZmsM89gZQ=="}]},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-rc.11_1600190150924_0.4349355491040221"},"_hasShrinkwrap":false},"3.0.0-rc.12":{"name":"@vue/compiler-dom","version":"3.0.0-rc.12","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-rc.12","@vue/compiler-core":"3.0.0-rc.12"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-rc.12","dist":{"shasum":"b8468cb3f81d43ca25592026482e1330b99f2b8c","integrity":"sha512-bCbXtJRYDaQL0e8i54rzUhmlB991ad08TAHiXyRK6ngTj9pO6lpJNcaHIeeOEv9gaZ6iUC7pEYtmC0708KkqDg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-rc.12.tgz","fileCount":14,"unpackedSize":606345,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfYlBlCRA9TVsSAnZWagAAMg0P/1mUZbKH3/1ksO4rncbU\n+zQtxSNEAUFeIu2G51e6chLp7UyyKLdWXXbntmF+pFs6cVhZihdkqQu3Z6+R\nOJ+sKc4hT/FZFVjx79gommlVApzHwc1BN7+wVtWjtdTYk/B28xZmvEtFrB2R\nVmB0l7CxdXnkyxMISO9HRtgGCjh89pFS9IEE4EUd80NhJzjNTJefIzOou3HB\nO9oYxrpE7sf01099gL8dv9efY/3khh3xigojwubxxAgJoUYfbO0fykzAhi4n\nzwP2N7MLF2RI4mIUS2tvU7/jk6KCB0Y0QKcqdAZISoq4qdn8FY4F2giNpvft\nRH/GxmfHWUeM0XolKjTLLJido6zd9oeZv2O6IeQbdeXY5vFFSNcJwKBwz5bL\n8eiMZXGQ1UL+FPOSek46Ucvaql8mVYly5sqpdRapTZwOSid4pkYpWrSZBlO6\nGaoqmyqJvWEBRJMl78D+DgPjH/dsuUNmeV5U+b5qCBG0dWqNYIxTHUQvzm0T\nHotzYKE4BJtm0GebOIMSFf1cKb1LCViSkeLTRwNG/UwgFE8sTzAKdNPO9Fhs\n/fv3M+vDKVcWxc7icc8V2SsWAiVyi2r2s9HKv+g96SZtiGzhNX6FGs1G0J+N\nxexexdbOdi3bbhY8URcvvNI0CsVabD3JF5fULbW0M1mmdP/4OPJMVUVhCxH5\n+8ZM\r\n=RxR0\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCxxcUJqf0InpAl7t+zHkTIhuUfzJOIeyq6nfQKsMEDNwIgTfWJM3LpweyMN+Snjao3ELlgNGwASgJU/IUfnNhgTjM="}]},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-rc.12_1600278627151_0.8379694732454843"},"_hasShrinkwrap":false},"3.0.0-rc.13":{"name":"@vue/compiler-dom","version":"3.0.0-rc.13","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0-rc.13","@vue/compiler-core":"3.0.0-rc.13"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0-rc.13","dist":{"shasum":"dc00b10c19a9d03a5302046de84daa5b1096d4cb","integrity":"sha512-D0x6cZFiDfz+rcmWSgvgxjhVQOADMmQy7kcbft3u5nlTurZaztBNBz7pwHYi57/z3FjhzyclpDf0daOrRvph4A==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0-rc.13.tgz","fileCount":14,"unpackedSize":606345,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfZEgdCRA9TVsSAnZWagAAaUkP/RFR/wQFYA+ozbWjWX0d\nZ8kvk7ugz1ICsGtJdgnJnwHSZF7TuvJMNx+VXLQoqKOHlYlgBHKvnaeyEEq0\nlCg6zIJ/t5DjSV0db8xzjsM0H9lhLnc0ph84hNmWcivctTV8Q50Z3Gvl15NZ\nWCclsrhNLwsMQgNMISKG/11N032lJBKQvNbkb4uyMddBPoZi9Wg10bbiCFhv\nCuGCIQWweHXgoOd+thQ+WdojskIh4R32qsTOxicyn3T9LUdYuEViX7qLj2DZ\ng715DH+aBrvRKpUoP5m+W/kPl/bLJdQWvJjmgiRKJs8DEQBYcmW/0GZhfFQR\nCN4NY9a1tK8OmixiqPGo42W/ro5R3vMsYtMOarOiks5NhXUYeDcntP9hFkaw\nHt3d52097LB9EZk69MRdEoMz2wQUpWqxylgSOkx4eTyNaeGWFI7bvwf7hqQq\npg1yXzS3zSzfi8hA+1vRh//tFbrh+iyqgKExv3NqyCST+VHRVTnYm0cfwV0z\nNHTnhJP4MkpndCVDZi8f53NCyQiIOhyYYiPuEhzk/iS6a/TOlE6HGJmBVeMX\nq8cicXUcA0g1cYhjcoJuLbKzqVz5Tr309BXcCLE5mfT1TOENi6+kTYPCvEXo\nxe2B26/YXiwyy3k/XjwYnuiZuiOYIdfOZo40OSjU8pUU7yKtMgHcAvplPXrf\neWZ7\r\n=U9n4\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDCMc1ck/9PXWywiATfwXk0EY17H4+uM9lwCIHG3VkC4AIgNtV1mxTNdfn/TauZ/omL4CrCSprGHHwGg5s1i3V9R7o="}]},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0-rc.13_1600407580678_0.6819491533571589"},"_hasShrinkwrap":false},"3.0.0":{"name":"@vue/compiler-dom","version":"3.0.0","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.0","@vue/compiler-core":"3.0.0"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.0","dist":{"shasum":"4cbb48fcf1f852daef2babcf9953b681ac463526","integrity":"sha512-ukDEGOP8P7lCPyStuM3F2iD5w2QPgUu2xwCW2XNeqPjFKIlR2xMsWjy4raI/cLjN6W16GtlMFaZdK8tLj5PRog==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.0.tgz","fileCount":14,"unpackedSize":606327,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfZNIOCRA9TVsSAnZWagAA3VAP/ihdAxyxtRrbNASXGwgd\nmRTCFZOq+4WlCq9mkkfTtI649uFmm9qDzP9x8TwjyTMLS0i/GSOwBVwMqv+l\nK10C5Ba+9mp1TuNOU6XaFA5SWiHPHkmYItdOGgCOcL7hvVwsESqKs5xD72Ib\n9oMgfdrLX7orlHxmeSepxLB+O8yCa7/TIUPkPSIaAq3xJcZPNZBgFGxvXMRc\nTp7hhHdM9nQlbzf/ymFfNpurs38cUDIfH+rsFE9EZkYDZn0PMualhIkExXZG\nrWAChuCBrNvKhmSFNqNAHny84rBk5bsca5/NqXFOwYKS6ntUvqRoO76PRh4T\nR3LrNU+oIQBIzvVMUaPWiY7OShz8nd3dwR8XiN2PIHQkwKHUBOud27HjClV9\npfCgFZXQnZuBbHn2IX37ewdjfl8Dcpab/d3HEXd1x2oJi/p9/WvBq/AJj55T\njrH29j7qygQr9iB38QIpyi7dUolST5f/xox45080OKKiT3MPjn86Fh+oqbsF\n6RRPPW8Jvt3p8M5OkSI/FVJhdsp7fb2R22n3L8XxA+PBo2GMB5UR9GwuSjt1\neDO2pNjMLpSMnkcW2JgAOyzpfyjWUw6s38drSjkGsAwYsJMc4PhoE9NCcddi\nQtZpWoU4wKPcejQ0UJ48b2i8BtRJcUkZUZixYrEMtdPwWb1tF4Dn5BW7KpSE\n5YpO\r\n=7mi5\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDqQPimcBgDwtaBhP8g215xkmSRbeKrpZ/HbnyXaW3r2AiA4IdGHwUEZoUH2Gw1cF9yKdok7ErBW4Ivq+L9nbLiPjw=="}]},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.0_1600442893636_0.5392155667507865"},"_hasShrinkwrap":false},"3.0.1":{"name":"@vue/compiler-dom","version":"3.0.1","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.1","@vue/compiler-core":"3.0.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.1","dist":{"shasum":"00b12f2e4aa55e624e2a5257e4bed93cf7555f0b","integrity":"sha512-8cjgswVU2YmV35H9ARZmSlDr1P9VZxUihRwefkrk6Vrsb7kui5C3d/WQ2/su34FSDpyMU1aacUOiL2CV/vdX6w==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.1.tgz","fileCount":14,"unpackedSize":607869,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfiHrLCRA9TVsSAnZWagAAtgQP/jBLophA7yv0O8mPeQRf\n46foXPgApvnZtmgWlRuQCZ9T3HC5GinWkzSs3eDQgHp9ecMEHXIO0kvtONI5\nORZNShIHBy2jRMWwBiC/beHplZZG7/Og942GwG/wg5OMETzd59Q6MNOPY1fX\nrqQy9CiAtUmIXc1mDzgm1MVuB0H4xMqovMM7lvslhIkui2N5VplmDDrtPhRg\nA7lgMTBQzGMXXM8h3BwjwFzWZmH3i9XquGJOPAzghvlx042in2B0dtijHwv7\nDdSl+qqy8wVpQ11ziFv5Jt7W1Ki+njlP4Gj0L1wzjKD++9YhF/IPAikwPYwZ\nEdM6Mp9dbYWK4oCURTiFtCfFUUD76XWgyuPS3yrL+VaCSYV9SPOSjge0T4d7\nd0VN/t2FD1aASLq+n9OLNyCm1etG3ihPdhqTAtKLfWjM/70oz/hgIcPDijz8\n2k72PRQw2/AvXMgP8WJqNSOTCmMSvg6LIYSfVvVsL2azEiXVyHDE/W3Qsb2+\njyEwqyTi2KW0KcWADtGuNI02GfeY7SSaUXKrk16clMXJtWCNfS3PHBYhI7Hd\nIzHEmcUNt5VGFm83qDngLA6q+0N5bNlDZJbxK2PcYx3oXqJjgCIuz1ewAyxM\n+1z8cLl0GltfWss7gqGfWvD6pozxpkyM70XQ9JGv9xtFYtfH3/AWtjr19tV+\n9h5J\r\n=m7a6\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDY2BIqd+DPSbsAUMGQWxWefY+9l+LGgwt0ZvRQn5RqoQIgPlI58A+MmoZyROdXhnOYMshDx9eDAKkYcQZr+9uqoQ8="}]},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.1_1602779851003_0.7101688713087979"},"_hasShrinkwrap":false},"3.0.2":{"name":"@vue/compiler-dom","version":"3.0.2","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.2","@vue/compiler-core":"3.0.2"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.2","dist":{"shasum":"1d40de04bcdf9aabb79fb6a802dd70a2f3c2992a","integrity":"sha512-jvaL4QF2yXBJVD+JLbM2YA3e5fNfflJnfQ+GtfYk46ENGsEetqbkZqcX7fO+RHdG8tZBo7LCNBvgD0QLr+V4sg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.2.tgz","fileCount":14,"unpackedSize":609878,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfj0d3CRA9TVsSAnZWagAA/S0QAJh7mDixN6uBb+8P6I7R\nleYMUZwwRtWElyn03GZ4jCtBxuIzm2CZ7BgwapiwRsj9qRIbV4VwWhqZrBpW\n+UeORFCzC0nh37WRU11oOP+S0wKDenjqBTjC2Hcc8HiF18YDYpBVNW6H+js1\na7kQLOrtON58IHZFGPfINvyFXFj8NCUapvjYHEYvQrexaRbdVepEj1aM7WuN\nsg0KbuPuoO8pCwK0aO7f8iIWT8NJdAyrk2+NSPGytCx6dEwEPcCmLMGWkC80\na0OVQFi/vBHi12TE8SRZbOz7FunD6T3aAIdAhMmD0MujADpO5fkpakZTZQ3N\nVMDIzQqIKag4j3K7xXfZjIxzMibJwH0X8787yK65Ca5v43PtuVM5oMRwRbDx\n4RxL+QbbdAFDszWNcEXRl288CHKpMcP18TpmcdHcR0gCe7NgDaJI9Np07F8B\nYJMRV8+TlYRMOwaVO64I3MKp3AR570EjS8PH6ir04NYPavVCp3W9zV+dYlU1\nnaJ1Kn+DQM9K2rImfLkirioFSX9V17w2+Im0JWkiR3KgZ9gXW+WH/8oS83rc\nym7limu/Sg+0tf7jkfv5J5XrBr3w7T/w3RSAnJqDUzdFHmsdf/EYIKm+wmkI\nC9WVvYdpk13K/JnsDU2fvRvh16lMZSMEKhS+ZayeNsQKoFHbIGxd9Znf/baC\nwBE2\r\n=Rko4\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCJWPETG0T8RO1RlZqbplouo/IQ/kgXuSyFSA2GfCcxEAIgHkFFt/gDxmtb+dODINixlXaXRHAzWyKD5ozVF/dDyrM="}]},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.2_1603225462383_0.748476085960116"},"_hasShrinkwrap":false},"3.0.3":{"name":"@vue/compiler-dom","version":"3.0.3","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.3","@vue/compiler-core":"3.0.3"},"readmeFilename":"README.md","readme":"# @vue/compiler-dom","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.3","dist":{"shasum":"582ba30bc82da8409868bc1153ff0e0e2be617e5","integrity":"sha512-6GdUbDPjsc0MDZGAgpi4lox+d+aW9/brscwBOLOFfy9wcI9b6yLPmBbjdIsJq3pYdJWbdvACdJ77avBBdHEP8A==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.3.tgz","fileCount":14,"unpackedSize":618243,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfvoNfCRA9TVsSAnZWagAAxnMP/0n72LKxDjJSaVuRz8HU\nv+1E6AHP8+0hxXSLgPOqPuKC9CyuaHReBYhUr7omTdab/9UQ9Hu8CbGIUVNq\ngt5Rn4vHaenk+pMDhCzlFBNMZMbVzUf/Lb3Qj6CQ7ZSRmbx72kPTCXQnEZ95\npfJhYcF9+sDRddEZLbqrozLq+k6la0VLxWCvHDfQy3SynLAdCl638ycAR5R6\n7Le/8TIQTzqN0OzwASOQhSsqr/Bw27SK6DIkBplAWFVXvLwZZs/NbvB2BFxv\nwJuMgzpKnawv/EsB/CQswsXejmi68+Y6kbqByWAv61Xf9C+AUg2N2wxaI9Ai\nWKrb1wHmPLSDRpXmxp1w52nosnWdPCUrVRDIO3DyZAfv7og3Uj0pToczAUbE\nk+R6ededjXkOO+HBOnE65yGuA6mdiqyoMsYnSrs9umuJ118hEBiBHn49nrB8\nRpVaqgAvcUeq303jLeJ5JMX0+xA9jFpcZPqCc9/aI0fnF0PRWreV1HKuo1+9\nAJUf/n3m4hEFg0QOEYcwN0y7FzngMUuhQe9OSaFxtULxhhSYy4Vd/L/zlZTK\nWl07pGAWiqsT+3A1TQy3vOq3XStoY4JFptC6FvalHn2cfTn5vjedwLtRY7B7\nXJkFhjO/GN9RialeqbJRrrc/i9ED29RYyR38HvV/o7Rax4HkUd2QzI0Gt07h\nQOzN\r\n=/Etv\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIETMaddZgyrsKly5suaDbFecaaUohYTzbHSzxY6LHMuQAiEAnokxDHDL7R63MDYtaRuQyhzC2cwPImCVSD9JTp2sys4="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.3_1606320991401_0.1935287729557118"},"_hasShrinkwrap":false},"3.0.4":{"name":"@vue/compiler-dom","version":"3.0.4","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.4","@vue/compiler-core":"3.0.4"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.4","dist":{"shasum":"834fd4b15c5698cf9f4505c2bfbccca058a843eb","integrity":"sha512-FOxbHBIkkGjYQeTz1DlXQjS1Ms8EPXQWsdTdTPeohoS0KzCz6RiOjiAG+jLtMi6Nr5GX2h0TlCvcnI8mcsicFQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.4.tgz","fileCount":14,"unpackedSize":612906,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfyBP5CRA9TVsSAnZWagAAprMP/j2clAIs5ZJ+tDFTzY7c\nVwCdM6ACCrrHvAMloABrOj1XlbHOKUVUCK8kcwsle3BqW4xD6ylfXjyEtOZk\njeCo6h4pvd04WnuqGPFjmgpTl+f/UXOGL+0fNpLZ3xjD2tubAAAGRv6GB2Bf\nHU316aKKpuIO0Js5+p1dkXekklt4DnPaDvHCEZbXr+ZKIhqiwpw+edcsA0Bi\nduG0/IqDmV47Cwc1TuFM/OclfeIsrU6Fw/PSmWjD57oRxAvnC5v+ZDzAnGQO\nyjMKcRPkHADU0nknsvP5a/OETRZ0nxoc844cCy6UjKsq2807FZiSLB/0bUeI\nkqFbH+egt06atsb0TDNJ2KC2fzN0MXwNHPVADLac5SXpDtjqADY0NboejHf6\n8M9SqZkDa3T1cPn/blsFbTVAV3xko714/qeIbvtS86IePDTbEBAjaMDUo6e8\nXBEVqNKHBA6TfZDlsqTkctZ+t91jjhlLoH8zO8K/5GF5YtiEHL9GjNZKRiA5\nWFt0j+sFBUPK1VRRoLp3GknT7ukFdGEDjW1NzH5650F17oN+M+FNBPov7OGf\npuHRZeufGfJ6Di6F+JxDDxX/NZcopKuTKxkHMpZ3cIQHQqNlxrXJtTCA1Bxu\nc7IMJF2b0PEr+MmfQPzHS2oySblfWZCj7o1TAb+3hIf+Mt0dMj6k79v7G4KK\nuvdL\r\n=tNbe\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDD3KGXC+7rAE6CMCLP/XnIQLNjDTaY5ifXI3P5a96cjgIgYWwWbVPxuGNF71vlYTKCqAzw+9vB2tGRXS0SrVLEn94="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.4_1606947833083_0.12669228509215036"},"_hasShrinkwrap":false},"3.0.5":{"name":"@vue/compiler-dom","version":"3.0.5","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom/global.js","jsdelivr":"dist/compiler-dom/global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.5","@vue/compiler-core":"3.0.5"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.5","dist":{"shasum":"7885a13e6d18f64dde8ebceec052ed2c102696c2","integrity":"sha512-HSOSe2XSPuCkp20h4+HXSiPH9qkhz6YbW9z9ZtL5vef2T2PMugH7/osIFVSrRZP/Ul5twFZ7MIRlp8tPX6e4/g==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.5.tgz","fileCount":14,"unpackedSize":613264,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf7OgaCRA9TVsSAnZWagAANrcP/1R3v9XQRjk8oB/ij5w+\nx6jt30uwgqgaHqpWirjgg4Pmu5eTJG1f/RFT34ZzIj4VRP8M4LaGOTOiMlWk\n0r6N2hv88gaNY4S15IviCnH7tk9fGchvt+XAGKhobc0xSZcqKAUBsCNyI2id\nsyyFp37wp4V7rqLL6fcT8pSKru2WleoZrKvzybZ/Ok2b27h82xnjkMGuJQzN\nJBvcOY1NepiE+91SvpGi8BS9F3iDqzXD1rJk7Ec6nKa/p5GDJOCAFeOFhPWP\n13CxXNQVlghhr8fyXYCIFiT4Ye1bKu4U4QrttzVRGNB79m2/Q3p0OL/cnXXG\nrBRT5PRSzIvaH8GKQCNVdgLcqbcOfew9MuCmKwf3x5gAaStVGuJWa/ghoQ2+\nFazbUg2fzaHyAX7T3LwZZ1elk6Mf5l57UygxmApgj8D7uwwQnHD6qa95wwEB\n1d+wYffUGkFocWDrQuHzzPSSpZH23PGJSwsvP2Cyw80QzIhTyvI0LoIKhGEP\nRAyy+eWHm6EjOqeDmIHtAlr4ZQH4VHzb06GTg+yEHtmiV/M2DaipjE/qu7cj\nZapa2i6Ar107Blx2lpLJWf0rDcXnKt7nzHOSHI+tAdPaXOPP9um9Upgr6dey\n3rc4BZF4E30vJa7TXPZ4MkBw/4M/ILrWq5D5/1QehbATkQRvN+VHG+2EPdTv\nryGf\r\n=RcGi\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCVUhl8dCNISiDTL60H4synw4qsrEBtzN6nkV//Ee+s0AIhANoPGTt86Uij1zd3YtiP9GG/jbhTzKxMj2QYs70SmlGM"}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.5_1609361434367_0.5130625806318532"},"_hasShrinkwrap":false},"3.0.6":{"name":"@vue/compiler-dom","version":"3.0.6","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.6","@vue/compiler-core":"3.0.6"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.6","dist":{"shasum":"f94c3959320a1252915bd02b943f96a7ee3fc951","integrity":"sha512-q1wfHzYwvDRAhBlx+Qa+n3Bu5nHr1qL/j0UbpNlbQDwIlt9zpvmXUrUCL+i55Bh5lLKvSe+mNo0qlwNEApm+jA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.6.tgz","fileCount":14,"unpackedSize":612919,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgNrTeCRA9TVsSAnZWagAAJdoP/11GIDKLPC0wyaAezJXn\nZfnh6oXnbzJ2sVnD+r6I81E7I4BlRkoOgwz4HxOfCL4VjyuuvJE2Jkn7JhOq\nZsifRgvT6LOyxJ5ekKMjO6W9Bm4nky+Vn5a5BshgXNpbnKWoqEKBDxjU0qzu\nCMOfBNLqSbC3+cDtJXu3wVXLjNaMwC9WLCTc9s1dmfaxRh1qB1BoRNjVR+6C\nxiM95KFCzuf2/EzOzTMHFqZWBQov9bmyRbHgyAn7x3dFrbuKY5cV/m3CUBEP\nNFy/60Ia7gRRFSHPwDVlfhhfy+QiGpN5m8B5agYCN3pq1SzNRu+LMqecR1US\nnzY/7kgnwxKiDAd17xJsUtoLUKK/GVhlT4dHcFhOyIFRxRKiCVuydUVR27rB\nKFx8aw89DDizQ1jIjQMOq2NRkaCsLs4ujBGLPhy7RJWCY6a0cEetFZMI2+3I\nOvXpndZ4kSD90PfYovjgL/l7C3Wf3qfulTJ4qi3I8EEsWUiYO19Ylq8rkO9O\nxrEKqKiy8pPKHewwEe/TeZ9mUrtZZJ+79x5l+nbp/tOUKo9HsA5vOm48Kv1m\nyUu5+RDjQidTNqs5A2ybgeJm5Vtz8OJCh/gUlDxlsohZQoxtnAyOdoNpmulT\n7WCAg9OJD7baXCkrf/mfbhiQ8HI7NVhoO4XFL7wbWIkEul4r/GGWocmLQ7vr\nZAxz\r\n=E9VY\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCybuziCOfMlXf7fkTDegVeWwMxc4nkZusJZJr2O2TDkwIgKpEGESuutKb3AfvXhkgpckh4U/sYXqNURbs+p+x4oqM="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.6_1614197981607_0.5602331279168977"},"_hasShrinkwrap":false},"3.0.7":{"name":"@vue/compiler-dom","version":"3.0.7","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.7","@vue/compiler-core":"3.0.7"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.7","dist":{"shasum":"54d2e12fb9a7aff53abd19dac2c2679533f0c919","integrity":"sha512-VnIH9EbWQm/Tkcp+8dCaNVsVvhm/vxCrIKWRkXY9215hTqOqQOvejT8IMjd2kc++nIsYMsdQk6H9qqBvoLe/Cw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.7.tgz","fileCount":14,"unpackedSize":612859,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgPQ9nCRA9TVsSAnZWagAAuY4QAI7ds6zfhyKOTtPOAL8B\nFZq15x/D5ccGHu/7Lnz2SaqMIx1dadP6z28oFmG2KWm09PQl4iGiEhEkdrQU\n6sBN1s4nll+eGBJwkEH2ORApFMTwQgOsBCWqbS5pt5O5Ie1O8muDZXfIBYyx\nRUmc5iao+wVt8hplRTTvejU8OK3Jvl8ONqDUJWtXxmTQs0m5RNyssv7C1BIN\nV/9Ln/8mkPVOhASs/KR8qbJ7zIoafdLJ4/8b+8jovYnVGtu3iGRBjXBcb2HD\nrPtJVG198+Gt+SxPB16Osu5UPrDqPjJ1UcHzTVO75E5HL81+eXXIKcLm4Eoj\n1TyBrqV2m7s6Z0h5oB+hAwGIyT56rjwjyyrv3TGOR7V2cW0zl28/Yph2cx7/\nag76FNR15EUBY6++Pw6+ZscYUGibXjFpSMwvShS45+rTHisT38aRpCJqtHbK\ny9eWoOQ7HAST77hTcgRLdLvlOo7wQTV0fbNzuGrvhhifrmSpxvFq1tD7kp/w\naOaZAMrJ7yDH7gAqH9nW6NmNqcaNULCyNGOZ5mOIydVO9a1GOA7QeOipkAbT\nusjG81w7pve8D9FZP5lMzE2X+QQHVJfqfRyaHFhcImR0kNji8RpVw/orx5jj\ndP590wUi8OufcbHWKtVSsHca2YIRr8B1quu9aoKQdmeV17srQRqERWC1WNRl\n4+//\r\n=RBmk\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCFLa9FePrCSBa4MElj7FQQ6QopIxvt8jiXCCZ4CqBUnQIgQWXWcFE3FrlLvNX5qlIu3kEXIKAfSmvkx5QyL1hdA5Q="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.7_1614614374736_0.7406608480921464"},"_hasShrinkwrap":false},"3.0.8":{"name":"@vue/compiler-dom","version":"3.0.8","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.8","@vue/compiler-core":"3.0.8"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.8","dist":{"shasum":"97b1a56998472247b8944b6ef71dacbdd708eb6c","integrity":"sha512-uMUtpFqWOXlbnV167ihPJehVa/84k5xfTrYHJh2bqKaSL7sA2b1bkhFjTXAfOss9LcrGnQSk/CjOPZGZfExEVw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.8.tgz","fileCount":14,"unpackedSize":619861,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgXlO3CRA9TVsSAnZWagAAhGYP/isOgMcu8JYg3rXT1pJ2\nyOAYXTkxzsKKPlHn7E7hJQNmMUablgBhK+D9EdXoHuK28tHtGyvDEXSYSjIh\nFFZYYi9VO5ZPrneoruQMJ+C/a+tX/xRAcfv1XAopcSez2r7FRhQ21GBdTCeq\nK3HUkshaKUIFC6fGgH4t4UyWUvvAt+7jog3dsJ+VUYC4LPU+DKmjToXZ3Xe3\nzFvgvl3685COtpMJDvNHwmdjRNFpJ3NF1viPydv0Sh9cVK3mPvckzs23XFVu\narJQREDDHx4+kyngsk366bl4EHX9YTJ6sA3MrrusLgp8gaGR35E4HytjIFcP\n5b9mqxxrNPRsJvgdHm3Lb0liSQayZosqgHfc7dGTyYVuBYTwwcSt8c7aCYM1\nUC4QLR/AMGfLwwRwK1pnxX1HJPvcbO6VUjsdJQDdzBOOuEgkv7qzwtAoweAN\nEf1CM4Lyp4MjegyNyZPumRGzxS0OFjh74H3TFVpvvZaLDgQc0Nq1b/pmfULH\ndmd/zzzgeTJMbIymInRaaGUY/0z+ysYOZDpZOpXKWGAiORiFdqAIBH+KN68g\nroj7Lvlk8JLEjrdXTBjnjhJy+6VC4nkunv1zx41hejAJ19MYn76Qc8pdS4x3\n9uAM3lzaYsT6y0XyqLXhyDE9Ii9vInSzKfauiSqojQ/OjaWbmlZpDCBzbFJE\nUV/A\r\n=tceY\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFdqFCsHVvWaoyGK2Mb69LdPHCDQiE+vhulCqIMiHKHEAiEA5O0EXLxSVj3kkJP9daMcBUa/DhrN1XydJsbbty75uIQ="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.8_1616794550962_0.43099927721971376"},"_hasShrinkwrap":false},"3.0.9":{"name":"@vue/compiler-dom","version":"3.0.9","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.9","@vue/compiler-core":"3.0.9"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.9","dist":{"shasum":"1fd554097d9ab36eca73bc6d0d9607fecf94e71c","integrity":"sha512-tkq6umPSELaghvOExWfGNwrCRc7FTul3RLykKzBZWhb87sSESq0XxiKELfBOfEbzdhWg6BJ1WXKDeq+al/viEQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.9.tgz","fileCount":14,"unpackedSize":620659,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgX0+KCRA9TVsSAnZWagAAJLQP/jAsLzOX+OGV02OsXp/H\neaM/+oJciyAbEEdLgJmeQYUbIyfUuZ+IkFvhFLv1j/QjD7caiicgaPPnctB1\nDykPK0TI5Sxwrul4ZfdYcZ4R+8jdq4TInHvAiL1Fb3Fz9Nruexja7cdUI8re\nXSVldRvSuL8zQ6loeGij3QDryqOx3T0BukHFlnnyGWiBPr14jpJDytuS4C05\nYkWM+rylyJHPyjSBM0JyLQGCSrbD80lLvID/UNTJks47CSQoIzG8CS4sP86r\nGnFwDQfa+B11JgH//AHUGLKw8pVWLigFVrLVBggVcci6Oz3rsXo5Py3UKUNC\nBG4XyCiXV1UjOq0V/j39EG0RBknFvhw3sH1Kvy4LAiulJB4B3kbCmqn50ylR\ncYbkmMHxzKjk4z8pp97dlhTaw/uyUhbthhfHd3xe0ckf4p8LeA8GlY3AbhWK\nSL8HCTLjhfa5kiIEdvifjiO/R30+urLwqEJ9QRQKZJ4QqClsJDnDPFBZ2WIY\nJlTjJJj+WGPwCktdCo9IFp1A0ayD0sunxmUtHyuUPCE7FSSj40/mpqW8CmJV\nRrc1NdOfFbMYdffVcwAmP+GBVsGWogqVFAfmN4IBapdI3WvKjtO2I79Fdp4G\nalQ3YkO9s24oEMCcHeKi63+WVTVLl77KdrS72Nkm91I6fbBbhYwGOqJ7lUIA\ni/BH\r\n=qztS\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDvHJOWGlmUyL6KahlFjGukEGGGIStIVdhlM6aABEUGLQIhAIlPyuwYBXfk+qR/0PvOzVhkhTBhkeFqotwnFU7caMfc"}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.9_1616859018165_0.13248002668614478"},"_hasShrinkwrap":false},"3.0.10":{"name":"@vue/compiler-dom","version":"3.0.10","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.10","@vue/compiler-core":"3.0.10"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.10","dist":{"shasum":"59d3597498e7d4b0b92f3886a823f99d5b08f1fe","integrity":"sha512-SzN1li9xAxtqkZimR1AFU2t1N0vzsAJxR/5764xoS0xedwhUU9s8s+Tks2FNMLsXiqdkP2Qd4zAM+9EwTbZmRw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.10.tgz","fileCount":14,"unpackedSize":621102,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgY7zfCRA9TVsSAnZWagAAxjoP/jXB0WbTdzZG+KcTwA7G\nqFh2jzlIeJJujFO98BlNgEbOF2+VERuimVJFWfQNgtqcNbEFwFAycRRb2fwY\nTEAXnuNn3X+anPJgcCCbuVbU5rZcAJ52MbfRgzYK2YMRHw2jgmnGmsA7oQbu\nSaUxgft1J3S4SiSh6Zi+t5VP7EprhbQquIQlzhLUM0qCkBc9yu4Je5zbkjCU\nG07Y22CunMwDHe8HT8RC32/fUxCsgElpfRnXpdQhQRCnCUzJ6RBgVR6l3Jf1\nRnMOun6+SZY09JoN9YsDWSYDv6vbe6OMZiB+q3KOTk7jQHsss6AbNHz8IkeW\n5GRBMSepRk1ft5vBJRNrHyA7Sq5vvMy8ct05YQ9MaZ82ke7YFaUE9TaAEetI\nBc/NAAZoIOUlCJfWbRsqteyB/yLBdm6KriiPiKKFZcDkHuJLArRVSWM5I3H2\n2bQBlk3jpnjbIRU2k3zkHNGse1B3+WfdDdchxsF8DL/Yfa3tGB66KfN2DfbA\nzAnUUURxZ35yz8cbJf8hhwsG4/kMKozKEYh/VACku4kJj+2DUNb+B+WBS5th\nOaWBxRqdWd5G92TinLa9jYFR5dAstxOTJIU2p7yHyQKYUAXSJGm3weZnIXj3\nmONxV/u78Q2K0r4QR8p5zChIlKc8FgMWvFMTV34fbwt/OmegBR+mSA3DNTLK\n5Rct\r\n=/ezR\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDyK3111w1EOdyZ88/ef+D9EfT/bXzzO88y8nC6FyiHmgIhALUKhhU97Vniipi3IjAg2tYnaLKK9OIdwjeAkKY83wjW"}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.10_1617149150821_0.22963152400951303"},"_hasShrinkwrap":false},"3.0.11":{"name":"@vue/compiler-dom","version":"3.0.11","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.0.11","@vue/compiler-core":"3.0.11"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.0.11","dist":{"shasum":"b15fc1c909371fd671746020ba55b5dab4a730ee","integrity":"sha512-+3xB50uGeY5Fv9eMKVJs2WSRULfgwaTJsy23OIltKgMrynnIj8hTYY2UL97HCoz78aDw1VDXdrBQ4qepWjnQcw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.0.11.tgz","fileCount":14,"unpackedSize":621102,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgZlzUCRA9TVsSAnZWagAA9xQQAIEJt8VybPNs8qRq1lgZ\nZ83l9+9mxarhQ64dz8NH0r425gkHmAtuHUaTwjLn4bKs8DmfDsDY42hOxXGv\nO7gpgs/a/9Bwya0oYHi+yG+7xrSo7ETc0CCb9Rpf8mn283wH3xNYL0XLIihs\n8dW8MGbpORSN5AIOcQAK13PRpss4SCx/BQwBWxTsAWmNr+kx9je9wKHpiZNX\nnaGRDCxtlu9rWTpLonHLcXt0ERA60qIJL6ORjPtSKALdsjzSMuO256132BQ3\nUhtb+Aa0PfeM+9cN7CW7qukQRIP88TZMXTTMNyXx4Hzze0L/OcUdR+XOHqe8\nLkaEuwpYSLehm4TJweyJT9+UAS69lmqK/4gQFv0vRReLJmwHyUkMTjRSUPjs\na6ex6mxNJk0h/01JLbWlAgV721olch2c6JW8zntqCgwDELk0hdVOQl8VwDHI\nkuh0aydNn+quqUaICTSdSY0lu68w22Y7dETlA6SA6SBwDshkKuyA3rHdnZGu\nwagewjSuEZVg709gagUE13Wu2QZic0evuoKD8cvW66YdTWoJKfS3Y48OMDcU\nDsL0m/9kWbuk+G++BH0cjo0V7tMHMlfES/sEwzUXnZmCfaMvkUkLvefRIxdK\nx+nFewjrEFgq4I2XB6J92Zl6huQnQhKYB0N1JydlRQ9+JkM34sCm1KdCgLCn\n8Ohq\r\n=qUmK\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEbmNXTEswaC61e8X0VHM8N888a2d+vS5gt+OoCfyAydAiEAzZi1p2rtIyildegoNmZIg0+4BwtnY6tA2+DRrTX1rKA="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.0.11_1617321171559_0.7923987889196475"},"_hasShrinkwrap":false},"3.1.0-beta.1":{"name":"@vue/compiler-dom","version":"3.1.0-beta.1","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.1.0-beta.1","@vue/compiler-core":"3.1.0-beta.1"},"readmeFilename":"README.md","readme":"# @vue/compiler-dom","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.1.0-beta.1","dist":{"shasum":"948fbc867c7e37caf49121c487b15ec99f5f5073","integrity":"sha512-OwOrNdtRrS1e6dzuj7N2veFOMMMfkL9Rqz4UgvwtyrrxDhiJ3CefqbcEVafM2wJNe52I4KnSmODUXxdHGQCnxQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.1.0-beta.1.tgz","fileCount":14,"unpackedSize":669539,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJglvOICRA9TVsSAnZWagAA464P/2/ECaWc48UVRPh2Dk8k\nHCKU7cffBozKH79l86naXsq2w9Y9op/XZpf/okgjmc81IWWGCdKj4xFRKNkT\n6eBrgWuo+hnifwE1PF9AcRiHr7kdscdgFcAmL473/QmjIp3tZPU3zhXCNyva\nn8oQS0V0F2h5D6OV9CnBFbd3JJQWm+gKpJ6ELBmOeZqX65IuW03mWjc2Ptyb\nJNn53H8U0PocFawFYrUYT4GAqMz8gwtL2y7uqM4xXsA6gwT7wNkZ3jFFWsmJ\n7nKHHIsYGxbV+UN6n3fJBJ34nGxK9BFj8saDjxIeZVLFOKpXuP+2/zbA8iHX\nb8A6piH+ixaG/vdVUdGJmKuQK7N1K7EJJxjVkHYKyE3b9DlWm+QEkt2rQzu7\nbOzY4AyKBF4R5EoI+nCn6S7u0XXXXf8oD1VMfFZxvoGC6oHDZnFuErK7ytD1\n0yZNRALLa8NlFOM8dvmJcGKqj3dKIpW4mGD0wDsB+bXUAdpDjERDDUe4oHTZ\n84TVpzxjwBYfzkIQTykjgLWvuL1HnxvJxB6h91FKkCmkW5JEdosAPmvlHJ3Z\nBaOo1cLcuLxuEMtSvjgJXOG2RcZ5Yc6bCYdbgEoJnIUk1Hm9hn+DqWStfiAC\nneWT2elLEm/xHRSogMFbUD4wZYFso64lhgZMBvIu5tL5alEQz0ebxRY5Jjo5\nmGsg\r\n=+pLu\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHfUH+QVcxdgVqr4vO1GSJZmT22r+o7eBM2Ro0eDaZwbAiAhyQrPEbHTYpBxT2DqulHnhF0xs3EVNXqVQUvGptyUmQ=="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.1.0-beta.1_1620505480119_0.6409581602084642"},"_hasShrinkwrap":false},"3.1.0-beta.2":{"name":"@vue/compiler-dom","version":"3.1.0-beta.2","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.1.0-beta.2","@vue/compiler-core":"3.1.0-beta.2"},"readmeFilename":"README.md","readme":"# @vue/compiler-dom","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.1.0-beta.2","dist":{"shasum":"4c415102e20b3f54f733dd47d299f396bd0026ca","integrity":"sha512-FgGCZyaJZ81eCydc6IY0u79DVt09vURYKj95bgQJo07doHW0tHptz9N3zRudfhA0VjoXuRMeDoKHMHuxI1rVHA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.1.0-beta.2.tgz","fileCount":14,"unpackedSize":669539,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJglvumCRA9TVsSAnZWagAAOXgP/Ai5UJcPTpRCnoGwUBdq\n7sRvk6MUql4W12eFly+W1MDOe6sWZd1AXlvAF8FYV7gUy9HNSyhjwSixynd1\nTtP4LiueWIhhUh9XHAMm3a++oT3R5FT8I6HGshyuVEBD9ZAYfCrVb+Ztiwz1\nAxR+ekR0jYQFN1WPb2K/kXa08OjADYEqJ8XebwNEImBNZ8KZtvlLrTu5tGgw\nHkVatH8rvX02UuXv0kEh3VyKhAI6+69JgyArqq+9qdruUiyWOk3JOJO9ZPIr\nkrQnJqySXB468J1wdMp4WJ0Y8o/su/v1vuY3yW+EXl7mUIHzjntTpLvsO5T+\n5F23oGhevtUuLjoeN9lZE83SGAsDIbRi4SOyWbbsiiPFwZMlb4wxu5A9YHZE\nlDmFbD4q5iBibiIyHD8ZYzuj9dxRRPBK1cxiZ+dzO0Gjbzja3XR1xA2ZVXT6\nbzlO98muF5ZZo4eS6yrwFsINmeckD/ioNgGvYOPy1alacIT3OxI8Hr0cbKBG\nijcZkGET8jLYI3W0FXr3H2t/yyHldy5EYrhKjbbWREGrpK9KW7FPW8QYW1iG\nCWkjoZAW4PFiK1Ah6yXEIPFL5O/Glu7+5G04GulI8G1EV3hJ3Q2zjcpuSRbL\n6TE6kXNZ4jbApnm9Mc31QbQoBDDE4XRWrsanBWk6esz8X1cMLk7F8+Oa/0wi\nkcoI\r\n=0/Xx\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBHXLad64Ek1BxBMODSHCcGpCJcHKN3x77BnFXv7ZGKsAiEAxPl+Oe6TOBkQ1MIuC0Jqyv00TNZH1RajLT/dM6iepFM="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.1.0-beta.2_1620507558175_0.9608289405557429"},"_hasShrinkwrap":false},"3.1.0-beta.3":{"name":"@vue/compiler-dom","version":"3.1.0-beta.3","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.1.0-beta.3","@vue/compiler-core":"3.1.0-beta.3"},"readmeFilename":"README.md","readme":"# @vue/compiler-dom","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.1.0-beta.3","dist":{"shasum":"2f17427de9c51046ff6d186f5a8100813084e9c1","integrity":"sha512-eN5fg6WLKauhX/vo7iiTsS7ITUXjkYRWl+KNRz94QeqmDkXKeK0f322u867tUtPZedO0bXnMt35VaBV6swJUEA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.1.0-beta.3.tgz","fileCount":14,"unpackedSize":670771,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgnEqJCRA9TVsSAnZWagAAqtoP/RkZ1wTPwdvOf/fOPofB\natiCP+Mf8NzhLBYpVyoYIQGNz9+XTQ/gLFDdpjH4w7stwpucemID3eYo+UBy\nnQTE0zPNTd1+WcLUIrzRMwB8fElfgVq/SVylvETV9OQ6mwaEhJvcH1dVTv6z\nl19tz/VqdVrr8nBxpodWtgFjxSl4Hq0T7lvYctWxMSL0PtC2CZ4J3LQyBU3f\nphBLMjyT7G97x3UX1xlyCrxLYDcaNmSSNPwjy5xFRwMQaQJukXcW97tlZiP+\nh3PP6xmt6YrZob8U9lcNY+NWgJupnCwLcEsFO47g8wozCS72iQYQMFAT/iD4\nbp9USEIizVoVLcl18xlhPVYAwp882+7yAG12YvdtnyFO1mR0XzlveXBb28PE\nmOAkkmzlqrhHU/qAkdNX+wAL8LpR1HZOxkMbtuYxriKuSboBg8CUpCklhf4g\nLJ+br633LmM1OSEfUEAv0EMpZyPJ5uK6irst/OFYB96EYJK2VkPDqFi8tUoy\nyJSKnnEgk8tFoMGosEX+WImzltXs7mW/NqpzKfMT5BE/VuJ+VzAif1dU1TxP\nmHMNrK8wR7T9hIeothgnCWLGnQp4PdGTdYII2LWpI/F9gD/daAQvIGersC1J\nI38HfwNVVMHkp2ECL7XWahlFbjRwdy1wnHiB0nuBu5pFUNl24KXIGqvQtU0f\nbYdP\r\n=kfro\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCpBzvJsU6k0epDwgEip7A52bXEz3jMiIfg3waTfLxIzQIhAKh1AxgFzPtpueylLYrL/BIioflg9fnUAYstg8ZrMvtJ"}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.1.0-beta.3_1620855432305_0.9296260498663769"},"_hasShrinkwrap":false},"3.1.0-beta.4":{"name":"@vue/compiler-dom","version":"3.1.0-beta.4","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.1.0-beta.4","@vue/compiler-core":"3.1.0-beta.4"},"readmeFilename":"README.md","readme":"# @vue/compiler-dom","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.1.0-beta.4","dist":{"shasum":"2d56d21bf39bc8e57278ecc3abb4c36f971c94d1","integrity":"sha512-D6s1WkunFOANb8gu3F9MhTsF0R0PwxrQAgswY9v0yTKur44vyv0mwaEgQCw0FIwnPNmL15wh5ahtItDvmfkbzQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.1.0-beta.4.tgz","fileCount":14,"unpackedSize":672661,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgrDPkCRA9TVsSAnZWagAAOqEP/3CCCa0zEI1barXCnwH4\neVli76abg5xIN2UFuc8mHal0XpzJ68ztiKXAQhJ2ygmkZBBkIvpwgB1uFLNZ\np59MOTKVL8h0VBtHbQSV2G0Nj6EQW0EKUl5CwicSQRHjbTYRMAzgztX+AynN\nIOn8lztMSY2X6kT8sTIIC7+B7Na00bNA/RpRptAdvef50Vb2SoAxzJN483sz\nN/qxtoOunIVd+xafPu9rte7MPVUaSOsJdHP1lLiBltYT190q9KiIixD9x2Du\n8FKJnEXLBtmtrtYtc4cES0nI8Vix/UU5NbihZfLDGAyGWddbgCqw/1j8zm28\n/fghhHXwmsZtqqr9pAqn6B3xc0GvvgfCHbww34WrlcFnMggr9UfpIPiF10zx\np1Z+tM/k4BCNaop5JXX5/ZAjtG2q2hj7VsKfFehbC6tPLY9FBE+EgAyXWCD1\nQyeqSKG/JAgRKCBOfLUJ3mPWygc6NVGF9vDjWrC08LvSWp+8IxvkdTIN9sax\nY0/Xjz6RhbKpvQyqjFAVaKDMJZzILyXnComLmKdVSjB3UZjVk3PcdhkAXftj\nZQqR4PTUYchGe2IGp8ukLaer4K3Sxso4tB6L/0qnd+CfR4N+OtDeQIobNxBD\nasVaqILKXMVRpsCJagGSY7MOP72Hj3kheksn0uwCNm8KYT3Sb/t1Ws0iPQPf\nPPih\r\n=C0ft\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDJm0J3vbSp+OgVJM6A/P5KltWThU9TcPknNoXO830sdAIhAP55Dubk8q0P1hoP9Wxwc5beb5FCSkXgK94MfFgCWGzw"}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.1.0-beta.4_1621898211613_0.5075950531594358"},"_hasShrinkwrap":false},"3.1.0-beta.5":{"name":"@vue/compiler-dom","version":"3.1.0-beta.5","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.1.0-beta.5","@vue/compiler-core":"3.1.0-beta.5"},"readmeFilename":"README.md","readme":"# @vue/compiler-dom","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.1.0-beta.5","dist":{"shasum":"c0cccdda578845351c9876f28cc4d68e2e021a61","integrity":"sha512-DZTx4UViFxALOEsCNNb44hClDJEV02JW46G3cdCJwakcLE0o6vppgrazF+7zIOV5qjrN00sAQeCf9EbaLrgY2Q==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.1.0-beta.5.tgz","fileCount":14,"unpackedSize":672661,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgrqpjCRA9TVsSAnZWagAA/ooQAKJJWCvlzel0rf2hvnij\nG3scWW73rYHxnxvZY1mKJMMH+QeNenO0R6G3ftH6rIylRlCshPkJjO6iuTDu\nX4496TyzFybjLlWjdVjhmd7TGqXcltQ7fATWbHUnvteDjta3xZNrKWk5mMh/\nn0hmHc4x6WYeYHN3YPSdG6lstoVjAJqEMq2+QmJrlPCCRxmGsshDQ1C6mIqK\nbbH6U4UiEQXTBK+dRaOZ5PqAqljVVvpiXZcWAXjMpCy5sz8r5AnG3LQT/BDD\nQA1R1e6B6EuS0sPSD+TGUq6Pp8FesM9oFUTixR5HFPyC4T29Gyc4/jGWKCLk\n9wZqWjWT45E9uvSvSm1Uq+gfg5jMBmd3UHmU+D01GqVS2Em0Q1Ma41f8iubA\ndDsRlMEF+AWzOFz0Xj1ZOiSa4HXawMHmbPh6ks8PmsmVr/aIS88ySkxM3YIi\nrcv31ovISqLKdfdUSHyem7Bj5QiVWXsz6Pm1pCTNwQR8kOxHRY6sLWNPaTEb\nHzVWjcWI+XErEgE/cm56eV5jiE3rMdoPExc6xqjpVfmV4h9BkHSgPc7v1m/x\nGKudtnIQfR/Bo146qlMoAsLG7IurxxBbScuMkxwbvG/gqzsTzLOGi1R91mfU\nAGeyiy4O/sqMgplgG9Dg5KWHQqrYLG5Z75+h3ItCDsxTFmTXnBpS6uBYDIeR\nGUx1\r\n=8x+S\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCw0uI8cVJmgs8v8VUJ0pguE0LuVEUsRA486oQgygxXYgIhAM5Sl0UL5x/A6lWPbNcSxnpuxyyyfJyR6Oa8E96+Sv5e"}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.1.0-beta.5_1622059619412_0.19451569716209027"},"_hasShrinkwrap":false},"3.1.0-beta.6":{"name":"@vue/compiler-dom","version":"3.1.0-beta.6","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.1.0-beta.6","@vue/compiler-core":"3.1.0-beta.6"},"readmeFilename":"README.md","readme":"# @vue/compiler-dom","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.1.0-beta.6","dist":{"shasum":"ccdc415d4b9078cd9553797fca216e8730d5cd5a","integrity":"sha512-IKLVm8ysBXeAQlxCzaiDrcaXHPf5n56Poy/IO+RRCgOuimMwA/6bbZBocAY1GxBc4zes+GwectRCPMmr/JU0pA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.1.0-beta.6.tgz","fileCount":14,"unpackedSize":674157,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgsVmXCRA9TVsSAnZWagAAdqEP+gNEX7/yDP9kOxYanuxq\nflMYgNRS7LCyOrl9bB4DqM/aerFC9/UqFLHCQgXA9Rr4O63q8Pd6jRjK4K/N\n7nEQn1TZL0og0aBOlCwUJAlKmgSJaaCJzzOLBbYTWAe09u0KqBkybLJnBeaq\n97sPihyiga4wtge3VUfT1ST2sdj8O3q4Ed5pbyHSQMsuvYuLGqoQBBgDLrtg\n8XzXZs406O0NT5g3/+cnBXI0k9NuyOwpcyX7QWKQb3j2kl5y2Cq3lnhJtRJC\nlCGo4+P7yExyuY3GnjCZLTTuT+2ZUCr13NNQL9Ot4Shgrx51URxRK4qPDVO+\nrwnqDDFAcDHNZweqq66o/ciAsL627ZRYhblmVZU1IpoqdrERz8oxsTyxRNwi\nYViN9C1X2JGP+EUC1pxja+lllt4auIAO6i50ItPtypueZ0g5H+FD9TehtvUn\nivjzQ2EEmFvV2B+pbc2KAWdGJ4RKNn9o8wX3VqqNs8csxaKtUxIaHgJaZcYi\nvnQZ4XmoMB8dT7xF8BY7AItgGniroSRdVgSYIo9yKufnt8GhGr/uygNi99Lm\n4i52sQNJqfYHgwL66sd+rYabrdRZbniJQIW9C9qp/bd4VwPQeydQ1fklKmLe\ngWAYgyKsINX8PuYaH/V+VMZ/tgotyox8xFUkdLkk8bpaweALZ2AyaN3devap\nGM9I\r\n=OL4v\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFtTJ1j/bRYd9cVi35zqma65hYayykO3rFvcRYvvWNCpAiA9p2KbT5MhQTnvJPBqop8LhTwiMMLTq0+f400jiuteDw=="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.1.0-beta.6_1622235542629_0.19611174627278105"},"_hasShrinkwrap":false},"3.1.0-beta.7":{"name":"@vue/compiler-dom","version":"3.1.0-beta.7","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.1.0-beta.7","@vue/compiler-core":"3.1.0-beta.7"},"readmeFilename":"README.md","readme":"# @vue/compiler-dom","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.1.0-beta.7","dist":{"shasum":"4daf45d013a036b560f702db1ae92942851c1810","integrity":"sha512-Nkrntjpm2+MPWJuFQmzakwoqSdZAG+CzJt/4ZQQoR+6Q/3EVHr06vnTa8PgS12mTVU3ewjqz37NM2dDG/xCX9Q==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.1.0-beta.7.tgz","fileCount":14,"unpackedSize":674157,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgt+ZNCRA9TVsSAnZWagAA48kP/3AIkO6QX2m1PAGsbM/f\n8dRO6tHH6dpxvlWh5tkjFCanfgwXD6YnQMkApCx0QH6PcyRGEz53EbcSOf0V\nLOsrduFeSetn9P1x9h4hjdVMve8wKpnnFMEvwsGx4A93RZpqUjDinaUAzueD\nnuObtiH8OaUecQBdZ2adE8R2rs4PbX0XunIgLzVV29AJBIxJG1+JqPgDXrhv\ncX5pDV6/NJrCWGlh/Jgkf6V4k3RtWbZaveI4DlQvAX5J7YLQFhUu/12V5LHN\nAdebviINq4wzBmPShcjgNMoKym0LZy90NhX7dQYQLYelu/u6/4rL8uyVy8cq\nkvxXONQhWDgdl7PZY7xpVtauQkCuUPXQleDIWLipRuXQGg6HO2w93uavx4nn\negqsitopDaOWZMgO7ulNyCgzB3FXruywxS5hApBeS06xSVBNP/kHA7/ODeHV\nwScnMKcxhBomVTSithtSDAJNxlYHwAKdwiaE+QC7Fsx70EQ/PLcbm7Bng1EP\nNapdP2xxkOxeui1Mjv4wHkfxFBFmeQuT20XBLI3THsq7gRDOm9e4cI6yBZhh\n1MODfWP6FUldHlQb0Jnj1utC2faxahd+Hus7wX+WX1v8HMdm8UYIwV90eaA9\nJm/N9q29H7HSfEm4x1kat0XexICObo5kKUaJlkX4oLYUzpTZpvcOCdF5DhNY\n61Ox\r\n=MK3C\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIANSxkDhaNoctxzchPjKuXQea6f3VVDUVqsnZ6OyrTp4AiBiTaEvWWbPX2qyZ+OoB/+3ZfVxf/mVLXkUfMiEBr6kSg=="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.1.0-beta.7_1622664781454_0.05574019379782946"},"_hasShrinkwrap":false},"3.1.0":{"name":"@vue/compiler-dom","version":"3.1.0","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.1.0","@vue/compiler-core":"3.1.0"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.1.0","dist":{"shasum":"1a94c04b8759f2e3d1b68c31508042563689cbf1","integrity":"sha512-Nz3XImMHiMpuJjgW1eTG952KkBgovjQ3KL5juzeXgU9dcHnjPMdWtfR3v1GxV5jq8q6IoXJtQIufytJEpBwGuA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.1.0.tgz","fileCount":14,"unpackedSize":674136,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgvkuXCRA9TVsSAnZWagAA+iwQAJ86AhgvvwYKCb8Pup5I\n0dmj9AtpnnbeI3XmJTKS1k8vepUm5WIKOu0vncTp6LtPm+0Ztv1lyQMI+w7I\nyVdCJ37HVOmbBgAYpQNxdRcijGQoWfMsp9Zj7i1HRhbShfJWyNGmcX97Y1Ty\n873eTnP8r7eGVwi+dZYe5Cl6v0bpwHT1xZhtdjSZJuJFSIYqZ5aHfGrLXYau\nRZDKNtjULYziSTjKttMDXZnwWRG+oJM4pGVAMWClwXrlWHnlXGHj/OsgzEpt\nFo/3KwJdpaIRnoyKnDiGroR6IlOvY1+JvDi7p4HB8hTYssDOsYp0vdzkC+A7\nJpTtdrZgpMXvc+BHSi99so3Cp4D8qG4WBG3xCC6VQjkDCs/O8oSBbzfL360F\nENdrnmUimk3HmNdI6Bas/k7ETaKsOA8wOzLzn7M/df0oRdjVbAmKfrz4RJoh\noS5/iT/Kg6PpiiTEx6l/qtn7frzBOjpgB0HeZb8XZw1lZdxqd9ofTEpZIMnR\nRZ4I+TzUKIXtBPS3B9M3CGkpBRQDf3SOhXnwVWBeJd27UWJP3/zzY3zmEhKb\nUv24mCEJ+tPRtGFh2r7KtjMzO62jJwc9eswyjK+bA5ADNXx8Wx3tvz2Lld57\ndqKL63yHxwx0Cmav0USgmTOgN4Nt83CU7zyEJPH+O3I56kEMJiBWH4wfsBG9\nMRgg\r\n=aOmf\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIC3NkyhIcDS3pQDFUhVvU5s0A1zdxlkNBWOJInE18aoTAiABKg9hxUKnxAMkRmKDPBtKzLCTXtO+u9Xamo4/kXbxUw=="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.1.0_1623083927287_0.2242379038168716"},"_hasShrinkwrap":false},"3.1.1":{"name":"@vue/compiler-dom","version":"3.1.1","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.1.1","@vue/compiler-core":"3.1.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.1.1","dist":{"shasum":"ef60d856ac2ede5b2ad5c72a7a68122895e3d652","integrity":"sha512-nobRIo0t5ibzg+q8nC31m+aJhbq8FbWUoKvk6h3Vs1EqTDJaj6lBTcVTq5or8AYht7FbSpdAJ81isbJ1rWNX7A==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.1.1.tgz","fileCount":14,"unpackedSize":674136,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgvoEUCRA9TVsSAnZWagAA2nYP+wcpUfGn89XLkJlQy2es\ny9X/up7n4WMD5rC0kpYyWuJGcjK2Ee1Yd1xSKbOHi+38S3vjuXlgkU7UrdHi\nmeU+keJ6DjJkD+bIsbg8gAwsjUjC/cMz+hGCnjdKxOExS9DEFrtX3dCHQd1+\nQ2LHW69UwUX4NFUmDg0mOKrt24raVyZC4veG3dCZ/VYHrUdRZ5lMdB6Q0xav\nvaNrjgjp3Dx/coydYO1NFDigN+uptCxVX5gKAd/o5fCz0D0u2sosyOQIEFMW\nBbVga6AX1dWoGZVH2d6gCyd07bzendpFqMleVzogjzMAfx+JVmX8cGZizqIY\nkgCumop39bPB8VlPvA7kOoYX2z3vFFWnES1zlgSzMvLY7amK+ODCFeIEs3KU\nXfYmGnQLN+PxLIjDk1CtqMDIZz5/tJuZJoWCD0FK0i8nPnlMLdpjAX8+61MN\nTSQpnJoXmA/mOCXtmA84Yw6BvXc5vwH0IbVxzZMcIpl1EYQQsoh58JEVvlqu\nk/jWjL6MRZjzT7YwMR2PM+8QAVOpAaFL/Rz4ig+wweCj8Pp8X7MoThO2mUsn\nYbbjb/zfDkYHnm7L+6CNxnUv9IeWFuqgYrnovDP+FNHjng90R8G5l1kGWiIp\nePgOKHGio/NOi1qiPq4wZLjTtowDkABzbBCypEjc+VevkUfn+WCP5rKeJshv\nEeS1\r\n=uqP5\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC0x7eNdyAnuUkohrC3SAJZ42M8wH9rtx/hpsWGXn9TXgIhAPdSRKYsB8CJckl64r8hAD2V8tG8Ij+cPnLaJLUPlswf"}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.1.1_1623097619921_0.9516549549069973"},"_hasShrinkwrap":false},"3.1.2":{"name":"@vue/compiler-dom","version":"3.1.2","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.1.2","@vue/compiler-core":"3.1.2"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.1.2","dist":{"shasum":"75a7731bcc5d9718183a3c56c18e992f7c13e7b1","integrity":"sha512-k2+SWcWH0jL6WQAX7Or2ONqu5MbtTgTO0dJrvebQYzgqaKMXNI90RNeWeCxS4BnNFMDONpHBeFgbwbnDWIkmRg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.1.2.tgz","fileCount":14,"unpackedSize":681160,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg0ir4CRA9TVsSAnZWagAAY8UP/0sF7C/IzUlnr11rFQSz\nKfRv9gZz8f8/LC1SfCNhY9ACmmKf+HaJ598+L0I/iX37dOGdMgUbp8fqd2T0\nIt0A2lrRhTqWGdvM+RHL5ZvlD1A27ONtgp+H04VhZ0STbfiUF77XT6TGNd5K\nf39uI7nT83hdziGII6D0zkHY/PBSYFh0vpnBh1cvhmfpCUQMFThyHIJr0CPS\ns4rw8PEK6mVD4Mp6XwOO0QY2ECaVRYbIlp+8s9LZt4Ol6y3k5DUmncv/Jcdy\nFEUVdIlRLrCqEACPQsFoEob8jPuD27YAyDQZJ3MIR6wc+BcbJL0vXa9uVCCL\nZ8f/L9Ow9Q4QvtKHayzSM67SBmEErQkuwXcN2li264MqIZ7r69DH/sG0q9nJ\n1HwgVBASmH7V9ZOZfaLRQFzyT3ffqI8kRJ2sv4T7xw8mHSToK8tKMkgFiqRO\nOF1TBQ0CAR468lsg9CdNoP0uQBnR7m0eyX5M9YbJBMlRYhW+I8UTzeC3giLg\nC+Oo5q9dpYSGNBG2RrqvmwFhQCa2qTGKpK2FU9ASEf32uoQH1h9rjmYoEWE1\nrlODKVcbrQ2dJERiPvfbKknMf5ZoscGGd26oq6ynhk8wE+Zrytquagdm6oI0\njxpDsuqdEFyOOj5PsEXK2BwXOCpNMv6LiJS0HkW/Dq+N8ThiNAeKV39QULbC\ncN1L\r\n=rEy/\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCCqM6pjx5Rj/oYxAYWghzso6UZBtR2fEpnxzh0AN/QIAIgMTNnvPcyACn4NeBtngxxxCmshcWBJB+ZFFoIec34kzA="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.1.2_1624386296277_0.6619654659155614"},"_hasShrinkwrap":false},"3.1.3":{"name":"@vue/compiler-dom","version":"3.1.3","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.1.3","@vue/compiler-core":"3.1.3"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.1.3","dist":{"shasum":"ade4ff7db4b0a197c543dd67b5bd467d737ac344","integrity":"sha512-BunLXKP+UvY1XJ0L6M7KD/De0XP+kOlIxFg3OfXtVQZcLLgnLcTgSK3t/ylvIpYJOadGaHhb+BfCK/hdqOVAyw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.1.3.tgz","fileCount":14,"unpackedSize":681598,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg3k+MCRA9TVsSAnZWagAATYIP/ii185/0uxE22OZDboHf\nFlkOxAmWTWkXneb26uZPHBjI3urj4OvY1X+HP+rKhe8CZ1aXLzn1/7N8Futy\nykCDMiNLz8SucROtJcF9968FAJYnXQlMF7/nFSMlZclMrCfyGy5smufXNmO5\nGVe/bgdnk1KQqjUPvgHCVW2lLrN2YwztD2bg8e8V0J5KkioPBet0KvDg+s1/\nbeCxsaPQBhqBWb0Boncm+31fpABi1huCOPoTHrFpBn0ttoTBjGso2toj9E7c\nPa9/kLoYn+3B9DNBoz8ss8RnBz9BsS1MqE8eue1UkmkH0DalmMIhEc3hS4HQ\nVd4zl+eVHFqKyp/5iUz3XWkPukFNJerpN88D9lsVMG3WxvNTR+sH8mB+Khs4\nJdjyzCogxep1/zZw82304mjsGFX3tx+RiaMzibV++EvybnsIAyRunBGLs1xk\nxBc79n8E8xJURreWwckLq8W3yjaidVVMUGDThmSUw3xCvQIX9o03RQ3Jq+hr\n57CQgQRyziq4gg65zZl9VU7ubQ6e5e4QUyFLGtJplyG/q7LN7ZW+215DezcB\nEH6Hsm+8ESw2Vyvd2Q4f9q1Hnxqr1kA8Y/T0zjIjAtHy7UuH8SqcujCmpRJV\nmZtZ2fbzoUAeVuZ+ygVLg7lhnDdn85Rr0mVwitftPmAziD0LtpTtdQnagc6y\n+O0N\r\n=URfV\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCeVuGZ8T9nYmzrFoZFblfzbT3+U7swajayJJCezOhs3gIgJ2RAzvjqiTY42dSTx993P0OBfm3zOoVqpDRQ9ZDhr+E="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.1.3_1625182092042_0.8190764742970413"},"_hasShrinkwrap":false},"3.1.4":{"name":"@vue/compiler-dom","version":"3.1.4","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.1.4","@vue/compiler-core":"3.1.4"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.1.4","dist":{"shasum":"bf3795e1449f32c965d38c4ea6d808ca05fdfc97","integrity":"sha512-3tG2ScHkghhUBuFwl9KgyZhrS8CPFZsO7hUDekJgIp5b1OMkROr4AvxHu6rRMl4WkyvYkvidFNBS2VfOnwa6Kw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.1.4.tgz","fileCount":14,"unpackedSize":681776,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg3wilCRA9TVsSAnZWagAAX5AP/jHxoxb05WJ3MhCAb/d8\nrz3ZHFGJBr0/ZirigdgV9l+J+YD8kWLcIq4rQH+PGHDNsQgng3o4BYE3DgbS\nLADU10I7BA/mgfbw8FE1IHhfIQMKN0iT4jedk9FJDuPuWkdMH7dYoACqBqu3\nt/2Buf9jeiiNI+qZBwntN5OCENCm6vpJQR/pCeBuPBKfSJ2R9T94sczsg6F5\n7lh0sjP4IYHKNU05NnATSD6bAatyxSvcB88blTz+Cu8YnMPgyEYoF3aRv3Xq\ngcDV2uEgs8dty6cgEB+A8IY66irqgL8p4TTmRbj7az7oLs6f9xQENEWGxNjn\nrvqj9O6jPdJ0+o6kTw3xeZx/fNjXcHllMOJzFXR0BpZMI+acCFMdOboFP/Fw\n+RyIdNJxQNujR4RPPKm3DH87IdwKt11hmSFzMOxwH4Vzh6mmOLDcWH0BwFim\n1FTl4TVYRHxN+SOKAPC1mGuD13njcuVMSxxHRb8L771dA35f+/TyXB3YpBS3\nSlaUBKEZURD8ERo6w0HEVmIIPkAbOfuM16kuO83iMxf/3f3Kd2gR0NHsfRyo\nn+j1h/dGt56m7iIzYNPCjtqrr9XD365SkpdeXMYVNVm5w6Jb9edsVO6GYwlQ\ndc1CT8YWkL1BCe5w+E7D7tIaeVTcvqLbYneCBAZGhtaCMOB4EMsfcHYNLdp6\nQMxW\r\n=rETJ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD97jLkJZLX/wlLmumE/JPnL2FyoMkOqpPPxbiBkw2k5AIgYom+TlfazdQIOWDIz2cDLsAEzi48Lx+FqkH52jDhCM4="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.1.4_1625229476546_0.7035074602802878"},"_hasShrinkwrap":false},"3.1.5":{"name":"@vue/compiler-dom","version":"3.1.5","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.1.5","@vue/compiler-core":"3.1.5"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.1.5","dist":{"shasum":"cbb97020c62a5faa3fbc2a97916bd98041ac9856","integrity":"sha512-ZsL3jqJ52OjGU/YiT/9XiuZAmWClKInZM2aFJh9gnsAPqOrj2JIELMbkIFpVKR/CrVO/f2VxfPiiQdQTr65jcQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.1.5.tgz","fileCount":14,"unpackedSize":686160,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg8bXvCRA9TVsSAnZWagAA9AAP/iW9W620yeX1dMxC2sua\ndBI+37GEUe0iYPnCS6lmhon/kdDYUOvVmG11Xf3BAw6ZiI2BodEujz9dtjaz\nVqJsriXcrK/q21f3+qiJTDeu8mRBJ9HCDTa97IBC+22LZp4Z+UHEKirP4905\nJTjTE7dAi1F/CkeUFHw8l1RaQDAevxW6IeZj67CX177crFj/jbnf25lVEDhU\nBQICGaQMR4MAE4dL2xoh8QjQ3VBm3TkLI/DclW0YVMxb9CO+auYuXSbXfJmv\naHQ2wwZsXSvfEtWYs/Ksxw/elRNptM8at3bzrK3T0I3sTsOT+jjbRJDEqlnX\nwBgveYDBiPKRQ7HBMZqWuTYD+GnCIS1KVpdvizWohcWpeiS8jPU0IHPJVGpc\nQ/5QnRNsSlkyzx4rPhAeD7hnXkad9Z50IM5wUEqFenLFvvAE9GmAmx0nLhNP\n+h/emTlT5pD4+Fg5NYkWnRE+8/W1lrgDZPgA4A9c1YlBRC7BRPcD8eCeRC6W\nyCje483ydqmaYtNF5HfqnTiouMgKlaLGbqBX+CS9FmYLSCgpYJLeuq+TbHlc\nE9R614B+NtqWUCErVQ7mO3dC/M6OUggIBy82CeJgo5P/XKMJgpMpQWKVappP\nFRCETnU8T6Rrx0W4ztTpBSJqpYJcvNpWMyeKKrvLDCKBAatcHYHE0pPVg2QW\nxd/Q\r\n=ZKqr\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGrVa9XoQ7UGOBOwPtPPHj0waDmHclhKrD9jpOKvOKUAAiEApt7oIpn2+DjKORD/aZl/1ahsDFuW6QJuKS8B4hir0YU="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.1.5_1626453486848_0.38457243749140124"},"_hasShrinkwrap":false},"3.2.0-beta.1":{"name":"@vue/compiler-dom","version":"3.2.0-beta.1","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.0-beta.1","@vue/compiler-core":"3.2.0-beta.1"},"readmeFilename":"README.md","readme":"# @vue/compiler-dom","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.0-beta.1","dist":{"shasum":"ec949a65eea9114fab94bc0eb4d77f85e33d36d2","integrity":"sha512-GRJ42kwSyvChpCKlCq1EszFFYnGDztaI9LJnXC+Cfu8/f/xmXYpkGqWYmDByjzyRIc1YqPKffxlaSCvXMnJd6A==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.0-beta.1.tgz","fileCount":14,"unpackedSize":717414,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg8dN6CRA9TVsSAnZWagAAByMP/j/zk/wAH3iOaojob8F1\n4gVF3SCJ9d6bo6sdDsUovekuzCH0W9Fw9QKrXDnMslRi8ju9WWmBVUBSumNV\n+DgJD37wt0S8jPFYaElyYbjz4Mkjtyxfhwgj7KYRzSNMqoJI639jZLrUj9nT\ngJk9Ps8WXYbqN6SlfqSEEFkCfvrnQ8wwmOFdph8mmuV/Y0kfBlXjQl1hca7x\noUt/sdhxQznH3L8qsm+l/MPogVVDL9buEH5XyNv30sXeX0pvq4MnxV0ruqkb\n96g8i1nyMLnO8TyXGWe125XiD9gkudJ41JKonervPITPWeTYrZGbndz5/Ejv\nLExmvbwTvnY+Ym7gbVJcNwujvuOtUu9wGOcfANSG2rNVjuOcYIIKpYWnv4Lq\nAcY6BND4Z0k+jA2npe/N9VOi/fkK7qjtw3o+fp3Ig277bblWFjmR2cqbaJ/A\n0CveBz6igTu1S5cwxCPq8OjNmJmJWEH0eWwi3Za0iAdKL06gpnw7HhzTSDvv\nN+NzSdExouthXovNL1XrG4bCEnyPBd5eCBvo9WTQBwu9ne3WPYWAPba2q9iz\nwy6bNE1lao9v2NtB3u7R6F9UWUPkIoQV8aEYaUrV75jZn0MepYQyvZLvmrdH\nHYq5wX3IIR+ewuLYncQY9By0ReUzMHtWhTloLNDAwf75wK71KXohQdlaiZWh\nrXil\r\n=L6sR\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCxIohJzGfjmbuOUMfDp3npS8ialUds0dmdH3yAg5riSAIgGKX4YuX+GXDeC3UuioDfUdfUuRvDA30UaM/WXnvavFU="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.0-beta.1_1626461050783_0.6684613730797713"},"_hasShrinkwrap":false},"3.2.0-beta.2":{"name":"@vue/compiler-dom","version":"3.2.0-beta.2","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.0-beta.2","@vue/compiler-core":"3.2.0-beta.2"},"readmeFilename":"README.md","readme":"# @vue/compiler-dom","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.0-beta.2","dist":{"shasum":"f8f1744e7766064916eecea34c0dad1736de1fa1","integrity":"sha512-bBA5V3EoP//8934pRS3+TQN/gwRT/+dv3bG/fpe0CveyLB/EEE5KW0dyGy83HYERcNNKNhR8mZKmPB6XyTz7DA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.0-beta.2.tgz","fileCount":14,"unpackedSize":718084,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg9gydCRA9TVsSAnZWagAADMMP/Rh6EcFmgnDrQwe/PmxK\ndfVsAzAcPPXuyzi/DFgzOg5f/rAVavVp4tKkFr3wKqLcARon1s6jucUe3NDB\nWpYlCtdx3c3WUwGep9v+2UngbIKlFEQOqabz/sML+zTcgw8Rb+Szf9cdroou\n47krXzaQ9LKd2bF2pvzsyrGnIpsCuZSskrX1belyLjPFC3JXxNhJv1e8y3bc\nIKNbf6ivIuCYlDlgusvspqxH//yBzeYL6XCsxzqdc9i9hxwJ3BqCPy7LTcZu\nIOL+brcgOLAM2o2GPORNuW9TVk9XRAYmMADYhf1NBJU9DeWSf+EYXYy5fzHi\no235Oc31U+o1Qe7JF1+kUHSoo6sp6dPsYbYKHCOYRqnDWwPWOMxLCvpeMJK3\n8XqSfBc0eFzhrGkI5hXPlGfeYYFIL+q0OkrIhaXaMCD1c7gstf6B5yTDg82K\n6S3dlRGIwRqklKPN3ri2PqvkjnIIsw6seJFXicKshbwBnbVyVNLe3K9rjH+f\nGdGMXAoAbE1/M2jIREoWJJaOK8Fer2Jcq+GIgn+jIh9Y0XbrmhnWl9vr9JVC\nLb5VZmPcQkVGFGIJcgONDVBYvgj9YJOmPJ+SfZ7m3I60OinngYIY+HfB7xwa\nXrXmoe5lVLgPrhs5nCd64MQpkyZdmE324/vQRTd8ycijgiQpmKeo75FWv3hT\nNfBk\r\n=SnNa\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAlLC7zfnXm92bmuiatgUyrnXqBlo5kFoRKUXCwPkM+mAiEAxI/hWYzAJDY53Tku3JjqJFy07/Xb2KeKwqjb6x6eOpI="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.0-beta.2_1626737821011_0.6800894103070183"},"_hasShrinkwrap":false},"3.2.0-beta.3":{"name":"@vue/compiler-dom","version":"3.2.0-beta.3","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.0-beta.3","@vue/compiler-core":"3.2.0-beta.3"},"readmeFilename":"README.md","readme":"# @vue/compiler-dom","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.0-beta.3","dist":{"shasum":"4fc64ad7ce708e2821800200d58f089aa4481b41","integrity":"sha512-scpBC68ZLGSU61W8xUJE97kZFZsrBZwaZtUy59dXFGrlIQtRd2HzyjCrXgLFgvYnlQLXPqaYpo5dJ1z1yNo2GQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.0-beta.3.tgz","fileCount":14,"unpackedSize":718084,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg90RcCRA9TVsSAnZWagAAvp0P/jebiZVYu6MuW0wfc2I3\nAu69z2/8beupBb2McmrzzF6bU/LnTdbZH0u+g8WGBhL/UcNZCxbQolEmB4f0\nqgtzz+vZbiNL1FhBjB/1TdVpGyiHvjnm0ePbpGUh/ETQcCYIFw7zCd6Mpmlo\nWLhpBFlcJzV14woQvS9K3r3wvwynWznwOiN3mAeu/jBG5W/g86jKTh81pbB6\nixJ/k5xZukaD7OIaOzCO1DwECKO2aciLz5bNMMV1qfJ3JhmmP/w+ysXTgC/J\nHfTnrj2IJiTiTqWkKkMNA6UGQtt3RC2uSBlaqMhbElfCZ4tVBpw1KXrtat64\n/jmhlz+ywGGRR6xMcQ4te1OSuLis2iE/+kv40wog070Hq8axRYiadkSueJ9V\nCLvWU2X7PDie7c67OJoLpUt0vhkYkxaf85IiY2cRIWmG4dk67nk896W9m049\nLEgyKeS8XzGxswHtyTYK+M6Yturgv2mn+BWjGmZbBEfdSmv8xlV3LLkIznYm\nSjXCBvhzc4QxW09/B7xCkfoV6ddunL8Hr9NGFAVJ7xeq/nAqEHo4OpvJYTuA\nVOojAXuLfJZAaIex2VPtO32AJQ/NJeXK6OTVlDZV1LV1sAYQ3I0tk4GnU06G\nq5GGRQqMVoG1mgt9peHLT9goDDGCsaW27v5czyBEYckCs/uHbyrgi/qKIh3N\nP5Vd\r\n=/cBT\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDqhEuO+HJgmoxk1EbifzG7b0/LljqQPiHiU6Hpg5giRgIhAOgjv/HVkwWunHWuxe4mmCLhWojVWroNAA3lCrP6BUkJ"}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.0-beta.3_1626817628199_0.9792816104993596"},"_hasShrinkwrap":false},"3.2.0-beta.4":{"name":"@vue/compiler-dom","version":"3.2.0-beta.4","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.0-beta.4","@vue/compiler-core":"3.2.0-beta.4"},"readmeFilename":"README.md","readme":"# @vue/compiler-dom","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.0-beta.4","dist":{"shasum":"1c0bdf84ec2c4db4da32f65773d902e0324541dd","integrity":"sha512-Vtql3zHmkGOfEg6j5NdrofMV3CmkeVlyyzMS3Rg144H98L2QnGRCiRiPhse7TrSyxP8mJtBsq+Ury6M4yi8K8g==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.0-beta.4.tgz","fileCount":14,"unpackedSize":718084,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg+JROCRA9TVsSAnZWagAA9IUQAIAh41zSsTK/PPSZeoVX\n39WFlnsRRQPm8e9FSRk//GI6+d43ikbs4uhlx8DVQ6DE0WPbn0jnbBzydxtv\ntthshKjuv+ORBxuhu6uKq3bHDJnOnbFXyglMb0JFW0wFMcAakFxMtItD0Wdl\nm81L38leGsbJokSoQOk2uhPVaC0ZaymNyG7u82v1znykeyLJcZObxLJIT9RE\n0BiaVrjJwV07uxjOzdLHAJX4G97GtZDeqZTd//jQF2P2T0ICZLSeEXsyoiW0\nSzvXcLHFt5bTlMaQzHEgJ1X/t2y3Aqpn+9eKNNHFDh3RNk940jz/hHzkkZ0g\nSnph+exQy5+Nnpl84zRWBvPccLzoZFS4BwLFsVvauISkh7SjNiaDRS8edCUk\n9AYEL3bRl85N+FJmBQ7u/nocXGcIv8YFV5y/GL6TOwJoYs9rUiCWwZWoxM7N\n0OuOT8mEoqIBUsUo81wcOkfWmdcI0UypGDvQbHMONVWkFd4qrHoLHcs2axZD\nAoU+4MPP0Tt61UB2rrqU0XN3pbGRKJIwTG0/5d82+jDz2LENO9wFreQ5sXvR\nq7Q16sedQ6JcfReGLttfcMVpdGZyTIDUHVSPOczHknaQCoakIbvUxEVF29T5\nt1k75knhaa1tC223NQJh3vY9kjN8TyRdWOPXkvpBHCSC7l5bp+ysv95PdpWU\n3Aqq\r\n=ZuFK\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIH6lNwaGeIS76HfX5Mt278pmKCYK/4uLk5oqBi5ed4RAAiA95fSZY4X0V4TZvx4ShJbF6XB4HA6S6EUQtZ/u17Xp9Q=="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.0-beta.4_1626903629996_0.09381574460954956"},"_hasShrinkwrap":false},"3.2.0-beta.5":{"name":"@vue/compiler-dom","version":"3.2.0-beta.5","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.0-beta.5","@vue/compiler-core":"3.2.0-beta.5"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.0-beta.5","dist":{"shasum":"e43c25166c2cd94745d06da2786d95e03a4a6180","integrity":"sha512-1jdWiXyPAvNh2FXkh2nm/uYFQnmGewldVAeMaw2l9FUbRtFc9itwZTAh/7Dp1xTIRqXoJ1by9xYaAsawJugJ/Q==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.0-beta.5.tgz","fileCount":14,"unpackedSize":718084,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg+yIyCRA9TVsSAnZWagAAK1IP/3M05mQ508StPFgpwzfE\nk3jHCsy2rzytBG+jUz3epiUOAKSY2Tbrqw5T2dql3agj1edcTb7F46ohMubn\nQmnucSlQETKG29Aw662eSVpPZz1uhK4/LfZu7Epqa4QBHevzqwBQs/SS1ztV\naTQRb60YliaKp8kFR7FYz3dnQ79/XyYKpgNEFqIRfamcbHAoPqkX2eZkreqm\nIw1e21+paSn6BWqvSdL58RvNjLi+NgqDF986aBecyhcGDtuubAvlj+E/VSAp\nfEe634YmCkUUNnjFQK30Ey7gBQIkkkQcOPNB275PmTyaf682QdOsduepi/iQ\nW8GHDgQKtnznP+5HbexqxMiyTeyTfWnl/Ncr2JMLYDv+HSk/eFAau+oroivE\n7+tv4CNQ+XjZLsHIyvjSnxOApUW9RLXlV5is7yEAZkajku1xJgjw965qM0Ku\nLhK8GiFljKm2MrK7AMW3o+L6rZVrERiBO6gfLcDWYrs5Y0cfuL48MmRUGxRX\nmP/8eXYuztUOVcWRKksevuF94a99kU4xGUfKe54EHoYb1lMwbXdRV1lo4vwW\njhubi6t9hiiuSGH6umydUyyd3gmRJ4PD7Wo1UV1Do0RmJL39QHRg02AMi6Dy\ncdgjNUeAworTQcKfpdxdd4cjPK9OBCneJVfvzV2M492b4Lo6e+JDi7uByuw8\nm5u+\r\n=E7WD\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFlOMgkpevYo7S4e1M1l1n3XMaLxIzrasUtZMjfqnLS6AiBFSOpEjORa4DKnF7mEgaEIaRVV+sgWjEMwufmw6b1kXA=="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.0-beta.5_1627071026267_0.543717594910158"},"_hasShrinkwrap":false},"3.2.0-beta.6":{"name":"@vue/compiler-dom","version":"3.2.0-beta.6","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.0-beta.6","@vue/compiler-core":"3.2.0-beta.6"},"readmeFilename":"README.md","readme":"# @vue/compiler-dom","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.0-beta.6","dist":{"shasum":"4d3c1221be1fa8177600d9e4e71fd84af82c18c4","integrity":"sha512-ThSXPhFzanH/XW1SGZ3I2r5x2z+DcXP0KO7TvTvgcTvxQ/sZod7WTj55uFjfErINcjvflaqLLoHVMtGBWnF/MA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.0-beta.6.tgz","fileCount":14,"unpackedSize":718084,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhAI8GCRA9TVsSAnZWagAAoZsP+gJxz+3ejH94ivL4+B4b\ncnc8LFwqJIomOXODzJpjgcEkI3jUThwVIRMmyYlHSGlzeAEopqpiA0aWsr8I\n0Si70+vKRKLcUJxtkllQeBg7TKuCLVJFEhzunwGqnw07fxUoC8tCZyYZyptp\nE6kR8hnBPbGn7epKnMbGBj7lOeLsSYFzi4YHcuHpzD45SZ1OGuah2g/byGaQ\nQIXrcSkOzcLcBFctP2/dVq9MKEFTdnFZ3C2BUx2F8IqE5vMT2AEWJWUdgb86\nod2Nds/i4foLC/DzkHfrIIuhmbK8WOVfe1y/jg0fbYuxPINIou/ovBp7u8qq\nZSodw0p6zmlBGeD6PG7rtl0KpQST9n/bv/kCAhL62aM5qOmfXKReUcs+McDi\nltoAjpn9Uncu+RR5vHHVWuynfuCXelsVzY7bxEPhVKJa8XBw+FDkNrFsjC6r\nNNiWetAFKMAeEMmo9juYNt7Cs0VCbVEbgxlT4hVpIeViGVWw6I1/vta8O2wt\nqT+hgGAN0AICPXiz31GLM/MU/OHMCpYyH3IlozItomZ+9ZiX/T3kndLfVeUK\nhHI/gZv4+RWEPprrZtMpasWume92OX2ShxQDEwc3xeMfTIOpLGBLK2JehO2M\nE6sLb/A1K5/t6nksw0yUUH3DdAhYDaZd8Fe+g4wjXFoBdYd2i31cu/Hh2CPz\n6DtX\r\n=oIIp\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHoPsEJnOWiHA67GXpaSSnvNdo8TXG9Jz8WzprIO8+g+AiAHy8lK1bsTCGFgKZXkoJc3wcCAGvFQzeon+aEaZA3ENQ=="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.0-beta.6_1627426566176_0.4390446994764601"},"_hasShrinkwrap":false},"3.2.0-beta.7":{"name":"@vue/compiler-dom","version":"3.2.0-beta.7","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.0-beta.7","@vue/compiler-core":"3.2.0-beta.7"},"readmeFilename":"README.md","readme":"# @vue/compiler-dom","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.0-beta.7","dist":{"shasum":"2099797206b5f773e949801dd1d6a3bd73d174ce","integrity":"sha512-51gwn3EaaNs1XI6D3aoPDuDmS1SxBb/HVlVZwlEYDoje6UeF3lx9M6pXOM6CoMLiFNat4CkwqQZu6SghlY0PYw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.0-beta.7.tgz","fileCount":14,"unpackedSize":718084,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhAuOfCRA9TVsSAnZWagAAT5wP/jZXm5mspu5U0mNBjX/G\n4mfmstfhNo+FIc2CULkwKSUgTIfQycRoFRIuI0LvK5WIwoIxl/RjdBR5Vg3S\ncePjuo0Nr0UlvRgp+HfHFMvLril1MzqKLTUHwxd4vDor+RmMpDZByTO+rKH8\nCO8Go9MZlaTClzJJ/m61pKczRobm0uS3TpXD7/vr9zpTcBZGpInA8U8xTRYo\nK9LGVOCSFPAsFstXzbJIfHHCvV/xX5MUc/6tV19iCEof4qecyrqpl/lBNqSJ\nhd4VvxLfOYAf14WBmd5mvXqyJyR2AzjuAzvp9Syk34m/3+26FnHxrNZJ0l/n\nNXnGkFfer+U9EJIvYrxc7e3p+M5pdiyon3fPYF+QCtHyQ9i/uKLeuBwMpux1\ncp/OixKgoSA0OuBdWjGRDQS3WEjJ+qIQUqUvlcewCqB3lBLbgbBpMox7g3GV\nEqcVLYMHmAv7nbSmfFnXcFp/Up9C/rJ78JLO2mCjg5b/hIygyC/DQOvhcE/x\nV1J1r7wuT85VZx9WRZu+oyfpfVzC3RdTmYuFfIwrSoqXqQz8orGEiiqgwUGV\ny8gEiZ58SN06LFEotNQjjLeA6JQVpHwhx/eFQiDcQ5kwQ+m/3YHyw33bTLfV\nD197GVZKT3o6GxEOMWV8pK5uvHJwmJDPjSUzeFfEYLUCsHDxDPwS7yaTSdVA\n0EcY\r\n=rJJH\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCtYqT7c3uAabAdJepAzKn+VgCWe5udq8lVwBzJSVnO0AIgMxlzCWgkrxmKvQR93cRuUbZekwct3mphXJeBTLpkEDY="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.0-beta.7_1627579294946_0.9818799524838366"},"_hasShrinkwrap":false},"3.2.0-beta.8":{"name":"@vue/compiler-dom","version":"3.2.0-beta.8","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.0-beta.8","@vue/compiler-core":"3.2.0-beta.8"},"readmeFilename":"README.md","readme":"# @vue/compiler-dom","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.0-beta.8","dist":{"shasum":"998dc20a7aff0b34e197c1d7b5b54d5a7ba00fdb","integrity":"sha512-A2RwLyUkN0jsC0fx/VOR1POzN64ZAzSFtnkhhuSs81K7MsIW0OgYmmFutqLJiycTSBXEs+yZ6J9cZPBhcfPxeg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.0-beta.8.tgz","fileCount":14,"unpackedSize":717740,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhDfogCRA9TVsSAnZWagAAaNUP/1bZN2H4N3V6hqVoRaU1\ntvDSx9FbchFglXC9WuZ8kBI0EVqSbCJb3KioQLLdp2zLnTn0Ic5/hkK3eV8l\nFTqUZdHyuNGLtP4DVWLXSLQ24L2RhDF+uJvguvAilPo2hKLbKBEzPQXdsc3z\nWEayxLJcCYLwmhe/D0FofeOxBKtI3eaFSiakJ+/ZRen15h7IvWTLKaQtur2D\nYtzvfwGZTrJm32XRiDwRfKkpl/nICgD4w+5iH1lMoLRiHtiKJJcHJol8XzCB\nElG9VKhJU1xquUBVsrQSWX6jAqrAA6jnMGEcpHAzfI3qCfIaOZSxJny2nrXq\nR1aUkuJ3IHdhF93gijxsT87j6ilE5xbn5UOzvnvgGY7IGoDJCZqxL00BW/lJ\ny8Osk20q5mQdRAzt2juWL3DSAqHO4C7eEaaDaZWkpZpJSChqeRzmcISaUvSQ\n0vVSGDkLdikvk/wKsPaDfDOJB09HtEhzF0KRwyU5ZU57x+XkHfHWPj7z5Uok\n3YmdV4QW3vXytoPesv3jhpITqn2CUVfy2FQih1b/BYsXaoMGbcg972Aj/Mqo\n1IFzMLgVZN91HmQEQrAmE1AdNgZtmMa/OhdXQNObg//h4TP2NlSsGFFAnG6A\nm5CPXect6x4ePP/TEOaHTXO2Ydkt8wZAlxXb0ugJXxyew9e2R4IEhi3cCLDa\n9cyS\r\n=h2vu\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHZ5VuhrNrN0osuTk/PzHFci5veMSNPcGLneAIItCgrwAiEA/VcBz7+wAKXHLyQqIuSbn420wDE8GUYf2RYPEX3I7d8="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.0-beta.8_1628305952320_0.1238722571054327"},"_hasShrinkwrap":false},"3.2.0":{"name":"@vue/compiler-dom","version":"3.2.0","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.0","@vue/compiler-core":"3.2.0"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.0","dist":{"shasum":"91bc35afddbd634b186e6da4c594f5705f68d6bb","integrity":"sha512-CqfATmX04+58LNBTTUPRBLyYGLP0bxtL+8b7B8pEvXja7fpmxiYcKBQsdaXfyqoRJsaTzA7eVXQt/t0dYhu/SQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.0.tgz","fileCount":14,"unpackedSize":718101,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhEYdeCRA9TVsSAnZWagAAG8wP/3DX62M6qPNOBkB8c+40\nQId+Ezuw2fhxj4xvv8pYSbVlda72k4S7g8vTN+s7PCQ8EF5axJVCP79S8Lf6\n/C0JwgShAtM2msi4G55QsMBslbZ5igyd1Hyho8L3BmvnXCqp4AUGzZWp5pEz\nFsQiJn+fhGoJo8OkmisblktgV3934XHxOkr91ehijsuxFfVAI62BwiXpdN/J\nuFICuUJbrG4i3YdrUIBgOAROU0Aw+a5LWxEI98X60CYH5gOiS5WFU+tzfozY\nz0pBEylSLdHRh7L7yHV7TYxG5pOjVwuZ5Vvy9Xz7gSeJollBDc4iRyhkFdMI\nqgwmDJLdEbpbPz0GiwyC8EKOcYP49i2TB1MUNKbibfvSemGw7U5xhaMnqdtm\nDL6V3wmt2xbEUCnl9DW7BhySTZR+l832fJkeRClHK3BC7XblmTudV6qxN8X7\ngawVUOCR/TbaGpANSyVuIo9Olb35BojGgMMNoypInVidQZ1B2lsQWtilLMMI\njcOKlDhMHgq8aoW1zZr8V0R4/unv3hPlgl1e0r7HJd7ak2LDS9zbGcB14Tia\neisqt0o8dkmn6+izzOJo8o2PxoAfgKrEAfGMtumdCVQ5uvnj/J89ed1Y4vJo\nhxA8cCuuyGgX/iLt2UHO5JY5Ifb8wIDDEbepgoiZQNNvXOwNc609J3DIpWMA\nT8O/\r\n=Spyt\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDSyXJZyBBlkl/n5IrtjnS0DBvNEKxFKxc92D/uBExghAIgAe1Laessw04EdEbvAkZ0aTeoXwheh5Kk1kJ8gaDp/Yg="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.0_1628538717890_0.4964982515920029"},"_hasShrinkwrap":false},"3.2.1":{"name":"@vue/compiler-dom","version":"3.2.1","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.1","@vue/compiler-core":"3.2.1"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.1","dist":{"shasum":"5cc68873f1928c7b9aee8c8a2846f7f362cb1ab9","integrity":"sha512-tXg8tkPb3j54zNfWqoao9T1JI41yWPz8TROzmif/QNNA46eq8/SRuRsBd36i47GWaz7mh+yg3vOJ87/YBjcMyQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.1.tgz","fileCount":14,"unpackedSize":718101,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhEZBGCRA9TVsSAnZWagAA7aMP/0kl8Bm2h7P0lee93FE7\nex4hCNfBQaDHBPHXbHIx6UV7i5HC+rjDSYDlpU3EEdxbcqJiL11yvElq2RpB\nBATolMgmbIO1dPygGHnYDjhWw46EMNAQsDf94vK8Pmmek67r4QUFLY3exqKT\nJxJHCXU0Dz/v/uLCbr+TQE3Etc+ypjLDb3YrIFfa2LMi9f9WQaTeB9Sgf/RD\nsV6MAlVx+iCnBpjexQ18FEuw0HLPV+dJlQg46sjCNQ1f20BvvqrQ4B4XaC+2\naNgr1I2gJeQsZMVOstvUwZuUyFzUHWdoH0/ueUjOqQ3LPBi/402WPNU5Ed13\nwbRjqf36D89rGI3wKTVGmwFIR5FZDRwLqMb1Fvfewhxr1IEKDqtzODoGrb3X\nCEmPr278Q/ulOTHGS+B23KVUlzmJGkscjmBMJoFURDGGSlU4F/Nsqbuhy7N4\njiSyU6o8IKnW/tu8XgOSzRbX1+Tk5XymCLZaEA9Kh3dHGEX5KG/OxLaO7PEt\n4SHLHB48dUUx4xHWYWxjDOXv8eH2+VcNeKPwDuhzQv3sTZzsLb0A99WI7r6T\n2iGgWguHy/HZSO2KI3WJwtBZZKoutJ7Zwn8E9dBj4DweYW+hAyKdvlSHh843\n2YIKJdDf0J1PuDrT2ZCc1B57NlBA+8Ma218TekJFVmf+ERuU53n5ZGAPuELP\n1eMo\r\n=NVdg\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC0VSRSpO/x+nFyukGUT4Zn1buM3DS7rb2O/VWxd/Om7QIhALz2XARdpJ3UZkAq0YfiDB1V5qbNtcDVWxIA8+NGL3FH"}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.1_1628540998368_0.07696731225635434"},"_hasShrinkwrap":false},"3.2.2":{"name":"@vue/compiler-dom","version":"3.2.2","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.2","@vue/compiler-core":"3.2.2"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.2","dist":{"shasum":"26e198498746c53047c3744d26fc95e670692ab7","integrity":"sha512-ggcc+NV/ENIE0Uc3TxVE/sKrhYVpLepMAAmEiQ047332mbKOvUkowz4TTFZ+YkgOIuBOPP0XpCxmCMg7p874mA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.2.tgz","fileCount":14,"unpackedSize":718063,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhE+9tCRA9TVsSAnZWagAAiFwP/3shTNSiRGAG6Axf9V3k\nq2AHbfdppZ2tGPeF35oo7Lv9soa5ne6t7xUFl473waYvdnKiMNVXzDKqcXVV\nyU3Qiqaj4E9axISIRij0Q2U5L16//TPM0YbBD9XXxqOVzX6TUFGaL9Ob9xuL\nBcFayI8DYkb8rIY5w+6ZiSxrk9NhnGIJ+zZrQaM83LJ3N8CD4NY1PpBd53Cz\nOglMU/6B8CtsmeyT1q1At6Fg7mkcsiKigib15RE8e7HIfUva6JOit+8U2mpB\nHg7Gxg2VH1Ov+OLQP5qJZrkGT/HlvpM8yTd9PNumZGC6boeorVZHEQEBfwgl\n+0uCNpMS7Z2tN270IONoad1CkQJBYNKoXJKEJY1crQab+PD4GHVaqv2jbuXS\ntArlNjN12afZx+N9Jm1gElWePUP4VKNurhUne6ef8XPwdpu/+I4hBeckLgcZ\n9jvzP8jnGdElF3YHJPmqf89giiRUktXRWt42gK6vxOCjN+bqSM0qByQ4Cidp\n/rBEqAloSeZKcIeDy4SvkxyGxlR64WDbbzZouekMC9KOys85q5awHHahH4dk\n/JSHDyCSI5vcKxBPaB9pZz0b3bDeWZUWjKiLFkfirAtqR9FkYnqmhm846bkV\nnPXY060wUtEvz/Uwi8qQ8M2I/1nIO4ANdoVlQELQmvCX1NIzK1AJIqYYsYm9\n4T4m\r\n=kanl\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDeen9cLxeIBRzEakZlO2GfSF1YhmZxvywoUvyIWY5tVgIgGifWJBAUjMb87koc4orSo0XvsDTxTHiCqn0YxxEgd0g="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.2_1628696429580_0.4725521856204635"},"_hasShrinkwrap":false},"3.2.3":{"name":"@vue/compiler-dom","version":"3.2.3","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.3","@vue/compiler-core":"3.2.3"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.3","dist":{"shasum":"2576959b979dd8a765171943cfa5409437eb1e80","integrity":"sha512-hEKd+h9eIT+et/l0Nmiup5CWFHC4KuhUcrdAIPLcv1uskVQA3gSDAAx9UGB/G9cRB2gmBpFONHEi8zKrlnsaWQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.3.tgz","fileCount":14,"unpackedSize":718677,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhGuXgCRA9TVsSAnZWagAAinwQAJB+dPEAhiR3yA4D3ZE5\nB2K3rrJFs6G6RjajHc2Q75WSVqk89QADGgdRjvg185DmGyWoSdB4GfdUi+Xd\nSIrz3EgGsS80OfHVheTuVf24nkhBeKJaEYk8mBB9wwuukxPACJQMcAH5/Qqs\nSA6pa9W/97KMWHfIlFaFY8d8iCbsFUMP4wywZQ1HSZsT3eCtOF6oqIKGKXNL\nEiWEFp4/TmKus4EVsvLmJF3AyBAcTwsTF68zEsx8qU892UDW4jIrCqaAs1Lc\niHhdMRp6pH9x/jywnMxgLkZPm6gu9Rf0UaVPJ+BJPy0Ujyam5lZWltgRKIeV\nzPITYtLHgJZfoZmuGUAmHbwQuwnEbHwRnsbbusqQsI4TXVjA///6K3u8Ebyg\nXDGOUKTlIH7s/bnhMYerT9/NLVgqW7UZvw6+rmXgry9EgPGb68VE2xaMyomw\nwVRLy21/Y1IYs2VdAZYNCig5mK7lY3Jy4V5vebfxbHogbpY/iEHnZTojS2os\nXiph2BVRnUZe5o7bGdD/i2+5bc+hJ2DZvENXH3vTxriPuQyVuSFTPTS6kL4G\nF1mVIBtYMes5cFlB+fj3RDNpjq+2Op/Ks7RXWkhS72iyahLyuiyHaltJQ4EL\nrvoRCSYH1/kWVUD5yRksqUUvKRAgZUHZnsS5JgaZJ/yO8FCFdq5uPVdo56tF\n+nFr\r\n=93R1\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICe6YbXohhX/GfsbEIUp2RgfQTPFa8KUxqR4nxHlE6vlAiEAl2Z1v9evWnWDJpNwDKgHgC26/RFGCTQXtf+9Z62aM30="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.3_1629152736540_0.654015361921241"},"_hasShrinkwrap":false},"3.2.4":{"name":"@vue/compiler-dom","version":"3.2.4","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.4","@vue/compiler-core":"3.2.4"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.4","dist":{"shasum":"3a43de243eba127abbe57e796a0b969d2df78c08","integrity":"sha512-uj1nwO4794fw2YsYas5QT+FU/YGrXbS0Qk+1c7Kp1kV7idhZIghWLTjyvYibpGoseFbYLPd+sW2/noJG5H04EQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.4.tgz","fileCount":14,"unpackedSize":718677,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhG+NQCRA9TVsSAnZWagAAYQoQAJLv3gk4rE+QRBJXik0+\nSwhW6GvGcL4i64Dug3smmIH/pLRRfvp3Glpj0QYDRnwMVBxzneTI1mZlpCvU\n7+qTqmzV/16QmyppXq2UsZlI8wPLlK3fG53p0HwjeHNDxuVOrubAa000QfEz\ni8my+iB0oPnJUjde4u+V2oXF7namTaImee/LCQ3NwmRqxXyBgTqJCE6scsGu\nBrHn8LHnxDLUOJl+TlgsKLgIyx7xE8kdAGpv4cBP8GSX+LNYbmeDzgUcGLnr\n1rA1ajMNNMiOarOIBhxBuF4tLtPFzfAjfrBOjFIs0EfGRXZlDDUX02Ts4EVH\nP668YLvZ9qw2jFzyxkBvtPx2EPajkT6wmuNDR7zdeNyNRIFyRkjtAyfB9R+y\nCb6IHbT8h0SpUwuBopW9HJlsemzHhnCBQapmIHtTzUnyJAADw8FH5L7yYoLZ\nK/ST1HflrWzOTdD4l89Ytpjvir3wN1zU/n3po9JqJar9358GOQNwc8MrgDyl\nVHsvLgKzQU8i+jn54ohe0vxjGGRwXGwcfFK5Utz34Lu4+IkgKfoGIdFWaSN5\nuVWIRKrzCQ2D8jgOw4VRRosg/M4rdjad959lZwxlAapK5shU9erYwx5HBD62\niZiqHROrkT36ThxkSRE0dy4DfoSg8Y5urcRbl+5YXrCuo2Jtk8RjRv6DvNme\ndCPE\r\n=Q5Nu\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDFGTU7iC5U/45+SzV2gdUkCmA+Rj62KIAWTHPPJk6RBwIgaQUEEZTEyfjXq+KhSV5UWjeSqcPyjnsPdGeNIRX4RJI="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.4_1629217616103_0.39295245955293434"},"_hasShrinkwrap":false},"3.2.5":{"name":"@vue/compiler-dom","version":"3.2.5","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.5","@vue/compiler-core":"3.2.5"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.5","dist":{"shasum":"1ed95468e0d16411950d5764d024de4e10b551dd","integrity":"sha512-BT+MqzrbwJeSdBY3S/0Z+nONrA1ufn9Gy62dStUQ6yr643JXr2+z+U3t/BIZSLS9y5v8TrQVJmPI+1zB9sfrqw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.5.tgz","fileCount":14,"unpackedSize":737213,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhJRYzCRA9TVsSAnZWagAAen0P/3lKIPn2A7ZIm+UosvRr\nx55DHvKs1qbj1zLcAh8oZ34uAUivkRvUXUBQEShWe5kfNqU3n/1sKKWU4ULf\nr79UqUnW6MPQO2BBqLuIpBNVlNBtC5gfrhibZ2lApjtDR3cXRKVlViF9cvom\nHi40G6fbnMKoH6tkNZAy/OXZOR/6hlNYMsvGeoWr4NfR8t4b/0snyZGFjbBI\nM0L6mXX3bzusN3h/WvBVz49vX3lWhimGK7Hv1FU1005U6QKh+ErHbC/5b6BC\n/T78D7u9QSC60zYHooDDm2t5NqGtTFxScxpGt7oL6tkJC3Vpl+5P2fECxwl9\n5B9IF8V4bom7sZx42nL4y+wNCGieS3NyINP9zZid8W3oGVn91kCTX9nOH+Uj\nba0LKxV2MbdNNGKOf8O17Q5jUkjvOOnJ5NA4GghiC3cadKur2EwhF6MtTM9k\nckaHeWMmJvqoXiBbo3cAaP/Eg/18ZH6YQXBSPnS6QNOjD0LeJ3STmLfrDOJP\nKYFQe11r2LCbSBnqFrK6G98ITfknlCPETkeomG+XAajAUm0vAo2z9tDJ+Ya2\nDT75sDDurAfaiq2XhPfUVQB6tRv0FJpIXTUy5VD2TgVmjzM9RUh5qcsHrgYC\n04l0c6MOwz9KL3gcQRo4GKoWTa13pTB+kSK+QqLlRyukHvs+aTR1JBkJGJ9A\nGwhv\r\n=veCc\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC6WikZSALzTtw7xksxCpYAhUjbpo2goUH32dmKCk9tygIgY0oAlyjnu2TPUA0Pe99Fh+CqFYGvyS24x2Yc2Mn5b4M="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.5_1629820467840_0.5770266121244974"},"_hasShrinkwrap":false},"3.2.6":{"name":"@vue/compiler-dom","version":"3.2.6","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.6","@vue/compiler-core":"3.2.6"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.6","dist":{"shasum":"3764d7fe1a696e39fb2a3c9d638da0749e369b2d","integrity":"sha512-+a/3oBAzFIXhHt8L5IHJOTP4a5egzvpXYyi13jR7CUYOR1S+Zzv7vBWKYBnKyJLwnrxTZnTQVjeHCgJq743XKg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.6.tgz","fileCount":14,"unpackedSize":729166,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhJSRLCRA9TVsSAnZWagAAaswP/2itpv6xyWhzDMDVtipB\nwVc8TTfFb8Dg4fWi1qQWCnQbvZeWerC+f/5eJv+LU44/F/16jhGumN0kOpAJ\nEFNd6qpgM96dcEnFt0lwKPItOk5eOOkuURCkn8xBYf4qygObtVCfiZI9Me+P\nxmrh8EozTDpnkHhdAk9vFiTvKJtmhAxoq2eH4vHL1F7u7rvV0veBdcYcF+cG\nUGvvdaQpaG8ZYWmqFsveDt+gZQzYyYGafhKd5LyHvb0kK0j1YXvyMw5ZfR++\ntIprriz2RY94jrEWVuvwjoNznwrTgX5sh7dlKT+lh/OWXp/Loub6LlvIfkvP\nBullJ9SQ0t9B4uL1f4ko3UAssVoCmGGWteDxO/FRjNhqv+s/pnqg0949HUiB\nbS1dsRZq8UQeiMw9tfmn4hmp5sr6U8qXK6CeHmEj3ZXiZ5OmBhinMWtHthp7\nR/R+0gRGR6EBQ4WW9P31AlPbOoKDJNaLw37hlth2QlKVRO/40ADInoVbPEql\nvY/Dr4u6wQcFcN8pjbslK6wz45yfgMxOusiRmIFUN8lWmKnWq4K8xIGZBnGr\nz6yeGYLTq+Gb8vegE86TTCCctHK3WJby2K6XfKFb3YLRSoScBvldD8YOmiEs\nZKz9dDYhFVM/GaZjImd3/8jJqQAkm2uklNkUJ51TIztSHlwMM426IShcI2Yd\n+Z60\r\n=tF3r\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCe+0jXa9XB77oD8cdCKmmENEF3kMVY60ifkgdfOQgLzAIgcwRAOL2EgHfh0KYA8brjupZm/8S1CSXf9UHrTbPM344="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.6_1629824075202_0.9368894078021814"},"_hasShrinkwrap":false},"3.2.7":{"name":"@vue/compiler-dom","version":"3.2.7","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.7","@vue/compiler-core":"3.2.7"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.7","dist":{"shasum":"33abaeef89ec653e1a733143d4f7b6392def3de8","integrity":"sha512-YZyZNoZlTbTMqyY8QMC8IhwmcDVOiE1DdVwjnXbyihg+XVqpGQkDjNcG5nyMTbtZDKXREsYkcjaZntEfKyWK5g==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.7.tgz","fileCount":14,"unpackedSize":728735,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhL/khCRA9TVsSAnZWagAAtWUQAIkbQxx6LFqVm40MaLR+\n+IGC211SpiENPznv4pqw0rQsmA8/ggOTAWpZeUlYvysKoJbCmBipGYSUteyi\nBwcJX895PN6aVNm+K6UMawP3LjwsDCAW4Bo6arncEH+Bp/u6Zu3jzyEa5UnR\nBAppvTzZpBC9e29AfRjywc7+C9CgM49iOj3QRS2kZQsUPcNgSWejl9bQhrws\nw3Bv7Esc81+K2K8SrCXRKy4nOA54k00SOoPFeY4ER4ZeJRwcnPfFEYhy9+e5\n4DJLDYRkWsWVi2WDgm3kFtsFWvrcgIBHYvzjVaOwJ4HdW9BroS37dIRDFI8q\nJMJouuGjYpCNzjCGW2ElXFfDiwt9StO/fmOBqR5wS6f95jjA4qAzTB018GNi\nLmpIN0Wqmiq5xlKc27hjhJfQaQW3bXxy2ZGNigUfxY2KMDc09oe9BZ0OkQQc\n/Rkuzkeio1wQGiqz4MscRMrH3KQFx5JftUWU8uM38aol32WWjIDggwPcDSyB\n9rIbgHx+bEjYqomJlpu/zIL4iLOMKN24VDraqADeytrokmTYh45jnocI+GlD\nTIgK1SAPAu02qQqh8WNx6gIMQPVflyfdgqybQEI3IjkJYTYW8ZndnrnSXqkM\ntZ6MWPJ1yFD3qNp1rUF4f6vMIkGwqCA3NKRQiZwzlsUXfQnl9IPJePuzAKal\nucSR\r\n=23Sx\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIErxAUZxr4OBqKbgws0liB0JaQJ3OqdZy7IQF/UmXesJAiAqVSx/wTnRhPFo73lUq+5eIPX3/nQ2AqrI/GhKkW7zSA=="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.7_1630533920947_0.910779722214424"},"_hasShrinkwrap":false},"3.2.8":{"name":"@vue/compiler-dom","version":"3.2.8","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.8","@vue/compiler-core":"3.2.8"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.8","dist":{"shasum":"69bc9e08928a12295c31299067f18d87301981a9","integrity":"sha512-nxBW6k8FMWQ74294CRbqR+iEJRO5vIjx85I3YCOyZFD6FsDHyFL60g76TcJzucp+F2XXIDaYz+A+F4gQlDatjw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.8.tgz","fileCount":14,"unpackedSize":729365,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhMRwLCRA9TVsSAnZWagAAkioP/ifxVepMGKMKnAvZYJb8\no5BT05Nxq/HEVm2uOMDWOPKxCvtzhOjA9oj5NmNPVMd7BnXeDkluHfGY6y+1\nyZknJNp6F1UeI+ZrjaBEy/mJz4oxliHW9kYwRtdtVg940yElrNW0+awtyqX3\niGo2BHxTp9Z17ZXU2zm6yD/GKnc70svhwVsuiAPDNSmIGf4TslYNLa0NRQmc\n4PeJwkkozndbEBRhcd+7+p456sO4+Vr/IAGFclh/IiWCvnEW9pI825gC9Wyg\npTqFF/ulvcTaOeJfnQN2u/DddG/wDOFLnDC+acMIjvlDWk93/pN8mR+lB1ga\nxHed0VAAf7IObsOoQoWD3Fv+jYkx6cM+YDVSjSe2yaZ/7Pc+Ym3Tc1eLeFgM\nlMrKkXV+eKcT/movgvTUOY9IwZWigFObAv2vjgsVAap6+PzjDcG6/mIjLY42\n5SMe1PXKKyQCKYji6vU41ivIeaJKoEMCLqTWkTUBnucNHhhK0BZS2LNwbq+C\nryMkYz7LDMrU51Nu0Q/ykGbBK8ccafohUfhPyQ3s/mFk+Dvh10bmLwjUP7wF\nOGJ/kkLu4sIMNIT0+w/VBnulGliBFulDMki/fybpRaCtCGE8Dz7Ag8vgq68X\nstB8SqtyKajKRaAFDb2jiDOdm6u8VEvgvKsNDQzi7E8aKjNjGTh2uJiiksIa\n3Ig+\r\n=Yhhv\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGw0RAtcRRH0hv0P+VX9E7jXI9mlMkYTLbIu3cpUZdEAAiEA+NN2ejQJv/zUlv5E9ZkZmRlCxeXzhtZ1ls0Mz0FqLiA="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.8_1630608395333_0.2872513826101648"},"_hasShrinkwrap":false},"3.2.9":{"name":"@vue/compiler-dom","version":"3.2.9","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.9","@vue/compiler-core":"3.2.9"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.9","dist":{"shasum":"e42b2bc285366224a1738f7ed6648d4260cbbbef","integrity":"sha512-7GAMoCyBGMzMsbzxxFFCQMdblg10NRXkgFFhkjLJ4djItL0hyeO8t9wSLmaDaJejo1xjK8lm+4xPAUwvHuC8cA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.9.tgz","fileCount":14,"unpackedSize":729531,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhNUOGCRA9TVsSAnZWagAAq9cQAIc2gk27vbIrUHJINJB9\neTi5pXOxByQAgwE3CN6JpqsXO730TT9OgDpbJhBYm914YUpu3DekKlGYsGUg\njAjsBBLov29V2X1r1OU/bi0BXnmZpvvbmYAfDLjQlC12G0kwyB2hnJGJiDs/\nBo+Pz6yPDJCW5wDeJwZUpI1fYSBWc5yTO3adXUl2DiGFbizjrskMIUYhUQyU\neL9K16RQPGlsZnPi1e+q2hilBbe/A8gv4eXJQ0jirW2r4f+9PIan1iH1HNVj\n18qOgZAOpOtv/bGfrOLe8TZoThE7CFaLq6053Erj913oKpfmFHVj2Hl30zcv\nnzfFvLLPLrYMHRoJZHQcY4ChSdEFYZuxM2w7Ei1yoJolLYVQGxBlZgqaBjK8\nbkQI01BFzGAJBJ11OHPzSrs1Ku/AdbZquyMigjTZu8Pl6Z9aubWBUq8lyPlD\nuz+CGtluQ8N9VPTOCYJhpjH4Ux/hYJTfEzFLuGDQ4bl/BJFeLJxeDOnuxBil\ne9oyi/bOUT/mdLpu8BSogeqHdi9cC9L0WFvQ+QmAO/PWU5QwRcZKuAZKfRaC\nQNQAYu9EHtEX5P6mZMT/yaJr5T/h2fNV3mN4wvlG3O6cQy5pi+ozzdlPch7E\nwM7xEk2Sh7ibTFa3yRu8N1dQbAms4xFZl3UFOC6A/5/ErO48XFy0KIlXmx0d\nl1fQ\r\n=KMin\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAPQnboqLgzcVtg3kxKHoirh7LHAcQF+eG+gCJ/AqJLRAiB/3TsKy/l7n0sZB9RG04kpd9GKuAsRlW3ZYZf0Ng9xAA=="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.9_1630880645940_0.7693121599545234"},"_hasShrinkwrap":false},"3.2.10":{"name":"@vue/compiler-dom","version":"3.2.10","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.10","@vue/compiler-core":"3.2.10"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.10","dist":{"shasum":"1b342e3a7930c99156945e6def27abe671a6a76a","integrity":"sha512-WFOWBj9dvIz5ktReYwvw2GMQ8YHtY//cOGTyCw5XSQw58sKm4JCQGe1HXfuEVDmRRI1s4L/gOFR2NgbRfGCtMw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.10.tgz","fileCount":14,"unpackedSize":730584,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhN8l8CRA9TVsSAnZWagAAb8UP/2QCcl4oVN0gTJd8WAT4\nx1pigRgF0hq8dt09/6P2n8mv8K1EwYvg+x0gwQMZtxJa8eJFlp14abjKPtV5\nDH2pJwsoFwlCcRcl7NWHRB2vmpJUwjpJOJCV2WDt7ET14A7nAb4mdQ6VN6yG\nNvgjurlFb3E7KiUEbqt/5Go3WBBNMm+BdX/zuu81rj8SCj5D+BNZ/SRVMigK\nrjMrUQ3D2EcNPxaFOoZLivOyOv6ESXKRy2ecl/bne2QPHQEweOKEQXSKUWdm\nSWVdG+mulwfCaj+sQkqRjdpbUtuIctR+ZCvA/h6hyKN9n6a3hTzwUbt1m0va\n9FUY0xHO3nghE8Y4Dc+8fB3TkGaEBY3X+Hggm8JaT85fV6o96qS+FpukvFr5\nxdy4o9mtFmrma2F5aUIqttBiNt4MQugKE8UXqcEXPyd2LcSSeAfDjY6FsLxG\nAtGh3rJvDBjMEgY6bnQ3nqiC/mUi16uPRUAygqS4IHVqWRrBk8wUAGj9yqVk\nyjfeciUlhqk1VVKnisCIbhtgB1P0Gg1eTU5CqjPhsS+kkSDpGuchZnNw7AWi\nYKD3A1WXN7ZBsFY5Tyzfw92NGYMZiYK4mdtvt5j0YXe/INv7LeKTsUTKeE+T\nWe1aCAtBXvRyW4BZUHenxn+1Efvw/hb2wEZrLALJAPvhPr2ilGLiHx0Kj+54\nPD9S\r\n=7E/H\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCc17j7feor16Z8kSjKLM1m+oWitv4fu5wLZSQLdDBxnQIgKRVzH7ayeTUk19dN1vv9ITHsMSeMQCD08eVikr72htU="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.10_1631046012240_0.779857935954704"},"_hasShrinkwrap":false},"3.2.11":{"name":"@vue/compiler-dom","version":"3.2.11","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.11","@vue/compiler-core":"3.2.11"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.11","dist":{"shasum":"d066f8e1f1812b4e881593819ade0fe6d654c776","integrity":"sha512-DNvhUHI/1Hn0/+ZYDYGAuDGasUm+XHKC3FE4GqkNCTO/fcLaJMRg/7eT1m1lkc7jPffUwwfh1rZru5mwzOjrNw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.11.tgz","fileCount":14,"unpackedSize":730584,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhOUAKCRA9TVsSAnZWagAAEKEP/2JL921UO9jO3kRj1Yd0\n7uq7Yx9o66T3vAa8aTAzblDis6IKMm4N9+FETy3Kr+WUY2lYj8kTFDNFST2V\noEKvS2tY8ljwd+bO+DMr7equcosx8rWkhPD5HLDB4+ClbaP5jyZ+wSUNw41R\nbGm1jGUmSDchATlm0AcRtqI8YbCa9nogF2YWFqCZwZd8zU94XaaHYnJWF4mK\nj+WRDV/GspAmYE+UZlkAc3qYRFQEkHJgeHPYrzPlGMnvBKsYY5QqPt8+vbzU\nJtyz7E9CV6LlgBJQRR87yH8/CXCW/O+mCNlgIfGxdxbUO42+UnQp203mmiLu\nnKnEIBXklDcQOg1Rl+eoVWvZF5Zj1d9QWBnLY05o2+wtp58Qr3K//bwRvV6n\nAkhicg7ugwUT44LkQ2MJAkA1vsJOBUi/mAXfpG6tuF/X0LGlD9VFgZa7IwA5\nm9XCgWu6dWayWrFHfYWLXEoGRPU9jVgx2gGa8rPNLbGu94sBq0hobLYiV6W8\n/OTLy0i5dkgdvSgMyDlwZ73672SpL8dbTkvmR7nUpBgBArq4xedfIP5++oP+\n9s8XXHDKTz874HXBlylrjMJaICBwy7CKK9wAwOT+X5dXi74Oip1A1ta0m90l\nWe/05tjZtQs+OTjdsPkgcIphwpFzEBzEJKZ68A5ibvoGaIc3j2/Ge7Qiuv8b\nqXWb\r\n=pTWJ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC1SCDnHhmc42dKYQ1Hrqr/ZdftqhCVzUYgDLyjmEOdsgIgcFQrKPclN/Ij+2bGP9+9RxSUfdyj7KBbHujrqatMbtI="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.11_1631141898670_0.43028981661805554"},"_hasShrinkwrap":false},"3.2.12":{"name":"@vue/compiler-dom","version":"3.2.12","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.12","@vue/compiler-core":"3.2.12"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.12","dist":{"shasum":"d6ba00114e73adb8b18940c3ff18797cc2b0514f","integrity":"sha512-MulvKilA2USm8ubPfvXvNY55HVTn+zHERsXeNg437TXrmM4FRCis6zjWW47QZ3ZyxEkCdqOmuiFCtXbpnuthyw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.12.tgz","fileCount":14,"unpackedSize":730672,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDiG/c+/WEIesenaPyGCSbepoKBfNTrW9iOLqD3x1JOtwIgGLLOFuRBJRCMWyQY0oJzsuk88dl+NGyhlHnteYA/I6k="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.12_1631890529020_0.23075742704517044"},"_hasShrinkwrap":false},"3.2.13":{"name":"@vue/compiler-dom","version":"3.2.13","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.13","@vue/compiler-core":"3.2.13"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.13","dist":{"shasum":"028982494fb9d97807d5275b42355732686f8ed7","integrity":"sha512-5+2dYgQyNzM97EEgbdAusUpLjulcKkvLM26jOGpd14+qwEcW/KCnns5DGjlZD/tsdEwToOoTDCm+mjx7cO/G1Q==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.13.tgz","fileCount":14,"unpackedSize":735059,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCjE4p0MdeUOW0zGjNDAgnwexq4DFWU8miuXoWOLXhCXgIhANM3ndJL2DdYSL5t/oY+YwhLeXBezW9sHl0qZQaD4bku"}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.13_1632248577389_0.841656262889261"},"_hasShrinkwrap":false},"3.2.14":{"name":"@vue/compiler-dom","version":"3.2.14","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.14","@vue/compiler-core":"3.2.14"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.14","dist":{"shasum":"acddabae94704df543448e2ac31fe476a70d8307","integrity":"sha512-AEfQPdvVvwy+U5WnvmVHKjQwaR3vWhALe/40swnu/AH/fQ4/wKrNf2e3ACMseAF0x8XdBQJJe+kZ+OaT0phc4Q==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.14.tgz","fileCount":14,"unpackedSize":734773,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFr9vVhFP8DBDoYEyZrI4COVznfCes6luCd5cBBDSgYgAiEAhKrLfXWJGNmOikiYS+JhapKLMx6IlrvyzWJy9mfPUmo="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.14_1632350219834_0.3712900281910152"},"_hasShrinkwrap":false},"3.2.15":{"name":"@vue/compiler-dom","version":"3.2.15","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.15","@vue/compiler-core":"3.2.15"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.15","dist":{"shasum":"7846a0083189ca47fc70909d5428a9a4179ac68a","integrity":"sha512-YS/kCwdqOhv3I6VmddJRMinRr/tOGGvfecERP/q/v6zHsJINptQ42ykaOlzWUA7zvthw3M3mxi911HTHrrn9Dg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.15.tgz","fileCount":14,"unpackedSize":734773,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHr3FiUBgDlB5K8zdNbOVGG80fQST2RamilFUrJyGwi4AiB+Rl+mxrCMHhMGEi+i34W2eIW+QUEXwryskcp4+8WrEw=="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.15_1632404942288_0.5324995883997818"},"_hasShrinkwrap":false},"3.2.16":{"name":"@vue/compiler-dom","version":"3.2.16","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.16","@vue/compiler-core":"3.2.16"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.16","dist":{"shasum":"b0748874c4fcf98dfb20efc8a40f629c90c8a620","integrity":"sha512-K7lYfwvsp5OLb0+/rKI9XT2RJy2RB7TyJBjvlfCDAF0KOJGqWAx++DLJPm+F3D29Mhxgt6ozSKP+rC3dSabvYA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.16.tgz","fileCount":14,"unpackedSize":735109,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHwY0Mey/KnPZUAfB55AFMMvp7hOjTuUxvC/7puA4p5hAiANtgRIO7X7MmFz0dKp9DMs89AJd7kCLeEF7lnMXEmgtw=="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.16_1632406624755_0.4657338012600569"},"_hasShrinkwrap":false},"3.2.17":{"name":"@vue/compiler-dom","version":"3.2.17","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.17","@vue/compiler-core":"3.2.17"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.17","dist":{"shasum":"32f564017efe6ccd7bc70a32165d63c0aab9a386","integrity":"sha512-ApLFcgIwKSwKSc70u0TpsDuq1d15v2JbBbIBWRhTr0+bU/3XH/bRyeU+9+goI4lkYBfCcOv8WdTp9NDyuKiOfw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.17.tgz","fileCount":14,"unpackedSize":732461,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDmQrL66pAafF4/K9n1ajYKdXNkS7KtJ60m48kOQskuwQIhAJhDyfhV1f42Gv7cxr+oYA2c7HzZNewGGUVG8d3Ri/V3"}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.17_1632501793685_0.5622729508037312"},"_hasShrinkwrap":false},"3.2.18":{"name":"@vue/compiler-dom","version":"3.2.18","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.18","@vue/compiler-core":"3.2.18"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.18","dist":{"shasum":"6bb3b0e318a7eb16c02eb42fefa96a58766c6730","integrity":"sha512-AqCND7Q0vYFlsBcwWnbcmOiVS/J/70qTZOCPxJnktvH+w4Y7F9omKDyuhsd/ZsJCmSvvpzqBNf2hgtMnoTjNiw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.18.tgz","fileCount":14,"unpackedSize":732461,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCeFdltcu2k2V6eOCztX2oYHQedCUePFsf4H+k+88OhcwIgFMOhKKPb602L8EEHROABN+PWTlHwPtq18xyQ5I9pM+E="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.18_1632513919896_0.8939477809488741"},"_hasShrinkwrap":false},"3.2.19":{"name":"@vue/compiler-dom","version":"3.2.19","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.19","@vue/compiler-core":"3.2.19"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.19","dist":{"shasum":"0607bc90de6af55fde73b09b3c4d0bf8cb597ed8","integrity":"sha512-WzQoE8rfkFjPtIioc7SSgTsnz9g2oG61DU8KHnzPrRS7fW/lji6H2uCYJfp4Z6kZE8GjnHc1Ljwl3/gxDes0cw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.19.tgz","fileCount":14,"unpackedSize":732461,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDHVzjZHhjyjdx6jkB7YcC2my0O4ULftmpHx14Cj5RrYwIhANLGvbyTZBdS3DTf3qWDQKI2eEVRsaYIAkb70oqghY5W"}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.19_1632596302789_0.38606142459431325"},"_hasShrinkwrap":false},"3.2.20":{"name":"@vue/compiler-dom","version":"3.2.20","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.20","@vue/compiler-core":"3.2.20"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.20","dist":{"shasum":"8e0ef354449c0faf41519b00bfc2045eae01dcb5","integrity":"sha512-QnI77ec/JtV7R0YBbcVayYTDCRcI9OCbxiUQK6izVyqQO0658n0zQuoNwe+bYgtqnvGAIqTR3FShTd5y4oOjdg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.20.tgz","fileCount":14,"unpackedSize":732481,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICdQuv3ZW1b30tyH4apHm0rs7v9kxj7H2D2rOdNfASI5AiAxXqSe1SrBs8xuR1VY9PsNPWeUGU6kMezm7ULQUu12dg=="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.20_1633712513952_0.46209619128125046"},"_hasShrinkwrap":false},"3.2.21":{"name":"@vue/compiler-dom","version":"3.2.21","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.21","@vue/compiler-core":"3.2.21"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.21","dist":{"shasum":"d6f6c85364ef8888f9c4e9122bfba11e78fb398c","integrity":"sha512-gsJD3DpYZSYquiA7UIPsMDSlAooYWDvHPq9VRsqzJEk2PZtFvLvHPb4aaMD8Ufd62xzYn32cnnkzsEOJhyGilA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.21.tgz","fileCount":14,"unpackedSize":732403,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICbClJzkIZHjkv7Bc3W2aFB6gbLRdD/YXIP9WddyHpBWAiEAmw/Tb5ZUOLJGbmPJBGUUpXAO61qR72EM1yjWFeKPTdE="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.21_1635834918067_0.2110565849492485"},"_hasShrinkwrap":false},"3.2.22":{"name":"@vue/compiler-dom","version":"3.2.22","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.22","@vue/compiler-core":"3.2.22"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.22","dist":{"shasum":"221cc358a6c0651c04e1dd22a8470b21e56ee1a5","integrity":"sha512-VZdsw/VuO1ODs8K7NQwnMQzKITDkIFlYYC03SVnunuf6eNRxBPEonSyqbWNoo6qNaHAEBTG6VVcZC5xC9bAx1g==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.22.tgz","fileCount":14,"unpackedSize":732361,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD7j/KaoXTPj/mBdmbDCuRBYj+eSih2ZfLJbeEpC7Fn7QIhAM/eD8txQjqXwnmNddHdGuXMEWTTsM/YI5dHUJGBMbhU"}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.22_1636947908697_0.2541404552935309"},"_hasShrinkwrap":false},"3.2.23":{"name":"@vue/compiler-dom","version":"3.2.23","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.23","@vue/compiler-core":"3.2.23"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.23","dist":{"shasum":"1dc5ba6c61f4d9e5e22442bfbf1ca306bb698507","integrity":"sha512-X2Nw8QFc5lgoK3kio5ktM95nqmLUH+q+N/PbV4kCHzF1avqv/EGLnAhaaF0Iu4bewNvHJAAhhwPZFeoV/22nbw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.23.tgz","fileCount":14,"unpackedSize":732361,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhoH/RCRA9TVsSAnZWagAApVkP/0NatTB6YxwIpqU3si1s\ntI9+fHBTDsGGJ9pwsIIjxpA5ZjWKF7zwFsSj0tu6sxWFWYh4PObbKvzx/DIM\nTpymJYxblXiTdZl6Wge584QFozgXwAE9Poyb0+L2in6lmWFyX6SCtHz5GPk+\njVre2B6psUg+pnNfZ9BSX2UYIdXhIZTNMNe+kTspf1HodgOWA5zztxPLCwDX\nNRtsjpBeunll85xqYMuiOEDt8HkLHNuUoU6aZmtmlXtkML0tcnRac8H/IiJq\nkpegDivZhc4kefR6A+igjgdwMXcM6LmdpJpOoMEZXx4ayGoeSDVkBqr+xMX7\nb3k3KnQJDySKuFj80f8iH0Vslm+FZCr4hnT/9SvbWV5FeV3GOFwfApUYqnEY\nxTjZhhHMWrYjYYJgivXEy7vh6sqIjl4RMuBUsmneRc43K25zpgSKbEI/d0QW\n8zGs2oYc9fkYA3kQpy7MVPEBWqX3/G+0c1512UssnOLoAPXTn2wFARdRVXea\nTkXKY0ZxMaEVk7NB2SdYo6BTp/jncrX2DQpvDuPepBGAKTg0lkiQAuCBAtSf\ndIAkfpqz6OCG3fe0lsqknfUofmq7ahebBTY3EkXOZ2RncWrQbT6V9nTgJWdU\nEOhevAAgNrypLEYERXdW88teBr+GvMcIGX+0sRrZIVH6ExUxlmxvl/To9j0A\nZVyj\r\n=cZb5\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAefWgjIkp5i9RcJsxB2cZnfnpM0Mzby3flaj79BByruAiEA8EXAhlw5ZJDPxh07IvrlRVr+zHmsZX4l+qCq26RCJDA="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.23_1637908433474_0.08682257680937111"},"_hasShrinkwrap":false},"3.2.24":{"name":"@vue/compiler-dom","version":"3.2.24","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.24","@vue/compiler-core":"3.2.24"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.24","dist":{"shasum":"32235cb444660245be5cc58f4beb76747400505c","integrity":"sha512-KQEm8r0JFsrNNIfbD28pcwMvHpcJcwjVR1XWFcD0yyQ8eREd7IXhT7J6j7iNCSE/TIo78NOvkwbyX+lnIm836w==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.24.tgz","fileCount":14,"unpackedSize":731769,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhrdHVCRA9TVsSAnZWagAAVm4P/2gIOg/rpODeTb6W4vf1\n/v5+Pl98D/JNiHsGwaG6WPs8kzPjfCF+kDfj7ip5NweuEqPMzpr+abtmcd4T\nJxQoTVCcHbO/n8KuQEDsloS7YTbr/TXShcmVuwhogydMIZnuUkWS4gxHTgTJ\nZ1H8xe5NbWEmgW+b4BosOeSG1lM8GXVNxKXGSLTmL5j7smmoakxjlziqO8Ho\ngSNYe4Z208Az9JthleYWXmMGc0gMeCgI9OPWZ4rU9ZXB1Dvd/NNLOX/clcZQ\n5Z1y5ud4kzLXi6sUkRGaD5KFJNJ/AEQWo1E5yx/s83+iBCbTFBY9spghWi1Q\n3J30NlRZVKBBIMncSQDxrX5jU75HMrNkJdLP+qPHUle/F0UkQ7CO0emDQvMY\noHcHduntDfLFB+Kf8+5fyzTf8PQotGCVDacMSxo4t3cX3fKkGPqPBU42v8gW\ni+kvlI/I6v6SS5XyncHY9V0r6eSum/5h2+7OtbMuivoEYvhxRKxf+E8ctDiH\nhoeixq2pP2ytQj/baXkh8uxKkvJHoU2XAZF97BNFMca5XcUkwD7DqItunSaA\nVA5zuUNpSkLcOUnPJ8Q20eyKgo7/mTwSv7c+Q6EuBGr62F6bMfe5f8PPJg1O\nLnE2Vdxd+K+fHFN5FUijGrJxBYLg7es9uHUsijxFCgn8n//6ATHirenHVxy3\ndakm\r\n=E+QH\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAlER3y9v5HtrznPwk2wAhSXAQs63Dc5zTV+PgET5Ub0AiAl3gZ/yKvyfODf/dSDUR7Xn8dHbySTGyC/5Xf4HWMPYQ=="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.24_1638781396814_0.3580458768999697"},"_hasShrinkwrap":false},"3.2.25":{"name":"@vue/compiler-dom","version":"3.2.25","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.25","@vue/compiler-core":"3.2.25"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.25","dist":{"shasum":"b1a3b1ef057aeacea5ee00f7b20dc3edb8bd1ed2","integrity":"sha512-4JrburkRg4VWbc8AKpzKFWbNY4MDXshqjFl53+vINq7zaw3Z7aSqnLv0EkKh8B8ynf/MYsAdygGutyVbEWYxOw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.25.tgz","fileCount":14,"unpackedSize":733779,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhtXi/CRA9TVsSAnZWagAAehIP/0KdPC7c7jCIPCREjJaJ\nnNLxOoMHMAgn4fTJkDGqH9CKXsmfz+7uQtMymX1HLTTKl9L91GQ3d9eOJbkc\n3hfp41HhBqSAVXOA/QLWveOUHshy3Lqp+DsEEs35vibnkh2i9pN1l1ouX4iA\npeffn7SjAXI8qnGIeycgN6gvnTr0gvY/08JyVvNoabt16+wlT4CGWCn/NEyJ\nPmJE4MsOdjI6I0qUzl024E0vHSvBXlE+l7S52oeJPFTb4peIfAtvfbMiTK4A\neaReaSBm4Ium/VIHCyKktlok21DOdkl2fm41+x0Dic6cMcZBMF17t+MoHuH/\nj7NpH3ojN+XQQRjxx2SBjKJiH+6K4VP9X7QA4A/HAL7af85YR4befJwPWwfM\nhrnz2D0sBEPsfl1ussQd9wik6MceI1UutwVpM0MKJuoEcEmZCgISwznhoYGg\n3t1kyacGnEKHGXHiIb/NjxYOD+UHMKEQhWiq03udBjfwnhDVOyVLYZ95TWig\njLnX1vLrzXqJf3QEljThzTIn3LQCTnZIWDdKSLIifd3zXk5yMqWlRrJ0cDJN\nU33JN7az4+E/uAysaXgMOdPJP8F5MeEmuJcMApa8HIKNdYT0gO1OIIdp7Ij/\nzt9Nknv5yNRPKf1bnykx5z5wvK6uRQkdegmElA21L8ofEFp/4sRyVU0kNpyJ\nf80d\r\n=iXW6\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDQX4Jl3Byx1bTrxdq4GU1g9skUJCiKY+Rcsyv2+efoagIhAMx1IClvf0aIZGY/u5db0KKEleVw+us4E+ryYn83rrKu"}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.25_1639282878992_0.9812985919119106"},"_hasShrinkwrap":false},"3.2.26":{"name":"@vue/compiler-dom","version":"3.2.26","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.26","@vue/compiler-core":"3.2.26"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.26","dist":{"shasum":"c7a7b55d50a7b7981dd44fc28211df1450482667","integrity":"sha512-smBfaOW6mQDxcT3p9TKT6mE22vjxjJL50GFVJiI0chXYGU/xzC05QRGrW3HHVuJrmLTLx5zBhsZ2dIATERbarg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.26.tgz","fileCount":14,"unpackedSize":733779,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhtZ7GCRA9TVsSAnZWagAAoAMP/iX6vOV7Tns5rjskxprc\nHr6aht3XvGUZLmUzDKv1ju2WIm3xtpc5H3yzuwoPlhgI08r1tCEEnlKDzCKl\nrCKib3epMjBJ6SfSzEUR5vd7LYygPrP+VjroGiaIJLMQB3GKeR0LNZ4HSkWW\nnYRCscO6T/F7/rTgY3bBPkT0+V0/EEGfbOnB7vjE3y4mXXjdhcq8ojVk3I7N\ncHxxMWpraII03IO/wgoFd/gqZPOOBKgjzrhyhjIKyvnQ1NESkmsXC/qmnrt3\nNBM0d/05TkGr4yjSfVRzT6EfcVizrb4Tzi4InBQw8TmDjFGL9Oz+DyDeJOp0\nJecwZZM/Ws8fJW/5ijwEd4E41OeZkKvvsMIY/ny4UltwMcJKc9YN9ldTalw2\nisYG+aOQ6d9hjJ3bjRlKLcLLdrbQV9DHYDXR58DihaeMSN3dXVRNfs0BqEM1\nVjzZTcRDjbeHsI0EYI3KRTtDZpszOMrmX1tE2vf3IWY3xTupq6bOA54/LiNi\nXhkU1qPfoyzqcMncsXOo0YdyJTrjkIG6jgI5Q5DIpTVC+ZAAiWcADX6a+2R+\nJJUK7L5o9ASJwpvju/LMLKMNSrp4xKrh4+7WtnMoMrDg/XlJp+jP05lddbwi\nrL8S+78aznW6w/m1yi4ssTa5i6Q1a0tHoEOPNeO9+UxwbwmlAiH/X7BK9vYj\nkMxZ\r\n=MJzF\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIArcYqF79HB/CyVICt5Moi2Os3ebp8zZsnXtF5ugojRrAiEA7k9axOKPJWLdxDY3yDPMLx+HgvQRlxZASWe0NYu1Tz4="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.26_1639292614207_0.7453727940597596"},"_hasShrinkwrap":false},"3.2.27":{"name":"@vue/compiler-dom","version":"3.2.27","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.27","@vue/compiler-core":"3.2.27"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.27","dist":{"shasum":"a12163e3f3f1d5ff1969253eba4b4ea3e67bbd0f","integrity":"sha512-NyQ7nEbopUBPUMHM4c3FPCbFbnQwptoPjW5Y5qfJ7hfiCNhOuhQsDNqi5JYKBxfpxiFNwjcN9F8t1AsnLrDloQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.27.tgz","fileCount":14,"unpackedSize":733779,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh5CbXCRA9TVsSAnZWagAAY/MP/jg+1N0QRh6LVBS7VGWM\nMv0F8yJ44XXZ23/bbuvI9Sdo7naUfLEy/t8kfWFdPe8G/d1aTGe1JhRghesZ\naARZaXzP2cZRuqvYG6R912K8Cu+KQFWW7r4nJMJrv0DfZhCKuMM+IBAQ8UPY\nNQlAbOccfYFQIAtzcCehirBGyVFttNtKt8BH9a5xIUEC0Xelfkd3mVDwo0t5\nhTBHUPiFWiPypywr8OFdcCre8Ud/MjduulX++rbdR55FqB3k/vnJGm7P21sf\nSQWq7vCPl0oXpNwCFUwTqqA0k9cedm0BmWoy6T2zCLwCvkEh+0ti7M863o4q\nRBCMUNCc34yTdH5zCtiAqRZXgPRrZqX4w2umTERyFIWcmBB5l5bVs2Fahx1y\nhbyJNZAo1MyxpFfndf2kvSk51impfD/m2TXgvR0ka+Yy6haNuhPidNIAWd4d\nTr7OyO1X+VQddsz8PVhX32iELOLgnL51ArtY5jMAV9u2R153vr/Aup8j/9Ru\nTA6+Jpp3FTmYLmHsRouutd/dR8Xnw931f2BCpJBT5YAD5X/eLsy0zlszFHwu\n8KKegcwuKRu62qafiXJUR+JX05cWUndhd5FiKaBhWKIlY1qIDXjgHdYWQ8ym\n+RJ9Oh9+xMbLD9LbXJBFvmVlbiSKBBju1i+RU1vTg0XkzomDe8KzKC+TdCxT\ngJ0L\r\n=RuEq\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCU2wGRiaJNlT1xHiybuIkQx5aPZmeZ/F0EgibmlpJ9ZwIgIZXwrg+CcK+48m59Ew88Frs+hVTppaSVX6rcP5KXU64="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.27_1642342103228_0.9405356029396765"},"_hasShrinkwrap":false},"3.2.28":{"name":"@vue/compiler-dom","version":"3.2.28","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/core.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/core/issues"},"homepage":"https://github.com/vuejs/core/tree/main/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.28","@vue/compiler-core":"3.2.28"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.28","dist":{"shasum":"cc32a987fee50673f25430df35ea943f252c23e6","integrity":"sha512-KA4yXceLteKC7VykvPnViUixemQw3A+oii+deSbZJOQKQKVh1HLosI10qxa8ImPCyun41+wG3uGR+tW7eu1W6Q==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.28.tgz","fileCount":14,"unpackedSize":734311,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh6muWCRA9TVsSAnZWagAAKjsP/jGIX9Rtw7MlpU1mXgnA\n6z8X1QTvxeDncjmLqebsYEvct6QRaiFXWOs2plRTed/sSf1RLFnGGW/TBYDG\nJPC7lFiyfJXxOrEmpWDqkjp9lHWmNIEkuKlpoqKXiJkUzAy8sxaivS2RJuaZ\ntnt1BV2aNP7/BNk3/8V5TSjKTHquzxL1GbB3hv77WbXvtmdPBx78PK5wf3JP\nQE5c+XlhAfTjVFa+BPcuhzEWm2mrj7NmDOdU5pm3+Cl8/vcQHn9ymA9V+dLF\na16CMc4Ej4cMlTTqjfIIsfDjQANIN2mqAqGR50bemkU1EVM+nwyjFJLF7vvK\nwV+oWaEE/yqF4HIPDc8nCcg7HjMq2kdBJ6VJjTa9Rei3CEXqQDFDeG2N9rlO\nYEZeTxfA42woEQomtJHlP7bF7/SR/MGBKJ3zL989wmR98yq2NdaJv0LWdAJL\n7Bj6yJK4j6X3De0Rf1/T5KeA8YAWIDTCe66EXxuPxGuAIifVAKJEB7xYP6Vz\nNFXbJLs2ZeoZDupdnFEXamxkiitBrFBohPIF4UiVTWu4AfoQVkjObC8P+nxw\nPogErvBS+nG5aXiQhcGsiEd6Dvbhi34yuBeCMgArDmiXpgM59WHRpUtsKfen\n76ttxaafY2ZB2tTQ22nuBZg3g6JegJUyqLScCRavIONicTBUnrog85xXoxgH\n9x6u\r\n=umR2\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCc6jsNJm/aCa9lGFv+p//1yLvhhw9klE095s6MYHDelAIgZcjQn1YNkUPBwejpQE3jpBC8atyAPaXCew41VriDwqc="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.28_1642752918161_0.7879480049535883"},"_hasShrinkwrap":false},"3.2.29":{"name":"@vue/compiler-dom","version":"3.2.29","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/core.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/core/issues"},"homepage":"https://github.com/vuejs/core/tree/main/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.29","@vue/compiler-core":"3.2.29"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.29","dist":{"shasum":"ad0ead405bd2f2754161335aad9758aa12430715","integrity":"sha512-y26vK5khdNS9L3ckvkqJk/78qXwWb75Ci8iYLb67AkJuIgyKhIOcR1E8RIt4mswlVCIeI9gQ+fmtdhaiTAtrBQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.29.tgz","fileCount":14,"unpackedSize":734311,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh7V/2CRA9TVsSAnZWagAAPP4P/Aq1E4Dnip2h8Wate1uq\n+Peo06ewmKEQyWAhY4NkPKbPQFbOt6OJtc6OALRW/dQD91X5v6aAPoCihMGj\nNqBFCC2oANGZN98LjVrY29tofTFiBUqcsZMBPsNMsQWxA+Xrq8jUbSGkumZG\n96TuXUtrJ0cs+eYDWRJ7XBi76EytSA2E3zLK0FsVNOskjQDRXVEZ8oIpqrIU\nTQpIAV5lgVePK+swyeaql8P+rBRERmS7YaMZtwOit9bWi8ABTnFX3fTo4eK5\nh3HiKv2j/7vodW0lUXciv4HdfspcnFQJm1Cviv4jRhoW9ExgiM3+WklHd/G1\nZKIasHh7wlsceb6jAq57s9dUc0f90A2T2MsUZJCI7nnXbWGFc4MzvxgYjLGl\nT0CFqWQm9AjBC5PzzIYx+QOxjMssdWlOMPzFJ1QY7vzNPROuD1Ivur29Bg40\noE5dgho9LoRA1mY7vyKrzTqPbpZ8ruk2ykaRhHTGPlRIkj9VbQKhnoPQoluZ\n+ETbq/alG96pp6dbWfdgatWGgL+hQ3NLz5Wug1CdHICuadjqyrqQWcbifvdD\ntTI3ANTK65XR52t1pIwtcJPJde3ru1R2tYS6etQmCvVpRp7/WEmnjHCCzQvV\nsQ21b52/gsD17A+IV5pac6lL3YQ7ibAGv+CZFtRRfFdV5y7qnx4i46+o/pIF\nampW\r\n=4MA6\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIA8KzX5UVntuGWFnNEfLj20+9JAJQNYiL9be8Cv6fb/GAiEArKcCn5SzPRY483RrxUzjt0jdCwhH3LVQpl1k9Owi+jg="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.29_1642946550175_0.42960271180178555"},"_hasShrinkwrap":false},"3.2.30":{"name":"@vue/compiler-dom","version":"3.2.30","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/core.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/core/issues"},"homepage":"https://github.com/vuejs/core/tree/main/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.30","@vue/compiler-core":"3.2.30"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.30","dist":{"shasum":"ed15e6243227baeaa445d04df804aee6e4926eab","integrity":"sha512-t7arHz2SXLCXlF2fdGDFVbhENbGMez254Z5edUqb//6WXJU1lC7GvSkUE7i5x8WSjgfqt60i0V8zdmk16rvLdw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.30.tgz","fileCount":14,"unpackedSize":735261,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJiALjiCRA9TVsSAnZWagAARu4P+QFKuLCjYLCOhasqdWu3\nj+d3uW4ZhxCSmIYbq1tvnehkn4cf47Imsl+Xj+mjE2qNEAeWQ1iYKD9+sR0z\nnOaNRCYhJaEXGUz6G4mnuA6malV6qLDNwV3BroYN4Eur6o7MT9l9kXm7tRMp\nUETzLKRrEMgCcFQ3Mq01bjQXrmyck6cdUPVJBJFMZq5HKflpgeZfw+C5WD3b\nTfnPM7zVxgOB4Zm8v0Q3Nn0ipQkeN3a/4i3FxImZxqbXjbMcubJyr0k0bB1a\nWs63ykheRvdLYl4hOKasBRkw3rZCKjcs+tOhca9Ikj2ns96WPn6lojvyXDCH\nPMH12ET7GCJmH/Zv7jnNZrOa2iLIAheXddGrvnZofL8Dt3iQaFTBm5Oth8V3\nzZ+RPzegsMk5F++AeyyITuaGye973opZA533S7Wsu5QCjqEAtmfjGywdAIML\nY7KK6lgQIJ/CLfTyXbuavNSnseS13HrSyGiFB0r+VdIYwZCJPmHOkhfzhg3G\nSsTcldJlNq9yV9SIfQhdseS6Zm62hCPx/pSI32FHdQkHG+J1XzamLt3+0/RW\naoeZH0rUWDtykpO4gO2LWeTkiWXSidmSYongixxBE2X54wREj/PzsaKznPd6\nOqQzsYMU9OG08AWvl93JTGzcPHFn/T1RS+B+VFnDQixB5xU/XQsm4tWFhfHL\n502T\r\n=nV+d\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEE7guyTrM/ImWzm5zdOeO9hbhhx9/Dgu7x4REHfS6GlAiBURSBDVkJgGXlKPEoGiIUfKAYDFopWqffQhCVNPWsinw=="}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.30_1644214498295_0.09467184032213916"},"_hasShrinkwrap":false},"3.2.31":{"name":"@vue/compiler-dom","version":"3.2.31","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/core.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/core/issues"},"homepage":"https://github.com/vuejs/core/tree/main/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.31","@vue/compiler-core":"3.2.31"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.31","dist":{"shasum":"b1b7dfad55c96c8cc2b919cd7eb5fd7e4ddbf00e","integrity":"sha512-60zIlFfzIDf3u91cqfqy9KhCKIJgPeqxgveH2L+87RcGU/alT6BRrk5JtUso0OibH3O7NXuNOQ0cDc9beT0wrg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.31.tgz","fileCount":14,"unpackedSize":735261,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJiB3LVCRA9TVsSAnZWagAA5OoP/je2QEWo6SC9lhqj7e/v\n4ZOBtI7bUF+UbpJSCzXfrrBWkg0yQeoXN+fHX2ozeUhf0MWLc4dgbnUrTi2Y\n83wieX3aLyke3IHezN5JrPDSgCymZ8SXfaMDpyUX8NuYHwk7frzvaOWd8fsU\nTzZWKYLETlwj4/Yx+csQzRR1QTUzCYLzC84tt+2ZDkrzOI5nYhmzufLzlT50\ne/XR/UmNRuAViQ0ofwdR871J7gUx4cV1NI7NOxJ8h44A9+TH+qEMoOmxGeGd\nWV2plr4FK0ubVVvqbmOJYke9lgMaNk+YIG4mbh7VlKq56N1jpWU44REafafU\nncOzcgc3JUYkZIQ5YDpDe7UuQSliQX9KVTjJJUHC9U0BlvuxWkEQgltC8v7v\n/P0Ov/iq++dERD3A++r8fWQPLYblT9Yj3uybaA+vjcGHj4X3uU59hi7XYkLq\nrxRzy/Cgb6nrCRaqVLIe53PA7LDCsTAviK4wHOo3Lq1wiLnANTTznjNfgjf7\nEaPi5To+/8QyE7wPJdJabQorPQqgDzdC6LUO5AG9KK8CRYCMzrUOfi0uJTjh\ne/jU6eoUnFgxAa3Zds0udp22bb9HAR8mtWsWLR35GmQX8HfDH8HXmY2cvv1m\n60RkS2g/tUVyeE25Ps0ZZScjzTZJJ524CYEnYCZz3eD684oOEGaq3n3WLxTY\nZ/P/\r\n=khWI\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCVr0gRifQ1oJ1zqONfXNMmmEOXCWi8fDXpG8l3CBgxDAIhALKZ7vt0mP7kTGfqG4t3VxX1NAc2m655wtqJBRaTKfFF"}]},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.31_1644655317396_0.9656397068081799"},"_hasShrinkwrap":false},"3.2.32":{"name":"@vue/compiler-dom","version":"3.2.32","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/core.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/core/issues"},"homepage":"https://github.com/vuejs/core/tree/main/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.32","@vue/compiler-core":"3.2.32"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.32","dist":{"shasum":"8ddae1ee463c18c5c3353c4716ec7c84ee29e5ad","integrity":"sha512-maa3PNB/NxR17h2hDQfcmS02o1f9r9QIpN1y6fe8tWPrS1E4+q8MqrvDDQNhYVPd84rc3ybtyumrgm9D5Rf/kg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.32.tgz","fileCount":14,"unpackedSize":735261,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDJI4m01FJMXqAgrtF3VWLJtmmJg9s1gCK/eG0S48mRkgIhAIwSM2ndzzl+a0OPA8nA5WnI0ni8wy9wblQco4LBJsDu"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiVTNSACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqCxQ/9ERrjEdFDKlChk4fGd9oSEuxOBkRgQ/ZVdtccBEPWZeQ8aZ8r\r\nDEFsiShvdCGRv/yJlEGiw1OaxB7g2xHaKCRduPck/luwlt883mnUrttSe7kP\r\n/h4txmeC8DiELQzpkTdXenCw7tpf0bx/XTnjjdkb80xZHQ591ZDKK/IFV6Ap\r\nyAwbqpT5ExmYsVkr3eFzUW7N0zDoooNR455f4X10BNE01bBAGOz4TgQ9f4oH\r\n5biHaIcqXO0YSddeW9KQnqTgLPabglEZBy0IHGk3Lwbsdjkvkaz0YIOeqJcx\r\nBvYSVLuhgtL0eZ0LOo/QzkoNmDlIxs86szSEedAWa0pIWxgcPrdf8IM10Fdh\r\nkEslTA33a92V0m4uoWj8myEelJzbCM36JjwTwJsESYeIHQTgeV+KAaVAb8V4\r\noqs3C2VhqD79pLmjGTaeGGOV+gkq9w2Il0UMuzAvkVhmqhezF6OIbBvDKAWR\r\nlV5V2SGosZzC5sOV/8UGtIs/BVNuP6l9Y2N0nsCE9E8fdfxya4iOb5C1TMPw\r\nArC+ynmHKttSPJGDm3Kxd19Yx7zncBvFoCvEKKBWcWCuvu/IJgf+b5a/+Rzz\r\nQ33IYM3DwKpNcpt4XPZNadvbgis/Qbe1SurYHWyEpgfF9NRqH8YJFGZurzIL\r\nTP94hz91IDwe/p10J0mczjm3bNOrWL8mkms=\r\n=1p1U\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.32_1649750866312_0.7500334028360971"},"_hasShrinkwrap":false},"3.2.33":{"name":"@vue/compiler-dom","version":"3.2.33","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/core.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/core/issues"},"homepage":"https://github.com/vuejs/core/tree/main/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.33","@vue/compiler-core":"3.2.33"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.33","dist":{"shasum":"6db84296f949f18e5d3e7fd5e80f943dbed7d5ec","integrity":"sha512-GhiG1C8X98Xz9QUX/RlA6/kgPBWJkjq0Rq6//5XTAGSYrTMBgcLpP9+CnlUg1TFxnnCVughAG+KZl28XJqw8uQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.33.tgz","fileCount":14,"unpackedSize":735261,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCw3+AFpJ5akF4OfIyc0anu5W5YOpiGxlC/QK7lAgiqbgIgWU0cEGJF/sKzQX0XlK45JVPWIzzSG7TX5poD7xRjum4="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiV/QPACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmochBAAhJ4vEd1YN9jIRHatnHmld6cAz/SHIJIY3zKIgJ2NpBnluUVD\r\nbhjbelvwc8yDu+X95tRsf8FsIQ2+P/qBK7ZFDkTWSsIr8/2FVgblfkmt3mwP\r\nQKvGReOUgX8t9Vr6kfsFcGF5CJY6+GBpggXaOio8DNXGs1XmvvpOzw5T7pZj\r\nVTHXqxvgV5dTNZ6NFQdKFH1On992xJ8jzv9yf/VQBp99SVeikfNbi6ocTp6u\r\n46IxJNuz9vHC9ztHUw59KCxxEid0+8M4+/WNA1FY6y6MkNKE3wcvmURlslfX\r\nnAieYP8YYL1ERUoQRgGuK4Dajnl8W69EqI9oSpnN745MTRz9PpdMXBMXbhmk\r\nwwAKjES/X77bndAgxUoXnGwjZ/r8prQOeTFkEbJwNnPRUU9h3YJlpIIFX08e\r\nmiBlQhgjV81ZyCNIkATXqVWI4BFZprhPmjxqhfBwwudGKO5Rtuu19d49oLRr\r\nc1ljUj3lC0jaPWbMcbi7cHM/XxUWrBhWsJ0aZzgS6E0J6cgqvBphZnZ4m7D7\r\nvpMoUd2IfFrGiBHerCXh8fPtpOB87MOb/TQ6FApRcbSCieliVP950Vh6kWQ3\r\nfn7ksEl/cXQHsCCp6WvPXuyp9oWh3eSuR8t3PugjQNanZDmbEoau2kd+G88K\r\nx8r4Q0bZ3hnAKZ5N+3p+E5Emk3bKSSYHCSc=\r\n=vUFS\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.33_1649931279565_0.0911598572082819"},"_hasShrinkwrap":false},"3.2.34-beta.1":{"name":"@vue/compiler-dom","version":"3.2.34-beta.1","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/core.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/core/issues"},"homepage":"https://github.com/vuejs/core/tree/main/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.34-beta.1","@vue/compiler-core":"3.2.34-beta.1"},"readmeFilename":"README.md","readme":"# @vue/compiler-dom","licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.34-beta.1","dist":{"shasum":"fc7a1a34b00ae380f6b36f41b6773faf4454cfe2","integrity":"sha512-VF60DU7TsvSDAP1jEki+ZmI5UG9MWoJxu9dcXwI2SSXECTMjfkVBDDTIWPCPKw8Qmk9OID9k0JBW1mKpR3o+Og==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.34-beta.1.tgz","fileCount":14,"unpackedSize":740474,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDxFjsYKWtg5xh9JaT/ILAQ67yBbeA9o2VNPlaCyM9wlAiB6Jf6Oi+eVr3Eq6Wa2SGW9sp30Fm2dluY3j9ro9SUkGg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJigyphACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq5lw//RJ+yNTWiPvIzri9i2hgTrIVn9qXSCZUdUC5+Yl9ykMIb1Nqv\r\nEgaVll90K2JD74jzAcT/bkbqVhTFMMETi+bbhi+q6byErU4Z+BZy6AOzTwL2\r\nykev5e0V1MIgVVSXRTRNJx7LpOTQXLeuRlvIvghTqJok0FdBwHGmR9WzxUNx\r\nxVZdU6m6qalf7u4Mw/8YQ2myQ6pJ3aPla2LTO0QUdnkiIDN5iC13W+JQ0Jf0\r\n0zPaEVk8WERbEbpm/DMfmiTb50gUNWnDBMFtIVvhZp3N59DNEz9UWDGvsGn7\r\n+q8fJrsY9ucY9cQ0+h552LiJiBmJZa2nbFNL3Y7cJbBmx4PoI6OFH67zwAeu\r\nuzskPnvmwgvCJsW7fjDlgNvMfNKw4QbMRj2ZxLHiOxkOWLPdZ1cN5vpdPvsc\r\nlwwm6Y6IJ7bLNwJez+9i57eLxAZcwSWwOOFmq9LnCzeASP8lK8qAFW2Ji6jN\r\nZRk8e8uidsD/YaWz0fti3/Tf8suvQa5O2WqrEX+cAeg7k2hgv0bpgArpJixs\r\ne/5G4N/IlcHGOZQgV2yUCzGd5pfsIEj50pCzKQuVo0UoGWInj+rhn/HlWZf5\r\npWAyA++/7TaQ/O/La+g8kg6ItHDEUtG0pHimr/H9J0OMtWG6mp4SGcZXLQcY\r\nrDpMNOL5lpAQJYNcXpWbNTextz2L1LogoNg=\r\n=sif7\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.34-beta.1_1652763233562_0.6796908697917228"},"_hasShrinkwrap":false},"3.2.34":{"name":"@vue/compiler-dom","version":"3.2.34","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/core.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/core/issues"},"homepage":"https://github.com/vuejs/core/tree/main/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.34","@vue/compiler-core":"3.2.34"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.34","dist":{"shasum":"3aadd83fd789c7feaa56f838e86c5c7146395579","integrity":"sha512-MFLUYDgy0aES9x1goU/pgxpzgT9IZOndO8qwQVSyVfUvl/CywEBtfBi5+8fsiBDhoGIT7g8qcsUUF1NYViU2vQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.34.tgz","fileCount":14,"unpackedSize":740597,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCC8Dew6ySofqh8xqMqrilqT7k0meLzuoZRnzXw7T9DdAIhAL7p+enBGka5uLQOw804L3uEqrOpeeUUBfv20uT6SZcK"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJihcq9ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp9KhAAgJ7aJFevE0yXomhWLAsrCexiOA+N6ycc+/P9frJ97hqDdEP4\r\n7f/sjbz8ofp/8Kct9ZOy4yrzmS/VVkhJ/FIPD8wGCVTJkciIw3redx/uhif+\r\nX/XiVD7L+b/Vz7iDfyLZ/iZB890Qk2wufSdg94a888A9m6SiArOwtAI+cD1W\r\n5XocRf3ymWLBv/t1LpeJQ4RCc5EzsTmXG1215noe5UC1Ohm0hBd26EP+C9Sl\r\nbHrYg4jKU9U5Fvx+acTOmfart7c2C0aLFM8g4TsWvjAHpq/owpUa9L4mOhEI\r\n8H5QaVCdbkYiAg03YDRc1WDI+RFzwPPaOP7Bw49airvGlLEB1pQkZEIC4sIw\r\nrWgtCLrIEPHF/SNpbPFh38OkSzD5V0JA9wiSZI+0LS3cBRoQsmcFHXT92Vu1\r\nPPjrXW8lCT/lE37RRnjfWtjuvtOEg5ErSosoIzut9wjyh5ZGl2qtgx4Cbxry\r\nuAhyaLmsXZzX4f43ApZQ6NMLmJ6Pph2pjzlk3XWKD/pdm4p/AQ3wnK9CpSZ8\r\naB9lsjHKXqzdAPyCDHVXn9K4KILxrzwv+O+y4lT4GvFpurxhZbXQc1x8MDrf\r\nngh9UF/U+HMvD29A0VMmODm87XGrCvfpESYOiBW7uQayvNXWxr8DrJZYm/lc\r\nYWrYPf7pMzUaC7bOKWGKXNgHJGAr3iakwbs=\r\n=YupW\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.34_1652935357339_0.08238137453323202"},"_hasShrinkwrap":false},"3.2.35":{"name":"@vue/compiler-dom","version":"3.2.35","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/core.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/core/issues"},"homepage":"https://github.com/vuejs/core/tree/main/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.35","@vue/compiler-core":"3.2.35"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.35","dist":{"shasum":"11bbcca0d49f9991d64dd8fbf8a0a4453caa571c","integrity":"sha512-I4bXB9MkRSTJ3gVXRQ4iaYJgABZGew+K/CCBoAh9fdLaeY7A7uUlS5nWGOlICSVfOH0/xk4QlcXeGZYCJkEleA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.35.tgz","fileCount":14,"unpackedSize":740597,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFFSPhx+m7ntu3srsh+UD8+ilQPzUuEvGnBhfmdRF8MtAiAMSyTRV1eIU8TGEHwygfkxFbora+uqVy+sjH/W2OWN+w=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJih8ztACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoaYA//WJMfR7t5/3ibz5wS9UBlyQ9uc6f3eBtJ+pi0pBJENaeowAjj\r\n2hEtsL8Fe2Jb4dIdUzbpH8ruFvLKlk990Z86aAifmXZfh3Y4nbBRhqjKpqz8\r\nij0rxpl7fh7SkEQ0avgwQKD+jzEzBsTI1oXCi5iLjAnjbjYQ8ekwq+eqzTtL\r\nkAlbxpUyr/QXFalP38ntSba0bOiDBModhfuWa9h19Uo/9M/ny51lIaItJ8BE\r\nMGyhGo9r45PEzAYl00tZUIaKzZC+iwU/CeIniTweCXwnp0v+Zc79YkrGeqTj\r\nFRbAtHv6vVNfPCH+Ra1d2kaR0pQ7967+0RU+mxhcIUbv9qsjPhoy5ZBQ4tI7\r\nJb7AOkYhwqZr7QKsOvTxZ7A1y7Vm8y2F9agtCk16i2TM4F45wG31JLEb91Ka\r\nsz9icW1sjcpjLvO4KczWYZjgVRHh7AB+qXVBOQZHEOe1eK4uSJmI3KjtWf6y\r\njyX6g0n9vSwWo/pparjbJ0gS9LBr0UWyE9Mb0BIj4oq6jlMOJq1giqd3nts1\r\ne1oL4ZoUlmWlu3/0pkZSXhFpxiOE0bG+A4179emNkR7X9DC/YR21JHQwfxN+\r\nr5CqmafhSpUXGJsJOVzXWBg5/uxAbZmtGEZ7tv6UIGnvDmvYAP3SaScK0IyF\r\nBAt0I1D+X5TqKjQqTEXjAJdy37yha2roYGc=\r\n=apUo\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.35_1653066989484_0.07061232591391708"},"_hasShrinkwrap":false},"3.2.36":{"name":"@vue/compiler-dom","version":"3.2.36","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/core.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/core/issues"},"homepage":"https://github.com/vuejs/core/tree/main/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.36","@vue/compiler-core":"3.2.36"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.36","dist":{"shasum":"16d911ff163ed5fc8087a01645bf14bb7f325401","integrity":"sha512-tcOTAOiW4s24QLnq+ON6J+GRONXJ+A/mqKCORi0LSlIh8XQlNnlm24y8xIL8la+ZDgkdbjarQ9ZqYSvEja6gVA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.36.tgz","fileCount":14,"unpackedSize":741601,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCID7h1viEl5+8hUZHIBpQemmb6FYxSbnk8Rvpmt/u1JcrAiBz8TLry401VNlsCHxjtYKp4TKHFvn8XBJJFIpAcLU+Tw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiiuufACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq8vw//S4PI8gMTlt3q4iLylxDxNt57+16B+2/HHPEIT3shP4y7Mqk3\r\nLfdSRpkhUC0/4renzELDTfjyMt7NQP2gXSuVQ+qGovpRsGhi3jI+8TGaA1Cu\r\naxiBcGL/pPcF/YnHhTSigI34IAGmtDQjNhZM/IwGynyyv76Ljl3vYSdGiuhA\r\nj83SWDqmJnr5D0ENU0piu0wgVfLHsV1tyzMSooK+OaS/MqonrvHamHfWglXA\r\nNwS64Va998wNWu/qpQUly2LMno6o5lxPlVMCIBVROX61pu934XlTK5tdZZ32\r\ndoI0njl13HFhK7K4Zi/p1w6qbIGBCfcYTq5dIxneHxjRvHmM9s8o5ayzPQNL\r\nmL2aXyRm3VakiG02GTEjJ5P83NekjuQP3L9l7iJktlsHDOmOdU/rbsnUZSmh\r\nxwY/X+mMA6kvks2PolCzYYi25aobRJFTyLJ+4bS3oahATVcf3OMMD2110E4c\r\n0JaoUIM30z9EAbsvrV90XbHxw7nCkU6bHPUtCOSaGwf2gZ6J2HG17ND48vab\r\ntWwA3VZdgaUncUNk0wMPc7Sl/Hwe8WRw7X2rDw1iFmVyAkcfSJtusiu8QbYj\r\nOWm01uLL0bJaG6jqiCQzLdkyb9s3aez6P7BKE6Wf8YCNdo6n+haHlrCZfn+A\r\n3tjWadAtI9xKCyqkwpnctWdQWCfRUzCTCLU=\r\n=YKNr\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.36_1653271455324_0.16589417802620376"},"_hasShrinkwrap":false},"3.2.37":{"name":"@vue/compiler-dom","version":"3.2.37","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/core.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/core/issues"},"homepage":"https://github.com/vuejs/core/tree/main/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.37","@vue/compiler-core":"3.2.37"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.37","dist":{"shasum":"10d2427a789e7c707c872da9d678c82a0c6582b5","integrity":"sha512-yxJLH167fucHKxaqXpYk7x8z7mMEnXOw3G2q62FTkmsvNxu4FQSu5+3UMb+L7fjKa26DEzhrmCxAgFLLIzVfqQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.37.tgz","fileCount":14,"unpackedSize":741601,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDoV34BXHP9hQNfDPhJ0JvWyEIwVQi89bBSee4pubxBfQIhAIVMcpOenjkcgDa4bIKFPescDchYQpAzq2SWKV305xMv"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJine42ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqc3A/+IOTjAY0SsuKSwz6v9Zfe/QQ6DB5AKZv8yavjUyLrZS7nvb20\r\nQiFO4r4MuOdPLL+OwjWnZEUq/wvbcw16iOuueJ8KhoDhllpUo/8eD8V/xkAl\r\nD7JL7/aaaV5FrIPnbcYIMOQUnjSfJkGvFHrzLZS8wa2hlCr2lGfVO8eYo1qs\r\nEjEoJ+J3XOpOauzxI+udkTK5nqzY4wDDdUuu8DzoHdfqApKtwaOwXjSB+PCG\r\n6fsWqERN8cQtDLI07tsxjKjHPZ1TbbgqYaHaLg87wXcBmMJGtSX7FeXvj6Fm\r\nK5B8UXTlLC10xM5wsNva85j1PevI4NW0xwaNFfWsLDloqzADMT3Xr7fInlPk\r\nTY5gSDK/Igo8S3w4ZbZjKfCBn21BfvjAVvyExfXE/Wpr5EbDCTf7FLUqmOUs\r\noMTwEw1+U1xKaPWGC+bnqM+aM1SdpqycyygxRqURVYgjPCzCqN60+nr8jDkg\r\noI2CoYnFjer7XS4DfkxJtdCbgUFAp18Ecsc2VHYgnDoAwkan9qxTyRnUsTP9\r\nQ6yrlA5maGXBGuDgeQlTsaYnpxU7DV+SjISub+bz/gvTAYzewPmQ04vM0Q5V\r\n7vEzHCKGYrC/nq6AIC6G/rWnJc7a08sAhLZS/B+QTBtR2gBGjXIFILeB0Sj8\r\n44uo/AW81Hsk8sNngfO3Nc55DmG5g4eoQoQ=\r\n=geCM\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.37_1654517302257_0.9508604786109682"},"_hasShrinkwrap":false},"3.2.38":{"name":"@vue/compiler-dom","version":"3.2.38","description":"@vue/compiler-dom","main":"index.js","module":"dist/compiler-dom.esm-bundler.js","types":"dist/compiler-dom.d.ts","unpkg":"dist/compiler-dom.global.js","jsdelivr":"dist/compiler-dom.global.js","sideEffects":false,"buildOptions":{"name":"VueCompilerDOM","compat":true,"formats":["esm-bundler","esm-browser","cjs","global"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/core.git","directory":"packages/compiler-dom"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/core/issues"},"homepage":"https://github.com/vuejs/core/tree/main/packages/compiler-dom#readme","dependencies":{"@vue/shared":"3.2.38","@vue/compiler-core":"3.2.38"},"licenseText":"The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","_id":"@vue/compiler-dom@3.2.38","dist":{"shasum":"53d04ed0c0c62d1ef259bf82f9b28100a880b6fd","integrity":"sha512-zqX4FgUbw56kzHlgYuEEJR8mefFiiyR3u96498+zWPsLeh1WKvgIReoNE+U7gG8bCUdvsrJ0JRmev0Ky6n2O0g==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-dom/compiler-dom-3.2.38.tgz","fileCount":14,"unpackedSize":759600,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC2mAYyYXARZ7RbubvapagWysT3wXmdqTbrSWTqw9KA3QIgOWXOYUllQuZbkyrKbvJKZ6QMkRLzwkGQ5HcpU/4gFnM="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjDcP8ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoA7BAAiXwXIr6HoY3c70aUrlTuChXxy29bfSEY01vGMhnbirIX09m6\r\nL6KKHDiaGolS3z9f9jlT096Lc5KS30RwOyzxlMNpkhT0v7aFb9t55kFQoDt7\r\nvtXMgqitb6QnNEr82mSt0TZEmhwTIdAoKfxH4vlxgQ+mnyRzjkZll6laf0oY\r\n/QFeiM5e/eeM56Es3Hh7l/YzaBSxbQpzrgdtCYQOkQj3AW2jIqKkkDuzgYd6\r\ntc9Vj1Zon3ANrFEvHFexrLQIG3g6hTLU47XJTwhFh/REXBwo3cM8sSwSYxOD\r\nMtYGZP1flljae4MHsAKvc5AYpqMPPCD2sBPtXYYnrIeJT9sfP4UEPiiySLA0\r\n76r7Fo1LM+ztzHhO9qF650066xcfy5VgUpL4dW8FkLZZG+3b1LrUC5L6G3vJ\r\nTlSQ6JluSUmBSDZw2QhLuZ81RAj+ePZzid+A7mTdj+bv8P6BgnfdwhC7DStf\r\ntNw5pLK88cdeBkY2F4mx7ddV5fB5ro8r92JVL3kIxAjZm/h1tZhuqAterBk0\r\n3zEEzpmgFzsWEg6ZZZtSbMdA608wDwH3CqCDKZW0hMRhdOUajN/YnedVnL4r\r\npqU+xwJm3TtL8nXcJrMUEDBE6KE22JQB4l+fko7fFn3/x2kInSpAG9N89cLx\r\nDACI1LOmo/ZF11abCcX87xzC8xhTmkHOouI=\r\n=jj9S\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-dom_3.2.38_1661846524253_0.9281179130610613"},"_hasShrinkwrap":false}},"time":{"created":"2019-12-20T18:39:46.475Z","3.0.0-alpha.0":"2019-12-20T18:39:46.788Z","modified":"2022-08-30T08:02:04.640Z","3.0.0-alpha.1":"2020-01-02T23:25:27.104Z","3.0.0-alpha.2":"2020-01-13T22:44:38.940Z","3.0.0-alpha.3":"2020-01-22T16:10:37.866Z","3.0.0-alpha.4":"2020-01-27T21:20:13.567Z","3.0.0-alpha.5":"2020-02-18T20:01:04.125Z","3.0.0-alpha.6":"2020-02-22T07:25:42.675Z","3.0.0-alpha.7":"2020-02-26T19:36:48.071Z","3.0.0-alpha.8":"2020-03-06T20:58:50.156Z","3.0.0-alpha.9":"2020-03-16T22:56:51.032Z","3.0.0-alpha.10":"2020-03-24T22:33:47.970Z","3.0.0-alpha.11":"2020-04-04T01:45:58.960Z","3.0.0-alpha.12":"2020-04-08T22:59:56.979Z","3.0.0-alpha.13":"2020-04-15T16:46:35.781Z","3.0.0-beta.1":"2020-04-16T19:45:14.765Z","3.0.0-beta.2":"2020-04-17T15:01:08.815Z","3.0.0-beta.3":"2020-04-20T21:00:37.990Z","3.0.0-beta.4":"2020-04-24T20:20:28.453Z","3.0.0-beta.5":"2020-04-30T20:20:37.605Z","3.0.0-beta.6":"2020-05-01T22:57:02.465Z","3.0.0-beta.7":"2020-05-02T21:06:24.839Z","3.0.0-beta.8":"2020-05-04T14:49:35.575Z","3.0.0-beta.9":"2020-05-04T21:14:51.176Z","3.0.0-beta.10":"2020-05-07T15:21:26.564Z","3.0.0-beta.11":"2020-05-11T18:25:51.165Z","3.0.0-beta.12":"2020-05-11T19:52:47.464Z","3.0.0-beta.13":"2020-05-17T01:53:55.257Z","3.0.0-beta.14":"2020-05-18T18:42:20.197Z","3.0.0-beta.15":"2020-06-12T22:09:15.478Z","3.0.0-beta.16":"2020-06-29T22:34:58.582Z","3.0.0-beta.17":"2020-06-30T16:08:52.085Z","3.0.0-beta.18":"2020-07-02T01:06:34.664Z","3.0.0-beta.19":"2020-07-07T14:04:48.692Z","3.0.0-beta.20":"2020-07-08T16:45:37.870Z","3.0.0-beta.21":"2020-07-14T21:18:17.397Z","3.0.0-beta.22":"2020-07-15T16:43:57.367Z","3.0.0-beta.23":"2020-07-16T16:49:05.755Z","3.0.0-beta.24":"2020-07-16T17:52:01.487Z","3.0.0-rc.1":"2020-07-17T19:30:25.395Z","3.0.0-rc.2":"2020-07-19T18:52:50.934Z","3.0.0-rc.3":"2020-07-21T19:27:35.964Z","3.0.0-rc.4":"2020-07-21T19:40:53.283Z","3.0.0-rc.5":"2020-07-28T21:42:13.729Z","3.0.0-rc.6":"2020-08-19T22:17:52.246Z","3.0.0-rc.7":"2020-08-21T18:13:13.495Z","3.0.0-rc.8":"2020-08-25T14:32:05.432Z","3.0.0-rc.9":"2020-08-26T22:21:27.570Z","3.0.0-rc.10":"2020-09-02T16:42:05.046Z","3.0.0-rc.11":"2020-09-15T17:15:51.159Z","3.0.0-rc.12":"2020-09-16T17:50:27.313Z","3.0.0-rc.13":"2020-09-18T05:39:40.874Z","3.0.0":"2020-09-18T15:28:13.902Z","3.0.1":"2020-10-15T16:37:31.258Z","3.0.2":"2020-10-20T20:24:22.660Z","3.0.3":"2020-11-25T16:16:31.682Z","3.0.4":"2020-12-02T22:23:53.247Z","3.0.5":"2020-12-30T20:50:34.582Z","3.0.6":"2021-02-24T20:19:41.798Z","3.0.7":"2021-03-01T15:59:34.931Z","3.0.8":"2021-03-26T21:35:51.208Z","3.0.9":"2021-03-27T15:30:18.415Z","3.0.10":"2021-03-31T00:05:50.988Z","3.0.11":"2021-04-01T23:52:51.824Z","3.1.0-beta.1":"2021-05-08T20:24:40.281Z","3.1.0-beta.2":"2021-05-08T20:59:18.310Z","3.1.0-beta.3":"2021-05-12T21:37:12.866Z","3.1.0-beta.4":"2021-05-24T23:16:51.734Z","3.1.0-beta.5":"2021-05-26T20:06:59.581Z","3.1.0-beta.6":"2021-05-28T20:59:02.870Z","3.1.0-beta.7":"2021-06-02T20:13:01.666Z","3.1.0":"2021-06-07T16:38:47.570Z","3.1.1":"2021-06-07T20:27:00.110Z","3.1.2":"2021-06-22T18:24:56.491Z","3.1.3":"2021-07-01T23:28:12.268Z","3.1.4":"2021-07-02T12:37:56.847Z","3.1.5":"2021-07-16T16:38:07.066Z","3.2.0-beta.1":"2021-07-16T18:44:10.918Z","3.2.0-beta.2":"2021-07-19T23:37:01.186Z","3.2.0-beta.3":"2021-07-20T21:47:08.405Z","3.2.0-beta.4":"2021-07-21T21:40:30.183Z","3.2.0-beta.5":"2021-07-23T20:10:26.427Z","3.2.0-beta.6":"2021-07-27T22:56:06.321Z","3.2.0-beta.7":"2021-07-29T17:21:35.183Z","3.2.0-beta.8":"2021-08-07T03:12:32.531Z","3.2.0":"2021-08-09T19:51:58.086Z","3.2.1":"2021-08-09T20:29:58.556Z","3.2.2":"2021-08-11T15:40:29.836Z","3.2.3":"2021-08-16T22:25:36.744Z","3.2.4":"2021-08-17T16:26:56.283Z","3.2.5":"2021-08-24T15:54:27.986Z","3.2.6":"2021-08-24T16:54:35.440Z","3.2.7":"2021-09-01T22:05:21.179Z","3.2.8":"2021-09-02T18:46:35.590Z","3.2.9":"2021-09-05T22:24:06.101Z","3.2.10":"2021-09-07T20:20:12.470Z","3.2.11":"2021-09-08T22:58:18.856Z","3.2.12":"2021-09-17T14:55:29.178Z","3.2.13":"2021-09-21T18:22:57.620Z","3.2.14":"2021-09-22T22:37:00.075Z","3.2.15":"2021-09-23T13:49:02.478Z","3.2.16":"2021-09-23T14:17:04.919Z","3.2.17":"2021-09-24T16:43:13.919Z","3.2.18":"2021-09-24T20:05:20.242Z","3.2.19":"2021-09-25T18:58:23.044Z","3.2.20":"2021-10-08T17:01:54.185Z","3.2.21":"2021-11-02T06:35:18.228Z","3.2.22":"2021-11-15T03:45:08.880Z","3.2.23":"2021-11-26T06:33:53.789Z","3.2.24":"2021-12-06T09:03:17.033Z","3.2.25":"2021-12-12T04:21:19.237Z","3.2.26":"2021-12-12T07:03:34.429Z","3.2.27":"2022-01-16T14:08:23.518Z","3.2.28":"2022-01-21T08:15:18.462Z","3.2.29":"2022-01-23T14:02:30.459Z","3.2.30":"2022-02-07T06:14:58.543Z","3.2.31":"2022-02-12T08:41:57.643Z","3.2.32":"2022-04-12T08:07:46.719Z","3.2.33":"2022-04-14T10:14:39.887Z","3.2.34-beta.1":"2022-05-17T04:53:53.780Z","3.2.34":"2022-05-19T04:42:37.545Z","3.2.35":"2022-05-20T17:16:29.715Z","3.2.36":"2022-05-23T02:04:15.589Z","3.2.37":"2022-06-06T12:08:22.503Z","3.2.38":"2022-08-30T08:02:04.554Z"},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"description":"@vue/compiler-dom","homepage":"https://github.com/vuejs/core/tree/main/packages/compiler-dom#readme","keywords":["vue"],"repository":{"type":"git","url":"git+https://github.com/vuejs/core.git","directory":"packages/compiler-dom"},"author":{"name":"Evan You"},"bugs":{"url":"https://github.com/vuejs/core/issues"},"license":"MIT","readme":"# @vue/compiler-dom","readmeFilename":"README.md"} \ No newline at end of file diff --git a/tests/testdata/npm/registry/@vue/compiler-sfc/compiler-sfc-3.2.38.tgz b/tests/testdata/npm/registry/@vue/compiler-sfc/compiler-sfc-3.2.38.tgz new file mode 100644 index 000000000..a12455d3b Binary files /dev/null and b/tests/testdata/npm/registry/@vue/compiler-sfc/compiler-sfc-3.2.38.tgz differ diff --git a/tests/testdata/npm/registry/@vue/compiler-sfc/registry.json b/tests/testdata/npm/registry/@vue/compiler-sfc/registry.json new file mode 100644 index 000000000..ec24f27e5 --- /dev/null +++ b/tests/testdata/npm/registry/@vue/compiler-sfc/registry.json @@ -0,0 +1 @@ +{"_id":"@vue/compiler-sfc","_rev":"169-86fa8aa102916a22c8bb8dd0f280ce79","name":"@vue/compiler-sfc","dist-tags":{"latest":"3.2.38","beta":"3.2.34-beta.1","v2-alpha":"2.7.0-alpha.12","v2-beta":"2.7.0-beta.8","v2-latest":"2.7.10"},"versions":{"3.0.0-alpha.0":{"name":"@vue/compiler-sfc","version":"3.0.0-alpha.0","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"prod":false,"formats":["cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue/issues"},"homepage":"https://github.com/vuejs/vue/tree/dev/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-alpha.0"},"dependencies":{"@vue/compiler-core":"3.0.0-alpha.0","@vue/compiler-dom":"3.0.0-alpha.0","consolidate":"^0.15.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","merge-source-map":"^1.1.0","postcss":"^7.0.21","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-alpha.0","dist":{"shasum":"f6376bca7f92421490b1e2a259e2a47f53aa3fd6","integrity":"sha512-4hXGviUL//FXdiLIqnTLc9hZsYu/UBe4/HKy7IfFGIs2t1cjkim1IOXv4Psu78h8XwFwGTRKKo+p2aOZRim86A==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-alpha.0.tgz","fileCount":6,"unpackedSize":36293,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd/RV3CRA9TVsSAnZWagAAPuYP/jF4aZtv6eSL5Ci5pCIQ\nR35A2IzSa31d2fkHFDg0PIR4+3XW6SC2J6EzBl9WzMdiksfBcOQPQ0Xcv8dZ\nLYR8sPiyU4dyJOay+fdcrY21Lic8T6/cirpuz0vwRXZE0qUAgmdqujqXG4tY\nZKdER92A3NdboMUeWZzQoEBYBljhhzpIYt/RaSFxeASAUB7nwN3iKg3qfM+F\nsIuhGl8NzMHeVoFSLR44BD/9IYXpA6c9VBx1rVPyEyH4frwxb/hOUtc1n/Jl\ndhoBovHyxsQDMdPKy+WzxXYqTF6kMGb54yeN7nbDe8T4X13MnZBiowOL8RQz\nrq9ErNmZKo6zh1O5zIPEsaVllCl6R5gA6s89WiIywxoP8/hzS+fpF0vURgij\nw+AmDo0aALG1Jjd/bWoaej/vlwru1ag9Zq79fOvHcpeNadSRdg24Ps26FHmL\n8bH0Vpj7Mu1+UI5BEi91z0zSxkerrfa4LFWyFczrl96JwBVO7k7EdmF0AKZO\nDjc+q28BJnXf2304SawDtQz0WBrXu/8UsvI/g3KVwf8L9L6Gn3uz/PAfWQEY\n+L8D1D9IuFazBsLCX7CeQ+yUcnDkEQMJni4OyYfPkwAZ1T8MDElYDDvRZ1B3\nS0OFiWtRWRSREjAJmoY9k28KLsPmy6gjRr7MvbfydDybWAqNZYHmen7A8CHA\nw2mE\r\n=Lqo+\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCvqMq4RzdS1TQn/+nMJnZysyFbjoNDWG3sG2xxJCbctQIhAInpnymjPTUTw8jaez17wWrmWiPA/17qkMAazv+TR/Id"}]},"maintainers":[{"name":"liximomo","email":"liximomo@gmail.com"},{"name":"soda","email":"haoqunjiang+npm@gmail.com"},{"name":"znck","email":"rahulkdn@gmail.com"},{"name":"yyx990803","email":"yyx990803@gmail.com"},{"name":"michalsnik","email":"msajnog93@gmail.com"},{"name":"chrisvfritz","email":"chrisvfritz@gmail.com"},{"name":"eddyerburgh","email":"edward.yerburgh@gmail.com"},{"name":"ktsn","email":"ktsn55@gmail.com"},{"name":"nickmessing","email":"dot.nick.dot.messing@gmail.com"},{"name":"akryum","email":"guillaume.b.chau@gmail.com"},{"name":"mysticatea","email":"public@mysticatea.dev"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-alpha.0_1576867190803_0.9347892950328227"},"_hasShrinkwrap":false},"3.0.0-alpha.1":{"name":"@vue/compiler-sfc","version":"3.0.0-alpha.1","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"prod":false,"formats":["cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue/issues"},"homepage":"https://github.com/vuejs/vue/tree/dev/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-alpha.1"},"dependencies":{"@vue/compiler-core":"3.0.0-alpha.1","@vue/compiler-dom":"3.0.0-alpha.1","consolidate":"^0.15.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","merge-source-map":"^1.1.0","postcss":"^7.0.21","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-alpha.1","dist":{"shasum":"f703abcfca73d39cf79286e58b88fe1cd884967d","integrity":"sha512-ww8WF5U6zSNiar8YIPLKsiLTmgJWP5O2pskN3gkPd3Uhc+K41fvH1PpH6eSLGH/sYozXNT0iA0sSOErbG2T0BQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-alpha.1.tgz","fileCount":6,"unpackedSize":37539,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeDnvrCRA9TVsSAnZWagAAEzYQAIs6jOB3dfzF5hRuF3cj\nZF8qK4qMAbiIjscmFa4dsO8PtDYwWotIFZV+/WRJiWS2Ip1hEBLXif7ZLfsQ\nbDdlUjePtS+xb8iOAGdvpab/wNay2oXtswCZ4E+rcsR9a2ct2IL3j88Dl8GQ\nDatRubep9IK6LMo6kQ9MqenlIb8WRJlqM6vz6jP26Qo5qQ7eFWTKAriUG3PL\nNET3oIYN1CCkWSqbCynal0S4YgYF5zoltRgp2YUw/Qw0KT8RDTuf1dvSXOAd\nKlVhreGoMQGJGq/eLhbUQqWoLQQx5i0Nad4sAUeO9OktJ6ZMbd2lTu1Ll0XM\nrkY1CgPIn+VcTojAoUn7BBITdvw47aM9q3XlCyTMsxuYXOKhzK2VjKYT/+W+\n5K6oS8OU5TWqXOIeUN99ARHjOlCLwZTpQBKteQafOQYPE81VBRBjgIfMyTYR\nPQ2oa23KyQ7sM6q89mV7+LBhX1vJSYI2HMA5Rr/OIeymxwIi6BiiFUXVyusC\n+zY1D4JTVElom1WD69Czi2rciK0xHu6NRvHVft8zORyRYsoYFlXmnohDvXin\n2/k3O8/Urgo7MePaCIxMuzJsCAvn7L/LnRL60k53FHdWBMD1Ieru6WWbmPbn\ndUnXt70fZ++ZXwU5veMD8H8QsTFmrBebjl0PpCSe6HGvJlyRXpN2ndS4eFDV\npfwf\r\n=TIj2\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHODL9rB8CPTVXOL+NhUoKtx+f7g95vcpm/FdAXuru9KAiAu5CB3/juTNbWF/KNNEzsbwj4cQBcVNLZUhrgWcFSeww=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-alpha.1_1578007530943_0.5937078639877789"},"_hasShrinkwrap":false},"3.0.0-alpha.2":{"name":"@vue/compiler-sfc","version":"3.0.0-alpha.2","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"prod":false,"formats":["cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue/issues"},"homepage":"https://github.com/vuejs/vue/tree/dev/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-alpha.2"},"dependencies":{"@vue/compiler-core":"3.0.0-alpha.2","@vue/compiler-dom":"3.0.0-alpha.2","consolidate":"^0.15.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","merge-source-map":"^1.1.0","postcss":"^7.0.21","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"readmeFilename":"README.md","readme":"# @vue/compiler-sfc\n\n> Lower level utilities for compiling Vue single file components\n\nThis package contains lower level utilities that you can use if you are writing a plugin / transform for a bundler or module system that compiles Vue single file components into JavaScript. It is used in [vue-loader](https://github.com/vuejs/vue-loader).\n\nThe API surface is intentionally minimal - the goal is to reuse as much as possible while being as flexible as possible.\n\n## API\n\nTODO\n","_id":"@vue/compiler-sfc@3.0.0-alpha.2","dist":{"shasum":"b8d7485c2075a107508a1554b75cc5058460ba0b","integrity":"sha512-lOlGX8znccwrC8iLcw/dQt58xt0rR9D+Sj7SDiWcIXCrOWEIE5j1obGdJnOjuysnZKu9w80XtQY5E4zeCNhJWw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-alpha.2.tgz","fileCount":6,"unpackedSize":37539,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeHPLbCRA9TVsSAnZWagAATxIQAIYMqe0HwFrBHRwohia6\ndI5bOhNX7ViVEhN8EGjV9lcXgknaJa5ixM33cVlSRDoTbOCOIdK4plrRE5fA\n60QWwbIjhIeJod8HDJDvD65q0VjR4/V/+6dlTYiXwjrA3UUo9C44QblazUDc\n2YaAeNoyBb4Obs3xDq0niXbIkXmGnmStWGDr3YuBggnfkoMG50Fhu6R39gkk\n0k8erW9bbubt7eO1U3VNwTG7hjooFyG/oGszUCZcNU+szhKKv4eEyeZjGhD0\nIw843YCYqKaM6u7QbWrSfdm/7V87lgodNfKOB2dS7FhUdi3wDXxExIa9raRL\ndPOUdExrj8lGKoc7Bt4/uouQWYV6qHLUUxMbFxyNlREKD4OhVTfwIHk7h8ws\nbCrre1swF6LlnZVYjqCDFMUAg5Z+f57KPgTZACIru44Jh+uJRzI7lZgWTbCT\nxX0SVEHcvcpLBSIVtP01K3u4pDkh6bmgUuBfUiHSykuoaksa0sol1Kc/In6e\nmYNYmmg5ATIulbys9dZkKMAezjy/C5rQpeum6F4rkSulclqc3BFGo4GapgTH\nj4EkAXySbtNyuMBA+UmsJAf6EC2AKfoA3+a+3BFJRrZ9E52miduipK2bOWck\n8Xy0ZjWbcFmNttCXbU8jZWhARlogFJ9n/pTqIta0qCG85tTp4oB0vQlOo0+9\n1wEH\r\n=XQbm\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCbV4Kz3pkkLYygOjn4FsEuakixiPbsK30gcom6/WPJ9AIhAJM0KZJ0Oot6pQQsLfMChdG3g2mqZvEDHQan6gjaWcKH"}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-alpha.2_1578955483015_0.6332485980300189"},"_hasShrinkwrap":false},"3.0.0-alpha.3":{"name":"@vue/compiler-sfc","version":"3.0.0-alpha.3","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"prod":false,"formats":["cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue/issues"},"homepage":"https://github.com/vuejs/vue/tree/dev/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-alpha.3"},"dependencies":{"@vue/compiler-core":"3.0.0-alpha.3","@vue/compiler-dom":"3.0.0-alpha.3","consolidate":"^0.15.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","merge-source-map":"^1.1.0","postcss":"^7.0.21","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-alpha.3","dist":{"shasum":"5e1c8fd5dda5b8d8075140a547afb146225fd382","integrity":"sha512-TmeS2xugaibC4XQqqMPeb7vyfMEoIVKepuI6nh7Ad54Mm1yl48eit3XJMoBUbKzSz6rrOw8ECvKoANu1WZFAmg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-alpha.3.tgz","fileCount":6,"unpackedSize":38269,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeKHQCCRA9TVsSAnZWagAATRIP/3rh34qcQu7zOtO9nJx3\nzZwQzOu87sdS0ACC8+uRig+FeOJqrlf/3OiQsBwmSBX9TiNpmhrQDyzo5n15\nUKPScf2JjoG6SzsxhyXGGP6MnDZzKeMDFAAJwHgXZ6hW6AeRFTTdgzn5sR8G\nVwABQbgkyJKvdkGrad7pnY/lKvhCQM7/H8QWbgdsCW+SMGWaPXXOVog8gjvf\n/nvKW0GT3WQe0xX2qM+VPbKYe4jELJjRzkTnOsGsD3mhe89JqSiVPXo5ptDo\nbHcMYkConBxzagDsNHrNj4vKcIX+RJcgc8fAnLwZ43p7KDvEo2kX1X4Zi6QG\npJalQa3hbVIF5q8FWssV/jZ+4wjhLaoUsuLbuTOT18x4jbcrJjbmaeTVUPpn\nj+GbgxxaLrObeRQMK4CMupDIuYkhY7rni1fKhw2mBdFuvYgy2X0DqFDqE6NU\nD//zchVGoXotOle4QfohFkDeIwInu9bybp2YXghCeLLiGL8YK7bUhy0gBbo+\nvFkwemGPUdBaI6igJM7eAFsSqaThgq/OsLEoDXOECe6+a0oHhEWkz5EXZe8t\nx35QZuYvV7yT5efNgXqPYu8sf7JAV0TocDQ2bBKkT/RvHcn1U7LsSIGxwNa3\noxg6ko2fsMIGp874o2YFOMw5uiTtUp5KxJ4TVdCBPskjHQ6jK3YSoYNppn0F\n36LL\r\n=YRPU\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDTO8I/eShjvtfkjrSc+tBFITphJqX6xUip5k96b4EPpAIhANE+eHZBZyCh0MkLSq4bI6RwcKnsVpQodid+gGZ0iOof"}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-alpha.3_1579709441621_0.18365372187600149"},"_hasShrinkwrap":false},"3.0.0-alpha.4":{"name":"@vue/compiler-sfc","version":"3.0.0-alpha.4","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"prod":false,"formats":["cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue/issues"},"homepage":"https://github.com/vuejs/vue/tree/dev/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-alpha.4"},"dependencies":{"@vue/compiler-core":"3.0.0-alpha.4","@vue/compiler-dom":"3.0.0-alpha.4","consolidate":"^0.15.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","merge-source-map":"^1.1.0","postcss":"^7.0.21","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-alpha.4","dist":{"shasum":"5013249b00f5c81ee1f247bc1b128f3233af4f96","integrity":"sha512-JlER3RUHC8seCMHV3dZgqDf48IrEGZ6HKrCWOi/ed3N825pJQAgmwJBe5XkPKNMmFBjiWypT4NYAkBU0YbLkhg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-alpha.4.tgz","fileCount":6,"unpackedSize":38269,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeL1QVCRA9TVsSAnZWagAA65wQAKElXJlEiH63gHUtRnS9\nAFeu5AfBDcdZ69A6mKT1IS/m5usRCpgC6r8w+nul3APd6cmUPuJinK7P3sGL\nPeGGbmdO3QzSPjb9DZYE8SHE8rCt0weK9laSKR133HImdlHGmYLe/37EaGpP\nU9QT2Fzyzw3nJvompfl0BYxnP4hhbVEDK3bdhgsnvMTQxnvrcycX5GzZHiJT\nVbLpP3z03MjRB+ULuhisaTfyZ8ouSyk5EOpSjH6SVv5SIuJjAxtytcqT+aNK\nvWu1AveWkEEdex2eHGrV4O12ooPt28v7X/ZSlUwwRBv+78wEdJfNfc1Xg+VP\nmS6YdR5495LV5B0US5dSmdZDTwmMYJVCyMlTs/ZXP4iuvw54dNpNvgkyJQY1\n1WbeLE9W1DbI0DKfyc00Tl13hXdaSp1SG0UWZB9rjjPRJhpbFB05pd5Dsvdx\n6kJgVXLDjnE8fXJl25H/U4C18nSRZ4yxX1RyevkmZPS2cNXGR56u2nFQ6nVe\nGiu3Kva980LQLJFd421egBpL1XflceLCUIihBbf9aHC29OU5sRsF8A2yQxH2\nb4b2Vl1Hqt2agBFDVVfWb10r5b0sFf417gRyjLb0elODMIGRkmFy4yfH6YiG\nvLX5OYpMT/VyLIC44cCd6x1k52fkvrLEY51xa/dlIO08Ypvjpvxl9GM9cn0C\nb1/6\r\n=pD9O\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEG2jkG3QD9dPy3CsksB/X3LXuZ16UyUt28W4uvy3HFFAiEAlVH8CkVLYf+wZZsKD/S7qSq9xERtsVrdnn7s1RgFSU8="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-alpha.4_1580160020775_0.3450590241587921"},"_hasShrinkwrap":false},"3.0.0-alpha.5":{"name":"@vue/compiler-sfc","version":"3.0.0-alpha.5","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"prod":false,"formats":["cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue/issues"},"homepage":"https://github.com/vuejs/vue/tree/dev/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-alpha.5"},"dependencies":{"@vue/compiler-core":"3.0.0-alpha.5","@vue/compiler-dom":"3.0.0-alpha.5","consolidate":"^0.15.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","merge-source-map":"^1.1.0","postcss":"^7.0.21","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-alpha.5","dist":{"shasum":"f215cbbbfa68b666e70a2fa50e7d96ce57846433","integrity":"sha512-hqh8WsoRihrWFXWQ6+DxeBOj+QN60/B599zMYspQSWzghEw93ldTYyoaZiUf+Gf5o8wnzLLe32vzccnQ23xBLA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-alpha.5.tgz","fileCount":6,"unpackedSize":38568,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeTEKFCRA9TVsSAnZWagAAkSoQAIL8+QVBxT7EgxDEinzO\nuQf8ixTyxeXM5UfuKXOY4LS/4gJB8jAv19H7/36FVNYdzx6+118lBhMq8k3r\n7oHTzTeVbL9EM+p8JOtBW03r44XYSOB/lFxba8aAfAMsZqANq3yzHMbQqfP6\nBgCl36Hq/LvcErpQ2IgnofV6Nfg/Em1ioA1ZHWPMPVJGxyJqFFnKO29seiEd\nWamK6hbz32QPjvpgv2zzNYpdcLZ9BlttqvwqEVBIEaLYuPjnUB4eJZoOjABv\nqZ/aZEoWxsoNdVou+4PJIi8CLHkVgKiE9oWlU4Xl6PWvTejL2b5TtFG3Ud+n\nn6wvSkH1yM81EToAbRw1PTcTXGOchtOOPf46o0IBcjOUJLGLwgW3Sl8Vt5AT\n3/BRoG12ZOm/7UFz4j6TBAmqHj/bgKhO704naAIwwofOuX7Ci81AmUnYKs08\nCBilJiNwq4tvApAm+n0sh0frE5k+lu5fBAnmut7lEfgRHNbto+No2J8cPduy\nj5baNXm0beOCbC2D4MQ99/lDjsM2GLExQSU6jIa8NNUIEi/O1s7RkKpP859t\nwKA6zn2i0gTZQkQ27djjxXhMv6EnNAcfWlqL1VrLfAaAd3QE8ZCBF4ERTNce\n3F4KNrD3+rVeoAZy1jWwHAkMY6y56LhYYmJ0Sien2w3vfRE+MMnfH/wxkUYf\netxS\r\n=nIIW\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDPpmSa5VUKpJWVnQBKgDSZ4QUeCg0jYGvU/wUjO4LFFQIgfCZO0CPDXr9gZ0bS3TMYiBRDUihQVnaYNJIQxsPdE0s="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-alpha.5_1582056069297_0.6996848030371381"},"_hasShrinkwrap":false},"3.0.0-alpha.6":{"name":"@vue/compiler-sfc","version":"3.0.0-alpha.6","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"prod":false,"formats":["cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue/issues"},"homepage":"https://github.com/vuejs/vue/tree/dev/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-alpha.6"},"dependencies":{"@vue/compiler-core":"3.0.0-alpha.6","@vue/compiler-dom":"3.0.0-alpha.6","consolidate":"^0.15.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","merge-source-map":"^1.1.0","postcss":"^7.0.21","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-alpha.6","dist":{"shasum":"d42036f0135ccabcb054a744e0baa93f2a73af6f","integrity":"sha512-i3SPUHHDHuyXkM+yA7SPn/JBcfnvgMhefyEuhMv3adUpjECwsjludyDCIKUw3MvITHXXRmGQ0eL5TXXaYICp/w==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-alpha.6.tgz","fileCount":6,"unpackedSize":38568,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeUNd7CRA9TVsSAnZWagAA7G4P/iKH/QSKrwx/DVZm0aYl\nzyojpHa+4r5xKhrX6cf/5cV88kxLdqjtteZfEgBoL+qr59of9/UNaKj/Ltke\nxAyFr6+18fcHzyrkHNhYYpJ4n7TpMpZXZXDAmJbZ0bu5ewsaxAD65hnfxXa6\n/LUbTKhuIeiwJmeGlS8Jt110Ji6/OvfXbwlJV01AY/h5LY7oQxlLPQSLj1Dl\n6377OYkVoxa7t1Jk8oCj5+NsR1p87KRWdblRpL7Kj4AZLqv5PUBvzqOgHQur\n8S6VQCOAvB2hacKPKoK5X8xsfXRgPb7n3Uj52Ai+Y50qnmj7E5oDlnoW/qbK\nzXP5jmVVP9ZCeITFQ5p8LE/pcEyuxixiElrw5PH6pWKL/5ql4HkGpsoYtafK\nQjb3rQrhJPtwWrJlfnuKxBrbkohbynlGplKpl3nw9lY7BGXcEAlGrRldCpZB\nmgj4+Drm0MaLwlLLbNMMnaUrTMMuxQ00AUpwYIBr1S2fg3bzfZ5Yo07x6WEp\nZgVwIZLpi9iuwyfCd0sekVE14xKoKyb0ZlO9esUw/WIE41aGEQRpmLYoHAn3\nFNasLNSHBax8vjGvEbDgxpI4nAv43E2GpNPqMw9D7H2BwxHoy2jooIEihnQ5\nHM1LOvM2sopih8Di+WryyYgY75kuGh4JlH+rY0IrYX+jGBEflivrAzHsXqvs\n5S57\r\n=OLwc\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDxrFlQuHDmhFu1t53SbPcNsO2AJo9x6WaY+cKr9osXKgIgAbZ76eIXIdP6Pyv/IpmlwP5vjajkJteLSlLmwqWiGMM="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-alpha.6_1582356346733_0.01432350634695645"},"_hasShrinkwrap":false},"3.0.0-alpha.7":{"name":"@vue/compiler-sfc","version":"3.0.0-alpha.7","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"prod":false,"formats":["cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue/issues"},"homepage":"https://github.com/vuejs/vue/tree/dev/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-alpha.7"},"dependencies":{"@vue/compiler-core":"3.0.0-alpha.7","@vue/compiler-dom":"3.0.0-alpha.7","consolidate":"^0.15.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","merge-source-map":"^1.1.0","postcss":"^7.0.21","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-alpha.7","dist":{"shasum":"4f60b7fef97fe4b973a59316e398fe8800cfc908","integrity":"sha512-CWksD0Vcl2z+zsYnrX2K38K9hHQU/IVjmD2zugjhLSgScNsXVFMU9DaB93oVqFEScdxeqfqj8P/56J/LbFIRPw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-alpha.7.tgz","fileCount":6,"unpackedSize":38568,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeVsjVCRA9TVsSAnZWagAAzigP/RjWkCRPjtcTWC3eT0kz\nYknQMbgf0X3yd9sFYTzHZKlbeE2NS8P/XAo2rsfpLUWPrzCtKDrnSfh5rMmr\npBuIfn2qAgVfYMed2F3ztq+COuJgACFc7gyAr14ATizGnJ/SsAw12QGYXxi7\n80csa2JJ1c6lD92JL7x7bVa2DzNiu9voTFb0lAmVLnX6jY22CCcouNtX4uJx\nVpbQ5Gw72e1T4vxNtNV8xwYCdIsC1/RwcHrEG37AvVxTtDyS9MMOH/dAVg5U\n9KYqZTWoTpkLaQX/Y/y9zzvjmqmDJcLQry0U+jRYjdnlGCq9w5DipB6hBvSw\n35L9MNXz/4CRMvqJSAF2LSuaeNZvMnVbM6KF8peb4QojWq/CqIZLkol8rqnX\nn2Sfr4l6XhMhFuJe/gHlGDl4Z0cPHh6y12aYMTVQ39MjItCn0OCEeuZka8QK\nf7IoJi9x7KCkoP44fsSSbmyv6YuXVQEPzPq1j8sd3iUQBg0zmtXsWwrfcK5c\nhgQOD0qUgNNeZvLswIVCOI2KCEKz7gg8AB0Tfyx/l8oP6KuPP7266bfy24Q3\ncgL9kroyVAM0kzaz2nyrxGuTmEsceGvBdTF14Z3khCXjQFRr9zA4vu7hscla\nBM7FEdAKbsUX71Tut1vpbKLpi56HcKi6dj6WZ1+VXSj0allsAUyOT+rwDrGE\nPLgp\r\n=vMFd\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDp3yW5KcgFrcedsB5Fv/k3y3Sn+K53pEyhgM5iZfFTFQIhAJ4vVGp5lZXGrvGWsMjrq14989C+R2Com3TxC47l+UjW"}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-alpha.7_1582745812825_0.8599575738755143"},"_hasShrinkwrap":false},"3.0.0-alpha.8":{"name":"@vue/compiler-sfc","version":"3.0.0-alpha.8","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"prod":false,"formats":["cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-alpha.8"},"dependencies":{"@vue/shared":"3.0.0-alpha.8","@vue/compiler-core":"3.0.0-alpha.8","@vue/compiler-dom":"3.0.0-alpha.8","consolidate":"^0.15.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","merge-source-map":"^1.1.0","postcss":"^7.0.21","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-alpha.8","dist":{"shasum":"e4f9a98df1af6e60f9e704e3dfd7fa3ca5edd65a","integrity":"sha512-BQezRHe7F7z+J9Qb3UbVP5G34nW5xiWoxvDjDJIkqwMMJ6p8s9ITz8LRSXMP+cTgpRbN0l5VqmA2NuhCffAdPg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-alpha.8.tgz","fileCount":6,"unpackedSize":37160,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeYrmRCRA9TVsSAnZWagAAEZkP/1AX37r9EsIFubicrTrS\nocCkqYEnzEEdWOTHL5aZNFFts1WP5HI3N+08gNZfK8OSd3GJPXFgvWW7JSiT\nLMAksXsnPfcXwiNKfb8+xWLlXto6mMhawkt+KprfcLroZhFd7RFODxwK/oLC\nqQRwXUxRCP7cDBNAWCCLTzv/A7ufzxlJMKeo6nUAFVzUBdfUd6+X2iO3y+qi\nKsNNcGDSR3ZxaWx5kWFgQCqZYno/22Ngsra9M8lm0Vyls0P9q4Pqa19Wez56\nFdZ6NZIL2I5veVxtPrifMdcOpFKCY3h0yKa+Neni3FuhQGBj5uwwb/VvzL68\n8JY7IgRuzqAm4rOVgGGBU4vaHyxpMePh1oCQgfoBhhsfcxHVyhUXLHzhNK4l\nvLEjpJ2oRxz3gXDqjQm9fyRKRD48ks6C9+ya2QTmKCADdPRPXsRfW55bDa0M\n3B0ryC+Zqhhlqj0t+743d/XxG0qG5cWQRQEEOUTMAo4JywxZ9VmPIyVvipYR\nRmv7hF2febQwNJBG6/Em9pF57uHy81XbmfvBuMfiTHoQnm5C9bE9Syn5JXm9\nH/z8x1uMn5mSldnzm8hoZIDacHdRu5dgF/tqhK4V5i2ASyniVb5U/wbunxf+\nJ2YHGaLG2+uykmjyxTs9UZ3tFdpsLboBHeYLQOW+SHnYr1vNBKl7AP0nvV/2\nYoIq\r\n=QFt0\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAFkz6/I5oCHBN9NLuRPivXx5vL8I3PLsAU6hWW7OVycAiEA8XwYLoXAGYoSn0cgW+/og1XsvmZ2rzg4gt940pp3r8U="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-alpha.8_1583528336744_0.9035227603472789"},"_hasShrinkwrap":false},"3.0.0-alpha.9":{"name":"@vue/compiler-sfc","version":"3.0.0-alpha.9","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"prod":false,"formats":["cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-alpha.9"},"dependencies":{"@vue/shared":"3.0.0-alpha.9","@vue/compiler-core":"3.0.0-alpha.9","@vue/compiler-dom":"3.0.0-alpha.9","@vue/compiler-ssr":"3.0.0-alpha.9","consolidate":"^0.15.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","merge-source-map":"^1.1.0","postcss":"^7.0.21","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-alpha.9","dist":{"shasum":"5d28d9d18fd0c4fb7fbe0e08f85f333fd7ecc8b1","integrity":"sha512-Wr4O0J/lO4Q5Li6RfhZFZNIuYlBkmhk6UxxgCWdW1iPko3/C/oI9/k2SBSiRQcGCE+J5N3l/x1elYlq77YHvHA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-alpha.9.tgz","fileCount":6,"unpackedSize":37272,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJecAQ4CRA9TVsSAnZWagAAqWkQAI4+oT1HKbF+3sRP7ChN\n1BdR30lFBe6t3ib/fgMcSkbL3F5SGe2sR/Mk+WwTlsfcWgejVdLrPygelEkG\nLGPC0oqUUQtWwUTAKNUWHZclVRVIClf7Let/GaLE3yKBpFkmkICUb0rYnMjf\nMrkit1kPPQ93PXb8o14mL962GUscOUfF1SqBZwRGuiyS1GOiJI+yN/FyJkwL\ns/FE/ICydMCWdFg1RcgtsRMZhk3uV3dVv7b1gh0qD7nwB8F9TRmccsXYwBpj\nZa3A293VoU/OXcqNvBwb8WI8TwHhS4inXntDHTrVhZcTJr9kKH6hm+2OI9vf\nJrzsq2mHZmlTEImOxPqj2ADWO2MqXt0GmXHWflbJicxF7tARefsRSa4cbS7V\nta4+Q+/bfbXnBSTntUMJPz/ISB1J7CpJRxp4TSsikvpn1TbDpQISKL/qv3ab\nSHujvBs7+0DeMtyrKAVmMk7n8J0GeAww7a9w3CYhloy9a6DHaUD4DD0kPYM+\nZg4djIZSFwLTjKfcIBPp9aIHpBRv7Aps8/WXW+CTR1sPyLRhThr+5Zla12IC\nvwRjDJ03E7JNYoNQNtUkL7VdSgOTS5LK6mFVgVA+x839Usl+7hmB2C5eocOX\nk9X0UlsCFk1RG6To1NPPRUWr69/bcbsA34DU7dWjnO73/CtqIPtyFCjUox/7\nVltV\r\n=tJEy\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHiKvVkSB+07tMvKhwxALRIN/eo2+Tc8sY/XU+yvfytxAiAQBcqy2ZCYj4EVcEAG9rzQKdhNr8SRi2bGDdqA0LGdtQ=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-alpha.9_1584399415792_0.294438830332008"},"_hasShrinkwrap":false},"3.0.0-alpha.10":{"name":"@vue/compiler-sfc","version":"3.0.0-alpha.10","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"prod":false,"formats":["cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-alpha.10"},"dependencies":{"@vue/shared":"3.0.0-alpha.10","@vue/compiler-core":"3.0.0-alpha.10","@vue/compiler-dom":"3.0.0-alpha.10","@vue/compiler-ssr":"3.0.0-alpha.10","consolidate":"^0.15.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","merge-source-map":"^1.1.0","postcss":"^7.0.21","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-alpha.10","dist":{"shasum":"c2e148d224bdcf8b1a1be026e492c8a2e65401a1","integrity":"sha512-JyZbNkAOTKcEk90/9eB+sqsBBCP5+exspDYLPmiL5HXak5G1+pQsVFB8sZAEqz35TMDoM2CxTLBuwKdhF6jEvQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-alpha.10.tgz","fileCount":6,"unpackedSize":37278,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeeorQCRA9TVsSAnZWagAA7nEQAIYqwLwbzBz5QlTHF7UK\nfLlOR9XqGayPc9rJYwVBqcjTUBFV58pMyBx66ot3c8vsmf2GbdXf1P1YkKPP\nAfcq46qJrIRYvXmPY9okTkaTge2QzXinzIcQrOGKZthQbjO1DJFTD8xIHiJC\n5mPifEbdHtUa7BwIG23Zgy8SG8oT3wmTPdOC4iJIv4pGJ2vHYhx5s/cdYhjF\nnKzNdyG9QrS+00yA6YlhFXqSLa1hdRX2N3Lsu+NUBw7K7o4INXkBj5RejRI+\nmDvQDSqpcOU8OOTODIl9w7IWu24BvGlFXTcSHl0V36l+VAQ9Kv+WhsC13IpM\nLFmPxyct99XADZrjxwu/qJ3XZK8GhS/R+1/FOgAagOGaCGRqaO1o9GkAnio9\n/XlpyaUH4E1txiycP6luhMeIvSzqWqlQsfwTTf2iEdGqpMWxM8qoqgbqz4q9\nGB7B3FmA3PU0hh9eAc5CVoNPXRwHGOrRjVkL/MkRlkcc3z83Uo/mJGqznrOp\nCASb/9dz/Mo2mqPectlzAHeFlvyODbBRLLdqxSIIgl9Sp0CW+b+VUZrn2t4a\nw6PSMZZcQd18SmyL2XAxmr+4Bs5zoa8GwQE/xmFIbZYTGTeK1kz510mjQsD9\nXc4VVl+Gp/ic0MQV1E/GnlhEdx3Bci+RrO0iMWCHH13lvRcKYBmfAAG62rBO\nD207\r\n=dlvk\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAdwugx/dXmlt9Pgmh8yqBVq50WB9M6nfYh8zNpPelE0AiEAiU/qK8ONp+TAW9qki6AswV5AdhfvGN5XFxgaidJ+nfk="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-alpha.10_1585089232125_0.7983286741784008"},"_hasShrinkwrap":false},"3.0.0-alpha.11":{"name":"@vue/compiler-sfc","version":"3.0.0-alpha.11","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"prod":false,"formats":["cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-alpha.11"},"dependencies":{"@vue/shared":"3.0.0-alpha.11","@vue/compiler-core":"3.0.0-alpha.11","@vue/compiler-dom":"3.0.0-alpha.11","@vue/compiler-ssr":"3.0.0-alpha.11","consolidate":"^0.15.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","merge-source-map":"^1.1.0","postcss":"^7.0.21","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-alpha.11","dist":{"shasum":"aab056a24900c7e8fdd3bc6083dbf8ccaa8f0734","integrity":"sha512-4/iBR/dUFVnR+6csWruBgOBZwQcYb3YzN3shbC7GslXUVVU29OOozTBjN/6y7tOfDwHe3lo/WRHYNq6gYQW0VQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-alpha.11.tgz","fileCount":6,"unpackedSize":37283,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeh+bbCRA9TVsSAnZWagAAul8P/0LwyEbMvFdY0awZUgv9\nD64mLW59CFzIr9OjfrAemfq9dX3NNm3LmbnkJw6CG+mN0zi5a3f3ak4puJ42\nwu2yiaPH9j7BOqgZK/E4j/DimVUxCaoPfQWm9u1yJoNcYVx3Q1k2wpOUpssn\nsUWE851Ua++7NNdv714DEQsiVaZ0B9bpPdyMKXvc0qcko/G1PHVpr0XMOuue\nxwqI3ia2s9OBYDSAYuowLttN7rrpUSZGWAVuyQB9iF/8kLt8PyY6iweTJB5S\nIeRjw7MOUaNSJgknkkicLufWVH8aycMPxwZ+asb4Sbz4zIBmDyZ+oJJIXHpR\nfKMTlf5hJtAa3WqOliHQckV53ei5yP3OQ/VINUG4iqj1OkupJSChFL37iUKK\nzY2Mh5E7vvtqTdGllPVnMYrMx221ZYjTpYg9a8JUSyS96IDYpyxPZtqHclBM\nmI6oKU2YJrgNrf/XdeEVZ6hVuRO96GCsenrTgO/CZhKJL5O55gelr9diikji\n7QZg0VNjfWG+3EgqCvM99qWv+RQQnBlduXV0NHmfikwkCeFcMQ3RNagOR+Gs\n/vC9CDbo03pe95R8/OilabG6mK8WBX+sBzltKgkWKDlpgxeQazpnw0wFaDM2\nDXDsU73wRB7WqBZ0FenUy5Jn5HB+oSaqnU6ZysBVHzRfOKnsnyrk6+oainTq\n8bs/\r\n=StoY\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDDZsLDI8j8O6yIW0t91z41m0fjKSRuG9c4SROuco2fPgIhAJDhLMQ4SJzgMdsOl70MVIZDHpjlcV0QkwStTMibZNzS"}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-alpha.11_1585964762769_0.8757039217720826"},"_hasShrinkwrap":false},"3.0.0-alpha.12":{"name":"@vue/compiler-sfc","version":"3.0.0-alpha.12","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"prod":false,"formats":["cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-alpha.12"},"dependencies":{"@vue/shared":"3.0.0-alpha.12","@vue/compiler-core":"3.0.0-alpha.12","@vue/compiler-dom":"3.0.0-alpha.12","@vue/compiler-ssr":"3.0.0-alpha.12","consolidate":"^0.15.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","merge-source-map":"^1.1.0","postcss":"^7.0.21","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-alpha.12","dist":{"shasum":"485db9f732486c9007402683eeac2ed78313a788","integrity":"sha512-rshwehh3tvRf5xx4ONYgQOYYjXKeZEwES2ZeSEG2oLRw4vnkHryFB9gLpV6I+E9fhlJ4RHiNRxR1Sj+kbDk71A==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-alpha.12.tgz","fileCount":6,"unpackedSize":37283,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJejldyCRA9TVsSAnZWagAAcfcQAJH7l+7tMUpIAbEiJe2q\n2vkQT4DMF4n4k8nqJG712/pQSX1sKjoraWqcUO8/oxjcbKUJZuL2BKtxFM2V\n7/AVrL8K7cigLaa47U2nkCEmUd54aF1KQiapm0gcNYU2uX8ETNUFO4FXzJAj\n5tPby8d4AMKNPCP/IrTLU3lObab0UkERGtvoPcYVNbqxSmoTQ/9dpgoWeY0W\n762wcw4GWgcQYefn17oRseyluWYh1LFQCxcF+H8rbkEkrZBpcGtd01U3+MVT\n+zK4CLf5A6rA3yb3mD0ic2w0eVb0Ose+oOnmDl3ZvHxx0ar8k63518uYkfbh\nBx+sSaEXUUGI79lJLXZrXg9oh7AplqFb2Xt6nB4A2ke+y2Y6UMLrssPIq8ni\nWjWGlQRLn6Zy624HPKKOYNtJPCS5xfmbHmfQslXcOzpKHAOWv0LH00k1Zdwd\nkm9NykVlzkVRR6UtIrMIOdUk4oNV87NuFxlUv+ZtzKg11/bpXVwvSR3ALIPm\nJb39hiXXwKJLIuU7z7g0hCUP47bZglDRYPilrzcqEvddxbymWwyoqmFuLP2S\nxkVQJhY9i075fJ8a4DIWpgHEso1z7g/fhz1lcbyIxL35fc6RQdHOkz+abrbN\ndpzy+BfzWfYVbhDh7JAlZL59wKpkahqgImqWSzChbc8DKscDRa9uVb7HGWO/\nTr0c\r\n=2pqc\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDUN2BA/w1hzEO7vmxWRg1x1JgqsXJm64h+1IIVvciL1wIhAL2e2ubMR67FHzI/JthF1fEP3O1zA4m06eEth1oc/d/5"}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-alpha.12_1586386800885_0.4171614573228144"},"_hasShrinkwrap":false},"3.0.0-alpha.13":{"name":"@vue/compiler-sfc","version":"3.0.0-alpha.13","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"prod":false,"formats":["cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-alpha.13"},"dependencies":{"@vue/shared":"3.0.0-alpha.13","@vue/compiler-core":"3.0.0-alpha.13","@vue/compiler-dom":"3.0.0-alpha.13","@vue/compiler-ssr":"3.0.0-alpha.13","consolidate":"^0.15.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","merge-source-map":"^1.1.0","postcss":"^7.0.21","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-alpha.13","dist":{"shasum":"075921331a01ab483e71e3b33bf4238c0c35a449","integrity":"sha512-koU+iNgyleTBRphI/XZ4V1UxveQC4ILniOXFVRNTHBCzSzfFI+Dd5lHMr3BDOABnb1EuUZeC/hAz6tc4U0qzEw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-alpha.13.tgz","fileCount":6,"unpackedSize":37283,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJelzpwCRA9TVsSAnZWagAAoQwP/1VrIMgtGtXkDHi5WfWP\neO526EG0mrveS5hMX8KFfHxA5BDSEIscfrOyCeQTX8YraFNcMKD2Oshq3BNM\nNdWKNOMgEiEJgPBjH45SivKSW0RnC5VgfgoOWBiRdTmKATqpwo39ARl2D0Z+\nVd2Ud52jQd9EgfoHoFaCLtDqT/VhhtfRTw8a2B8F/KUv9+rRvPWSKTCr9tfk\nzC4/GqgfJ7VRwP37WQrgyNJ50bgcZ3cUIBNz83FBKLjyMiC3ykYN7QaTbF13\nKkCDc1KDTODplv+59z+e9DM4XH8TmlQ5Ib2BrOSRPt4dkT3sgQuoZt2SB9Tr\nGxqNmPvPeDjyeroHFG1o0kBI1eieK3UC/joSPtB7MOqQDlUTxjXlV5VReXi/\nMi053v+cqHvn89A7axefI5O2yfLezOY/fcLIbAl2e08Da3BFu5u7b3guJ7Ri\nFykKSFl7JwCGxwkOEgINAqd0vb7u55Ct9Om5ZxHw6Caun6Vz/8nkYfpN/ha+\n6IW7bdqSQx+ELHtQub4WafL7hOpLYmDjzXL/qdI6K7l3Nkh/idodNxzftL/w\nUdABmnm8xXrDVIVnl+X+e0C4CvFjBiDzkOMYlq5/ld0fs+99MBRqGUcXxiKy\nvz5xpk9tOlomsA0l+RCJ+EpWbc0TX72DnnadXf4w8BV+Qi/BXH2f6IOrXu4V\nt3oh\r\n=Bdf9\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIF8aicuPnkjUGyQvT/WcENndygsgHUUdCamcZI1QO9yPAiAs6CIRinapRNaGAhcvhXQztiDMW4UzTQANOo2ejtcGKQ=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-alpha.13_1586969199804_0.9685040168982058"},"_hasShrinkwrap":false},"3.0.0-beta.1":{"name":"@vue/compiler-sfc","version":"3.0.0-beta.1","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"prod":false,"formats":["cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-beta.1"},"dependencies":{"@vue/shared":"3.0.0-beta.1","@vue/compiler-core":"3.0.0-beta.1","@vue/compiler-dom":"3.0.0-beta.1","@vue/compiler-ssr":"3.0.0-beta.1","consolidate":"^0.15.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","merge-source-map":"^1.1.0","postcss":"^7.0.21","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-beta.1","dist":{"shasum":"1d1ae5e2d2ba83f5234d4b2f84e4ba4bd5741c27","integrity":"sha512-Dv+cKKGMwGOpDzE9UuWe/jCerIdDxwd0CAtxgF2XrXULxNeHGSedmx7m2fkPLSKqqDfHtbPZuU55jWp4axL6wA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-beta.1.tgz","fileCount":6,"unpackedSize":37271,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJemLXSCRA9TVsSAnZWagAAhtMP/1HjBvhTcVRgEkZ38Zo6\nHTomd1+n57dOWvozdhGeHDa+dUhiuR32MFw78LtS1VWmc/9pu9JyQelG44z8\nQbsnZ3tqaQxt5GZOQlEal+dODokOau6chIJYfDcYgJm14Kz/u1BvMy0WXmty\nzc7wb2XqEfnENg0mYOAD9rNa+A2tR+ycXmg6QuqdbWoNHNuWBbq+U5xS+np3\nJYgTw14vYyxFh3PYbJDqZUuPsqKfwaRPnt6rNyC8I6yyqbMf6zD3VsI39mIS\nbk4XiF2skRFBTIV1+iYVSJesyAA8vAV/Wce7H0uiMd14R8xnct8hhMLV8Zvg\nH02WWdlVVFBmChxYvosiXH7j06oHsl5gb+V9PV2xhOaduYICbsB7Oka8rbcw\ngSWMBNycbAbLhrYW5mCo4C0C/DAku/XMPciQTo/L1+nkENUmhZ2NzZFHhloq\nQGhJOFkUc0IdVhNn6xJ+XtzJlFXtQCoGiJlOd1rG+hlGo0WQeaC8AyLhs4Yf\nSaPLGLZQPtEKSrr5dh4R+XcWBv76SBCQv5mF1EUa6Z6wFOxMmS9XD3wDzBo5\nUG/GbSqRmVID5BpWnlpW59c0Hxy8pM514KH2WZ3yR+SfdCWrmNSy8Ybj5NWb\nHFlOUh/rRiQb6NNdagDNh8Pxn6Qxx47Yl20QM3XBdvKmPz2I9pyowlLalkk0\nZqRk\r\n=xHSG\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEDmB+cqUlc1qSPFEiKlSfXGMONqO9993hdoLYNFiyxhAiEAyWNK7oSITgXcKvD+WSvXLvPHw7ExYIqZp8ajQ8m8meQ="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-beta.1_1587066321685_0.22974857322688558"},"_hasShrinkwrap":false},"3.0.0-beta.2":{"name":"@vue/compiler-sfc","version":"3.0.0-beta.2","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"prod":false,"formats":["cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-beta.2"},"dependencies":{"@vue/shared":"3.0.0-beta.2","@vue/compiler-core":"3.0.0-beta.2","@vue/compiler-dom":"3.0.0-beta.2","@vue/compiler-ssr":"3.0.0-beta.2","consolidate":"^0.15.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","merge-source-map":"^1.1.0","postcss":"^7.0.21","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-beta.2","dist":{"shasum":"610697d29e067165d5e2ccf81bdd238399b6d156","integrity":"sha512-v3zQ8fR+Oc8U/WZFmJY641b05ayP1cdngZMn8PUgPecRwjQkdR/k9ikCMZpsrWtoS4am0e3PHyCt/BBZCxA4nA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-beta.2.tgz","fileCount":6,"unpackedSize":37271,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJemcS6CRA9TVsSAnZWagAA9iQQAJtVvmf7baAimkIcIWe2\n3ssjf4SpZu9wEFcQmLZRRkVWroijrKE069/dOXI+qcEMHCSfvYY+ByaS2rRU\nTHVj3U9H88/Um/87YNQp4b5dVJvr/7mrL/DxhpEfMKosMebup4yuP10O/aAL\nA20UVptfnV8OWecxnCgGQb5key9VnCB3duTBSaJLetp32n8Z8Qyh5gq0TVoY\nZTVZXRxcQrJwxxznEXnVzd3VN8cHijF8kgMI+U/lPbvS+Kt+f/8pvfDa7Wwl\nxY/cbcTG6VTrgYF8RTlAYVXKdbAz6aQsO84l6Dn9LKijQQOfuwi7+u6RLP43\nyxb4BD8NVRoBNeV/+g9KNjC3w0fNcNz6XZpaqvqnPAYffzCVSfxPVerIfuc4\ncNHKy3q0KsO8T1Wbvd9ZRe0njWhch6INmaJ+X5VmEpJNJNeUhERIZ1XYelEg\nG/VEEYmkhQuYvjLky2BTTCGzINpPrupye5FlN+pa/lrNWjvjgz8mYiXXU0xm\nsHstVm2/hi2g42y+N5NoIc4wFw84H14XFM0hGJWV9MgKturz86bY7VwR5Gyr\nY/lbFIfbMjx7uu/GviZKEefa+jKy8eDcwdfWFZBA5Gd4JgJ+dpeMA4jA9irx\n81w+fHmWCAJXsQNZy4WGe1WHByzhQ/2Dtyxd+WFvJWX62uS/EXkFYAWcJHwQ\nFkc/\r\n=shXc\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDwbfbCAkCi8AjMT+fsXHtUt0bTsXXHQkrvjdRvwE+/7AIgWyDK5a0/PmN1Mgt0PejeF5p6pCy2HehG10JQR8sp8tY="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-beta.2_1587135673648_0.8799317075854352"},"_hasShrinkwrap":false},"3.0.0-beta.3":{"name":"@vue/compiler-sfc","version":"3.0.0-beta.3","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"prod":false,"formats":["cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-beta.3"},"dependencies":{"@vue/shared":"3.0.0-beta.3","@vue/compiler-core":"3.0.0-beta.3","@vue/compiler-dom":"3.0.0-beta.3","@vue/compiler-ssr":"3.0.0-beta.3","consolidate":"^0.15.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","merge-source-map":"^1.1.0","postcss":"^7.0.21","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-beta.3","dist":{"shasum":"c3d2d0a7fa606b246bb875a5fa6f7b19a03d0b09","integrity":"sha512-R8gfZX5fm43dig/cKf0jOKOIhKXIZibf4ycF+yjbNGzHfA2lgVbBGOp/4dYxe9l7ajCBqGTgHkAHwXTeorKKYA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-beta.3.tgz","fileCount":6,"unpackedSize":37271,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeng18CRA9TVsSAnZWagAAH40P/j8wLBwyyGBeySWe8jqV\nXtY+BTQNWfJOu5/OFBEdb3mWArCrTN9a9nGle2FrFO/9rsFIV5CV/2UILbUQ\nyCWNeew2t+apvNcacBl+9bpZdSX5avVUB4fene0yZ1ysLpxdHkguSToxAyDD\nkbxBIqn1P3FroM6UjnVlZLVy+E7HOPLejvvIbyuURGf+5Ltu6QmiKfrnM0lZ\nYk1RL4phrtVD1qjxETr2aCtVbZof8Bx6QejDF554vceyO2y0veJ63YfWfKjA\nKTe6tnOuDft/e7xeUlEnqIXBGSlKBIDm5moO/8JYgl8lwKKs+XxjAmYsufSN\ncjyjb6Tw8aj9c+537l5ajJASM2/VVmvIaypS2qhvsxK6uIAWbxPAtMVmhtE2\nI0j5jcmqCgL9NYFUf0qxLWl7kWdQn9BHdBOMVWe2LLHVF3/lvQx67Gbp0GdV\nJ5XIwIMWNZlXWI8hUv/mH0YkPh3nlZA9bkJ0Cz05ZuvjMCK3AHmkbgEL9Bf4\nl6S4YCNKMVqPLKS4BVp8XJvIuF1blCjHBUqKkN+arv3O+/PQleQpvspYOpUD\nqGT9I18wF5mEOWTMKHAUhKUWs4TlK5TfG9TOEqoqY7CtWoLwUwfwUDIHUepK\nQRk/NLMJrO9k6Pfns9ljMh76HFywYrUlsCMq4VFVmhlkpab+baHXBrRpJZgN\nE0U2\r\n=XERb\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD5K+yGa2Vq9muM1MJ2X0vvF5Kbbt4+zoFfDyBQkayBgAIhANSZiMw4qQWToWFqghylDogE4OrYPgZTzQuhn5TtIns7"}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-beta.3_1587416444409_0.15197263891575008"},"_hasShrinkwrap":false},"3.0.0-beta.4":{"name":"@vue/compiler-sfc","version":"3.0.0-beta.4","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"prod":false,"formats":["cjs"]},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-beta.4"},"dependencies":{"@vue/compiler-core":"3.0.0-beta.4","@vue/compiler-dom":"3.0.0-beta.4","@vue/compiler-ssr":"3.0.0-beta.4","@vue/shared":"3.0.0-beta.4","consolidate":"^0.15.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","merge-source-map":"^1.1.0","postcss":"^7.0.27","postcss-modules":"^2.0.0","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-beta.4","dist":{"shasum":"057e7269effd390959b20190d30b39f3adab90e7","integrity":"sha512-XTXPxU8Rr+C2UHaWd7LhFG7yM56uu1gFq3UpBDA6DC3ME7Na08j43/e/r8f3jb3vYZl4yRB1HT1UInYnnb5j8Q==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-beta.4.tgz","fileCount":6,"unpackedSize":38415,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeo0oRCRA9TVsSAnZWagAA6rQP/jM/VEvaFU+vHp/ewzQ2\n4jt/R3Dpmb/lucfk8xdM1zSJksjOyYGE22Df1lqCgbptmvkp7N6Y7fakeKat\nMpAioypKkbh4lp2oYWzukOTIHYDqujc8gyPPA835jtNWkBUNU80rlULXgWPY\ngfOii4qiy15wWRQtNJ6QgpazsMUEfvx2r/6czsraOUd5BsU1G3eS20gbt+Vf\n0FDtIUwk7AfNmKXnye2fnkJqOw4Qhje/cCuE8sSI/xGQNRvJqlbDBPJC0VIw\nEA2pteHrF9JfNTBKfDv3VYgbcA4G0uUz6eJ2+I/ZoBFNwFo22XTv5/8COPEA\nKIs8/h2PLu7oVwEJNqbuz/LT5wkmH+PO+ujN0aXrclag5SznbDc9A5HvzXu9\nvn6om7tu6pSZB221un1I0yI6kIR+MYwLAaTWz527o0CYUYUbQjmv1tMmHEtz\nOTmc6LL4NNo/9vxgCOGQUAnQUhmwKbgkstAdvtpVKkhtEQxiLHAU3xcXhabf\nb9Ov2dsn1/lt+LrdBcm8hJn+WKuy0nHCoXRaKOiqWLPn7MrVRjVg4R3mcNl8\nIwIRLUV0m2kEE7/TwoXedEUWcnNDZF95aOmFnIVlGP9mdK/Ys9dxmGdg5wqw\n5MKLhQ69Nt7YdRhqjG61aNnmN8qpUc5/0g7lHjNAJsD0AEyMZjqAiHy8Da7O\n+N4U\r\n=hkAM\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIG7jvFT9B/FZEbZzgjp3bcrieidQcBGDFD8j0BUfY5bCAiEA68Xh3ktDyiKvVjnnHbDS2iY3/v0WVrDUG5JaKgdZR7k="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-beta.4_1587759632641_0.15494807019119516"},"_hasShrinkwrap":false},"3.0.0-beta.5":{"name":"@vue/compiler-sfc","version":"3.0.0-beta.5","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-beta.5"},"dependencies":{"@vue/compiler-core":"3.0.0-beta.5","@vue/compiler-dom":"3.0.0-beta.5","@vue/compiler-ssr":"3.0.0-beta.5","@vue/shared":"3.0.0-beta.5","consolidate":"^0.15.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","merge-source-map":"^1.1.0","postcss":"^7.0.27","postcss-modules":"^2.0.0","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-beta.5","dist":{"shasum":"0c79c68cb77cf5c02b07962ad120ecc6952227ad","integrity":"sha512-s/GgBhh915PKi62CD3VBzLJMOJaAs2za8pyBz2rZP3BO5xPkUry8wkaZIEkypfXVOgqxIEJHaLGynEFIgl1Z3A==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-beta.5.tgz","fileCount":8,"unpackedSize":2128979,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeqzMaCRA9TVsSAnZWagAA4OkP/it+eGnVLu+ZUaSC91XM\nK3+Cjl1ByuuCgddHJy7Hs0d2Yf+7zg9FJC0mU4D6lBNyQjrm8JLBBHAjhAxC\nhV2gawX3iYwntTxLuAB/pvw4rELhFddUffF2514pjDcrUQgFXIdEJxRpK2y8\nhwHGeKBavgE8Hp1u3TEHLiFtb/1DFgU9ViCjgher2+sqn7IGwz4ChUB18LTU\nkXr01rac3hvA2SQUxQGtg6ZXhUas3zw1wjcesbihpIo+moX2Svvg9bUTJeff\nXZCdJVOzeYIB/wPsRDzoU9PO3olSCYnPBqWyL+vate4bv/Td54bROgPvm2VX\nIBqGmlVf6qlmgYciJwkAehB0pcUXzPf2NTsidNq7gYMwpBz+Kx3awV9sSPos\ng/VmgtsvLZ96ZHiBrsT01/urUPWKrho/4eO/whlYjydfL49tmAdmN7g1j81w\nnqzcD9WZi+AsWZoNV/+Cj7Iv0JqXskfcjCP9Fg7kt04hkJEwCcuMO0lHOAie\nE/RqymxWv9CCQmYGB0T6MQ3QMU0ZLgOe6/J921KhPYCWfo0eR9lXsKFDV9O/\ngpnQp5wQPnwqWh+HjCUcQT6j3ar55RCRdkxuHt3RqkxfFpAoTIulmmKyOuip\n/bZRWgOANyjjUt0NwG/q3ixExpeKb2+AMkmSt+twa5tSVvadBDTY3pk0Yqik\nogbr\r\n=b8+B\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCzJT8usX3FLESCmYT7VLUr/DZCJYhHMddXR/647YAc0QIgEyKArcPgGo+t7eSC+JFiiswhVP03REEW3zcsSMwl5PU="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-beta.5_1588278041960_0.435031864937947"},"_hasShrinkwrap":false},"3.0.0-beta.6":{"name":"@vue/compiler-sfc","version":"3.0.0-beta.6","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-beta.6"},"dependencies":{"@vue/compiler-core":"3.0.0-beta.6","@vue/compiler-dom":"3.0.0-beta.6","@vue/compiler-ssr":"3.0.0-beta.6","@vue/shared":"3.0.0-beta.6","consolidate":"^0.15.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","merge-source-map":"^1.1.0","postcss":"^7.0.27","postcss-modules":"^2.0.0","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-beta.6","dist":{"shasum":"f214ea718110c2f099e6467918d329cdf31b3a47","integrity":"sha512-ZMOSYhIJwa3W1qckH97XLg8In1L2dk4DkfB9tnSttUUbe76fA+1ffhXtrIT2Dq3iYykAcaog7UXNbPXPVIz7Ew==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-beta.6.tgz","fileCount":8,"unpackedSize":2134743,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJerKlFCRA9TVsSAnZWagAACr8P/Ah5wxT+/bkSGFpuUnji\nJrBK2TFFYOmuoC5tww8hBDVjpiu4FUuw//D3q7McESMLmDFlSYzX/IzPYlcV\nIN2dcLXogUkpCXpa7sUdIQfCxg6iyqpNBoHtCye222A3qz4ilnx6ejmfIUGP\nFIZMXXIj5s/f8wWJSwCt48OkbJzRDhI/QcSNZSosENRzaHkhe2ScQlpP2Zww\na1qbZMeVSlFTf39gC5LK+ICwOg49hlgGqYaQVGDO6ot7HGey5pi2mCFho3Ao\nkSvrrwPIR1rUrWJ5nR4qCl2+3eurtTy+LXOb2Vg8SYBF/na99PQeOTHPa53A\n78P8Ie15+r4zBa5PF2lbKDw2rQwKpqVsVFafbj1VgCJPcb61zdErDip9WXMO\nDQaeJ6rtR0q6UaON4Oz0+uVIfkCbjhga4qdflG6TpU/cE3X/wkJ5Q7ZGf92J\naJPwlqw1MJKoMUSXQzWFQDr4yOMtrF88bxQkhgHmPLOTANBZWHdvtMq0spto\n3J0efH6lurmgkQ3khX/OsGdOjelxWMqDY3CgAVqMxBC75Y9x1RDR8ZMHeXAg\ntj9buJHMZYfcmVBEm63aJjLTG8UEUH7TGx1ChUF1WikqhcYbqCzKdK9PnvUg\nLL1hl+4+OTAAUNTjcI7bpvdhA2agtAQKhdn2WCsb84FHseWRJq6CGpgsYR3m\nFUqg\r\n=4+qu\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCncf7gRqR55/Jr9gSUidrhZ1o7L2onOn+vQSJlRrw+JwIgSi59tX32nkztY+DNlY+x25DwcWk6LNgI7JyB0q5zsQ0="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-beta.6_1588373828792_0.9105521900139817"},"_hasShrinkwrap":false},"3.0.0-beta.7":{"name":"@vue/compiler-sfc","version":"3.0.0-beta.7","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-beta.7"},"dependencies":{"@vue/compiler-core":"3.0.0-beta.7","@vue/compiler-dom":"3.0.0-beta.7","@vue/compiler-ssr":"3.0.0-beta.7","@vue/shared":"3.0.0-beta.7","consolidate":"^0.15.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","merge-source-map":"^1.1.0","postcss":"^7.0.27","postcss-modules":"^2.0.0","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-beta.7","dist":{"shasum":"d4d6e1b60802e7f90c61c86986b366cf69bcbb61","integrity":"sha512-BhDO3gzcKPt5S9UonTYvM/3WgrLWxYgEV3D40/X0aRIrCp88DCzSpKxDvTtHSdaZpCzm2HgW3E2fdGWVbCWeqg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-beta.7.tgz","fileCount":8,"unpackedSize":2153306,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJereDVCRA9TVsSAnZWagAAN1IP/27j/de4GwrUOeXgDzS5\nrE58qt0XmAoUxtDVX/QwKNr5JaiiPgHWm+HJYJWx+p/D+7KQfhejyop5/eII\nme+SPQ5bG/e5GSafoui8F/leKw8gMReWqNLlFIOnOjCROik+540y73eIGCvD\nwH+zoiAICHFwC3INy1uZS87xAGP9JhfVQdSiVGSmpExY7zed6yjBsSHUDCm7\nVL1IZRCordpHdJcgpX1l0o3AW9NRUSp/KrE5hCqiC4tmKbuBUGo3WvL8luBs\nyajX94ywj4/1Ew0SEIcoFaURDEQx0hh0gRsv2q0jpKbjRpftA7f3NiUGfzYt\nyMzVQPolDYBHwE5rt3ezXKyGP/hs6kXRx2Y8bazrYTazupYl/YkxCF3RUNM4\n/zLAbaRufp+t9MYZPKkDQYwimQLAmMXB03/0JHJrGSCXMQwGHWHKoI+oceSi\n0yJZBLA5oZp6rTtyMxzfb79XN78Z7n8XpaokWdh71C3Hl6BUqg82EI2t5i49\nv5Wx9kElxzcgAilr731D+Of0eC0gkVTYjVFVdT/xnNwBMf9xsP+J8t5X/kKz\n9lBbrM6woNOELSrQtWuzoo6BeQ+L0GXwsNOoiAcuTSao175Jg6E1FDNUqxJB\n/p6iivQLkOjvwCrRi23PxA9BMvEqZ5776t4/LE/hc8ZYB+hgg0JfUKAty0YS\n2eoT\r\n=VKw1\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCvmgodyhhnFkkXOuz12lIq0DTIi2up87jKLUY2EWvPIgIgY7GrwLzJVTNkjVVFC6bjkIPBmt4PGVsbs+qFX/64Dvg="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-beta.7_1588453589065_0.8574787375753654"},"_hasShrinkwrap":false},"3.0.0-beta.8":{"name":"@vue/compiler-sfc","version":"3.0.0-beta.8","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-beta.8"},"dependencies":{"@vue/compiler-core":"3.0.0-beta.8","@vue/compiler-dom":"3.0.0-beta.8","@vue/compiler-ssr":"3.0.0-beta.8","@vue/shared":"3.0.0-beta.8","consolidate":"^0.15.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","merge-source-map":"^1.1.0","postcss":"^7.0.27","postcss-modules":"^2.0.0","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-beta.8","dist":{"shasum":"e0509e578c3771d24793dd6c8b93e789b68e6dbd","integrity":"sha512-rHELIv1LAvg5ctS0pptoqnKq/JL3xkUqH8QnqJ36x/o81P1Tu6mFdc9da0TKbI+RZK6HjJNHqMsEtkDLnpFXxQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-beta.8.tgz","fileCount":8,"unpackedSize":2154322,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJesCuJCRA9TVsSAnZWagAA3b4P/iylVwbUyPmCVW08PiF6\nbFOTrZMTgkPVPoTgHVwdNIUmE/bVQ2Btrh/GuzqbRwBbH/fsW2tKeplmMURQ\nB5SV6KGmERioavIW0eZpqNJldrkDs77gRuYj8rj4rKikTA8DE4GHdEb3OaEQ\nzzZWCfiv+WW2+NBJ0Wqtn8CPtEWcAkGLcQogQIi59GbHRaZR9DJHclumQiIJ\nHkMl/IeUeW24fkOj5x95vDwRYbrKZVS5+Tojx3bf4TVYpCJ3+B0rD72DS6Jx\nryox5um/1KHFNjoC6nDCqpnGls8dh3eEKNvWOOopfcrsX9YuTs5wWHQ7kJ3w\nwA9lc28u6tmu8HTfY+19K2ZvrDL7KTtLFKPekOztrj1bkUSmT8bP42aZQo+P\nXXozxPZ7ypI6LIk/iNGELG/cteft2uudY1hpfKGdYBILQSCafXrLbFera7yf\nlYJVqLik9FViy9WvFDW2CALqRgEilzo5smUg20ga3DWoHJzL/EtPBSKfivWv\n7jhlEYmaKz70qUOgkAMceMjwx5ngM4Rki2+VsC4NPc9/m3bbxBZcqdmP2zqI\nIRKZg9hFirIdLtRABKTcvCOS88Ix/5RlW7u1hpkPJizdJc7U3TKIMWqBjts+\nKWrY8+aDHYWpOtWKCGbUMtmEelBm7J/zsQDs7caF0MFez/9vtXa+oQYaiHeL\nIVVZ\r\n=ZqO+\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDwNXA4SC+b0t/d47rS0yvzjWZKkIeSCo4W6AwbLg5DqgIgQ7eaJ5EAf4IMrJQfpwQ6x0tnFI7ZuQo8IFaAh3+UJm4="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-beta.8_1588603784573_0.9927420083391971"},"_hasShrinkwrap":false},"3.0.0-beta.9":{"name":"@vue/compiler-sfc","version":"3.0.0-beta.9","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-beta.9"},"dependencies":{"@vue/compiler-core":"3.0.0-beta.9","@vue/compiler-dom":"3.0.0-beta.9","@vue/compiler-ssr":"3.0.0-beta.9","@vue/shared":"3.0.0-beta.9","consolidate":"^0.15.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","merge-source-map":"^1.1.0","postcss":"^7.0.27","postcss-modules":"^2.0.0","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-beta.9","dist":{"shasum":"3b85acf7c8b9792ffcfa9880cb8684fe679d25b3","integrity":"sha512-J6C4l8GxP2jWRZFXGO4AwZcOzHUYNT08kGTFZM2V9GBMg3UaLmE6DvUPTPBTrBL55RTyaV2O+U44S5iYlyUi1A==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-beta.9.tgz","fileCount":8,"unpackedSize":2160758,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJesIXQCRA9TVsSAnZWagAAdBQP/jCtHiIQDvIUOIsBXEG9\nHtXPaRxXACLixeeLWIvyem5fxaDN6zlMh67N/yP5FEHMBVDnyTtxh7gZvNmd\nh0P5EvhpQ7l5RCkaeBZBtjVzgTjtH/ThXuF992XONCifJsYalAn99ozFc56/\nId5flOlP5pmv5VsSvJI594ArcmXHerYdTLIH+hDzkQYD/LK8r2PZesJ+i/ru\n1wMS51OLBvITYLmq0r4XfzwT+2B21NhGhKcFPM2L/mGruRgovX6/SVNC+iJC\nVLjH7PHyNm/prAV2Z3S+1OEHMd2Cr60/Agjgp7ijPCTCzpon1yOaGsLNQKpW\nuHHlPzPJFpXSXDA4CJE6ov4bCQP7frdx6DChgZFztcos/knWxXw1KlWCVVPn\nlVAeWqDKCAvd0t5Ikp3jJqgxZPLqP53AVi9H3hKlBZM7hUX4cyqLD5RN1ThD\nOMdblkmPmXKjPSnzp4JkrDvDVk9shcfw2zaBTfarUxtvS/Y3AwCPt0gs40Wk\nHvc4HSEKhyW4Yhs3UdKe6MxcxrlibPOucWuLIDQuuzn35ebD0R0u+mTndC6x\nbXRsBXJZEBMeUtCEOg0Z6HGYGuvslzZRxVarDedG/F0KKZarIhZLf9SPY+UL\nFHie8R9o3n25znNiaG/4mMflWD9sHE8sTQx05GjWkaXDzSRnFt5NwE88LPYP\nt8mE\r\n=mYhe\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCPnW8p6cWR/uNSzVf5GLhRnTjr2qf97skoUrdVM3HwnAIhAKoOvPZJngEx57o7YtZF5sQ8w2RJEvVJvmGsDEr2BM4r"}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-beta.9_1588626896130_0.450938473211399"},"_hasShrinkwrap":false},"3.0.0-beta.10":{"name":"@vue/compiler-sfc","version":"3.0.0-beta.10","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-beta.10"},"dependencies":{"@vue/compiler-core":"3.0.0-beta.10","@vue/compiler-dom":"3.0.0-beta.10","@vue/compiler-ssr":"3.0.0-beta.10","@vue/shared":"3.0.0-beta.10","consolidate":"^0.15.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","merge-source-map":"^1.1.0","postcss":"^7.0.27","postcss-modules":"^2.0.0","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-beta.10","dist":{"shasum":"bfde1343c79147a270b64b96a0608ce8bc7cfd6d","integrity":"sha512-m8N0zP6Mpdka3o1bCnpyPvGQ47SVqgsnLuL/xmwIsMl/ml2f/UQpbsICY8ANN1/1QLvmXEP5Gl5PcoEVB7uHpQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-beta.10.tgz","fileCount":8,"unpackedSize":2166807,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJetCd7CRA9TVsSAnZWagAABiYP/3bHOxzh+1qGaCAz/hXR\n6hiLgg6EF7mpNEfOOnHmBppTian4o35cpLS1REjBzOyfDXdcP4QgqOWYt6+I\npuWdErpByOp7+1wmI5M3HSV7TpL1H98xb2qKLxcYIJf4ZU41V8JQqFLTmQK7\nJKc2HOzHnzr+MKdfMz0UhSonY/vDaQ8AhcZrddliksQTv0sJcDUOqBJzr8u6\nxzzLY0pjepb7mqnhhlRHtgW4BtkoN5UYiVlC1qqMF8qeOWJigKGxFof4IP9J\njO2t2k9c3Oh4y9K4jGi8uWbCInJGMqahW6Hq9zxCmclTjKfkWQYkMTJv5g0m\nGHj3sDSUM9t9SWRtr6ybw6Bim1tTULXFu6i+sHkWzxrHtGKWT9B35ObxPNtp\nE5Yjjvn8RjCV76aq0CaKzGLAN/ZGEg3QPvR8WXTuZhW9LRnoujmtmdoUoKDi\ncb4EQT8LMyQI7QUc77beKurmr4u6z+hhr5uLB2YVf3aOboXd7RddSukzcS4B\nfOVOxRN3ta6jT1J4vJeEcJIv+OGdvbvJE6lLIeIDPNTxRkgOBXv5JJ7qG6NR\nCb4FpNVAZNj3DSzjJKjJu49Waw51GvudymNS8EEZdUxULGnDuZHzvZkxihfT\nTDGDhe4y6eubFfnyMIp3UIl3KghIAyB179HN0qvVsViic5K+tfO0XAPqsYX9\nQIbz\r\n=HT5c\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGvN07eWik3RlAzyZJo+EzWSvu/aBSAUvsC+wlQsWZRYAiEA4jyNctEruXb8HSfbYWu4v9CyM9NC1JhrjfM/d4ScVmc="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-beta.10_1588864890942_0.07274457867961637"},"_hasShrinkwrap":false},"3.0.0-beta.11":{"name":"@vue/compiler-sfc","version":"3.0.0-beta.11","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-beta.11"},"dependencies":{"@vue/compiler-core":"3.0.0-beta.11","@vue/compiler-dom":"3.0.0-beta.11","@vue/compiler-ssr":"3.0.0-beta.11","@vue/shared":"3.0.0-beta.11","consolidate":"^0.15.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","merge-source-map":"^1.1.0","postcss":"^7.0.27","postcss-modules":"^2.0.0","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-beta.11","dist":{"shasum":"91db20acd897aaa5ecad02198ecec032e3fe8f57","integrity":"sha512-dCdmVBqm/ZgEwlsSDHaqprrcGWHSS1ymJW7bKJaGuoOKklTCSi87z/jG3Ot0j7NSJzUICBX4VSDpriHbFvqe3w==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-beta.11.tgz","fileCount":8,"unpackedSize":2166807,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeuZi0CRA9TVsSAnZWagAAKyYP/RJ9SfjZJYT0Nf9ApuCt\npT8mUeK7tkHh5F2pG9/cRPmmMMNAaJJm7gJnraCV0craOxA/Jx4CFpYZ21WI\nv2qvRzy9ibaJ73RlT8IhD4/f6yZBbXY7HTuuqI/WKRAJRy7J2e9NzOwfendN\n3Mo5ad59JFjKivjoickyz3z4mDhVH4HtA02TmgnSkUeqF8KmhdH8/nB3U5Fa\nCPVUnBA8GpIBJCIPsqdY5sZGKr4XwxYwQK1MFHyDhV3AuAjRp0CBfXTaXZz1\nT0KghE+F2s2oZviAnpxOkeLG2IQtqDxrQpi/ULdk/S/HNvDSHClwf3pkQPBi\nV7Wa40c7d5ROuraYh2+W4fIRtjaI4rTt7HgHF2YpqZaCUyRJnalhia8XM48n\nY8AqMqqaIl6dQYzX8RHGzv9FZ8ebhg9fNv2iXnqFNZYFsH8KKH2j3ge9fNYt\n9zJBtdkAA/dROshBa4VuKbGfhGZmhiTk5q0HmgSi0K7OagQMyVowJGozt8Zu\nedaQGBWNyfuYn138NRySeBRgpBEm1az0TicbfrYEeRXyh7Qgx4sQcOv9kI+e\nj73p7zyhL6ZyvIWF3wAFxVeGPKC2JsO59BWywUbdK+8sbcR6jyv2P01QcJ8W\nNNUsiAb040bR3/HXmRHphDfCngxQB/JFWWKq2KA+BSPTYC5LXBm9DhRLjE/o\ni+PH\r\n=Epsn\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDd5WRFIq1KnaT4pRFh1YxkW8NEycQbkQbwKcvmzEuWbQIhAOp8qV1SETzqOhNd2T7aOqvbqNXa3EcjRBB3E7O4auUF"}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-beta.11_1589221556094_0.49988877714757596"},"_hasShrinkwrap":false},"3.0.0-beta.12":{"name":"@vue/compiler-sfc","version":"3.0.0-beta.12","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-beta.12"},"dependencies":{"@vue/compiler-core":"3.0.0-beta.12","@vue/compiler-dom":"3.0.0-beta.12","@vue/compiler-ssr":"3.0.0-beta.12","@vue/shared":"3.0.0-beta.12","consolidate":"^0.15.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","merge-source-map":"^1.1.0","postcss":"^7.0.27","postcss-modules":"^2.0.0","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-beta.12","dist":{"shasum":"ed93aa0f07d5d099cea7582118e05fbb7c77b1c6","integrity":"sha512-YtX7SJdk68eKPwcL0u515MjOerMSao5UrM0EtL5zxLlQUiokmqxddxALEM28C62CoUonAWr8CWqnb262u0DBoA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-beta.12.tgz","fileCount":8,"unpackedSize":2166807,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeua0VCRA9TVsSAnZWagAAbeoP/ArkOK4KaRkMAuFYHDOc\n244tJnYhqqwnC8WIkyCohYWINsmQ7Zt06LVCUESF8gCCzbM6lBhZV0Q4qnIE\nIFrYSCcIuvGv9LfAakcMJeJNzp9f9e7x2CgZ9M2qv5TUhraX7Gont96mjzfJ\nR3jdKKdVncpEhBDEPXBkUwxXMxwtycUg4QmcuxewzcBdlzWT1NoeTgxLkvYy\ntjtjJBMQRzTCkP8leTL6BenqLGwXBMRa60OcV48fUNdPV1jknOiQFzRn/Bk+\ndAKjOemK9D/Wm5fGiYO5mL8Ad0gtDyGmMjsqL3zwHyW1g0c8tSWaJuctLx8b\nuJqIrLnsX+qXQWAQ+FiGB+QYX8rshQf1pBj9vPbKaQ+qGADoGnjukcNXaOHw\nnQwl7gMobOyoonl1UQ52jYN8itHjMxuWQdDRpZMG89ApUJtgThzlmGwLMlyl\n6DOrXYZgHuktGJdGxJ5vG4BepaHKAwLSrqzw3xOPSKJzxaqO0tqCzGVSIZpR\nBO1MLcwHIOXYlcjNG6GR8Nfym1UzjOrJxHfiXYPCfu9W057qKjfMg/k4MgTo\ntrz4mnFjEbgplJ5oIfziPzjocuxTSKKosrz9qhh3+y24+4Jlg/kCSnWJ0wJp\nM39kftEdlP43ujt7NVUcnKQR+6l5xLPT89YrddB/xqvnjC6L2Pv8jRLTNWT2\nM/Go\r\n=AdQB\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDQCEKt1H40qz3oEn8WtHiULQEJpZgFxpdJSpb+jK2HmQIgIC6fZnJFpJk224/1FYXcJIUtMImBtN1DRJDMk9YT9qI="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-beta.12_1589226772414_0.9540862339299709"},"_hasShrinkwrap":false},"3.0.0-beta.13":{"name":"@vue/compiler-sfc","version":"3.0.0-beta.13","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-beta.13"},"dependencies":{"@vue/compiler-core":"3.0.0-beta.13","@vue/compiler-dom":"3.0.0-beta.13","@vue/compiler-ssr":"3.0.0-beta.13","@vue/shared":"3.0.0-beta.13","consolidate":"^0.15.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","merge-source-map":"^1.1.0","postcss":"^7.0.27","postcss-modules":"^2.0.0","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-beta.13","dist":{"shasum":"131cfda84489141889ec76cd2c9371fa3a118d2b","integrity":"sha512-wAjwSSf5j/DUIO2ugBdHlYJxw7GXdO1tF1upo7kDOJft+qCUThuhsg6rsxVN+zZ+dmiqBf/Yj9u4RjDRHXkeLw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-beta.13.tgz","fileCount":8,"unpackedSize":2174759,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJewJk4CRA9TVsSAnZWagAAXzMP/izANzAt6dP2agHKhn8Y\n4CRAhc5Dyq6i/pZi5J3rnO/31SOZaWaaXIrM1A76f1EvQzn0qvX0OC3DdITE\nTE6ckjKymL+p4Wc6s+ud5v3RIKhwUIN6iY7GsxYaKBZE6WE9REQXCZZ66UhU\nuKnLGWBo9GOr8d+YYtuNuHQ6crVj3ntIReT0nq7YVPVQ+8Ekzj3qHC/rvPQs\nKrRXo+ICnR3HSn0glmlczWA55wPXWUTBuCmmLhS+pfSw5sP7qka46t7eIze5\n4tpo0v8w47p/e1M3rHYUhzNnfZegiddUpBp/sV6ILw66U903l8fDhqg7yyIu\n+ko+0u0/X1cYhUJC7cynrgk4HJpwLgCjJQU9KaQblWstW/ZLoAaJYVjm6rsm\nJ65AnetwvBEeqrBqkU/izS0HXXFSTTCuoohoXimxfEtI8CL2j7ZBx7KhN7mX\nWo6qhwC6ExjLCl+xbM12OBGEhIEG9WwmkMJUFbzPvbIRxTgC8Y5qnpSZNncn\nl1SlH9rf7SleJGioGTS+IUVEoQgOb5/krEnq7wRJQKHK+AJ/vv+CMUi6eX+J\nRXuAobVXXTEnDBZZZ0ny94T9lyUnQjSnI+nTp11vkofAaZEJERDOvrqc0DyI\nBz/hlSxkf21gnSYtSc6VOxr6V8l1pD5WAcRVyeLTf5DIQtbMabROik0ajG89\nsxk6\r\n=FNgm\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIF7vKGT6M4NfWwVM82vz278lsXvvGBnGrc+QS8DvJUWbAiEAq2Iu4sZgCeXnzVitq6vzqKAvO5OfWArUEnL75MZvKUQ="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-beta.13_1589680439800_0.5917996311646894"},"_hasShrinkwrap":false},"3.0.0-beta.14":{"name":"@vue/compiler-sfc","version":"3.0.0-beta.14","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-beta.14"},"dependencies":{"@vue/compiler-core":"3.0.0-beta.14","@vue/compiler-dom":"3.0.0-beta.14","@vue/compiler-ssr":"3.0.0-beta.14","@vue/shared":"3.0.0-beta.14","consolidate":"^0.15.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","merge-source-map":"^1.1.0","postcss":"^7.0.27","postcss-modules":"^2.0.0","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-beta.14","dist":{"shasum":"3984416c0ed1bbdfbeee9d33c8a2c1152ed00770","integrity":"sha512-pS/vTlLWBEkyyA2oZBQHqqObaLEy25BKX9LzNphDBC+zKRufGQEObecwSbJK2QGdu8/bzxI3sAJvBlPm8ZmDOA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-beta.14.tgz","fileCount":8,"unpackedSize":2179493,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJewtcRCRA9TVsSAnZWagAARMYP/0J87o+JwDYM9uL6Gs+f\nZhMCK+TQIe+GgXGeF0vvBNa0bHzhXuoJWXa/IBl3LaKLPEbo8wIqqv2gcpGV\nw+pwUSoB6HAy5+Ljdojn8La5u2akIHrmDnORpIsyxDQ6dMvUXYv7JiBdsaof\nhQuhANoGXgNrb4VvievaJeYKgpacyJULEm4YHUJ2Dy6ZyJxREXqg7PestQbq\nCVGPS5ZPEdLgx5/hXNlI7l5lG+AYvxtjIKf1JQoNHpkcLY4J388QUpcWJd6I\nxniJwOmklHuARosmOH8iEftSKcDjxVPN+4AqOzgrXaUYc9qViY40IJKwaj38\nUuHUG1nVdOsBXUprKILPjUl8KyCJauOlHaM1dHZpmlrRl7sMxtqDtqeY5NQ1\nfhXzaWcB9iqSCCW6fICcvgCw8e/Bladz3oAP+2AP/0KPGzEN1pOpDnVrwMyG\nFC+ryvvCJLkjUx1t8FzxkklF96R0VXZCmkhrDe9nYbPBA7+hrCitInr7Vhrx\neQHfHUnYsAarw9bb1ETlOoLm/Co6R/ijNw1ijcPkHtWvwd683TXzyFsTmGOZ\nUAJU6coRVRPQG469LxxPB+olIFGsRSxff7NxCWHwgF+1EgOvOnypgMaecG2f\nKIaIMCqqsQ9CN5rgOVlRe59ow4RLhhbHGlqgLxNrv+tCoBWmDrSDX6nwekFG\nLH4d\r\n=4Isx\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHik9s/C3sfEgM4qeI5pAI6wr2CFexn6NaHXl+PsxsSdAiEA/ueRJx0Y7gbRv3LonbTQWvRigGENLFBpW7B+Zi/sj/A="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-beta.14_1589827344528_0.4351686551764673"},"_hasShrinkwrap":false},"3.0.0-beta.15":{"name":"@vue/compiler-sfc","version":"3.0.0-beta.15","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-beta.15"},"dependencies":{"@vue/compiler-core":"3.0.0-beta.15","@vue/compiler-dom":"3.0.0-beta.15","@vue/compiler-ssr":"3.0.0-beta.15","@vue/shared":"3.0.0-beta.15","consolidate":"^0.15.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","merge-source-map":"^1.1.0","postcss":"^7.0.27","postcss-modules":"^2.0.0","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-beta.15","dist":{"shasum":"8a8cc309fd56d5ceca76160743a4eb4e8a43281b","integrity":"sha512-ZNHwUCbhGJHNmUQ51Q/Er7kvPUWru00DlWTGC3u/C1wbcqx/bwgzJ6YENbFq0rcGwrUCo7H6nP6ZSAhE2Euiog==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-beta.15.tgz","fileCount":8,"unpackedSize":2190459,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe4/0QCRA9TVsSAnZWagAAWSEP/0ijMZW4bRWMNdb3GqWM\nZjoDOoPj0QLFwLqqxYkMI/giBTZUjgOksO9hkiI6LMHhcpvSh1if5+aTNZax\n4h8SHTEtdaK2FAtW6EkIXUvEP/ZEu4OdS7SNsGXuMh4tFjZEgNlkFM5hEzKy\n9JgUvnF//RGtB8ihpfkwINoKJ3VLAHy/6RhExRCiQt/LM3QsHbz3ULfvkvEb\nda192uuxUkOk5PUo9h1b8Kr60XGxXPg5vYdH8ogDomvwHHtujNYxkp4jvKC1\nxj3iBccvevkF3bSSdD61ZmCV6BECsYGQVH8Z/F9Zp1rnRFjXG5IqVsSDbjoP\n6ODdI+qA8wPsYEWEyK5Tknovuyye+4kXA+NKDevlUXMu+6sArAwSLn/R6IPh\nQwrilS799RY3ixX+s8YwncB/085Iwb6pwivDq2o+0RT3773vUHPk76JvOI/+\nVB2QzZ75NpbUT2r6VwB8YKnY4DfhLBYCCyGTiaULc40I3kOyQddulFEUf8AW\n2cO9ZyewjrbpdB2n+N8pXXccztKOtqeUcI/AhAf2AIGIBO9+74mZed8Moz0i\nUedOSMo7ksHSF5uSj4B2PqaK3RlMSUArWd9A9OyedXo3y7Sg00gKYwta8M/6\nLEKObnJDnkSTvqPLQkuLkghFat19kfjuRgmtsq0gvhNNtiTIYIxKXYUPpnY3\n3sFa\r\n=p2QS\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC8MjpdDN5C4HhHvXPUcz7BgaLPLqnFFrFcjm47jAtDDgIgWufaRD6YLICStPcvsvt22+CELunH9pXw0kfIrDwhimA="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-beta.15_1591999759949_0.9747891805293476"},"_hasShrinkwrap":false},"3.0.0-beta.16":{"name":"@vue/compiler-sfc","version":"3.0.0-beta.16","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-beta.16"},"dependencies":{"@vue/compiler-core":"3.0.0-beta.16","@vue/compiler-dom":"3.0.0-beta.16","@vue/compiler-ssr":"3.0.0-beta.16","@vue/shared":"3.0.0-beta.16","consolidate":"^0.15.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","merge-source-map":"^1.1.0","postcss":"^7.0.27","postcss-modules":"^3.1.0","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-beta.16","dist":{"shasum":"83fcd21e54ecb92a2729aaac486f6d9be9677c52","integrity":"sha512-VTDi9A8tQaB7BjzVDcSPKp2z8/u3XcrkFYaTv/FxdVqr9Vpu7IN4ioPochQhB+Fpg07udhJzUP0dCei6xdG//g==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-beta.16.tgz","fileCount":8,"unpackedSize":2191324,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe+myZCRA9TVsSAnZWagAAw2IQAJSoYKEvqnYQRCSjrhyC\nuinvBy7eRuAbmJfamqOhqWmUHtJuPi+YzV5k09qPnhcHWf/cvkja55yhiUKZ\nrKOg6JE0tOgBsHut2trfAaYV91ccuPUYxn+swDiZjKq4MyYg5gkcRw0AZNl+\nlb6crzBAzMPnsp9FK9zSHkc2anb+2TK4LmIo7d7231+f3NoSKcwTxpJzqEI0\npO30Gn2zIqsSRGGBA1uCHIt96uKe3mlMQH8NJ+z1a9ysog95Gv6GwBFQrnGd\n+WJ+U+oKZMUpzkXs0VHroB0dQAOM/SlcaoDgIdjrs8nytzoE6AnbGR5dVS3o\noT9QjlzzNYMMqYexokOsP815qsQp6ItTuTI/NLpgmuGuudGXO/naVEZm9Tjo\nObD4nuvG0J36Ly2OSIrFyj8fMHtQ1+sGrwiynchena4aCIQPiFPin7tXNNjd\ntFo3HmJMkvj8gAyMFCfM4+pxIPwfu6qwwcTpjDyT1ZgAOP9Y9RPO3SuKZJNt\nT2hoXkKcn/uI04a5suCU7JvL4JmQANvDaQKuIz8+QleEd94iyZO0xhsnGlI5\nLZJSA8Lwsd5+JEvj1l7JZFbgwgy4/5PeObFbdbys+bOaI04/qW9rHSbr8ZyH\nx/L5tLcZ528VIBwQKKOB7OTkncVztarJqEmJ2uk6Y3X7QrbnqM79QgUJeu8p\nYFSv\r\n=kg6P\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFpIJkMt4gjqv0CHb2ugrtqf5BaMctBKmMSptJog/4VFAiAyIAJQAXTYIwkpRVg1aSfurj4ByD9SVoaUvXt4XAAZfQ=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-beta.16_1593470104587_0.900298728071872"},"_hasShrinkwrap":false},"3.0.0-beta.17":{"name":"@vue/compiler-sfc","version":"3.0.0-beta.17","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-beta.17"},"dependencies":{"@vue/compiler-core":"3.0.0-beta.17","@vue/compiler-dom":"3.0.0-beta.17","@vue/compiler-ssr":"3.0.0-beta.17","@vue/shared":"3.0.0-beta.17","consolidate":"^0.15.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","merge-source-map":"^1.1.0","postcss":"^7.0.27","postcss-modules":"^3.1.0","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-beta.17","dist":{"shasum":"d932a9e5fe9074fb447a6d82f22c52503d1da0dd","integrity":"sha512-MpU0rtDNzSWyhoLCqcov8XyrXIO8lqwA8Nlt7uy/EWndZv/Vw2VQVQYmfQQZzv2fDQ39f4s7LYcgEM5prRHX1Q==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-beta.17.tgz","fileCount":8,"unpackedSize":2191324,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe+2OZCRA9TVsSAnZWagAALtMP/jXOIecgwIsrC91swKVM\nICSliZKpIBHPVDvAWuJv58qI5wellfWL0o+lpT6VISjO0hdfKtufuVt08aFi\nwwc/docuLlmkW4cj/F0x132jNzOPgg0PelGww6aAUf4S1L3dL90jN9yH0xp+\numskCHxWUjnrrwIkpuztCKGbEnWOZMvUOSLAWVWDq3QR6jrZWH0dojAE/2a7\niWUnF4OHx/gkrTzK0z5jtAsucdWplKjdKrNq/bYKKa97q07OI0VM7hIytv2T\nBVUT4tTD9MiEcPW7J7NRePU+LunHGc9I5fyE3TOgj57miErfMWXGJpNva6De\nFOQq1YxHVZpQMButR5NQV4q1qLkgSr5ppsv/UoJM4bL5UHXMNhh02PryVBMs\ncgyOUGJYoyQw2w4Ke/FXY11epf6ky/5LO+W9HvIpmrZFm49HX/lKx2UOEF+x\nRGx/A8ycBKPqEbu+8HRHxL9vsjY/D3Af3T9lQ2cKDVky+sfy81dEN3QoV8vA\n5cj6EPIWGUMbpufeNbzhm+yZw8TvhuqvFJhv5t6Mgqua70LFJfy9hE3st8G/\nOy2vTek77udTaGNI6+0+hej0DJQv7oYe/HLvwKtNyQEmOBKU7yCHgUlV78tq\nJWGCDDR5YkVEoTsElzA8lLrDr7mIwCT4tEaVJHeR50RcnUX5tEAVUo2z9N2a\niRg5\r\n=zxe/\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICwYet+Aa5qDN8ntj9KoH8o7aGG4bx/9hVsU9uPN8LTrAiBmUr65fR/tiF3DG8monrOkW0ImAdOMPmgi6TK3cZ1m9A=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-beta.17_1593533337000_0.39307625739465535"},"_hasShrinkwrap":false},"3.0.0-beta.18":{"name":"@vue/compiler-sfc","version":"3.0.0-beta.18","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-beta.18"},"dependencies":{"@vue/compiler-core":"3.0.0-beta.18","@vue/compiler-dom":"3.0.0-beta.18","@vue/compiler-ssr":"3.0.0-beta.18","@vue/shared":"3.0.0-beta.18","consolidate":"^0.15.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","merge-source-map":"^1.1.0","postcss":"^7.0.27","postcss-modules":"^3.1.0","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-beta.18","dist":{"shasum":"3c4660396ca267b443214c09b71923bce17c5d8e","integrity":"sha512-RSErTbnKWkI4hAFBTOLg1tCHHVP2hG7NDbf2LVJdf9OWBr9FWoTQaMTby25rJs6aiSch7reNRzToq6XMLagQjQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-beta.18.tgz","fileCount":8,"unpackedSize":2191324,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe/TMfCRA9TVsSAnZWagAAFWYP/0aODjyi3sey2sOazBaj\nqW22lxKlK6mLKod8INXee9ZkRuHr9WtGvbAfkXX5bIH/rk6EOvqmBmfaWkTh\nfkQTJXVcMvANr8HwoH2GmLYxkwXl88vjCtcYLYj0baeeEsXKsMLXRCio9I+W\npMoMNLZSuxlxBQidruw1ERk2P47RumeM/c5P2HGh9yHLyzlLyl1gB+rUM3hT\nURhyi9DgiBVOhF62aiSfqD8UrjQA5hwODkjR6bl9zcrjIY4P95gPHAFAalTs\nj7aiEuceA+8YLkrLaIEzHcXAN6L3fPg0mUyCDcVGk4UxwUeyFnYBpLyRBmVQ\nGgTX7j4ONW2Fcgggl5XwUB6a4eH0ws3yhSowYO1gtmWdZRzc/vBnFZm/1zIV\nEygSgr+WywXZmXcgxgEi8Z+PnTmLaDmTuDRl+xUhA+MqJ11soWYK/FT/87AK\nh9kCQqQ3XVwFYUKBv0AgA6PFUQpAp4XfvkdSkYx4LQ0hwpUzx6dLT78wky8T\nMLEU/8zP2/SpPREAxje7ds1Pz0lylRwJ8PbqX3sXXSMLnFF/tm0Wr+PF9pLa\n2AdOsFwCr3YUazRB2PE5nvsXvHE6r8HzTmKq68QcZbiRUh/h6Fov/+tqDYb0\nYsEKVc6/gl9/kGKgLP9qVZSLYi6RwVmEZcjOLLyskhqlu/RA7w1vzIEK/WEf\nvMWj\r\n=2xbe\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEomtGigNv95LJQ/3nER6F1bIjgE7Ae7Kcy+cRDfyLG/AiEArENKYPliBFJljvb9z0lsntwvo3Kn+uWMXFz1L9IvOJI="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-beta.18_1593651999322_0.22035296866565512"},"_hasShrinkwrap":false},"3.0.0-beta.19":{"name":"@vue/compiler-sfc","version":"3.0.0-beta.19","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-beta.19"},"dependencies":{"@vue/compiler-core":"3.0.0-beta.19","@vue/compiler-dom":"3.0.0-beta.19","@vue/compiler-ssr":"3.0.0-beta.19","@vue/shared":"3.0.0-beta.19","consolidate":"^0.15.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","merge-source-map":"^1.1.0","postcss":"^7.0.27","postcss-modules":"^3.1.0","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-beta.19","dist":{"shasum":"3d7e4c8e249d24a9415f9eb55ddfe73820f74be3","integrity":"sha512-sblKw+a3pRMrLRF8netMKcrxCKtid7fMTig/p4nc8pkiy1WmHOQbkAA7iF1OYu0wAxyBZeHL4TFm2v70YX8QeA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-beta.19.tgz","fileCount":8,"unpackedSize":2194056,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfBIEJCRA9TVsSAnZWagAA+d4P/1BreEbWU7ZxjkQilSxV\nM+B2rpkC9f9+cH774o3S5LEl5WDQVNsxn2Yn9/YTtGgUI7znIupMB6gtqCmM\noGmcAyz8WeiLs3Q/eBlRp2WUsbyCVKBXh+WTjG0GyBQUbskggSYnkzDbymTL\n4PbaiSqfiUX8UQ0exFa2tqlvRT68S4l3ZY6WoU7PAR7sdc7J79qqRO1HEkrG\nBnTWXVci4lg0PaddiPq4Eq29N4t3pV6scxWtywscnnUBaV7v4vM0w7MXBIhI\naAEEcNvJp5TdZu4AvBSGSYqZjo+8mcfrZdDRiRUpyoIfBTVPJ+Xk/qBDYIF5\nIa95c3O8kQ3k+eKWrxscwuZP1YFYkqM92p83ZECiHb6EsiTfeLXVydf6azu3\n0dJRMvP2lbO7XYLqllqiP2kzROA4BJBVUt0hYWhpe+qpZmHeY0wbZiXt+Y/7\nzh0lwM3yIt9J2OetgnRn9ZpHi4U2Z+zeCuqCXqldDtCTXb2nFFiPuNYnj2Dz\noXmyFJZT7vezpixWQsp6lElY1RZYtYgU757Hd2f4FNDT9hk7IKkSFPcBPtui\n3NL/pGBNL6ldt9fEA8OTottSYSQM6HqBih1t0QITPxw6Q30Xa2g77tcOQRM+\nDQ4t/7wGRtfw4phNpVo0FmjWc6D185F1FwH5TNMWqixByTX+nc8sLQzQzm0Y\n7FDa\r\n=zUqp\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAmaQjFln/IHmnNP7W+cayBMC2r+JhqJpI9s5RWEFATVAiA5NBppNS5hU9bdK2hYUOfjl+N+VM+z36amcAN9+NEIdA=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-beta.19_1594130696965_0.6419913695519306"},"_hasShrinkwrap":false},"3.0.0-beta.20":{"name":"@vue/compiler-sfc","version":"3.0.0-beta.20","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-beta.20"},"dependencies":{"@vue/compiler-core":"3.0.0-beta.20","@vue/compiler-dom":"3.0.0-beta.20","@vue/compiler-ssr":"3.0.0-beta.20","@vue/shared":"3.0.0-beta.20","consolidate":"^0.15.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","merge-source-map":"^1.1.0","postcss":"^7.0.27","postcss-modules":"^3.1.0","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-beta.20","dist":{"shasum":"8ffe1a31e709713708fb625cae62e7efdae90b14","integrity":"sha512-n5bNvZCxvzGJqH2EXsurmzJDHnimOi93ezoeJTOguqNG2XYiiN+IOwzoOy+eYGem945FtKcgvawPhUMr5vPFug==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-beta.20.tgz","fileCount":8,"unpackedSize":2199698,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfBfg2CRA9TVsSAnZWagAA9HUP/0Jz6GfWbWnWi+rIp3TN\n+Rn/uOFXE8vgf74NN5AqKW8Gv/DWwHSDqxDctAz5P7fr3B/70Cp47o/m0ghi\nnzzDR3k9wqFnwbqFe4U95KIJNJvX08YgkwWDIxxcSHVGnvgHn9CzwXN6dg+S\n6MHQhOdTXXX+ASahrTGE58RspUfhfCJ/aFPmC1QSvGzgjWzq0FqHbPya1XQY\n+dJILJrUp/+7KWHKzGvNDyNhGcGTNldFZIW9mfBjpMuBQptYogG7JlVH5r+L\njba6C3a7v86Yb6qQe9cC50LHQtvb6pLJssYny4DuI94Ice2rIIyH5MDK+uVA\nOaNUf4Iz4WJ6Qq+P8+3roOHdp51vZc3SZMBd0ox7aQl0v5OlVmnqBj+H5OnX\nujdfXm8dq/TWidzWknmptpF5oZu/NTV8GpmlagJd7ZWsz9Ig5x7XwRVuDjZX\nuZJ57UQx5cQMWnhyDppXHg21kDWs3XLm7x8iKY9GoZUp7wC63zXhfVcsV1Pq\nJ2XZ1FocQevRo1jlhmaDYwPIDjisSDsceIpvgw9qEveWBXnDYaVaMGC8UjY1\neNKC2QFjN6a0TpEmE8U4P/BHhqKM8jt/eFto2tnVP6h9Q6iVNvZHAE9q5Xgr\nzM/5W4+q+xtFCqO2N+Li1nWscn75z3F+fvHRzs/vsy92tt2gHhuXpsK2eiqB\nKVkO\r\n=kNnj\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEvp+sHCPtr28Pmxyr4XgcptpuuYaW8e24yIFS1ZHe/vAiBpVrwDnIh2hXppO3dd8Jrcz3TJU57N+Kh5WbbVI3Tg3g=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-beta.20_1594226741744_0.7251661332617412"},"_hasShrinkwrap":false},"3.0.0-beta.21":{"name":"@vue/compiler-sfc","version":"3.0.0-beta.21","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-beta.21"},"dependencies":{"@babel/parser":"^7.10.4","@babel/types":"^7.10.4","@vue/compiler-core":"3.0.0-beta.21","@vue/compiler-dom":"3.0.0-beta.21","@vue/compiler-ssr":"3.0.0-beta.21","@vue/shared":"3.0.0-beta.21","consolidate":"^0.15.1","estree-walker":"^2.0.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","magic-string":"^0.25.7","merge-source-map":"^1.1.0","postcss":"^7.0.27","postcss-modules":"^3.1.0","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-beta.21","dist":{"shasum":"56c256c0d1067ca1ac58556fddb2c7adfcec9572","integrity":"sha512-AvjEiGqonKKA58EkoeycRVvgGxSAMefcf7VMn11Sw6wiz8/dwfGCiVvae9ezN0NI30yQd5+9x2VyWXlbOgP/qw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-beta.21.tgz","fileCount":8,"unpackedSize":2384607,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfDiEeCRA9TVsSAnZWagAAWu0P/3WS6cmXLaZOkfM3SzPB\nfw9Tg5kt/UjHSmd1F0Akk/aONd1kLPohx49fyyJKlkLaYSVoLtcj9B3lvyRL\nKOxbOZ3T+evgAykgl+CLlG+OcTNRoC8bsei4ggCs2xi8WakPSV67iiIOktOw\neQOPiKINvrvFGG7NG3et6xcqTXZLrpT8NMK1G0+mk4stBBEMoCFKfjlVvJSJ\nrjCd8xh9HrqfOBf8CzVhA1OBf//gPIdq8L7EQEm+tbKdWAk7ueyC0BX+lvD1\nElmRdpoxBSlAx7ph8ECZYh3OUeSVY01SiA3qbo2w0St+060zXG1LXeH1EO/H\nm6IHh0qCtDEURLt1Nc+hrH4Ai9RgVGKofogT9PKS4f1CLKYne6salu9SAVoc\nwYTT4I1P5Mq94ubFdN2FJI1oTN+HRgLISqsB1cbRFfw/EBlpCvU7Zc4vUtCh\nMC5uEg9G5ET7zLtg7yDYtcW/hfiZIu/v7/b6g10byOmkqZjm4r706ndr6nNf\nblBPtapYyMhIcoyRy10UV/35qS1CFZ8esydsm9DJNx4MfJSqRugDNKu2Bhu7\ncEqFcm0PxtPsIzJtdF5mYiC/qhOe9wdPBqObLb5QL2gaaorNFKYhVkEfgrmA\n9xVg+LcTfm8vXG9DzKnCBwQGPuTwQ+ZUrcPqlBDLfO9wJ/DLq6y+ktG2pCJE\ns+Hi\r\n=WfQb\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFnQNXQhkPRfBvIF4p6v7aBkGmB288oFqyjn7nMNcJkeAiEAlRBDI+SrdcfyBUaQXe5rtUeEc1nOo32Y2O8K2JAnxxc="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-beta.21_1594761502112_0.04927644220059313"},"_hasShrinkwrap":false},"3.0.0-beta.22":{"name":"@vue/compiler-sfc","version":"3.0.0-beta.22","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-beta.22"},"dependencies":{"@babel/parser":"^7.10.4","@babel/types":"^7.10.4","@vue/compiler-core":"3.0.0-beta.22","@vue/compiler-dom":"3.0.0-beta.22","@vue/compiler-ssr":"3.0.0-beta.22","@vue/shared":"3.0.0-beta.22","consolidate":"^0.15.1","estree-walker":"^2.0.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","magic-string":"^0.25.7","merge-source-map":"^1.1.0","postcss":"^7.0.27","postcss-modules":"^3.1.0","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4"},"_id":"@vue/compiler-sfc@3.0.0-beta.22","dist":{"shasum":"14694b57b78c7332d7c65084395b5eb457241be6","integrity":"sha512-G2ex92dbhrsshQV38SrPKwlvBi3kNqxXs2yJ49OojPxuQrH/ndcLHeFaiuK2T6W796xHMBesGCsS8AmHFNuOBg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-beta.22.tgz","fileCount":8,"unpackedSize":2385974,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfDzJUCRA9TVsSAnZWagAALMcP/1vZ6YFylnO6eYvatooF\nCJhgyJVG3Kx2Ymt+Rh57dKRqnS+czf5+TmefghlU0zaghcc6tjzU+6QZe2JD\nq5r8oYpamu3f/TsDJibh7xK7nfekbjzL27pc44sGHhzVOpxOtgrPlbdsq9Zo\nOMsVWGsxrxatJHP/UyyscyvXHbnyiJ6aUk/UIIL65UR42356eAO1XIrOqaR1\nc/h8z942DrTPXcO2oEogRxvExiPEeZJeJd+MeFSRZi/1EKgk4mxsIMn9eHqg\n4n9UzSQKDS4Ugki8geCq1wSkHxG3cE7woqj/7o2jsdnTpS3Z3c/ueGV56PHc\nQVIZb9H1nGfCh8Xi8LDtC0wxzU8pGuXXojx+zu6k/kRJuKmHZ9Zule1dr84a\nuj9iyMB9RYyONg5/9IMqHctwmsW01TGukSHArriEGDSoobUmg7BRfssQcDwm\nqfNUGXmpB2C30Z8jikYVDTAEFERWCjQNr97Be8kCPwXyWV1kcAYM+gc7FNn3\n+3D3FzT9EFwvDlpHCRivzhMK3pAkGAObmUQCyvSWcSrmIy0yz2bPzCuAymM4\nwyLKgNOQ9v9xQYEm9N45kbQllom5RQ5eWTb1ibPgViSzmcR8Az4ErufjuUOY\nyAaQDzue4976ZcbCJGqrh2n9D1zd04B9l3D2u3aH5Xng+fy844GNoMxvjdjR\n+aaD\r\n=obK+\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHTJn4A35zLodtLkHWIsFFxkGg8ACKl5bwKmEQtuZm/XAiBrFkijvEoCAa5E4nsOCp0PevJ2okF8iX3tTRj2tJPDGA=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-beta.22_1594831443944_0.5777679027610003"},"_hasShrinkwrap":false},"3.0.0-beta.23":{"name":"@vue/compiler-sfc","version":"3.0.0-beta.23","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-beta.23"},"dependencies":{"@babel/parser":"^7.10.4","@babel/types":"^7.10.4","@vue/compiler-core":"3.0.0-beta.23","@vue/compiler-dom":"3.0.0-beta.23","@vue/compiler-ssr":"3.0.0-beta.23","@vue/shared":"3.0.0-beta.23","consolidate":"^0.15.1","estree-walker":"^2.0.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","magic-string":"^0.25.7","merge-source-map":"^1.1.0","postcss":"^7.0.27","postcss-modules":"^3.1.0","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4","sass":"^1.26.9"},"_id":"@vue/compiler-sfc@3.0.0-beta.23","dist":{"shasum":"f29d471401fce576b8fde8e4e5c4d419fd725edb","integrity":"sha512-w4nemZpp2cPzetiNc0fm+U8N2HhEa+bYrTEQgkzLI+JmDEY2u8xJa1yCf7e1Gw29jxh89suhRSSPNlVq8Eytlw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-beta.23.tgz","fileCount":8,"unpackedSize":2393786,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfEIUGCRA9TVsSAnZWagAA88QP/3tbeEfOFCqG1V/jYldq\ngdWyYbNhTEX9NIPcDjJGe07r8ALAnJ7Y/CCkoN/cU1wTr9kzEwV1D/047r55\n0OyvMxYDg3rVY3m1PamnQSF1u5jlWanoHc72Hz3kxCWhhoBrpK9epjYHjYC9\nniOiEDFcmY2d4nYCQT5utoBbVSpiraiNkl4ei6SnSVLmQ0Cnd1baygnZIb1v\nC8oI1ncs9pQom08h5KxfNNHukMnU84iScDBIyu01HrYcab8xNrU5/C/KV/6E\ntxc08rzjCzbDSjE4M+Q0/wfRUxUJzqHpnfQmbvcZFQU3Y9eqfu0u1oTsytnl\nxzvKDDoXm/ZgDbPjf8P8HK7kyRqlt02MGIcAXLCvFGldTsPT1ytbMh2qp1S6\nPApk8E+Is3v6P6axX20Gqa36x01oK9H2ULcvEqwIDunLBAjTkQH5Ai6RhElr\nIFqCoioCzfrqv0ecd/DkEN+SuNtmd0RFgdb1pOcX3AU677m4u4JRcRoKn2SH\nBfKamyy/i8xu9nESzwFS8msLqweTEa1ba3jUwpoX3ouf0T9qc6A203OG4lNG\n7TB4ayFFZYe8nN59eE4p8BgyaybP/PA991bwz1lO1d4Vkc6oupCWb+qHkkNJ\nBqqSYKpJNGggcDa7UK1bAo7rz5VeZmTgKacAfTgETKQmUtid/0aHZgSwk/gO\nOzPM\r\n=9uja\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFIQaTGSr7ZGrr0wJPOMukAcFDJlPE5Z10W69/YLCzKfAiBXX/eZLzsWnwtsHWjdaMpzTopPOHEu/0wv7NnCBj/kzQ=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-beta.23_1594918149814_0.4613280120284111"},"_hasShrinkwrap":false},"3.0.0-beta.24":{"name":"@vue/compiler-sfc","version":"3.0.0-beta.24","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-beta.24"},"dependencies":{"@babel/parser":"^7.10.4","@babel/types":"^7.10.4","@vue/compiler-core":"3.0.0-beta.24","@vue/compiler-dom":"3.0.0-beta.24","@vue/compiler-ssr":"3.0.0-beta.24","@vue/shared":"3.0.0-beta.24","consolidate":"^0.15.1","estree-walker":"^2.0.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","magic-string":"^0.25.7","merge-source-map":"^1.1.0","postcss":"^7.0.27","postcss-modules":"^3.1.0","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4","sass":"^1.26.9"},"_id":"@vue/compiler-sfc@3.0.0-beta.24","dist":{"shasum":"0ecc8b682a3688c41ada23a6db1ad4b4547aae25","integrity":"sha512-okWJnk2yiJEVUMbrm+RT7gMRBFtkNqSnAqFQFvQzJgbjzDccMAnH0Y3B4oYU88t0+4xGyl6xxtHGRVmP93JTCA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-beta.24.tgz","fileCount":8,"unpackedSize":2392538,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfEJPGCRA9TVsSAnZWagAA508P/29Xewaimvi/0aCaYpBG\nT27AH1Hs2Pulfak6aKoIHmIANvPo27hFxSUdu+/mFnG9eiSXU5GfWuh7E35o\nWgZBLibEfcMplA3GeEtLZnEXhLULJLFw6cxtXAFygLpsmz8+hlonlSWDZ7E8\nf+h+OdBIJcPRfV3Vqpm9wscWJ6oUU0DjIVTyu7/5EmxTlqFmvQjMriZciA+V\nAYbwy0/3QaZr3MDS/tD5ePv4yoy3NDnwIn0eyGJxwi8M9GEaajyTfnL8h1iv\nzMJulFNBQXpiixZ5wErf4LcC1d7mehLPvMGAI9PxC3NbE22BaOyhuyjhPWj6\nQWgETptselDzP1nVsP6HlZFaxR6LA0nMCM+ISDwNRWcYURAubDLDRLezq/tt\nSqaZLOE3/qbCTErlu4LEw8j1mGLVZmHNA/8SFUV+wAdJKBEHvLRsoLBiT0Kw\nuclF+djlnGEu0nqUuxm2dloeX1WtWjniTCb5JVCWfoy/8E4CrumR4Odd8vey\ne6mP2rJ6qh0zVgBhmC5+svYcv84RHNNOaUfYz50NVnxYzUXAjJ3t5vn4f08V\nMDuv3iCi6kncxJkt+BBc1V/jIY3ujT68QyPIF4aJs6JURELdqJSNUqIl/qqX\nQxBYRDlUb8+xOBctP3rNuGpI4DpVAi6JOOSExtxPPyjlv4Z1D3U8KbEDWPKe\ntAi1\r\n=3uQe\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDAgydE70p10xc1nK/URaZ9f5vF7ohNa+7qbrNDRxkXoAIgbOvKsy5hr0DhXsSPr3ZolzzvIyWva/bxuu0JoOxP3so="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-beta.24_1594921926091_0.3450269119640186"},"_hasShrinkwrap":false},"3.0.0-rc.1":{"name":"@vue/compiler-sfc","version":"3.0.0-rc.1","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-rc.1"},"dependencies":{"@babel/parser":"^7.10.4","@babel/types":"^7.10.4","@vue/compiler-core":"3.0.0-rc.1","@vue/compiler-dom":"3.0.0-rc.1","@vue/compiler-ssr":"3.0.0-rc.1","@vue/shared":"3.0.0-rc.1","consolidate":"^0.15.1","estree-walker":"^2.0.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","magic-string":"^0.25.7","merge-source-map":"^1.1.0","postcss":"^7.0.27","postcss-modules":"^3.1.0","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4","sass":"^1.26.9"},"_id":"@vue/compiler-sfc@3.0.0-rc.1","dist":{"shasum":"a46d50cdab1993c7b8674604086fe1c75e161586","integrity":"sha512-DmP9MfmCOvSg8rc55Dhhiop659Q+swlhvmiym/i8qyHQiFgvcdSbxSL1WfECywngep8bD1ABEuG8nuRLGp0R8A==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-rc.1.tgz","fileCount":8,"unpackedSize":2392511,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfEfxYCRA9TVsSAnZWagAAklYP/iVL5DqsUZ/w4uABi6en\nXaqFgK6B4qPnRDRU2xz4Bq6WX4D/isix9d9W8H6fq1il+1EY7R6uiQPgli/e\nBth7zmhXDgugGQwAyH/+iZMw5MRh7LB2GRzLZOGysNSgyca40BHrd6uPHzUw\nxCRAPjHpcsWA65N34/SHw6GbHkXC6JbFXixXdBjDIy9Y7ekvXw8VA4LfQRcd\nQSxmWbrfDuWAE3LB9dz7MpgX340+NB2FWTbWbcluwI/qMNVktYryJM7W1KWO\nAhv4Lus1IAkALqy3mABIPVpO6XfkV7TbxOeuPwtoqyHOmNupj9lHiKvnfU+1\nbRdMD6CBo5S765yIVtxWa4zCyUTTDyRvXo0cJJ2CAEDeemshS4b3kYK21s59\nFnOpq+IZfzwESdT3KvpWzZMhP0BZpA8sOfZ8Ik9reBrfoLPuEfyBxUTCAAbj\ntJFgLDQRuErUmGEG3byWe9+DeFyp6Gn9OUlIM5gvKJkFc9S6++Y3j9/Zbiop\nYyZVPeocKhqrd1CIobRa35MDt1zHdHmrPvXDQDPxF/3q6Yq04exwlANHQMiH\nXgvmF48l0VmqOFtBVJ5XuOeKbAO5SmepNVaRpwx8r2je1QlQ2CDP+Zz/PtSV\n1ikWa1a/I5ZHXl/Oss7rtPwGqLc/eSG+ZFvvJylLGTu247W0iums8/GrDqPe\n1Tl6\r\n=6rZd\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGn5AC7l6MIV9cPzS75rMyI7mlXrQpCDhYEK6N4DNnZKAiAsYuUcu9Oe4Qy5Vdyr3vbRk3gFnAQ/yvuYMcsVeuqVMg=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-rc.1_1595014232468_0.25205205302146494"},"_hasShrinkwrap":false},"3.0.0-rc.2":{"name":"@vue/compiler-sfc","version":"3.0.0-rc.2","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-rc.2"},"dependencies":{"@babel/parser":"^7.10.4","@babel/types":"^7.10.4","@vue/compiler-core":"3.0.0-rc.2","@vue/compiler-dom":"3.0.0-rc.2","@vue/compiler-ssr":"3.0.0-rc.2","@vue/shared":"3.0.0-rc.2","consolidate":"^0.15.1","estree-walker":"^2.0.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","magic-string":"^0.25.7","merge-source-map":"^1.1.0","postcss":"^7.0.27","postcss-modules":"^3.1.0","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4","sass":"^1.26.9"},"_id":"@vue/compiler-sfc@3.0.0-rc.2","dist":{"shasum":"c92ef9ddb6fdd37d1c5a5dba53af7e4384aa9e31","integrity":"sha512-DFQOVrUzkcjbv65wJEjRI7v//9cAXoeOBj2nx527287DMNWBQK9WuFyNVt1+U1hTOjRohL6VBFtSbw8fy21s6A==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-rc.2.tgz","fileCount":8,"unpackedSize":2392633,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfFJaHCRA9TVsSAnZWagAAK9wP/iozNYvNRbct6RFGz/OZ\n8xzff2lkraRkwrIrjuBkTT8UQCchvKia6eH3JcHgcVcasHBqm12HwQqb0ORG\ndZpDrXbRcprT06HepWTaOplVeZ2MVOMOnvJ4VnmHIYedacdYO3eiioO3dvfi\nlTv6jFhMa8BwN1dTzBEexvdmAndOrPLAkFYDDmOHiVVy1n8hnQwJ2u393ygO\nqLE19VkU2lgUKdxtt/iU0AEXyDTGwCsIlu6iKjg8cRh5jV3QiZI9At7FnDsM\nxrzhKog2VVGSN0rWxMKIm8U0mRLyPy/V7kUZrbDbFqkYt7mK7EVC0TfNPRCZ\nANjXHi5QB0U98WFttpaGxebUD2l90rlqmVugXxkTJmQ63wq3ImgWI2xtQhcY\nMJR2qhAwPEE+TIBEd4+0/4lkdnrFFKv9CCrv7Nd/oatYWgJWhcebriFlSZNT\neR55qd8WS6VFNwz36MgnezStvoD9sYCNmOOF3PIdFv7lVHDeN4BDb4sF1xdG\nUphtzqjPub8T9TM7IMST/IW6WcMoX1NYhwMvyI68apRxObGh/7q7HtQ6b85z\nE79pfk3lki+VYiTvjN2q07mnJVg6CDFVVWDI6HDwakeYU/trV7fq6+g20FWl\nxAQ0aYeyR+00sdvMDHOAtIyJym8FgCbFlzgOP20xLdmFSVoWIJ2gMAqspLP2\n+pT/\r\n=Q9UT\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAGXVuVy7GZoAioc8zxyApe0g+53QOIFzdbG+XVYFpFEAiEAzmQ6Wq9VOR8G2UwGzEdZq7ONq3gMEdFB2zrqlmvj6FE="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-rc.2_1595184774722_0.5779094717431876"},"_hasShrinkwrap":false},"3.0.0-rc.3":{"name":"@vue/compiler-sfc","version":"3.0.0-rc.3","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-rc.3"},"dependencies":{"@babel/parser":"^7.10.4","@vue/compiler-core":"3.0.0-rc.3","@vue/compiler-dom":"3.0.0-rc.3","@vue/compiler-ssr":"3.0.0-rc.3","@vue/shared":"3.0.0-rc.3","consolidate":"^0.15.1","estree-walker":"^2.0.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","magic-string":"^0.25.7","merge-source-map":"^1.1.0","postcss":"^7.0.27","postcss-modules":"^3.1.0","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@babel/types":"^7.10.4","@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4","sass":"^1.26.9"},"_id":"@vue/compiler-sfc@3.0.0-rc.3","dist":{"shasum":"8f6acc9e71f1fb250fc81200c02e882578fbd653","integrity":"sha512-fx4qqwGDzUegtDiAT7/NP66w7YppzbgsOIn9vW1GTgNJTIAkh6YCvwvl0+xzP7EAl/5VZSSiTXSdbEG3Pgp1jQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-rc.3.tgz","fileCount":8,"unpackedSize":2392239,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfF0GtCRA9TVsSAnZWagAAkWwP/1xK9yC8acUi5rHeSCfj\njKAqzcb2Icxe89Swt9d5SpPB6pNXCALpakc0bUzB6tqEB43dS+hwXrlKsL0G\nIbYoP9VXa9NTW+BR+Il7UqQrEgET7jPjVGPZszuaYmT+8btKyTLiMLJbXJn2\nlHYXgq396mhf4Ac3xNEFqFPvXVEojgW8CzNPn1juSQPBT6GKI7aELfi9awIN\nvMW2inRb+ihn4qs4g+hpRPmfOBQPWGI3kVAvuF6D66narfqa7JDkm/hcVTRk\nD0EISWGypnN59t9RVl4zqEA5mHZet4aF+Bj6wDTgWuYsg/3V1pKZ3WQbNNI3\nlFdLJWr53TukfFQeJookbUn9wilebcFTb9PDQCpL48suJGwQqMko38mdsh22\nngqq/gT2ekDOqSUfW63SRaUxsYpvjMPfnAx8J5N+OU3CGCfIRTI2kEVj+qm1\nWmgPF9pB5HflGdv3i2zXBisEyoDXZdCxz2wdtAbS2DYYBzNj5jRfWqtkIHka\nPzFQi3AA7SmkTUnFHOY3ev+iDOjr/NjDUfF8Y9NlVvUvx+rS2HU85aM63sqo\nOq/PGXttcgDhgXpL5JaNOFWWLazI6sSmzNl4tKdJlqKWQg76npt98kA1Dy9N\nSqOySykL2aji/OE8Q1HIvnY7GhKaBFQmFNwCmENotXL72/pT6Jzku3bCN0VP\n6A20\r\n=D/S0\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDlB+/Ui5g168I+BQO+ve1497fRdiXH4xbPROe8gSC3BAiEA0TZixCY1j+PtL9HV2h68l92YydS37WiCRfieAg2MNpI="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-rc.3_1595359661073_0.7138407943535021"},"_hasShrinkwrap":false},"3.0.0-rc.4":{"name":"@vue/compiler-sfc","version":"3.0.0-rc.4","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-rc.4"},"dependencies":{"@babel/parser":"^7.10.4","@babel/types":"^7.10.4","@vue/compiler-core":"3.0.0-rc.4","@vue/compiler-dom":"3.0.0-rc.4","@vue/compiler-ssr":"3.0.0-rc.4","@vue/shared":"3.0.0-rc.4","consolidate":"^0.15.1","estree-walker":"^2.0.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","magic-string":"^0.25.7","merge-source-map":"^1.1.0","postcss":"^7.0.27","postcss-modules":"^3.1.0","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4","sass":"^1.26.9"},"_id":"@vue/compiler-sfc@3.0.0-rc.4","dist":{"shasum":"cdd8154c3a6a4dc34405fbdb75db4a55db2fae26","integrity":"sha512-zY2F+mk5y9TDF2kzLVU9JmI55sNJQEXmI3STuSbyaSKun2Tfhw4A43AY/TXTI2aHuIWBXnZWzjBG/29SMZxvNQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-rc.4.tgz","fileCount":8,"unpackedSize":2392239,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfF0TJCRA9TVsSAnZWagAAiE0P/3IhuTVAT1Iwn8s9nO9u\nf1OOg4Dz8KnTHk3mA7cFD0l2odZxVbjXj7Av1QX2R1nEcKWaYXslteGn8MwD\nuSEr+KhZwSIRz7BDhmPnfEVcnHbxN7n7ttQHkDLzkh9GMWTJ8Qa8efTeTADc\ni9dJf4pSDGkZG66hK2bq+H5I7+VMTdPzANpiROWmWT6L063haZzIGZHeavp9\nS7ODDz+ejxyTpsKbvYclU/bYGOE8sHEL0MhLzOsOYGa3QeGAcbgR+sCdgGgw\nRsyH7JOHsE1ghc9xIj6INw273qf4LeU8e5VSv1ox3iKgQOr+c3x2ntS1lxCZ\n2diwdAkhSYxIxBVxYHQtVnUGkscTSvulAQZEhR+lbn7jfwmtQ3X6df9cGVGV\nW1t6CzF3dzT6sC3dUNO+XOrWWN1R/0X1Ngv9X1jWOBgj8Od+Egv33eIF2IOn\nc4basp2DLjwBqNH/8pV9LnwgbgPHf7/CIeUoIHyCxbOVquupTnL7hJK1ijKf\n9qWE+Y4tTrxoyLl0QzRoqMoHd+Upemy3m64/17esmtv+mLvg5fYfmHoMZYp/\ntiHEnMX0sxm+NcqS56HIZ/5zYvzsqPH6vnqbwqOA6kiBG7+YeKwwYqcn7xGO\nrmXKIQU8inwDLjKRHvgTKzO6nnTIcwp7IGgUgebs1PitP2rNnI3D9zGimvnz\nC/m/\r\n=jaht\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIC62siYv29Hly/gwAT/+kjIbCR3pmT838J/jV/NnLx/oAiEAkg+GEDyPG8LVPmG3tq6bDQBor7vT3cRiBjVXLvJWB14="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-rc.4_1595360457405_0.909718542553595"},"_hasShrinkwrap":false},"3.0.0-rc.5":{"name":"@vue/compiler-sfc","version":"3.0.0-rc.5","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-rc.5"},"dependencies":{"@babel/parser":"^7.10.4","@babel/types":"^7.10.4","@vue/compiler-core":"3.0.0-rc.5","@vue/compiler-dom":"3.0.0-rc.5","@vue/compiler-ssr":"3.0.0-rc.5","@vue/shared":"3.0.0-rc.5","consolidate":"^0.15.1","estree-walker":"^2.0.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","magic-string":"^0.25.7","merge-source-map":"^1.1.0","postcss":"^7.0.27","postcss-modules":"^3.1.0","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4","sass":"^1.26.9"},"_id":"@vue/compiler-sfc@3.0.0-rc.5","dist":{"shasum":"374e52a6fbf8fb9aee1213026050a0f1c496fecf","integrity":"sha512-huoIFEfFCJxHcpoByAUQti7CIwJdHPLJXKuy2HG7J1B+IEKugtBdF50CLH35ZD8dWM0nyOMFFqTbO7i6CCjL3Q==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-rc.5.tgz","fileCount":8,"unpackedSize":2395153,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfIJu6CRA9TVsSAnZWagAAgAsP/AhddgIRIijpwZfY3Qmm\n9c6DzXC576sv/4bT+v4jDBvyOPcuVC+jaTDr4Nc3Xx5vf6YUpsKxYoVPdiv3\ndaMrNt+3OJBF7QhpXC7xByLTVXs85qSi19yyZi/Ym5so+hBpWYZnPqnt+8+e\nFVhvjuPdX67y5QrHzan2P8kO5Nz/Dg4i2PmyVaan2vs3tLkyYnVMN36sjYbl\na93miKvNWEh/dXbftL1HBWV83FrcyU5sq4t6knReDbG7o/sMJfHnY4womP3D\nQE+1hdNeMPrw2eKRHVqZagtF4Ym7FVmfR2e7lgGTpv3LZD6qknlbsiBDESCc\nbh+F2IBxVJ2ccH54k4HAsUb/rNOyPYceiGaslyShm9L2EdHYd5LXHEy7Qzal\ngTUbwCM1CUB8u0WRXnj3YUJ91VQ2qYSbfxSDuiw9PDefOeciiIpl+lxbevJy\nckoFZSCsT9XhFjulCcE/5Qn23MupvhFLLB9ZBXZaOQ/0Y7qMawyN3kSTruaD\ne9rA1HNovHQgJryprL2ZpRrGQjoWvfEM175nKLSG6qJRRgmg+dJeg27l92H+\nTq/Qu5JvYNYDuK0pjBwyYbf6hZ532Xc30DWduXWgOI8sJme49mfErzIni/xF\n+OJ+bCFm5OXksJ0z9IPfi39TD3u7c2gBqobP50RGW8fkyNuwjABgYAxPCdaW\nMMKH\r\n=r7C9\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDAy1HxtVKqJER1U/xULwx9wj3dotSsyRaTDLm7JnsQwAIgUDKhpmjOqhverNfCg9vg1Z4XOhKaEuDEDlIjb+eLGUc="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-rc.5_1595972537830_0.6774564769808911"},"_hasShrinkwrap":false},"3.0.0-rc.6":{"name":"@vue/compiler-sfc","version":"3.0.0-rc.6","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-rc.6"},"dependencies":{"@babel/parser":"^7.10.4","@babel/types":"^7.10.4","@vue/compiler-core":"3.0.0-rc.6","@vue/compiler-dom":"3.0.0-rc.6","@vue/compiler-ssr":"3.0.0-rc.6","@vue/shared":"3.0.0-rc.6","consolidate":"^0.15.1","estree-walker":"^2.0.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","magic-string":"^0.25.7","merge-source-map":"^1.1.0","postcss":"^7.0.27","postcss-modules":"^3.1.0","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4","sass":"^1.26.9"},"_id":"@vue/compiler-sfc@3.0.0-rc.6","dist":{"shasum":"22eccc19936abeb860535b3be1f00869456507b4","integrity":"sha512-ebzFDNhnQYsmZFh0t+TF/ro8LinyHebdNQEfCZ2sYLJZC0fn4NyvryxflLXwpFtPMl+5s3dWk37wQMDL8NbYHw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-rc.6.tgz","fileCount":8,"unpackedSize":2406147,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfPaUVCRA9TVsSAnZWagAA2wQP/31FN6M9upICuUBrA0m8\nHt1YgFIbB/bQMl/QYimLt3oXjAvp/1Fqcjz3G6xTB7ten686GzmZAGa0cCsi\nBjOY0qUcwd8uiII7tAVE48bFGpm3rExwzgwWQpdUwwpNYGwcgprqUQejezXi\nNDbIGDnDbKL2bqwVpdAdsUCpz08GQW5yu6a1tAEVXSK/f/SCXFk2g6hWr98n\nDEy8EuDbl4yaT4FMLJErbhznmMYlYmbHpw8vasunkX9QKht569NYMOaawoug\nzrYfaUwTlrIIQ4zRdyvt1bFJKW/i5rBoF+4z+CVzpBnTfbcIFSLJDWrYXzO5\nNjMZUpyx5/7eYeHWhtQbWE4PqUQis9CjF/TQzH2vsYUTE6tfG/0TRVJnbPIf\nH8v2EpeQzkvyaXUD6V1eUNg/q3MhWF3fCoCRGTpL9i1PH0T1kmBnyOqBagVq\n+4eqgnhbPMCsqDNqbFIeCWXOsu6emVrc4dgslbg9cIxwUkXEooemqGYqzj7z\no4qnklEgShk4+hVvZPaP1cWdqZt0F9UQ4QBq7+L6zUhFKlj3yw7W83R2IbLm\nqWSUtslpKS4rJPKz6Ky19mPR1aeu7HB2B+8IV46zSKjhZMU+LRkeWdTEgbFS\nnhXrHE5T11paA7jzHO4Jk4ZQfz8IhlkRMpeJa5eRBbpC1kLGqkfjw2P/bbt7\nimvl\r\n=uL7l\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCdtFUIz+op75bUnfYXeMBZ1zyBhWShyMAig+ocRMdpnQIgKfso1pAhTBWfzF/xa+OIJkFJfteD8DeIp6fvPA7Aihs="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-rc.6_1597875477304_0.2867365041931229"},"_hasShrinkwrap":false},"3.0.0-rc.7":{"name":"@vue/compiler-sfc","version":"3.0.0-rc.7","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-rc.7"},"dependencies":{"@babel/parser":"^7.10.4","@babel/types":"^7.10.4","@vue/compiler-core":"3.0.0-rc.7","@vue/compiler-dom":"3.0.0-rc.7","@vue/compiler-ssr":"3.0.0-rc.7","@vue/shared":"3.0.0-rc.7","consolidate":"^0.15.1","estree-walker":"^2.0.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","magic-string":"^0.25.7","merge-source-map":"^1.1.0","postcss":"^7.0.27","postcss-modules":"^3.1.0","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4","sass":"^1.26.9"},"_id":"@vue/compiler-sfc@3.0.0-rc.7","dist":{"shasum":"9fb8dd5b1715a7ffba9c82e74596655832cf2ebd","integrity":"sha512-4DSOw7yczVf5E+Dbs9/OmyEmG2zWsDx7dmOYWcv75LOj2/dqOys3fVtcJfsfeIXzKBTy51hX80+P1lB0nWq32g==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-rc.7.tgz","fileCount":8,"unpackedSize":2406505,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfQA6+CRA9TVsSAnZWagAAYU0P/0QXQHzKOKHaWVS9NkQf\nYtQf6ROYc74KcRu6U2DMEM5PAAIWhJHvhxWIF+mzdbuptLpaP9Ro25E9e8LW\nHr9WAogBT5nC1FGcYfSDTym1GAEbVadW2fROCa6d0/29Don6BRc87lDsNcNt\nLeSUBy9WE82Wnn+fKy6LSyolnbgnDg2gofOBytosrNKh/Gkt/MmPLATD0Q2Y\n0EosVJCOsR6OtrB4qoasz4vuPSoW0DecIvPVUvF1rFtobSqTjKVN/9S9r0PN\nGLrBJ0aufdNtHsLCykNW6OWAkbkNFsOXVYcuKexO27d2D1F8e2lTadrxwh5U\nwKEInj+57z3S1JB2sW1Q+zwYkbp5Fy1vjWcvR1reEuSS91bRvtvRuk+5/5i/\nyvr4ntKcbYFJ9rARdxcYxQvwKoDXAdxsvE/o8aVDFdYGyDJDJd2lqnWoQSPz\nldsnGvAizZvKdQF55umFpcUMiRtDFjy3llS2C/iR5xigcTVoxXDIf3dgmiJj\nZtZluIvDCjKZppjHiwY7iP1PMO6aqSF3jOm7vkllPhiHoHEEml8hZBC+30Jv\nzbbknPaDzHnO8v5EN8jJz/gPRWfMCR4m/zrldR6Djn+LxmcxqWar6a3S/tEo\n329ekQlvf+bx2XpGhA2fd9MXeokYr1cqRj3RUUS/O2qpp+D/YFQkMrkHm9Py\nhjhP\r\n=Y/A9\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDI7byNYebv9MntIrU87cUdFAKLPipjOpEUmxsZg+4JYgIhAJSWIqXS/WojANm65B49ZPO8jhCSGzIJ8ZERmIxuxhxh"}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-rc.7_1598033598003_0.5971606874238764"},"_hasShrinkwrap":false},"3.0.0-rc.8":{"name":"@vue/compiler-sfc","version":"3.0.0-rc.8","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-rc.8"},"dependencies":{"@babel/parser":"^7.10.4","@babel/types":"^7.10.4","@vue/compiler-core":"3.0.0-rc.8","@vue/compiler-dom":"3.0.0-rc.8","@vue/compiler-ssr":"3.0.0-rc.8","@vue/shared":"3.0.0-rc.8","consolidate":"^0.15.1","estree-walker":"^2.0.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","magic-string":"^0.25.7","merge-source-map":"^1.1.0","postcss":"^7.0.27","postcss-modules":"^3.1.0","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4","sass":"^1.26.9"},"_id":"@vue/compiler-sfc@3.0.0-rc.8","dist":{"shasum":"ca2a90188039def429103732eaefa705743bb406","integrity":"sha512-oJXHqMVVXRiI04rV5ncbyv+lwJMSxMFHxZBCt10bUDBBl9E7ze6/01OcSI4/mzB0RRDa1X1byMDMAgLq/07lAw==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-rc.8.tgz","fileCount":8,"unpackedSize":2406505,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfRSDqCRA9TVsSAnZWagAANDUP/iUcLMgxhYe4XQ7SHjGJ\npWWVhJCebfFgK8mS9GiRuzEKHdDtuJmbr3rhBkKTZu+XVCfnsIWGb3ka2CuW\nHHIfNdN7SbtQ3w5cbWcmUZM8edCoPscln+94CEvoL+0fM7fAQu2ybrxd0WXa\na9oduWRi/oc1sOGe6vTtlLmMU4nIZkvLmzIOVKqtodjEtKDda/jQkVf5XFR9\nokHtjuF4cbq/+PeZ29Msa//DWsS+6K06WClD3UUHUGILzxJsyjLPiuIdL6vW\nsWJVC2LsKYWH2uiQBxIxZeAzny4WGB8EJ5/Xd3YnkKuC0TkPbhE6dxZBrVdK\n9iOAwMEevbXo+bkV3nYZN1/CQMWBQDsRH1iQ7xgcl5XqXIEa26t8DNX8bE32\nqt4qiy9iqr/3E4FCspkf+ySeFMmx6dVP677Azl7jd6QKokWUD59zQzaC6xlD\nFr+Ukqix8RwVZ4XDzhmuut6N+/HRshnJ7p50BfX9WcrgYk49F834HURuAFZR\npt24RK1pkqNb9j69rSu8xn9IIsk9iK4pa1XbOdhY4g2F5W4PGxwEIzqsTL/Q\n9VpnMV6eZ6S9c6OtVNdvF9vnmPL6kLKTHHVT5SNQGOnvBVDZAJFg96v2+uCv\nL1rAsZAj9M4rjEOGHu5lj5DMhyHlckwhRbyg7ChP/33y7YuRRCgiCi+ndW70\ntOCo\r\n=bbM9\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDyUBacT51Hj9z64+vWU2ElbdXp2i6In73ZidH5yJzo4gIgbf4zZw9yRnYMSizlfQA28VEbKxQLzz11ignMbMJM1cY="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-rc.8_1598365930358_0.9913891069817564"},"_hasShrinkwrap":false},"3.0.0-rc.9":{"name":"@vue/compiler-sfc","version":"3.0.0-rc.9","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-rc.9"},"dependencies":{"@babel/parser":"^7.10.4","@babel/types":"^7.10.4","@vue/compiler-core":"3.0.0-rc.9","@vue/compiler-dom":"3.0.0-rc.9","@vue/compiler-ssr":"3.0.0-rc.9","@vue/shared":"3.0.0-rc.9","consolidate":"^0.15.1","estree-walker":"^2.0.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","magic-string":"^0.25.7","merge-source-map":"^1.1.0","postcss":"^7.0.27","postcss-modules":"^3.1.0","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4","sass":"^1.26.9"},"_id":"@vue/compiler-sfc@3.0.0-rc.9","dist":{"shasum":"8b1af6bf1cb2561b5f92ce11053e5d21b558ca8b","integrity":"sha512-kmjGzcyp93Q+ZKfvxC3GtI9bEXCa9TxsuO+Q9WtiyvOWBLxZkklQc1n5DFn6vtAUIjjlIE5GZoKawvn9LfKejA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-rc.9.tgz","fileCount":8,"unpackedSize":2406505,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfRuBsCRA9TVsSAnZWagAAzY4P/0Ta8HPYGbtZV+OPU+H1\nPVrxOHU6rBMfot4sYHTKlfe4/Ae7brWqBR3mBko6dO40c/sbb448jJ6XIF7s\nLgBZe/N1C3pVHg4hySYIKHfMYnwDACOsX5LByEyivkJSmtmHIFmpMndPad7V\nSPoXF5CWcUr09XgLIBXu2Xy/XG41aUbLlt5a0d9SKhYblDQjnKSkPCQiY5rS\nKQj9YXeuwslKHWq3QUafgG9wCrrZjjQMRHV2j738P4rV3zZC3etoghntGSXh\nxd5tAUaYRS6+ZsIXYsA10mH91UGxGaAycLDWgUgNhh/fsIrOpwDvW2NjOuAN\nJqo96BWUDyeNlybFvfDknOVHMLCrZo1YQNEWux14wAJu6901CX5jrHVxQgHR\n3kP/vIGbMXHlyr2M/NRNx2mXMOTSR2jYutP2Ay0cYw6gm+1qkAy6/4sYwIFJ\nsi+n54cbWd5j7dzH2oOr1w3mHEWSDdQ9cPd3d5S1qhFWRDYDf6ujScDSJElO\nEqu7WbN0ELYsef2+j5Nz2iXtSC+UjvaaubSywN1FNv3KyvAtZlknPNjNLBmE\nDbjr2xArcL0p06DLxRVCghaOE2yURpZBYRACphaCtEyd0p9ctNk8DeMnCV72\nZSSSLTwo0GMTLxfz5ol+2BniVtNUtsTSY//1JbguotJCG2Y1BkhvgDY5YYvJ\nv89J\r\n=yuPB\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBcanqqdgOdaZ4cyVGakgSJIQbpF1zsBY1/chSetjrcBAiBTbUWCjq83F+QZWGjbxYoIXuYxb1G83A0YxQeI8aTzrA=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-rc.9_1598480492354_0.4226273410887398"},"_hasShrinkwrap":false},"3.0.0-rc.10":{"name":"@vue/compiler-sfc","version":"3.0.0-rc.10","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-sfc"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-rc.10"},"dependencies":{"@babel/parser":"^7.10.4","@babel/types":"^7.10.4","@vue/compiler-core":"3.0.0-rc.10","@vue/compiler-dom":"3.0.0-rc.10","@vue/compiler-ssr":"3.0.0-rc.10","@vue/shared":"3.0.0-rc.10","consolidate":"^0.15.1","estree-walker":"^2.0.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","magic-string":"^0.25.7","merge-source-map":"^1.1.0","postcss":"^7.0.27","postcss-modules":"^3.1.0","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4","sass":"^1.26.9"},"_id":"@vue/compiler-sfc@3.0.0-rc.10","dist":{"shasum":"4351ece66cdf4d758877482f69421c43d994dbaf","integrity":"sha512-VIJ+VXqeM7WoRNgD9uYSARVb6CYq+JS2NNHfeerfNc7Uk3pjYHRv1MwEicAvN6zWFm5GLC1ZYTVD+WFg3xGAkQ==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-rc.10.tgz","fileCount":8,"unpackedSize":2418820,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfT8tiCRA9TVsSAnZWagAAcIMP/2BO562ubHJCxXXzGfxK\nx2jzOimxMJ2DTdc2w1jAaSvGE+SwBxf+D7hIMrkuIONyNSSY/ZNSRMCdV0/D\nE99S9dHxblutrIv/cNlzme3w9MpYPtj8UZy+P4tzGv1FaFp47By0WKxOB7bc\n01yk4wpItbuJdvvOqNnbJH1DMs/U+WYOCnw3+fI8Lk8Z0P9L1WrqISBu+boB\nldhBRefzYYeEMIQ+QDaUxn51bMNBfjbGCmw0b8jHlI382fT+bnlJALfwmhvX\nkNrXUG6An9t1WoQ5GWP6Oom9k+ZjxRS8BKvOlbWcB6HMylPgIqcl8/Ns6cPU\nTXMqZWj7lT9R0jJV4qbpMiWQN6BiFTljOyC8GAXFtGGjTGZgutBijmfGFwIb\nRe2axz/wrTsh0tca0Xwx1uhQ2/bzJ7FHKytxUSu0yzOJewcCO8RXEhWC+hmC\niRu4uawATlMlwrQ2JtBXMB8P2tPUdb++BIIuzbtF0pwm/qodWX+Nx33bkUH3\nvQw597N8Z6JDiTcIinJWkJ3EymDiVBJx8OpcxZf1KP55k/ENPKoILHeWvDmC\nPaiZjG2rLNi1lEHgSyURpKYumpXPZLR3F0t0xlmA5xftrNGf3WqiRMnhkfMt\ntq93bfpZb2F9S9d9WEtjpnaNO+QhOd3PFET8F78jL7SQJaXOsW9YSKapH1Xa\nwPmr\r\n=FNIY\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIF0O2HeZzdJTssFbRNfUURpUZBfvlxiRvvAhzCjtiqEoAiAsHg4T+J5//XEIX7J+WA07z5AbjPgQJnFVnnZ4jdOpdg=="}]},"maintainers":[{"email":"yyx990803@gmail.com","name":"yyx990803"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-rc.10_1599064929707_0.7622017548421969"},"_hasShrinkwrap":false},"3.0.0-rc.11":{"name":"@vue/compiler-sfc","version":"3.0.0-rc.11","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-sfc"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-rc.11"},"dependencies":{"@babel/parser":"^7.11.5","@babel/types":"^7.11.5","@vue/compiler-core":"3.0.0-rc.11","@vue/compiler-dom":"3.0.0-rc.11","@vue/compiler-ssr":"3.0.0-rc.11","@vue/shared":"3.0.0-rc.11","consolidate":"^0.16.0","estree-walker":"^2.0.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","magic-string":"^0.25.7","merge-source-map":"^1.1.0","postcss":"^7.0.32","postcss-modules":"^3.2.2","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4","sass":"^1.26.9"},"_id":"@vue/compiler-sfc@3.0.0-rc.11","dist":{"shasum":"bea07c12c5985ed97e744af1b0461169e7501a60","integrity":"sha512-5rNbRiY9pG/govbwv53Y5PcL5qZRDv6twz7Nmap+hfo06u/yhjFmMeU6ftulc6fu/u/hpePVu4rrthFrmOj3hg==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-rc.11.tgz","fileCount":8,"unpackedSize":2419442,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfYPbMCRA9TVsSAnZWagAATS0P/iy/FZt+F9mHnSNwyVG7\nOAvHSXJ7/4mPExNt76khGFFvmY6TxxjUdoBkXoMS9RbzuThhsUEtjCc84oXs\nVOLEkA2DxnYoasCuzCrn4rpHJGrB6ktWXMXLHf/krRBfxkN/51/HGnGVSs05\nvNLirBFPq//6rlwXUrlbQ9KIQYjg4TrShFtCE8qnx+x/Qkd4E7C691aLeCzW\ni6FD74FDEtRfFLFoY9WLahOutJcPYLgQRQpQ8uAP3zM9pCXp/fyoTYAl/opK\nxgseXC88mUJkiZ509rigkc9Kuv6phhIpBWYXoaCboIXtPVeg0O8Br+97eNp9\nxxLIiLTAseNvSysi+n4tACqM7NNADPZ26vItUjz3vl/IMKRKBq2fHdRjyHKX\nWb9f/VEUP99y/TvNqboRlrw7mVi1o0FqZtJmfcubE0MtZUJ4OaybHiYouwPw\nqJAsMNvT0kr964IO4SP3+CY0GAQRzlLyARkFYqaj9X5Fbvw6i3xFGn+m+nCK\nQr8DpZeDTnnTbmez9nn9zkCG03JaolmlbQ5L1dnwp3GHAQeSskvppdkI/Lvl\nCeMEwdnp7oz51F3hMegYiyAz8B5Sr0R6X6ZEpsKSsjFyk1o29OIjj8DQxzhm\n5DYfo9w4gKAUD7P4N8S573FDJVc+6U2GiGLOf94JSCaUe/e189/cCjWTZl3K\nCs4/\r\n=GIi3\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC9LCp4GdZT4rKPnMVXSzsDoFd3J7NoK+e0VEZPyfyxsAIgIXbANwLGdwp15lEN2ZKVgOMNAvBA3PhwCnVhyCnwrls="}]},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-rc.11_1600190155665_0.7542798109959705"},"_hasShrinkwrap":false},"3.0.0-rc.12":{"name":"@vue/compiler-sfc","version":"3.0.0-rc.12","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-sfc"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-rc.12"},"dependencies":{"@babel/parser":"^7.11.5","@babel/types":"^7.11.5","@vue/compiler-core":"3.0.0-rc.12","@vue/compiler-dom":"3.0.0-rc.12","@vue/compiler-ssr":"3.0.0-rc.12","@vue/shared":"3.0.0-rc.12","consolidate":"^0.16.0","estree-walker":"^2.0.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","magic-string":"^0.25.7","merge-source-map":"^1.1.0","postcss":"^7.0.32","postcss-modules":"^3.2.2","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4","sass":"^1.26.9"},"_id":"@vue/compiler-sfc@3.0.0-rc.12","dist":{"shasum":"eff29e9688b8ed840506d88b94336689cf2970f2","integrity":"sha512-lHy0LK33KjVBeu6aCX0oLUSZtatOIY/1w927Fh5nFrN1SNnqA31q2wg/IDmvNU6+Y6F3s0MZyN5H6dyZgO5r/g==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-rc.12.tgz","fileCount":8,"unpackedSize":2420536,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfYlBrCRA9TVsSAnZWagAA8FgP+gKih2no37Hfr61FcN/I\nTngZpOESWGPi24PU/nfQfKjSiCYQIFicLrXV07yWtiVvjkAKCsOVT+KCdJJn\nqiJjybyMhmY7nW/Lp0knPJjCB7+7xYtFCtQlJXMEvzmtfQtsV4QfMr69EaLe\nG2WeLgqBIhYUH5fqXGKM4CR9eNka3ZurZ+mXV7UQtlmVUMApCmEWwFaFpkCL\nxE2cwm07mA8HKSrVCGPlZf1vpcCSe9yFNJXxRMf05nZOtgJnztmOq38flsT+\ncIrxrRZ8Iw6gbjN1Tp9s1rjWQ7/W3aNGVziWpAw318lU6mS1+QFzOH87JxsE\n89AbcZ7aX029u8nXdBhXZfElJpvB9RrPQnnsSEKluYI5JrE++mTftLCWc2Ix\n0w/zy7SB4zZECflyvmrvJL4Ke//3hM4grU2j4ecO6ZtyB9QtI87xJi1ddTNS\nVWD2RHUDmewiE2btmjtoIzXxGd88P/M2eiAiRvEhvz+WVVBV+YinvXK3ujmg\n/GLAtyg7OeMoXcalUeJVM4BnEvee1i1szbK4VrU9iV8E/K+9FQJYuuDq9iHp\nfrmdLaPIpyFd8f1pDqgaQjU5v8IuX6zxv4/FH+VFmAufX+1UA8/nbWZWFuM3\nLnHnm6Pby0kRjQNnxzsRfcNLbMWs4HAgYUJxFm1ZcZ6WUH3og8393rZlaCcc\nJ/jt\r\n=j8eu\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIA7AF1BbD7BebbpJgcZ2XaH6Dc7XvoGkUUST7NegD0DPAiEAiuzQOulCzvdaPzlY1UW6gbctRnHyGqVl+eQoYm6DWKg="}]},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-rc.12_1600278633368_0.7502667672786252"},"_hasShrinkwrap":false},"3.0.0-rc.13":{"name":"@vue/compiler-sfc","version":"3.0.0-rc.13","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-sfc"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0-rc.13"},"dependencies":{"@babel/parser":"^7.11.5","@babel/types":"^7.11.5","@vue/compiler-core":"3.0.0-rc.13","@vue/compiler-dom":"3.0.0-rc.13","@vue/compiler-ssr":"3.0.0-rc.13","@vue/shared":"3.0.0-rc.13","consolidate":"^0.16.0","estree-walker":"^2.0.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","magic-string":"^0.25.7","merge-source-map":"^1.1.0","postcss":"^7.0.32","postcss-modules":"^3.2.2","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4","sass":"^1.26.9"},"_id":"@vue/compiler-sfc@3.0.0-rc.13","dist":{"shasum":"9048c95537be38ab5a31bc3084f0444000b061fd","integrity":"sha512-b98HQgq1dEWqWUzUFMnGxeRpuOfbehCCWbT6+cH+SARNVwUi+/5UPHLxJ58GyXlyy6hMY6IDr6TUmGPG1aXV7A==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0-rc.13.tgz","fileCount":8,"unpackedSize":2420536,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfZEghCRA9TVsSAnZWagAAjY4P+QHOhupsnXQdxR3EXVCZ\naUw//EdjxiYjEvEH0q+PX+pFccskIUVcrSYCIci3kxcoS7XGnfCRbiEsLim6\nD6GGCkkxumy+r07KZjwY3tIoYfvqidVKATX23nV7BCJfgQQdgF0lU8eGbFXh\n+a8xtZ0o4hH4ESZYzJRaVS4fEqios7+V1ZPV5X3ix+y9uwDDKeZMNJYXLUhf\nwct88SWugWTMkfACjk+0jIyaG5Jrvh9RqLke7XEuJywxx7woXsdnSrGl8Z9i\nwi+ew4SGcuPR56e17QXYZ+TjKV/DAgK8fpnLN0VjNzYsAIr/+/RKYDQM1wdM\ngMH4g5ciigl2o+ZoQZuaKpKTNv2MZEb7HBJMnWOFSvoH7GgIciCDqnXgR/66\n2vWkc/ZTbaxu2x8gqHK6msERjzf1cgFaI4y0JvuzsxiUdNMf1MNYZAZvwC6r\ns11TV0fiTZhZriVQUME/shJ3bmMKnRYarIse1fcE9mfSH/TPoO+jzm/Ukdo4\nWfwCivaD8P29Nbb5Fd8j9LBQSHD8Ie04lbuW2v2Ujtaiyvmd8RhJ1egvdSp4\n+PHyOxuPeg4+7HBwAWp+tkz3Tn66cVSzGE06kA0aPrc8QQ0v7EzhxhH2UhGv\n3lSTfUErlVUBgfllUqsfRbLhzydmLNAwcqz26oPhzNm8rBm+/9wIBIThjmEw\nQi8A\r\n=6vEs\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCvbPEYzx1vMqwYYj4cLWeaCg37M2ralzzGNnxMZUbA/gIhAOUSphSlaJarpzg1TRR+o2ldG/oIxLEGqUtHvo1wfabq"}]},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0-rc.13_1600407585170_0.912006671835192"},"_hasShrinkwrap":false},"3.0.0":{"name":"@vue/compiler-sfc","version":"3.0.0","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-sfc"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.0"},"dependencies":{"@babel/parser":"^7.11.5","@babel/types":"^7.11.5","@vue/compiler-core":"3.0.0","@vue/compiler-dom":"3.0.0","@vue/compiler-ssr":"3.0.0","@vue/shared":"3.0.0","consolidate":"^0.16.0","estree-walker":"^2.0.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","magic-string":"^0.25.7","merge-source-map":"^1.1.0","postcss":"^7.0.32","postcss-modules":"^3.2.2","postcss-selector-parser":"^6.0.2","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4","sass":"^1.26.9"},"_id":"@vue/compiler-sfc@3.0.0","dist":{"shasum":"efa38037984bd64aae315828aa5c1248c6eadca9","integrity":"sha512-1Bn4L5jNRm6tlb79YwqYUGGe+Yc9PRoRSJi67NJX6icdhf84+tRMtESbx1zCLL9QixQXu2+7aLkXHxvh4RpqAA==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.0.tgz","fileCount":8,"unpackedSize":2420500,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfZNITCRA9TVsSAnZWagAAO3AQAIFNFbbpZKeFtewuj5/r\nOW7DCdQgxuswiwmoUgaEAmMqzdHE/4P4B5bNrGmCs4uvI00CsiQ279EhkTpa\n9spWQ/+lUovAni9oCtDUx0WhBkCy0G+KjNJ1oRoqhQzn3171vXkGWafSzbMC\n7VapJ/J8XjiXIk2Xh6nl0YtK1Og6Kxv0uLL1EPhpbAAHOrK2xKr7cElJkvvp\nZLmygeVbOY6MbVCEBLuQyvr7QLg6wfhtUd9V4fb86RfmvXwtXnizBO+jZLHx\n8BxRmM57zraBvOZy+liZCuhBSGxpV1Nzo3irDW/o5jkJa6uPBqbibjGntA9G\nVe4VrHxj/Nzp2Q0ztGdBHpiXoq+3ZI5PxMEyNaBBLy5+TpkcCFsIbUFBLpSI\nhxZS94oIwKubJx/RHNmEMNgLGkpqV1ww17/U7JRXdUKamwBbyLbTk79Q9HQC\nIZJXW72beKJfho9v+zLxV5io+eU8c/CD6/5q8KuRqeT8XVvOyd5FhyC6555Z\nNAp11nglL9FQZcxHbHvHhPAN+ovVv1DjCfoWe9TO2rOmL4/1qiFAVMFrncPC\nosu2OlXbR5oQrKFCzOTiTsBw2QecYiUNkZfG8FlaKb9dbdGsSvJEINeA4Ya6\nCdyDpi4GmTIS8ZB5yHzTpvlmaFMHw/Uf8YqayYaILRFIuPCntvKaGUTpr/IA\n9wcy\r\n=pKHT\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDLK5k9y4C3tTiSrw/zSS5t6CxvfMzeN5jVgSsbRNVFfQIhANOSjIptR17PFbWto/VpZtBT93NeA3OeYn5Gd0ZfN2Si"}]},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.0_1600442898819_0.670224560254649"},"_hasShrinkwrap":false},"3.0.1":{"name":"@vue/compiler-sfc","version":"3.0.1","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-sfc"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.1"},"dependencies":{"@babel/parser":"^7.12.0","@babel/types":"^7.12.0","@vue/compiler-core":"3.0.1","@vue/compiler-dom":"3.0.1","@vue/compiler-ssr":"3.0.1","@vue/shared":"3.0.1","consolidate":"^0.16.0","estree-walker":"^2.0.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","magic-string":"^0.25.7","merge-source-map":"^1.1.0","postcss":"^7.0.32","postcss-modules":"^3.2.2","postcss-selector-parser":"^6.0.4","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4","sass":"^1.26.9"},"_id":"@vue/compiler-sfc@3.0.1","dist":{"shasum":"f340f8f75b5c1c4509e0f3a12c79d1544899b663","integrity":"sha512-VO5gJ7SyHw0hf1rkKXRlxjXI9+Q4ngcuUWYnyjOSDch7Wtt2IdOEiC82KFWIkfWMpHqA5HPzL2nDmys3y9d19w==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.1.tgz","fileCount":8,"unpackedSize":2450761,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfiHrRCRA9TVsSAnZWagAAXBAP/iAB/LQzyvLopMVxXKgo\nPeynsEyi5voeOO31PoS8QWzTYzMS0IelVRzacK71ApyGPVXwNrObd2EhFr28\nP7knB4ZItIs/YPBIqBwbfqzxfW9cckY7doF2XDDHthIsRBUVpEOjDsa2z92K\n0YHBj+i0oSZumXI1600WuPq6Q5W1Ar93yWbzQNh7Pii+zpuTu+CUFOCpAGdF\nHXKzbioHeBlCPRCYz310Tplny5OPwB6n/ic6dYQ67PveeqZds/uQ+u3joIFZ\nkUMgfxJylax5oypWtNpr8UHStxrxGief8jCGaZKaihvZN8l6AxWZBS0vRoRH\nL4g9gVo+QrWdObg3K0RtGxsStJ8S9ZfHwVtXFbqaVR4XJW0y52edgsRnmhqo\nqk4KXLDHlaBnyI3/Jqi5iGyVhjbkXmf0OFPcX5n9Lq+b7PTOS5YPRjluwNCg\nLnI0fiy9gvX12hiRP/Fl28fW7kn3U3LwgGFVC1JOku7ZuzUcalKPwbFgmtpN\nLLTjjInKDQ8ALeJAa4WvMhyBDeVaVCKMiEU6aE4UaR9Sj9RDIKmoaaZrC8hR\n+GBLD9RXhQoBB22Qz7HrrDsvV4eKMk9LS88vIbnCgH8UlNtfnDBU/zb7zRpr\nzfLxzE0pIj4VBFIhjir90TWZhPtSHNd8WN288x/moPnhiivqArIQaqHxbMZh\nCtsp\r\n=FbLh\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQClvtXQHEKmPhqj0kMl5T3rXqq7oCXsz95UfDReB27bkwIhAKxDDrPIA7+FiFg8wkZmU2LNK98d0VaFGP5lmsqryJWl"}]},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.1_1602779856612_0.6241619451366851"},"_hasShrinkwrap":false},"3.0.2":{"name":"@vue/compiler-sfc","version":"3.0.2","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global","esm-browser"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-sfc"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.2"},"dependencies":{"@babel/parser":"^7.12.0","@babel/types":"^7.12.0","@vue/compiler-core":"3.0.2","@vue/compiler-dom":"3.0.2","@vue/compiler-ssr":"3.0.2","@vue/shared":"3.0.2","consolidate":"^0.16.0","estree-walker":"^2.0.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","magic-string":"^0.25.7","merge-source-map":"^1.1.0","postcss":"^7.0.32","postcss-modules":"^3.2.2","postcss-selector-parser":"^6.0.4","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4","sass":"^1.26.9"},"_id":"@vue/compiler-sfc@3.0.2","dist":{"shasum":"22c70fed72c347a4d5fa2db2e80594b3193dce57","integrity":"sha512-viYjT5ehDSLM3v0jQ9hbTs4I5e/7lSlYsDOp7TQ1qcwHRvzoTQMTkFpY/Iae+LFKM124Ld17tBfXgfrZl9dt+g==","tarball":"http://localhost:4545/npm/registry/@vue/compiler-sfc/compiler-sfc-3.0.2.tgz","fileCount":8,"unpackedSize":2451995,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfj0d7CRA9TVsSAnZWagAAm28P/2V0LJqU2Trh3dPcxf5K\nRI4iurTYFM94nu1PniR2b21w/8dPeqx2L9CPf+eipeHWN9OrfLgAtWXg5FKT\n5TsK8prsZRyABgnJj5vG7KQqZVnHHKimhlXW4Sw0q1ziwpJL93GN7gmGXeae\nZETIx85r/bE9eQNAoXIfaaXqSiW+rr/EQ1/o+cOdpvuZB9sKIfwCzfxYgCt2\nknN4FF3RFzRVIa9lw+a++nsZDa7eRrO5ahICBhPSkd5mbQNLcZ9bTFBTgYMk\nCtL8FqC4DJRoToXntpPH9op1xQUj/NJHn9t7eJTY5QX14pe2XfUzBNkU81hn\nWNWe1JE+ttovIG4HLIq32oidChR7ngLPHFMy6U5UKKhy8E1zx9YTXAe2eMhZ\nSlx8QN/4YsqS9ubUnpCBa0Zp2Z606Ap/G9DpXBPsguRvjRiGj1Bvz5gfYcEV\nb+f5f1Kz2DWwPqpesN3JJ5JCR18YJBglacOL2y4DKuYm08DZ5Nf3IItqD27t\nPHRJMEUY4U4xayDdmeX0TWGUTVSu6/ymKQZG3/DPms1QLBOm/gwb/hqLmQU2\nbv7AspjWZK0qx2+UfKv4aLbxTxgukktT5qSj5AqOaTnukOUe2VwY0qjUNuR8\n89zxEXNho5TrnzlVlMWPhpUZytQ4LGdDcauIPQl+k85kg0CAz9SmcBtcQBTz\nQh8j\r\n=R6v7\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGy2IHX8YMu/UQiiZvEA6nckI5ZRuEMuqtzjWrsMlxJUAiB4M9vK1erEyhfR35TmNmgt+e101daZujhrP3xr7jMkuQ=="}]},"maintainers":[{"name":"yyx990803","email":"yyx990803@gmail.com"}],"_npmUser":{"name":"yyx990803","email":"yyx990803@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/compiler-sfc_3.0.2_1603225467100_0.8676910625001324"},"_hasShrinkwrap":false},"3.0.3":{"name":"@vue/compiler-sfc","version":"3.0.3","description":"@vue/compiler-sfc","main":"dist/compiler-sfc.cjs.js","types":"dist/compiler-sfc.d.ts","buildOptions":{"name":"VueCompilerSFC","formats":["cjs","global"],"prod":false,"enableNonBrowserBranches":true},"repository":{"type":"git","url":"git+https://github.com/vuejs/vue-next.git","directory":"packages/compiler-sfc"},"keywords":["vue"],"author":{"name":"Evan You"},"license":"MIT","bugs":{"url":"https://github.com/vuejs/vue-next/issues"},"homepage":"https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme","peerDependencies":{"vue":"3.0.3"},"dependencies":{"@babel/parser":"^7.12.0","@babel/types":"^7.12.0","@vue/compiler-core":"3.0.3","@vue/compiler-dom":"3.0.3","@vue/compiler-ssr":"3.0.3","@vue/shared":"3.0.3","consolidate":"^0.16.0","estree-walker":"^2.0.1","hash-sum":"^2.0.0","lru-cache":"^5.1.1","magic-string":"^0.25.7","merge-source-map":"^1.1.0","postcss":"^7.0.32","postcss-modules":"^3.2.2","postcss-selector-parser":"^6.0.4","source-map":"^0.6.1"},"devDependencies":{"@types/consolidate":"^0.14.0","@types/lru-cache":"^5.1.0","pug":"^2.0.4","sass":"^1.26.9"},"readmeFilename":"README.md","readme":"# @vue/compiler-sfc\n\n> Lower level utilities for compiling Vue Single File Components\n\nThis package contains lower level utilities that you can use if you are writing a plugin / transform for a bundler or module system that compiles Vue Single File Components (SFCs) into JavaScript. It is used in [vue-loader](https://github.com/vuejs/vue-loader), [rollup-plugin-vue](https://github.com/vuejs/rollup-plugin-vue) and [vite](https://github.com/vitejs/vite).\n\n## Browser Build Notes\n\nThe browser build relies on a browser-bundled build of `postcss` to be available under the global `postcss` (since it can't be properly bundled by Rollup).\n\n## API\n\nThe API is intentionally low-level due to the various considerations when integrating Vue SFCs in a build system:\n\n- Separate hot-module replacement (HMR) for script, template and styles\n - template updates should not reset component state\n - style updates should be performed without component re-render\n\n- Leveraging the tool's plugin system for pre-processor handling. e.g. `