diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3e99130c..f04ad7c2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,7 +28,7 @@ jobs: steps: - name: Clone repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: submodules: true @@ -39,7 +39,7 @@ jobs: save-if: ${{ github.ref == 'refs/heads/main' }} - name: Install Deno - uses: denoland/setup-deno@v1 + uses: denoland/setup-deno@v2 with: deno-version: canary @@ -49,7 +49,11 @@ jobs: cargo fmt -- --check deno fmt --check + - name: Build (Wasm) + run: deno task build + - name: Lint + if: contains(matrix.os, 'ubuntu') run: | cargo clippy --all-targets --locked -- -D clippy::all deno lint @@ -59,24 +63,14 @@ jobs: deno task tailwind git diff --exit-code - - name: Build - run: deno task build && cargo build --locked --all-targets + - name: Build (Rust) + run: cargo build --locked --all-targets - - name: Test (no highlighter) + - name: Test run: | cargo test --locked --all-targets deno test --allow-read --allow-net --allow-env --allow-write - - name: Test (syntect) - run: | - cargo test --locked --all-targets --features=syntect - deno test --allow-read --allow-net --allow-env --allow-write - - - name: Test (tree-sitter) - run: | - cargo test --locked --all-targets --features=tree-sitter - deno test --allow-read --allow-net --allow-env --allow-write - - name: Publish if: | contains(matrix.os, 'ubuntu') && @@ -90,3 +84,19 @@ jobs: - name: Publish to JSR if: contains(matrix.os, 'ubuntu') run: cd js && deno run -A jsr:@david/publish-on-tag@0.1.3 --allow-dirty + + # - name: Install cargo-llvm-cov + # if: contains(matrix.os, 'ubuntu') + # uses: taiki-e/install-action@cargo-llvm-cov + + # - name: Generate code coverage + # if: contains(matrix.os, 'ubuntu') + # run: cargo llvm-cov --lcov --output-path lcov.info + + # - name: Upload coverage to Codecov + # if: contains(matrix.os, 'ubuntu') + # uses: codecov/codecov-action@v3 + # with: + # files: lcov.info + # fail_ci_if_error: true + # token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c53e3f7b..0fa2da0e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,8 +4,8 @@ on: workflow_dispatch: inputs: releaseKind: - description: 'Kind of release' - default: 'minor' + description: "Kind of release" + default: "minor" type: choice options: - patch @@ -20,11 +20,11 @@ jobs: steps: - name: Clone repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: token: ${{ secrets.DENOBOT_PAT }} - - uses: denoland/setup-deno@v1 + - uses: denoland/setup-deno@v2 - uses: dsherret/rust-toolchain-file@v1 - name: Tag and release diff --git a/Cargo.lock b/Cargo.lock index 1e44a677..6c45f40a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "Inflector" @@ -14,41 +14,46 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.21.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] -name = "aho-corasick" -version = "1.1.2" +name = "ahash" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ - "memchr", + "cfg-if", + "once_cell", + "version_check", + "zerocopy", ] [[package]] -name = "ammonia" -version = "3.3.0" +name = "aho-corasick" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e6d1c7838db705c9b756557ee27c384ce695a1c51a6fe528784cb1c6840170" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ - "html5ever", - "maplit", - "once_cell", - "tendril", - "url", + "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + [[package]] name = "anes" version = "0.1.6" @@ -66,37 +71,37 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.82" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "ast_node" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab31376d309dd3bfc9cfb3c11c93ce0e0741bbe0354b20e7f8c60b044730b79" +checksum = "f9184f2b369b3e8625712493c89b785881f27eedc6cde480a81883cef78868b2" dependencies = [ "proc-macro2", "quote", "swc_macros_common", - "syn 2.0.48", + "syn 2.0.89", ] [[package]] name = "async-trait" -version = "0.1.77" +version = "0.1.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.89", ] [[package]] @@ -112,23 +117,23 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.1.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-targets", ] [[package]] @@ -155,15 +160,6 @@ dependencies = [ "scoped-tls", ] -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - [[package]] name = "bitflags" version = "1.3.2" @@ -172,9 +168,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "bitvec" @@ -197,17 +193,62 @@ dependencies = [ "generic-array", ] +[[package]] +name = "boxed_error" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17d4f95e880cfd28c4ca5a006cf7f6af52b4bcb7b5866f573b2faa126fb7affb" +dependencies = [ + "quote", + "syn 2.0.89", +] + [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +dependencies = [ + "allocator-api2", +] [[package]] name = "bytes" -version = "1.5.0" +version = "1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" + +[[package]] +name = "capacity_builder" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f2d24a6dcf0cd402a21b65d35340f3a49ff3475dc5fdac91d22d2733e6641c6" +dependencies = [ + "capacity_builder_macros", + "ecow", + "hipstr", + "itoa", +] + +[[package]] +name = "capacity_builder_macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b4a6cae9efc04cc6cbb8faf338d2c497c165c83e74509cf4dbedea948bbf6e5" +dependencies = [ + "quote", + "syn 2.0.89", +] + +[[package]] +name = "caseless" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "808dab3318747be122cb31d36de18d4d1c81277a76f8332a02b81a3d73463d7f" +dependencies = [ + "regex", + "unicode-normalization", +] [[package]] name = "cast" @@ -217,9 +258,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.0.90" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +checksum = "066fce287b1d4eafef758e89e09d724a24808a9196fe9756b8ca90e86d0719a2" [[package]] name = "cfg-if" @@ -229,9 +270,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "ciborium" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" dependencies = [ "ciborium-io", "ciborium-ll", @@ -240,15 +281,15 @@ dependencies = [ [[package]] name = "ciborium-io" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" [[package]] name = "ciborium-ll" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" dependencies = [ "ciborium-io", "half", @@ -278,7 +319,7 @@ dependencies = [ "bitflags 1.3.2", "clap_lex", "indexmap 1.9.3", - "textwrap 0.16.0", + "textwrap 0.16.1", ] [[package]] @@ -292,10 +333,11 @@ dependencies = [ [[package]] name = "comrak" -version = "0.20.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f18e72341e6cdc7489cffb76f993812a14a906db54dedb020044ccc211dcaae" +checksum = "d8c32ff8b21372fab0e9ecc4e42536055702dc5faa418362bffd1544f9d12637" dependencies = [ + "caseless", "derive_builder", "entities", "memchr", @@ -340,22 +382,13 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.11" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" dependencies = [ "libc", ] -[[package]] -name = "crc32fast" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" -dependencies = [ - "cfg-if", -] - [[package]] name = "criterion" version = "0.4.0" @@ -395,43 +428,43 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.12" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "cfg-if", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.17" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e3681d554572a651dda4186cd47240627c3d0114d45a95f6ad27f2f22e7548d" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "autocfg", - "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.18" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3a430a770ebd84726f584a90ee7f020d28db52c6d02138900f22341f866d39c" -dependencies = [ - "cfg-if", -] +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-common" @@ -445,9 +478,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.14.4" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" dependencies = [ "darling_core", "darling_macro", @@ -455,34 +488,34 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.14.4" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "strsim 0.10.0", - "syn 1.0.109", + "strsim 0.11.1", + "syn 2.0.89", ] [[package]] name = "darling_macro" -version = "0.14.4" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 1.0.109", + "syn 2.0.89", ] [[package]] name = "data-encoding" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" [[package]] name = "data-url" @@ -502,18 +535,20 @@ dependencies = [ [[package]] name = "deno_ast" -version = "0.40.0" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d08372522975cce97fe0efbe42fea508c76eea4421619de6d63baae32792f7d" +checksum = "8b64adab8b7eb6a8713d7ada508b2ef5dc41f201acf6c42d4214ca1917365958" dependencies = [ - "anyhow", "base64", + "deno_error", "deno_media_type", - "deno_terminal", + "deno_terminal 0.2.0", "dprint-swc-ext", "once_cell", "percent-encoding", "serde", + "sourcemap", + "string_capacity", "swc_atoms", "swc_common", "swc_ecma_ast", @@ -529,16 +564,15 @@ dependencies = [ "swc_visit", "swc_visit_macros", "text_lines", - "thiserror", + "thiserror 2.0.3", "unicode-width", "url", ] [[package]] name = "deno_doc" -version = "0.142.0" +version = "0.168.0" dependencies = [ - "ammonia", "anyhow", "cfg-if", "clap 2.34.0", @@ -547,32 +581,28 @@ dependencies = [ "criterion", "deno_ast", "deno_graph", + "deno_path_util", + "deno_terminal 0.2.0", "file_test_runner", "futures", "handlebars", "html-escape", "import_map", - "indexmap 2.1.0", + "indexmap 2.6.0", "insta", + "itoa", + "js-sys", "lazy_static", + "percent-encoding", "pretty_assertions", "regex", "serde", + "serde-wasm-bindgen", "serde_json", - "syntect", "termcolor", "tokio", - "tree-sitter-bash", - "tree-sitter-css", - "tree-sitter-highlight", - "tree-sitter-html", - "tree-sitter-javascript", - "tree-sitter-json", - "tree-sitter-md", - "tree-sitter-regex", - "tree-sitter-rust", - "tree-sitter-toml", - "tree-sitter-typescript", + "url", + "wasm-bindgen", ] [[package]] @@ -582,8 +612,10 @@ dependencies = [ "anyhow", "console_error_panic_hook", "deno_doc", + "deno_error", "deno_graph", "import_map", + "indexmap 2.6.0", "js-sys", "pretty_assertions", "serde", @@ -592,21 +624,49 @@ dependencies = [ "wasm-bindgen-futures", ] +[[package]] +name = "deno_error" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4da6a58de6932a96f84e133c072fd3b525966ee122a71f3efd48bbff2eed5ac" +dependencies = [ + "deno_error_macro", + "libc", + "serde", + "serde_json", + "url", +] + +[[package]] +name = "deno_error_macro" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46351dff93aed2039407c91e2ded2a5591e42d2795ab3d111288625bb710d3d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", +] + [[package]] name = "deno_graph" -version = "0.80.0" +version = "0.88.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1ec763fcd824d63cc056f153ba7fbf6254b515c347ec8b7d1a21515742547bb" +checksum = "8514a537cc6746ee7958b02f62273eff615ada6fa30bf8f5b38eaa68180992a7" dependencies = [ - "anyhow", "async-trait", + "capacity_builder", "data-url", "deno_ast", + "deno_error", + "deno_media_type", + "deno_path_util", "deno_semver", + "deno_unsync", "encoding_rs", "futures", "import_map", - "indexmap 2.1.0", + "indexmap 2.6.0", "log", "monch", "once_cell", @@ -615,31 +675,51 @@ dependencies = [ "serde", "serde_json", "sha2", - "thiserror", + "sys_traits", + "thiserror 2.0.3", "url", + "wasm_dep_analyzer", ] [[package]] name = "deno_media_type" -version = "0.1.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8978229b82552bf8457a0125aa20863f023619cfc21ebb007b1e571d68fd85b" +checksum = "600222d059ab31ff31182b3e12615df2134a9e01605836b78ad8df91ba39eab3" dependencies = [ "data-url", + "encoding_rs", "serde", "url", ] +[[package]] +name = "deno_path_util" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "420e8211aaba7fde83ccaa9a5dad855c3b940ed988d70c95159acd600a70dc87" +dependencies = [ + "deno_error", + "percent-encoding", + "sys_traits", + "thiserror 2.0.3", + "url", +] + [[package]] name = "deno_semver" -version = "0.5.4" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b49e14effd9df8ed261f7a1a34ac19bbaf0fa940c59bd19a6d8313cf41525e1c" +checksum = "4775271f9b5602482698f76d24ea9ed8ba27af7f587a7e9a876916300c542435" dependencies = [ + "capacity_builder", + "deno_error", + "ecow", + "hipstr", "monch", "once_cell", "serde", - "thiserror", + "thiserror 2.0.3", "url", ] @@ -653,42 +733,62 @@ dependencies = [ "termcolor", ] +[[package]] +name = "deno_terminal" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daef12499e89ee99e51ad6000a91f600d3937fb028ad4918af76810c5bc9e0d5" +dependencies = [ + "once_cell", + "termcolor", +] + +[[package]] +name = "deno_unsync" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f36b4ef61a04ce201b925a5dffa90f88437d37fee4836c758470dd15ba7f05e" +dependencies = [ + "parking_lot", + "tokio", +] + [[package]] name = "derive_builder" -version = "0.12.0" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8" +checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947" dependencies = [ "derive_builder_macro", ] [[package]] name = "derive_builder_core" -version = "0.12.0" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f" +checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" dependencies = [ "darling", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.89", ] [[package]] name = "derive_builder_macro" -version = "0.12.0" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e" +checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core", - "syn 1.0.109", + "syn 2.0.89", ] [[package]] name = "deunicode" -version = "1.4.2" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ae2a35373c5c74340b79ae6780b498b2b183915ec5dacf263aac5a099bf485a" +checksum = "339544cc9e2c4dc3fc7149fd630c5f22263a4fdf18a98afd0075784968b5cf00" [[package]] name = "diff" @@ -706,11 +806,22 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", +] + [[package]] name = "dprint-swc-ext" -version = "0.17.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a0d5b63e52434314e3d767c463b1f68c467c31e61d279bc019227016c44e535" +checksum = "0ba28c12892aadb751c2ba7001d8460faee4748a04b4edc51c7121cc67ee03db" dependencies = [ "num-bigint", "rustc-hash", @@ -721,11 +832,20 @@ dependencies = [ "text_lines", ] +[[package]] +name = "ecow" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e42fc0a93992b20c58b99e59d61eaf1635a25bfbe49e4275c34ba0aee98119ba" +dependencies = [ + "serde", +] + [[package]] name = "either" -version = "1.11.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "encode_unicode" @@ -735,9 +855,9 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" dependencies = [ "cfg-if", ] @@ -756,26 +876,16 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "file_test_runner" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8797fcdc5c6b8c06839900c30f5c59b3541ef2bec218579470ce7b1afc17ee9" +checksum = "05b23dcc1b671771c6f59fdace6da685735c925f859733e8fd07fba6cae6462a" dependencies = [ "anyhow", "crossbeam-channel", - "deno_terminal", + "deno_terminal 0.1.1", "parking_lot", "regex", - "thiserror", -] - -[[package]] -name = "flate2" -version = "1.0.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" -dependencies = [ - "crc32fast", - "miniz_oxide", + "thiserror 1.0.64", ] [[package]] @@ -795,13 +905,13 @@ dependencies = [ [[package]] name = "from_variant" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc9cc75639b041067353b9bce2450d6847e547276c6fbe4487d7407980e07db" +checksum = "32016f1242eb82af5474752d00fd8ebcd9004bd69b462b1c91de833972d08ed4" dependencies = [ "proc-macro2", "swc_macros_common", - "syn 2.0.48", + "syn 2.0.89", ] [[package]] @@ -810,21 +920,11 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" -[[package]] -name = "futf" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" -dependencies = [ - "mac", - "new_debug_unreachable", -] - [[package]] name = "futures" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -837,9 +937,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -847,15 +947,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -864,38 +964,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.89", ] [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", @@ -919,34 +1019,27 @@ dependencies = [ "version_check", ] -[[package]] -name = "getrandom" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - [[package]] name = "gimli" -version = "0.28.1" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "half" -version = "1.8.2" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] [[package]] name = "handlebars" -version = "5.0.0" +version = "6.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94eae21d01d20dabef65d8eda734d83df6e2dea8166788804be9bd6bc92448fa" +checksum = "ce25b617d1375ef96eeb920ae717e3da34a02fc979fe632c75128350f9e1f74a" dependencies = [ "heck", "log", @@ -954,7 +1047,7 @@ dependencies = [ "pest_derive", "serde", "serde_json", - "thiserror", + "thiserror 1.0.64", ] [[package]] @@ -965,15 +1058,25 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "hashbrown" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" [[package]] name = "heck" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" @@ -986,20 +1089,31 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.3" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hipstr" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "97971ffc85d4c98de12e2608e992a43f5294ebb625fdb045b27c731b64c4c6d6" +dependencies = [ + "serde", + "serde_bytes", + "sptr", +] [[package]] name = "hstr" -version = "0.2.10" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96274be293b8877e61974a607105d09c84caebe9620b47774aa8a6b942042dd4" +checksum = "dae404c0c5d4e95d4858876ab02eecd6a196bb8caa42050dfa809938833fc412" dependencies = [ - "hashbrown 0.14.3", + "hashbrown 0.14.5", "new_debug_unreachable", "once_cell", - "phf 0.11.2", + "phf", "rustc-hash", "triomphe", ] @@ -1014,84 +1128,202 @@ dependencies = [ ] [[package]] -name = "html5ever" -version = "0.26.0" +name = "icu_collections" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bea68cab48b8459f17cf1c944c67ddc572d272d9f2b274140f223ecb1da4a3b7" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" dependencies = [ - "log", - "mac", - "markup5ever", - "proc-macro2", - "quote", - "syn 1.0.109", + "displaydoc", + "yoke", + "zerofrom", + "zerovec", ] [[package]] -name = "ident_case" -version = "1.0.1" +name = "icu_locid" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] [[package]] -name = "idna" -version = "0.5.0" +name = "icu_locid_transform" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", ] [[package]] -name = "if_chain" -version = "1.0.2" +name = "icu_locid_transform_data" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" [[package]] -name = "import_map" -version = "0.20.0" +name = "icu_normalizer" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "373b8288ad259df0d1314e3e8b2fff0e5e63f22e01bc54ecd2c3c7ad77b9200c" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" dependencies = [ - "indexmap 2.1.0", - "log", - "percent-encoding", - "serde", - "serde_json", - "url", + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", ] [[package]] -name = "indexmap" -version = "1.9.3" +name = "icu_normalizer_data" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", -] +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" [[package]] -name = "indexmap" -version = "2.1.0" +name = "icu_properties" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" dependencies = [ - "equivalent", - "hashbrown 0.14.3", - "serde", + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", ] [[package]] -name = "insta" -version = "1.38.0" +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eab73f58e59ca6526037208f0e98851159ec1633cf17b6cd2e1f2c3fd5d53cc" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" dependencies = [ - "console", - "lazy_static", + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "if_chain" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" + +[[package]] +name = "import_map" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1215d4d92511fbbdaea50e750e91f2429598ef817f02b579158e92803b52c00a" +dependencies = [ + "boxed_error", + "deno_error", + "indexmap 2.6.0", + "log", + "percent-encoding", + "serde", + "serde_json", + "thiserror 2.0.3", + "url", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +dependencies = [ + "equivalent", + "hashbrown 0.15.0", + "serde", +] + +[[package]] +name = "insta" +version = "1.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6593a41c7a73841868772495db7dc1e8ecab43bb5c0b6da2059246c4b506ab60" +dependencies = [ + "console", + "lazy_static", "linked-hash-map", "serde", "similar", @@ -1099,14 +1331,14 @@ dependencies = [ [[package]] name = "is-macro" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a85abdc13717906baccb5a1e435556ce0df215f242892f721dff62bf25288f" +checksum = "2069faacbe981460232f880d26bf3c7634e322d49053aa48c27e3ae642f728f1" dependencies = [ "Inflector", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.89", ] [[package]] @@ -1120,9 +1352,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "js-sys" @@ -1135,15 +1367,15 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.151" +version = "0.2.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" [[package]] name = "linked-hash-map" @@ -1151,11 +1383,17 @@ version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" +[[package]] +name = "litemap" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" + [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -1163,60 +1401,35 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" - -[[package]] -name = "mac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" - -[[package]] -name = "maplit" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" - -[[package]] -name = "markup5ever" -version = "0.11.0" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2629bb1404f3d34c2e921f21fd34ba00b206124c81f65c50b43b6aaefeb016" -dependencies = [ - "log", - "phf 0.10.1", - "phf_codegen", - "string_cache", - "string_cache_codegen", - "tendril", -] +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ - "adler", + "adler2", ] [[package]] name = "mio" -version = "0.8.10" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ + "hermit-abi 0.3.9", "libc", "wasi", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1233,11 +1446,10 @@ checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ - "autocfg", "num-integer", "num-traits", "serde", @@ -1245,19 +1457,18 @@ dependencies = [ [[package]] name = "num-integer" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] @@ -1268,52 +1479,30 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.3.3", + "hermit-abi 0.3.9", "libc", ] [[package]] name = "object" -version = "0.32.2" +version = "0.36.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" - -[[package]] -name = "onig" -version = "6.4.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c4b31c8722ad9171c6d77d3557db078cab2bd50afcc9d09c8b315c59df8ca4f" -dependencies = [ - "bitflags 1.3.2", - "libc", - "once_cell", - "onig_sys", -] - -[[package]] -name = "onig_sys" -version = "69.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b829e3d7e9cc74c7e315ee8edb185bf4190da5acde74afd7fc59c35b1f086e7" -dependencies = [ - "cc", - "pkg-config", -] +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "oorandom" -version = "11.1.3" +version = "11.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" +checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" [[package]] name = "os_str_bytes" @@ -1329,9 +1518,9 @@ checksum = "7f222829ae9293e33a9f5e9f440c6760a3d450a64affe1846486b140db81c1f4" [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -1339,15 +1528,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets 0.48.5", + "windows-targets", ] [[package]] @@ -1364,20 +1553,20 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.6" +version = "2.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f200d8d83c44a45b21764d1916299752ca035d15ecd46faca3e9a2a2bf6ad06" +checksum = "fdbef9d1d47087a895abd220ed25eb4ad973a5e26f6a4367b038c25e28dfc2d9" dependencies = [ "memchr", - "thiserror", + "thiserror 1.0.64", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.7.6" +version = "2.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcd6ab1236bbdb3a49027e920e693192ebfe8913f6d60e294de57463a493cfde" +checksum = "4d3a6e3394ec80feb3b6393c725571754c6188490265c61aaf260810d6b95aa0" dependencies = [ "pest", "pest_generator", @@ -1385,37 +1574,28 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.6" +version = "2.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a31940305ffc96863a735bef7c7994a00b325a7138fdbc5bda0f1a0476d3275" +checksum = "94429506bde1ca69d1b5601962c73f4172ab4726571a59ea95931218cb0e930e" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.89", ] [[package]] name = "pest_meta" -version = "2.7.6" +version = "2.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7ff62f5259e53b78d1af898941cdcdccfae7385cf7d793a6e55de5d05bb4b7d" +checksum = "ac8a071862e93690b6e34e9a5fb8e33ff3734473ac0245b27232222c4906a33f" dependencies = [ "once_cell", "pest", "sha2", ] -[[package]] -name = "phf" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" -dependencies = [ - "phf_shared 0.10.0", -] - [[package]] name = "phf" version = "0.11.2" @@ -1423,27 +1603,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" dependencies = [ "phf_macros", - "phf_shared 0.11.2", -] - -[[package]] -name = "phf_codegen" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd" -dependencies = [ - "phf_generator 0.10.0", - "phf_shared 0.10.0", -] - -[[package]] -name = "phf_generator" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" -dependencies = [ - "phf_shared 0.10.0", - "rand", + "phf_shared", ] [[package]] @@ -1452,7 +1612,7 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" dependencies = [ - "phf_shared 0.11.2", + "phf_shared", "rand", ] @@ -1462,20 +1622,11 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" dependencies = [ - "phf_generator 0.11.2", - "phf_shared 0.11.2", + "phf_generator", + "phf_shared", "proc-macro2", "quote", - "syn 2.0.48", -] - -[[package]] -name = "phf_shared" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" -dependencies = [ - "siphasher", + "syn 2.0.89", ] [[package]] @@ -1489,9 +1640,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -1499,17 +1650,11 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "pkg-config" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" - [[package]] name = "plotters" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" +checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" dependencies = [ "num-traits", "plotters-backend", @@ -1520,36 +1665,24 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" +checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" [[package]] name = "plotters-svg" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" +checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" dependencies = [ "plotters-backend", ] -[[package]] -name = "ppv-lite86" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - -[[package]] -name = "precomputed-hash" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" - [[package]] name = "pretty_assertions" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" +checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d" dependencies = [ "diff", "yansi", @@ -1557,27 +1690,47 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.75" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "907a61bd0f64c2f29cd1cf1dc34d05176426a3f504a78010f08416ddb7b13708" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] [[package]] name = "psm" -version = "0.1.21" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874" +checksum = "aa37f80ca58604976033fae9515a8a2989fc13797d953f7c04fb8fa36a11f205" dependencies = [ "cc", ] +[[package]] +name = "ptr_meta" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "quote" -version = "1.0.35" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -1594,18 +1747,6 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", "rand_core", ] @@ -1614,15 +1755,12 @@ name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] [[package]] name = "rayon" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -1630,9 +1768,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -1640,53 +1778,47 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", ] [[package]] name = "regex" -version = "1.10.4" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" dependencies = [ "aho-corasick", "memchr", "regex-automata", - "regex-syntax 0.8.2", + "regex-syntax", ] [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.2", + "regex-syntax", ] [[package]] name = "regex-syntax" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" - -[[package]] -name = "regex-syntax" -version = "0.8.2" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" @@ -1705,9 +1837,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.16" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "ryu-js" @@ -1753,9 +1885,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.198" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] @@ -1771,25 +1903,35 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "serde_bytes" +version = "0.11.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" +dependencies = [ + "serde", +] + [[package]] name = "serde_derive" -version = "1.0.198" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.89", ] [[package]] name = "serde_json" -version = "1.0.111" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.6.0", "itoa", + "memchr", "ryu", "serde", ] @@ -1807,9 +1949,9 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] @@ -1825,9 +1967,9 @@ dependencies = [ [[package]] name = "similar" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa42c91313f1d05da9b26f267f931cf178d4aba455b4c4622dd7355eb80c6640" +checksum = "1de1d4f81173b03af4c0cbed3c898f6bff5b870e4a7f5d6f4057d62a7a4b686e" [[package]] name = "siphasher" @@ -1846,9 +1988,9 @@ dependencies = [ [[package]] name = "slug" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bd94acec9c8da640005f8e135a39fc0372e74535e6b368b7a04b875f784c8c4" +checksum = "882a80f72ee45de3cc9a5afeb2da0331d58df69e4e7d8eeb5d3c7784ae67e724" dependencies = [ "deunicode", "wasm-bindgen", @@ -1856,9 +1998,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.2" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "smartstring" @@ -1873,19 +2015,19 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.5" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "sourcemap" -version = "8.0.1" +version = "9.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "208d40b9e8cad9f93613778ea295ed8f3c2b1824217c6cfc7219d3f6f45b96d4" +checksum = "dab08a862c70980b8e23698b507e272317ae52a608a164a844111f5372374f1f" dependencies = [ "base64-simd", "bitvec", @@ -1900,6 +2042,12 @@ dependencies = [ "url", ] +[[package]] +name = "sptr" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b9b39299b249ad65f3b7e96443bad61c02ca5cd3589f46cb6d610a0fd6c0d6a" + [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -1908,15 +2056,15 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "stacker" -version = "0.1.15" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c886bd4480155fd3ef527d45e9ac8dd7118a898a46530b7b94c3e21866259fce" +checksum = "799c883d55abdb5e98af1a7b3f23b9b6de8ecada0ecac058672d7635eb48ca7b" dependencies = [ "cc", "cfg-if", "libc", "psm", - "winapi", + "windows-sys 0.59.0", ] [[package]] @@ -1926,29 +2074,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] -name = "string_cache" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" -dependencies = [ - "new_debug_unreachable", - "once_cell", - "parking_lot", - "phf_shared 0.10.0", - "precomputed-hash", - "serde", -] - -[[package]] -name = "string_cache_codegen" -version = "0.5.2" +name = "string_capacity" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988" +checksum = "fcd14cb3a5abda6d2626370785f5f788b22e95476f597159faa4a2cc2966961a" dependencies = [ - "phf_generator 0.10.0", - "phf_shared 0.10.0", - "proc-macro2", - "quote", + "itoa", ] [[package]] @@ -1960,7 +2091,7 @@ dependencies = [ "proc-macro2", "quote", "swc_macros_common", - "syn 2.0.48", + "syn 2.0.89", ] [[package]] @@ -1971,9 +2102,22 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "strsim" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "swc_allocator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7016ee7a5186d6a80e381aa1926e0f3c7b06eaf444745ff7af3632e978eb8dc5" +dependencies = [ + "bumpalo", + "hashbrown 0.14.5", + "ptr_meta", + "rustc-hash", + "triomphe", +] [[package]] name = "swc_atoms" @@ -1989,9 +2133,9 @@ dependencies = [ [[package]] name = "swc_common" -version = "0.34.4" +version = "0.37.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9087befec6b63911f9d2f239e4f91c9b21589c169b86ed2d616944d23cf4a243" +checksum = "12d0a8eaaf1606c9207077d75828008cb2dfb51b095a766bd2b72ef893576e31" dependencies = [ "ast_node", "better_scoped_tls", @@ -2005,6 +2149,7 @@ dependencies = [ "serde", "siphasher", "sourcemap", + "swc_allocator", "swc_atoms", "swc_eq_ignore_macros", "swc_visit", @@ -2015,14 +2160,14 @@ dependencies = [ [[package]] name = "swc_ecma_ast" -version = "0.115.1" +version = "0.118.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7be1306930c235435a892104c00c2b5e16231043c085d5a10bd3e7537b15659b" +checksum = "a6f866d12e4d519052b92a0a86d1ac7ff17570da1272ca0c89b3d6f802cd79df" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "is-macro", "num-bigint", - "phf 0.11.2", + "phf", "scoped-tls", "serde", "string_enum", @@ -2033,16 +2178,16 @@ dependencies = [ [[package]] name = "swc_ecma_codegen" -version = "0.151.1" +version = "0.155.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5141a8cb4eb69e090e6aea5d49061b46919be5210f3d084f9d9ad63d30f5cff" +checksum = "cc7641608ef117cfbef9581a99d02059b522fcca75e5244fa0cbbd8606689c6f" dependencies = [ "memchr", "num-bigint", "once_cell", - "rustc-hash", "serde", "sourcemap", + "swc_allocator", "swc_atoms", "swc_common", "swc_ecma_ast", @@ -2052,21 +2197,21 @@ dependencies = [ [[package]] name = "swc_ecma_codegen_macros" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090e409af49c8d1a3c13b3aab1ed09dd4eda982207eb3e63c2ad342f072b49c8" +checksum = "859fabde36db38634f3fad548dd5e3410c1aebba1b67a3c63e67018fa57a0bca" dependencies = [ "proc-macro2", "quote", "swc_macros_common", - "syn 2.0.48", + "syn 2.0.89", ] [[package]] name = "swc_ecma_loader" -version = "0.46.1" +version = "0.49.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a9febebf047d1286e7b723fa2758f3229da2c103834f3eaee69833f46692612" +checksum = "55fa3d55045b97894bfb04d38aff6d6302ac8a6a38e3bb3dfb0d20475c4974a9" dependencies = [ "anyhow", "pathdiff", @@ -2078,15 +2223,15 @@ dependencies = [ [[package]] name = "swc_ecma_parser" -version = "0.146.12" +version = "0.149.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a4e0c2e85f12c63b85c805e923079b04d1fb3e25edd069d638eed5f2098de74" +checksum = "683dada14722714588b56481399c699378b35b2ba4deb5c4db2fb627a97fb54b" dependencies = [ "either", "new_debug_unreachable", "num-bigint", "num-traits", - "phf 0.11.2", + "phf", "serde", "smallvec", "smartstring", @@ -2100,15 +2245,15 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_base" -version = "0.140.3" +version = "0.145.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d37dc505c92af56d0f77cf6f31a6ccd37ac40cad1e01ff77277e0b1c70e8f8ff" +checksum = "65f21494e75d0bd8ef42010b47cabab9caaed8f2207570e809f6f4eb51a710d1" dependencies = [ "better_scoped_tls", - "bitflags 2.5.0", - "indexmap 2.1.0", + "bitflags 2.6.0", + "indexmap 2.6.0", "once_cell", - "phf 0.11.2", + "phf", "rustc-hash", "serde", "smallvec", @@ -2123,11 +2268,11 @@ dependencies = [ [[package]] name = "swc_ecma_utils" -version = "0.130.3" +version = "0.134.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e62b199454a576c5fdbd7e1bef8ab88a395427456d8a713d994b7d469833aa" +checksum = "029eec7dd485923a75b5a45befd04510288870250270292fc2c1b3a9e7547408" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.6.0", "num_cpus", "once_cell", "rustc-hash", @@ -2142,10 +2287,11 @@ dependencies = [ [[package]] name = "swc_ecma_visit" -version = "0.101.0" +version = "0.104.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce0d997f0c9b4e181225f603d161f6757c2a97022258170982cfe005ec69ec92" +checksum = "5b1c6802e68e51f336e8bc9644e9ff9da75d7da9c1a6247d532f2e908aa33e81" dependencies = [ + "new_debug_unreachable", "num-bigint", "swc_atoms", "swc_common", @@ -2156,47 +2302,47 @@ dependencies = [ [[package]] name = "swc_eq_ignore_macros" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "695a1d8b461033d32429b5befbf0ad4d7a2c4d6ba9cd5ba4e0645c615839e8e4" +checksum = "63db0adcff29d220c3d151c5b25c0eabe7e32dd936212b84cdaa1392e3130497" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.89", ] [[package]] name = "swc_macros_common" -version = "0.3.11" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91745f3561057493d2da768437c427c0e979dff7396507ae02f16c981c4a8466" +checksum = "f486687bfb7b5c560868f69ed2d458b880cebc9babebcb67e49f31b55c5bf847" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.89", ] [[package]] name = "swc_visit" -version = "0.5.14" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "043d11fe683dcb934583ead49405c0896a5af5face522e4682c16971ef7871b9" +checksum = "1ceb044142ba2719ef9eb3b6b454fce61ab849eb696c34d190f04651955c613d" dependencies = [ "either", - "swc_visit_macros", + "new_debug_unreachable", ] [[package]] name = "swc_visit_macros" -version = "0.5.12" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae9ef18ff8daffa999f729db056d2821cd2f790f3a11e46422d19f46bb193e7" +checksum = "92807d840959f39c60ce8a774a3f83e8193c658068e6d270dbe0a05e40e90b41" dependencies = [ "Inflector", "proc-macro2", "quote", "swc_macros_common", - "syn 2.0.48", + "syn 2.0.89", ] [[package]] @@ -2212,9 +2358,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" dependencies = [ "proc-macro2", "quote", @@ -2222,46 +2368,33 @@ dependencies = [ ] [[package]] -name = "syntect" -version = "5.1.0" +name = "synstructure" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e02b4b303bf8d08bfeb0445cba5068a3d306b6baece1d5582171a9bf49188f91" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ - "bincode", - "bitflags 1.3.2", - "flate2", - "fnv", - "once_cell", - "onig", - "regex-syntax 0.7.5", - "serde", - "serde_json", - "thiserror", - "walkdir", + "proc-macro2", + "quote", + "syn 2.0.89", ] [[package]] -name = "tap" -version = "1.0.1" +name = "sys_traits" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +checksum = "638f0e61b5134e56b2abdf4c704fd44672603f15ca09013f314649056f3fee4d" [[package]] -name = "tendril" -version = "0.4.3" +name = "tap" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0" -dependencies = [ - "futf", - "mac", - "utf-8", -] +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "termcolor" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] @@ -2286,28 +2419,58 @@ dependencies = [ [[package]] name = "textwrap" -version = "0.16.0" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" + +[[package]] +name = "thiserror" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +dependencies = [ + "thiserror-impl 1.0.64", +] [[package]] name = "thiserror" -version = "1.0.58" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +checksum = "c006c85c7651b3cf2ada4584faa36773bd07bac24acfb39f3c431b36d7e667aa" dependencies = [ - "thiserror-impl", + "thiserror-impl 2.0.3", ] [[package]] name = "thiserror-impl" -version = "1.0.58" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.89", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", +] + +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", ] [[package]] @@ -2322,9 +2485,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -2337,32 +2500,31 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.35.1" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" +checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" dependencies = [ "backtrace", "bytes", "libc", "mio", - "num_cpus", "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.89", ] [[package]] @@ -2384,7 +2546,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.89", ] [[package]] @@ -2396,132 +2558,11 @@ dependencies = [ "once_cell", ] -[[package]] -name = "tree-sitter" -version = "0.20.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e747b1f9b7b931ed39a548c1fae149101497de3c1fc8d9e18c62c1a66c683d3d" -dependencies = [ - "cc", - "regex", -] - -[[package]] -name = "tree-sitter-bash" -version = "0.20.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57da2032c37eb2ce29fd18df7d3b94355fec8d6d854d8f80934955df542b5906" -dependencies = [ - "cc", - "tree-sitter", -] - -[[package]] -name = "tree-sitter-css" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3306ddefa1d2681adda2613d11974ffabfbeb215e23235da6c862f3493a04fd" -dependencies = [ - "cc", - "tree-sitter", -] - -[[package]] -name = "tree-sitter-highlight" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "042342584c5a7a0b833d9fc4e2bdab3f9868ddc6c4b339a1e01451c6720868bc" -dependencies = [ - "regex", - "thiserror", - "tree-sitter", -] - -[[package]] -name = "tree-sitter-html" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "017822b6bd42843c4bd67fabb834f61ce23254e866282dd93871350fd6b7fa1d" -dependencies = [ - "cc", - "tree-sitter", -] - -[[package]] -name = "tree-sitter-javascript" -version = "0.20.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d015c02ea98b62c806f7329ff71c383286dfc3a7a7da0cc484f6e42922f73c2c" -dependencies = [ - "cc", - "tree-sitter", -] - -[[package]] -name = "tree-sitter-json" -version = "0.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a9a38a9c679b55cc8d17350381ec08d69fa1a17a53fcf197f344516e485ed4d" -dependencies = [ - "cc", - "tree-sitter", -] - -[[package]] -name = "tree-sitter-md" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c20d3ef8d202430b644a307e6299d84bf8ed87fa1b796e4638f8805a595060c" -dependencies = [ - "cc", - "tree-sitter", -] - -[[package]] -name = "tree-sitter-regex" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efb5a53e9c990757895476216796b170fd81e4d173d08f8b082279c4e6ff8c5c" -dependencies = [ - "cc", - "tree-sitter", -] - -[[package]] -name = "tree-sitter-rust" -version = "0.20.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0832309b0b2b6d33760ce5c0e818cb47e1d72b468516bfe4134408926fa7594" -dependencies = [ - "cc", - "tree-sitter", -] - -[[package]] -name = "tree-sitter-toml" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca517f578a98b23d20780247cc2688407fa81effad5b627a5a364ec3339b53e8" -dependencies = [ - "cc", - "tree-sitter", -] - -[[package]] -name = "tree-sitter-typescript" -version = "0.20.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8bc1d2c24276a48ef097a71b56888ac9db63717e8f8d0b324668a27fd619670" -dependencies = [ - "cc", - "tree-sitter", -] - [[package]] name = "triomphe" -version = "0.1.11" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859eb650cfee7434994602c3a68b25d77ad9e68c8a6cd491616ef86661382eb3" +checksum = "ef8f7726da4807b58ea5c96fdc122f80702030edc33b35aff9190a51148ccc85" dependencies = [ "serde", "stable_deref_trait", @@ -2541,48 +2582,42 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "ucd-trie" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" - -[[package]] -name = "unicode-bidi" -version = "0.3.14" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" [[package]] name = "unicode-id" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1b6def86329695390197b82c1e244a54a131ceb66c996f2088a3876e2ae083f" +checksum = "10103c57044730945224467c09f71a4db0071c123a0648cc3e818913bde6b561" [[package]] name = "unicode-id-start" -version = "1.0.4" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02aebfa694eccbbbffdd92922c7de136b9fe764396d2f10e21bce1681477cfc1" +checksum = "97e2a3c5fc9de285c0e805d98eba666adb4b2d9e1049ce44821ff7707cc34e91" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "unicode_categories" @@ -2592,9 +2627,9 @@ checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" [[package]] name = "url" -version = "2.5.0" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna", @@ -2603,10 +2638,10 @@ dependencies = [ ] [[package]] -name = "utf-8" -version = "0.7.6" +name = "utf16_iter" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" [[package]] name = "utf8-width" @@ -2614,17 +2649,23 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" [[package]] name = "vec_map" @@ -2634,9 +2675,9 @@ checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "vte" @@ -2651,9 +2692,9 @@ dependencies = [ [[package]] name = "vte_generate_state_changes" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d257817081c7dffcdbab24b9e62d2def62e2ff7d00b1c20062551e6cccc145ff" +checksum = "2e369bee1b05d510a7b4ed645f5faa90619e05437111783ea5848f28d97d3c2e" dependencies = [ "proc-macro2", "quote", @@ -2661,9 +2702,9 @@ dependencies = [ [[package]] name = "walkdir" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", @@ -2696,7 +2737,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.89", "wasm-bindgen-shared", ] @@ -2730,7 +2771,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.89", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2741,11 +2782,21 @@ version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +[[package]] +name = "wasm_dep_analyzer" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eeee3bdea6257cc36d756fa745a70f9d393571e47d69e0ed97581676a5369ca" +dependencies = [ + "deno_error", + "thiserror 2.0.3", +] + [[package]] name = "web-sys" -version = "0.3.66" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", @@ -2769,11 +2820,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "winapi", + "windows-sys 0.59.0", ] [[package]] @@ -2782,156 +2833,198 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.5", + "windows-targets", ] [[package]] -name = "windows-targets" -version = "0.48.5" +name = "windows-sys" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", + "windows-targets", ] [[package]] name = "windows-targets" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.5" +name = "windows_aarch64_msvc" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" +name = "windows_i686_gnu" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] -name = "windows_aarch64_msvc" -version = "0.52.5" +name = "windows_i686_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] -name = "windows_i686_gnu" -version = "0.48.5" +name = "windows_i686_msvc" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] -name = "windows_i686_gnu" -version = "0.52.5" +name = "windows_x86_64_gnu" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] -name = "windows_i686_gnullvm" -version = "0.52.5" +name = "windows_x86_64_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] -name = "windows_i686_msvc" -version = "0.48.5" +name = "windows_x86_64_msvc" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] -name = "windows_i686_msvc" -version = "0.52.5" +name = "write16" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" [[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" +name = "writeable" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" [[package]] -name = "windows_x86_64_gnu" -version = "0.52.5" +name = "wyz" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] [[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" +name = "yansi" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" [[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.5" +name = "yoke" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] [[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" +name = "yoke-derive" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", + "synstructure", +] [[package]] -name = "windows_x86_64_msvc" -version = "0.52.5" +name = "zerocopy" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "zerocopy-derive", +] [[package]] -name = "wyz" -version = "0.5.1" +name = "zerocopy-derive" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ - "tap", + "proc-macro2", + "quote", + "syn 2.0.89", ] [[package]] -name = "yansi" -version = "0.5.1" +name = "zerofrom" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", + "synstructure", +] + +[[package]] +name = "zerovec" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", +] diff --git a/Cargo.toml b/Cargo.toml index 867fb42a..7a23e605 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "deno_doc" -version = "0.142.0" +version = "0.168.0" edition = "2021" description = "doc generation for deno" authors = ["the Deno authors"] @@ -11,10 +11,10 @@ repository = "https://github.com/denoland/deno_doc" members = ["lib"] [workspace.dependencies] -deno_graph = { version = "0.80.0", default-features = false, features = ["symbols"] } -deno_ast = { version = "0.40.0" } -import_map = "0.20.0" -serde = { version = "1.0.140", features = ["derive"] } +deno_graph = { version = "0.88.0", default-features = false, features = ["symbols"] } +deno_ast = { version = "0.45.0" } +import_map = "0.21.0" +serde = { version = "1.0.204", features = ["derive"] } [lib] crate-type = ["cdylib", "rlib"] @@ -22,74 +22,49 @@ name = "deno_doc" [[example]] name = "ddoc" -required-features = ["html"] +required-features = ["comrak"] [dependencies] -anyhow = "1.0.58" +anyhow = "1.0.86" cfg-if = "1.0.0" deno_ast.workspace = true deno_graph.workspace = true -indexmap = "2.0.2" -futures = "0.3.26" +deno_terminal = "0.2.0" +indexmap = "2.3.0" import_map.workspace = true -lazy_static = "1.4.0" -regex = "1.6.0" +lazy_static = "1.5.0" +regex = "1.10.6" serde.workspace = true -serde_json = { version = "1.0.82", features = ["preserve_order"] } -termcolor = "1.1.2" +serde_json = { version = "1.0.122", features = ["preserve_order"] } +termcolor = "1.4.1" +itoa = "1.0.14" +deno_path_util = "0.3.0" -html-escape = { version = "0.2.13", optional = true } -comrak = { version = "0.20.0", optional = true, default-features = false } -handlebars = { version = "5.0", optional = true, features = ["string_helpers"] } -syntect = { version = "5.1.0", optional = true, default-features = false, features = [ - "parsing", - "default-syntaxes", - "default-themes", - "html", - "dump-load", - "regex-onig", -] } -ammonia = { version = "3.3.0", optional = true } - -tree-sitter-highlight = { version = "0.20.1", optional = true } -tree-sitter-javascript = { version = "0.20.1", optional = true } -tree-sitter-typescript = { version = "0.20.3", optional = true } -tree-sitter-json = { version = "0.20.1", optional = true } -tree-sitter-regex = { version = "0.20.0", optional = true } -tree-sitter-css = { version = "0.20.0", optional = true } -tree-sitter-toml = { version = "0.20.0", optional = true } -tree-sitter-md = { version = "0.1.7", optional = true } -tree-sitter-rust = { version = "0.20.4", optional = true } -tree-sitter-html = { version = "0.20.0", optional = true } -tree-sitter-bash = { version = "0.20.5", optional = true } +html-escape = { version = "0.2.13" } +handlebars = { version = "6.1", features = ["string_helpers"] } +comrak = { version = "0.29.0", optional = true, default-features = false } [dev-dependencies] -anyhow = { version = "1.0.58" } -clap = "2.33.3" +anyhow = { version = "1.0.86" } +clap = "2.34.0" console_static_text = "0.8.2" criterion = { version = "0.4.0", features = ["async_futures", "html_reports"] } -file_test_runner = "0.7.0" -tokio = { version = "1.25.0", features = ["full"] } -pretty_assertions = "1.0.0" -insta = { version = "1.38.0", features = ["json"] } +file_test_runner = "0.7.2" +futures = "0.3.30" +tokio = { version = "1.39.2", features = ["full"] } +pretty_assertions = "1.4.0" +insta = { version = "1.39.0", features = ["json"] } + +[target.'cfg(target_arch = "wasm32")'.dependencies] +url = "2.4.1" +percent-encoding = "2.3.1" +wasm-bindgen = "0.2.92" +js-sys = "0.3.69" +serde-wasm-bindgen = "=0.5.0" [features] -default = ["html", "rust", "ammonia"] +default = ["rust", "comrak"] rust = [] -html = ["html-escape", "comrak", "handlebars"] -tree-sitter = [ - "tree-sitter-highlight", - "tree-sitter-javascript", - "tree-sitter-typescript", - "tree-sitter-json", - "tree-sitter-regex", - "tree-sitter-css", - "tree-sitter-toml", - "tree-sitter-md", - "tree-sitter-rust", - "tree-sitter-html", - "tree-sitter-bash", -] [[test]] name = "specs" diff --git a/README.md b/README.md index bbf4a24d..b107271a 100644 --- a/README.md +++ b/README.md @@ -36,8 +36,27 @@ $ deno task build $ deno task test ``` +### HTML generation + +If you want to work on the HTML generation aspect of deno_doc, these things will +help you: + +`deno task tailwind`: this regenerates the transpiled tailwind from the css +files and mentions of classes across the codebases, be it in rust files or js +files. This needs to always be run to do any updates to the styling. + +`deno task gen_html`: This generates a `generated_docs` directory which is the +HTML output based on the provided files. + +`deno task debug`: this calls the above tailwind task, and then the gen_html +task with all the files from `tests/testdata/multiple` passed. + +We recommend to use these tasks above to develop features or debug things, +rather than recompiling a dependent on this system, as it is much faster +iteration and easier to debug. + We use [insta](https://github.com/mitsuhiko/insta) testing tool for taking -snapshots of the html output. If you change the rednering of html output, or +snapshots of the html output. If you change the rendering of html output, or change the fixture files for html testing, you need to update snapshot using [cargo-insta](https://insta.rs/docs/quickstart/) command. @@ -51,6 +70,40 @@ cargo insta review See [the insta docs](https://insta.rs/docs/quickstart/) for more details. +### HTML Internal structure + +Most of the HTML generated, except if its in very small fragments (ie a single +element or two) is located in `src/html/templates`. This is also where scripts, +CSS and icons live. The `page` directory in it is an extension to that which +only relates to generation of a full-fledged documentation page (like +`deno doc`), and is not used when just generating fragments (like +https://jsr.io). + +Rendering of a symbol is done in the `src/html/symbols` directory, in the +corresponding file depending on the type of the symbol. Namespace is a special +case as in it is used for things besides namespaces, for example the "all +symbols" page. + +A collection of symbols that refer to the same symbol identifier (like lets say +having a class and namespace with the same name of `MySymbol`), are called a +"symbol group". + +The markdown rendering is pluggable and a default renderer is available via the +`comrak` feature which enables a default markdown renderer using the crate with +the same name. + +A internal struct is `ShortPath`, which is a wrapper around a `Url` instance +with some additional information, including the display value and if it is the +main entrypoint. In addition to this struct, we have another wrapper struct +named `DocNodeWithContext`, which contains a `DocNode` and information related +to it, like a resolved identifier for representing its name in a namespace, and +also data related to "property drilldown". + +Property drilldown is what we call being able to view properties, methods and +other accessors on classes, interfaces and applicable variables and type +aliases. It however does not refer to an item in a namespace, as those have +their unique handling. + ## Contributing - If you are going to work on an issue, mention so in the issue comments diff --git a/benches/doc_parser.rs b/benches/doc_parser.rs index 3ab0571e..b260ba82 100644 --- a/benches/doc_parser.rs +++ b/benches/doc_parser.rs @@ -15,8 +15,9 @@ use deno_graph::CapturingModuleAnalyzer; use deno_graph::GraphKind; use deno_graph::ModuleGraph; use deno_graph::ModuleSpecifier; +use indexmap::IndexMap; -async fn parse_with_reexports() -> Vec { +async fn parse() -> IndexMap> { let source = std::fs::read_to_string("./benches/fixtures/deno.d.ts").unwrap(); let sources = vec![( "file:///test/fixtures/deno.d.ts", @@ -41,16 +42,15 @@ async fn parse_with_reexports() -> Vec { }, ) .await; - DocParser::new(&graph, &analyzer, DocParserOptions::default()) + DocParser::new(&graph, &analyzer, &[root], DocParserOptions::default()) .unwrap() - .parse_with_reexports(&root) + .parse() .unwrap() } fn doc_parser(c: &mut Criterion) { - c.bench_function("parse_with_rexports large", |b| { - b.to_async(FuturesExecutor) - .iter_with_large_drop(parse_with_reexports) + c.bench_function("parse large", |b| { + b.to_async(FuturesExecutor).iter_with_large_drop(parse) }); } diff --git a/build_css.ts b/build_css.ts index 5a1e061a..8ef8a079 100644 --- a/build_css.ts +++ b/build_css.ts @@ -1,6 +1,6 @@ -import $ from "jsr:@david/dax@0.40.1"; -import browserslist from "npm:browserslist@4.23.0"; -import { browserslistToTargets, transform } from "npm:lightningcss"; +import $ from "@david/dax"; +import browserslist from "browserslist"; +import { browserslistToTargets, transform } from "lightningcss"; const browsers = browserslist(">= 0.5%, not dead"); @@ -33,10 +33,22 @@ const reset = await $`deno run -A npm:tailwindcss@3.4.3 --input src/html/templates/pages/reset.css` .bytes(); const resetFinal = transform({ - filename: "./page.css", + filename: "./reset.css", code: reset, minify: true, targets: browserslistToTargets(browsers), analyzeDependencies: false, }); await Deno.writeFile("src/html/templates/pages/reset.gen.css", resetFinal.code); + +const comrak = + await $`deno run -A npm:tailwindcss@3.4.3 --input src/html/templates/comrak.css` + .bytes(); +const comrakFinal = transform({ + filename: "./comrak.css", + code: comrak, + minify: true, + targets: browserslistToTargets(browsers), + analyzeDependencies: false, +}); +await Deno.writeFile("src/html/templates/comrak.gen.css", comrakFinal.code); diff --git a/deno.json b/deno.json index 3e239d17..157e29b8 100644 --- a/deno.json +++ b/deno.json @@ -3,17 +3,25 @@ "build": "cp LICENSE js/LICENSE && deno run -A jsr:@deno/wasmbuild@0.17.1 --project deno_doc_wasm --out js", "test": "deno test -A", "tailwind": "deno run -A build_css.ts", - "gen_html": "deno task tailwind && cargo run --example ddoc --features=html -- --name \"std HTTP and Assert\" --html ../deno_std/http/mod.ts ../deno_std/assert/mod.ts ../deno_std/collections/mod.ts --output generated_docs/ --main_entrypoint ../deno_std/assert/mod.ts", - "test:update": "UPDATE=1 cargo test --locked --all-targets && UPDATE=1 cargo test --locked --all-targets --features=tree-sitter && UPDATE=1 cargo test --locked --all-targets --features=syntect && cargo insta test --review" + "gen_html": "cargo run --example ddoc -- --name=gen_html --output generated_docs/ --html", + "debug": "deno task tailwind && deno task gen_html ./tests/testdata/multiple/[!_]*", + "test:update": "UPDATE=1 cargo test --locked --all-targets && cargo insta test --accept" + }, + "workspace": ["js"], + "exclude": ["target", "benches/fixtures"], + "fmt": { + "exclude": ["**/*.gen.css", "generated_docs"] }, - "exclude": [ - "target", - "benches/fixtures" - ], "lint": { - "exclude": [ - "src/html", - "tests/testdata" - ] + "exclude": ["src/html", "tests/testdata"] + }, + "imports": { + "@david/dax": "jsr:@david/dax@0.40.1", + "@deno/cache-dir": "jsr:@deno/cache-dir@^0.14.0", + "@deno/graph": "jsr:@deno/graph@^0.82.3", + "@std/assert": "jsr:@std/assert@^0.223.0", + "browserslist": "npm:browserslist@4.23.0", + "lightningcss": "npm:lightningcss@^1.26.0", + "tailwindcss": "npm:tailwindcss@3.4.3" } } diff --git a/deno.lock b/deno.lock index ec772d69..83005ef9 100644 --- a/deno.lock +++ b/deno.lock @@ -1,1029 +1,775 @@ { - "version": "3", - "packages": { - "specifiers": { - "jsr:@david/dax@0.40": "jsr:@david/dax@0.40.0", - "jsr:@david/dax@0.40.1": "jsr:@david/dax@0.40.1", - "jsr:@david/which@0.3": "jsr:@david/which@0.3.0", - "jsr:@deno/cache-dir@0.8": "jsr:@deno/cache-dir@0.8.0", - "jsr:@deno/graph@0.73": "jsr:@deno/graph@0.73.1", - "jsr:@deno/graph@^0.69.7": "jsr:@deno/graph@0.69.10", - "jsr:@std/assert@0.223": "jsr:@std/assert@0.223.0", - "jsr:@std/assert@^0.218.2": "jsr:@std/assert@0.218.2", - "jsr:@std/assert@^0.221.0": "jsr:@std/assert@0.221.0", - "jsr:@std/bytes@^0.218.2": "jsr:@std/bytes@0.218.2", - "jsr:@std/bytes@^0.221.0": "jsr:@std/bytes@0.221.0", - "jsr:@std/fmt@^0.218.2": "jsr:@std/fmt@0.218.2", - "jsr:@std/fmt@^0.221.0": "jsr:@std/fmt@0.221.0", - "jsr:@std/fmt@^0.223.0": "jsr:@std/fmt@0.223.0", - "jsr:@std/fs@0.221.0": "jsr:@std/fs@0.221.0", - "jsr:@std/fs@^0.218.2": "jsr:@std/fs@0.218.2", - "jsr:@std/io@0.221.0": "jsr:@std/io@0.221.0", - "jsr:@std/io@^0.218.2": "jsr:@std/io@0.218.2", - "jsr:@std/io@^0.221.0": "jsr:@std/io@0.221.0", - "jsr:@std/path@0.221.0": "jsr:@std/path@0.221.0", - "jsr:@std/path@^0.218.2": "jsr:@std/path@0.218.2", - "jsr:@std/path@^0.221.0": "jsr:@std/path@0.221.0", - "jsr:@std/streams@0.221.0": "jsr:@std/streams@0.221.0", - "npm:browserslist@4.22.2": "npm:browserslist@4.22.2", - "npm:browserslist@4.23.0": "npm:browserslist@4.23.0", - "npm:lightningcss": "npm:lightningcss@1.24.1", - "npm:tailwindcss@3.4.1": "npm:tailwindcss@3.4.1_postcss@8.4.38", - "npm:tailwindcss@3.4.3": "npm:tailwindcss@3.4.3_postcss@8.4.38" - }, - "jsr": { - "@david/dax@0.40.0": { - "integrity": "1e0534a437e1d6c915979f19a3d048e5e2ce2a91176555a0ea1e89d929187279", - "dependencies": [ - "jsr:@david/which@0.3", - "jsr:@std/fmt@^0.221.0", - "jsr:@std/fs@0.221.0", - "jsr:@std/io@0.221.0", - "jsr:@std/path@0.221.0", - "jsr:@std/streams@0.221.0" - ] - }, - "@david/dax@0.40.1": { - "integrity": "0c71d32a0484d3904f586417995f8ec26d45144f0eba95d3e5bb03b640b6df59", - "dependencies": [ - "jsr:@david/which@0.3", - "jsr:@std/fmt@^0.221.0", - "jsr:@std/fs@0.221.0", - "jsr:@std/io@0.221.0", - "jsr:@std/path@0.221.0", - "jsr:@std/streams@0.221.0" - ] - }, - "@david/which@0.3.0": { - "integrity": "6bdb62c40ac90edcf328e854fa8103a8db21e7c326089cbe3c3a1cf7887d3204" - }, - "@deno/cache-dir@0.8.0": { - "integrity": "e87e80a404958f6350d903e6238b72afb92468378b0b32111f7a1e4916ac7fe7", - "dependencies": [ - "jsr:@deno/graph@^0.69.7", - "jsr:@std/fmt@^0.218.2", - "jsr:@std/fs@^0.218.2", - "jsr:@std/io@^0.218.2", - "jsr:@std/path@^0.218.2" - ] - }, - "@deno/graph@0.69.10": { - "integrity": "38fe22ac5686f6ece5daeec5a4df65c6314d7d32adcc33f77917a13cfaffa26f" - }, - "@deno/graph@0.73.1": { - "integrity": "cd69639d2709d479037d5ce191a422eabe8d71bb68b0098344f6b07411c84d41" - }, - "@std/assert@0.218.2": { - "integrity": "7f0a5a1a8cf86607cd6c2c030584096e1ffad27fc9271429a8cb48cfbdee5eaf" - }, - "@std/assert@0.221.0": { - "integrity": "a5f1aa6e7909dbea271754fd4ab3f4e687aeff4873b4cef9a320af813adb489a" - }, - "@std/assert@0.223.0": { - "integrity": "eb8d6d879d76e1cc431205bd346ed4d88dc051c6366365b1af47034b0670be24", - "dependencies": [ - "jsr:@std/fmt@^0.223.0" - ] - }, - "@std/bytes@0.218.2": { - "integrity": "91fe54b232dcca73856b79a817247f4a651dbb60d51baafafb6408c137241670" - }, - "@std/bytes@0.221.0": { - "integrity": "64a047011cf833890a4a2ab7293ac55a1b4f5a050624ebc6a0159c357de91966" - }, - "@std/fmt@0.218.2": { - "integrity": "99526449d2505aa758b6cbef81e7dd471d8b28ec0dcb1491d122b284c548788a" - }, - "@std/fmt@0.221.0": { - "integrity": "379fed69bdd9731110f26b9085aeb740606b20428ce6af31ef6bd45ef8efa62a" - }, - "@std/fmt@0.223.0": { - "integrity": "6deb37794127dfc7d7bded2586b9fc6f5d50e62a8134846608baf71ffc1a5208" - }, - "@std/fs@0.218.2": { - "integrity": "dd9431453f7282e8c577cc22c9e6d036055a9a980b5549f887d6012969fabcca" - }, - "@std/fs@0.221.0": { - "integrity": "028044450299de8ed5a716ade4e6d524399f035513b85913794f4e81f07da286", - "dependencies": [ - "jsr:@std/assert@^0.221.0", - "jsr:@std/path@^0.221.0" - ] - }, - "@std/io@0.218.2": { - "integrity": "c64fbfa087b7c9d4d386c5672f291f607d88cb7d44fc299c20c713e345f2785f", - "dependencies": [ - "jsr:@std/assert@^0.218.2", - "jsr:@std/bytes@^0.218.2" - ] - }, - "@std/io@0.221.0": { - "integrity": "faf7f8700d46ab527fa05cc6167f4b97701a06c413024431c6b4d207caa010da", - "dependencies": [ - "jsr:@std/assert@^0.221.0", - "jsr:@std/bytes@^0.221.0" - ] - }, - "@std/path@0.218.2": { - "integrity": "b568fd923d9e53ad76d17c513e7310bda8e755a3e825e6289a0ce536404e2662", - "dependencies": [ - "jsr:@std/assert@^0.218.2" - ] - }, - "@std/path@0.221.0": { - "integrity": "0a36f6b17314ef653a3a1649740cc8db51b25a133ecfe838f20b79a56ebe0095", - "dependencies": [ - "jsr:@std/assert@^0.221.0" - ] - }, - "@std/streams@0.221.0": { - "integrity": "47f2f74634b47449277c0ee79fe878da4424b66bd8975c032e3afdca88986e61", - "dependencies": [ - "jsr:@std/io@^0.221.0" - ] - } - }, - "npm": { - "@alloc/quick-lru@5.2.0": { - "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", - "dependencies": {} - }, - "@isaacs/cliui@8.0.2": { - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dependencies": { - "string-width": "string-width@5.1.2", - "string-width-cjs": "string-width@4.2.3", - "strip-ansi": "strip-ansi@7.1.0", - "strip-ansi-cjs": "strip-ansi@6.0.1", - "wrap-ansi": "wrap-ansi@8.1.0", - "wrap-ansi-cjs": "wrap-ansi@7.0.0" - } - }, - "@jridgewell/gen-mapping@0.3.5": { - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dependencies": { - "@jridgewell/set-array": "@jridgewell/set-array@1.2.1", - "@jridgewell/sourcemap-codec": "@jridgewell/sourcemap-codec@1.4.15", - "@jridgewell/trace-mapping": "@jridgewell/trace-mapping@0.3.25" - } - }, - "@jridgewell/resolve-uri@3.1.2": { - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dependencies": {} - }, - "@jridgewell/set-array@1.2.1": { - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dependencies": {} - }, - "@jridgewell/sourcemap-codec@1.4.15": { - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dependencies": {} - }, - "@jridgewell/trace-mapping@0.3.25": { - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dependencies": { - "@jridgewell/resolve-uri": "@jridgewell/resolve-uri@3.1.2", - "@jridgewell/sourcemap-codec": "@jridgewell/sourcemap-codec@1.4.15" - } - }, - "@nodelib/fs.scandir@2.1.5": { - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dependencies": { - "@nodelib/fs.stat": "@nodelib/fs.stat@2.0.5", - "run-parallel": "run-parallel@1.2.0" - } - }, - "@nodelib/fs.stat@2.0.5": { - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dependencies": {} - }, - "@nodelib/fs.walk@1.2.8": { - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dependencies": { - "@nodelib/fs.scandir": "@nodelib/fs.scandir@2.1.5", - "fastq": "fastq@1.17.1" - } - }, - "@pkgjs/parseargs@0.11.0": { - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dependencies": {} - }, - "ansi-regex@5.0.1": { - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dependencies": {} - }, - "ansi-regex@6.0.1": { - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dependencies": {} - }, - "ansi-styles@4.3.0": { - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "color-convert@2.0.1" - } - }, - "ansi-styles@6.2.1": { - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dependencies": {} - }, - "any-promise@1.3.0": { - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "dependencies": {} - }, - "anymatch@3.1.3": { - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dependencies": { - "normalize-path": "normalize-path@3.0.0", - "picomatch": "picomatch@2.3.1" - } - }, - "arg@5.0.2": { - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "dependencies": {} - }, - "balanced-match@1.0.2": { - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dependencies": {} - }, - "binary-extensions@2.3.0": { - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dependencies": {} - }, - "brace-expansion@2.0.1": { - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dependencies": { - "balanced-match": "balanced-match@1.0.2" - } - }, - "braces@3.0.2": { - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dependencies": { - "fill-range": "fill-range@7.0.1" - } - }, - "browserslist@4.22.2": { - "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", - "dependencies": { - "caniuse-lite": "caniuse-lite@1.0.30001611", - "electron-to-chromium": "electron-to-chromium@1.4.744", - "node-releases": "node-releases@2.0.14", - "update-browserslist-db": "update-browserslist-db@1.0.13_browserslist@4.22.2" - } - }, - "browserslist@4.23.0": { - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", - "dependencies": { - "caniuse-lite": "caniuse-lite@1.0.30001611", - "electron-to-chromium": "electron-to-chromium@1.4.744", - "node-releases": "node-releases@2.0.14", - "update-browserslist-db": "update-browserslist-db@1.0.13_browserslist@4.23.0" - } - }, - "camelcase-css@2.0.1": { - "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", - "dependencies": {} - }, - "caniuse-lite@1.0.30001611": { - "integrity": "sha512-19NuN1/3PjA3QI8Eki55N8my4LzfkMCRLgCVfrl/slbSAchQfV0+GwjPrK3rq37As4UCLlM/DHajbKkAqbv92Q==", - "dependencies": {} - }, - "chokidar@3.6.0": { - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dependencies": { - "anymatch": "anymatch@3.1.3", - "braces": "braces@3.0.2", - "fsevents": "fsevents@2.3.3", - "glob-parent": "glob-parent@5.1.2", - "is-binary-path": "is-binary-path@2.1.0", - "is-glob": "is-glob@4.0.3", - "normalize-path": "normalize-path@3.0.0", - "readdirp": "readdirp@3.6.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": {} - }, - "commander@4.1.1": { - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dependencies": {} - }, - "cross-spawn@7.0.3": { - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dependencies": { - "path-key": "path-key@3.1.1", - "shebang-command": "shebang-command@2.0.0", - "which": "which@2.0.2" - } - }, - "cssesc@3.0.0": { - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dependencies": {} - }, - "detect-libc@1.0.3": { - "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", - "dependencies": {} - }, - "didyoumean@1.2.2": { - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", - "dependencies": {} - }, - "dlv@1.1.3": { - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", - "dependencies": {} - }, - "eastasianwidth@0.2.0": { - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dependencies": {} - }, - "electron-to-chromium@1.4.744": { - "integrity": "sha512-nAGcF0yeKKfrP13LMFr5U1eghfFSvFLg302VUFzWlcjPOnUYd52yU5x6PBYrujhNbc4jYmZFrGZFK+xasaEzVA==", - "dependencies": {} - }, - "emoji-regex@8.0.0": { - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dependencies": {} - }, - "emoji-regex@9.2.2": { - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dependencies": {} - }, - "escalade@3.1.2": { - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "dependencies": {} - }, - "fast-glob@3.3.2": { - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dependencies": { - "@nodelib/fs.stat": "@nodelib/fs.stat@2.0.5", - "@nodelib/fs.walk": "@nodelib/fs.walk@1.2.8", - "glob-parent": "glob-parent@5.1.2", - "merge2": "merge2@1.4.1", - "micromatch": "micromatch@4.0.5" - } - }, - "fastq@1.17.1": { - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dependencies": { - "reusify": "reusify@1.0.4" - } - }, - "fill-range@7.0.1": { - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dependencies": { - "to-regex-range": "to-regex-range@5.0.1" - } - }, - "foreground-child@3.1.1": { - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", - "dependencies": { - "cross-spawn": "cross-spawn@7.0.3", - "signal-exit": "signal-exit@4.1.0" - } - }, - "fsevents@2.3.3": { - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dependencies": {} - }, - "function-bind@1.1.2": { - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dependencies": {} - }, - "glob-parent@5.1.2": { - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dependencies": { - "is-glob": "is-glob@4.0.3" - } - }, - "glob-parent@6.0.2": { - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dependencies": { - "is-glob": "is-glob@4.0.3" - } - }, - "glob@10.3.12": { - "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==", - "dependencies": { - "foreground-child": "foreground-child@3.1.1", - "jackspeak": "jackspeak@2.3.6", - "minimatch": "minimatch@9.0.4", - "minipass": "minipass@7.0.4", - "path-scurry": "path-scurry@1.10.2" - } - }, - "hasown@2.0.2": { - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dependencies": { - "function-bind": "function-bind@1.1.2" - } - }, - "is-binary-path@2.1.0": { - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dependencies": { - "binary-extensions": "binary-extensions@2.3.0" - } - }, - "is-core-module@2.13.1": { - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "dependencies": { - "hasown": "hasown@2.0.2" - } - }, - "is-extglob@2.1.1": { - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dependencies": {} - }, - "is-fullwidth-code-point@3.0.0": { - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dependencies": {} - }, - "is-glob@4.0.3": { - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dependencies": { - "is-extglob": "is-extglob@2.1.1" - } - }, - "is-number@7.0.0": { - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dependencies": {} - }, - "isexe@2.0.0": { - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dependencies": {} - }, - "jackspeak@2.3.6": { - "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", - "dependencies": { - "@isaacs/cliui": "@isaacs/cliui@8.0.2", - "@pkgjs/parseargs": "@pkgjs/parseargs@0.11.0" - } - }, - "jiti@1.21.0": { - "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", - "dependencies": {} - }, - "lightningcss-darwin-arm64@1.24.1": { - "integrity": "sha512-1jQ12jBy+AE/73uGQWGSafK5GoWgmSiIQOGhSEXiFJSZxzV+OXIx+a9h2EYHxdJfX864M+2TAxWPWb0Vv+8y4w==", - "dependencies": {} - }, - "lightningcss-darwin-x64@1.24.1": { - "integrity": "sha512-R4R1d7VVdq2mG4igMU+Di8GPf0b64ZLnYVkubYnGG0Qxq1KaXQtAzcLI43EkpnoWvB/kUg8JKCWH4S13NfiLcQ==", - "dependencies": {} - }, - "lightningcss-freebsd-x64@1.24.1": { - "integrity": "sha512-z6NberUUw5ALES6Ixn2shmjRRrM1cmEn1ZQPiM5IrZ6xHHL5a1lPin9pRv+w6eWfcrEo+qGG6R9XfJrpuY3e4g==", - "dependencies": {} - }, - "lightningcss-linux-arm-gnueabihf@1.24.1": { - "integrity": "sha512-NLQLnBQW/0sSg74qLNI8F8QKQXkNg4/ukSTa+XhtkO7v3BnK19TS1MfCbDHt+TTdSgNEBv0tubRuapcKho2EWw==", - "dependencies": {} - }, - "lightningcss-linux-arm64-gnu@1.24.1": { - "integrity": "sha512-AQxWU8c9E9JAjAi4Qw9CvX2tDIPjgzCTrZCSXKELfs4mCwzxRkHh2RCxX8sFK19RyJoJAjA/Kw8+LMNRHS5qEg==", - "dependencies": {} - }, - "lightningcss-linux-arm64-musl@1.24.1": { - "integrity": "sha512-JCgH/SrNrhqsguUA0uJUM1PvN5+dVuzPIlXcoWDHSv2OU/BWlj2dUYr3XNzEw748SmNZPfl2NjQrAdzaPOn1lA==", - "dependencies": {} - }, - "lightningcss-linux-x64-gnu@1.24.1": { - "integrity": "sha512-TYdEsC63bHV0h47aNRGN3RiK7aIeco3/keN4NkoSQ5T8xk09KHuBdySltWAvKLgT8JvR+ayzq8ZHnL1wKWY0rw==", - "dependencies": {} - }, - "lightningcss-linux-x64-musl@1.24.1": { - "integrity": "sha512-HLfzVik3RToot6pQ2Rgc3JhfZkGi01hFetHt40HrUMoeKitLoqUUT5owM6yTZPTytTUW9ukLBJ1pc3XNMSvlLw==", - "dependencies": {} - }, - "lightningcss-win32-x64-msvc@1.24.1": { - "integrity": "sha512-joEupPjYJ7PjZtDsS5lzALtlAudAbgIBMGJPNeFe5HfdmJXFd13ECmEM+5rXNxYVMRHua2w8132R6ab5Z6K9Ow==", - "dependencies": {} - }, - "lightningcss@1.24.1": { - "integrity": "sha512-kUpHOLiH5GB0ERSv4pxqlL0RYKnOXtgGtVe7shDGfhS0AZ4D1ouKFYAcLcZhql8aMspDNzaUCumGHZ78tb2fTg==", - "dependencies": { - "detect-libc": "detect-libc@1.0.3", - "lightningcss-darwin-arm64": "lightningcss-darwin-arm64@1.24.1", - "lightningcss-darwin-x64": "lightningcss-darwin-x64@1.24.1", - "lightningcss-freebsd-x64": "lightningcss-freebsd-x64@1.24.1", - "lightningcss-linux-arm-gnueabihf": "lightningcss-linux-arm-gnueabihf@1.24.1", - "lightningcss-linux-arm64-gnu": "lightningcss-linux-arm64-gnu@1.24.1", - "lightningcss-linux-arm64-musl": "lightningcss-linux-arm64-musl@1.24.1", - "lightningcss-linux-x64-gnu": "lightningcss-linux-x64-gnu@1.24.1", - "lightningcss-linux-x64-musl": "lightningcss-linux-x64-musl@1.24.1", - "lightningcss-win32-x64-msvc": "lightningcss-win32-x64-msvc@1.24.1" - } - }, - "lilconfig@2.1.0": { - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", - "dependencies": {} - }, - "lilconfig@3.1.1": { - "integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==", - "dependencies": {} - }, - "lines-and-columns@1.2.4": { - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dependencies": {} - }, - "lru-cache@10.2.0": { - "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", - "dependencies": {} - }, - "merge2@1.4.1": { - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dependencies": {} - }, - "micromatch@4.0.5": { - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dependencies": { - "braces": "braces@3.0.2", - "picomatch": "picomatch@2.3.1" - } - }, - "minimatch@9.0.4": { - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", - "dependencies": { - "brace-expansion": "brace-expansion@2.0.1" - } - }, - "minipass@7.0.4": { - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", - "dependencies": {} - }, - "mz@2.7.0": { - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dependencies": { - "any-promise": "any-promise@1.3.0", - "object-assign": "object-assign@4.1.1", - "thenify-all": "thenify-all@1.6.0" - } - }, - "nanoid@3.3.7": { - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "dependencies": {} - }, - "node-releases@2.0.14": { - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dependencies": {} - }, - "normalize-path@3.0.0": { - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dependencies": {} - }, - "object-assign@4.1.1": { - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dependencies": {} - }, - "object-hash@3.0.0": { - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "dependencies": {} - }, - "path-key@3.1.1": { - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dependencies": {} - }, - "path-parse@1.0.7": { - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dependencies": {} - }, - "path-scurry@1.10.2": { - "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==", - "dependencies": { - "lru-cache": "lru-cache@10.2.0", - "minipass": "minipass@7.0.4" - } - }, - "picocolors@1.0.0": { - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dependencies": {} - }, - "picomatch@2.3.1": { - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dependencies": {} - }, - "pify@2.3.0": { - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dependencies": {} - }, - "pirates@4.0.6": { - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", - "dependencies": {} - }, - "postcss-import@15.1.0_postcss@8.4.38": { - "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", - "dependencies": { - "postcss": "postcss@8.4.38", - "postcss-value-parser": "postcss-value-parser@4.2.0", - "read-cache": "read-cache@1.0.0", - "resolve": "resolve@1.22.8" - } - }, - "postcss-js@4.0.1_postcss@8.4.38": { - "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", - "dependencies": { - "camelcase-css": "camelcase-css@2.0.1", - "postcss": "postcss@8.4.38" - } - }, - "postcss-load-config@4.0.2_postcss@8.4.38": { - "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", - "dependencies": { - "lilconfig": "lilconfig@3.1.1", - "postcss": "postcss@8.4.38", - "yaml": "yaml@2.4.1" - } - }, - "postcss-nested@6.0.1_postcss@8.4.38": { - "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", - "dependencies": { - "postcss": "postcss@8.4.38", - "postcss-selector-parser": "postcss-selector-parser@6.0.16" - } - }, - "postcss-selector-parser@6.0.16": { - "integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==", - "dependencies": { - "cssesc": "cssesc@3.0.0", - "util-deprecate": "util-deprecate@1.0.2" - } - }, - "postcss-value-parser@4.2.0": { - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dependencies": {} - }, - "postcss@8.4.38": { - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", - "dependencies": { - "nanoid": "nanoid@3.3.7", - "picocolors": "picocolors@1.0.0", - "source-map-js": "source-map-js@1.2.0" - } - }, - "queue-microtask@1.2.3": { - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dependencies": {} - }, - "read-cache@1.0.0": { - "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "dependencies": { - "pify": "pify@2.3.0" - } - }, - "readdirp@3.6.0": { - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dependencies": { - "picomatch": "picomatch@2.3.1" - } - }, - "resolve@1.22.8": { - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dependencies": { - "is-core-module": "is-core-module@2.13.1", - "path-parse": "path-parse@1.0.7", - "supports-preserve-symlinks-flag": "supports-preserve-symlinks-flag@1.0.0" - } - }, - "reusify@1.0.4": { - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dependencies": {} - }, - "run-parallel@1.2.0": { - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dependencies": { - "queue-microtask": "queue-microtask@1.2.3" - } - }, - "shebang-command@2.0.0": { - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dependencies": { - "shebang-regex": "shebang-regex@3.0.0" - } - }, - "shebang-regex@3.0.0": { - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dependencies": {} - }, - "signal-exit@4.1.0": { - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dependencies": {} - }, - "source-map-js@1.2.0": { - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", - "dependencies": {} - }, - "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" - } - }, - "string-width@5.1.2": { - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dependencies": { - "eastasianwidth": "eastasianwidth@0.2.0", - "emoji-regex": "emoji-regex@9.2.2", - "strip-ansi": "strip-ansi@7.1.0" - } - }, - "strip-ansi@6.0.1": { - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "ansi-regex@5.0.1" - } - }, - "strip-ansi@7.1.0": { - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dependencies": { - "ansi-regex": "ansi-regex@6.0.1" - } - }, - "sucrase@3.35.0": { - "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", - "dependencies": { - "@jridgewell/gen-mapping": "@jridgewell/gen-mapping@0.3.5", - "commander": "commander@4.1.1", - "glob": "glob@10.3.12", - "lines-and-columns": "lines-and-columns@1.2.4", - "mz": "mz@2.7.0", - "pirates": "pirates@4.0.6", - "ts-interface-checker": "ts-interface-checker@0.1.13" - } - }, - "supports-preserve-symlinks-flag@1.0.0": { - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dependencies": {} - }, - "tailwindcss@3.4.1_postcss@8.4.38": { - "integrity": "sha512-qAYmXRfk3ENzuPBakNK0SRrUDipP8NQnEY6772uDhflcQz5EhRdD7JNZxyrFHVQNCwULPBn6FNPp9brpO7ctcA==", - "dependencies": { - "@alloc/quick-lru": "@alloc/quick-lru@5.2.0", - "arg": "arg@5.0.2", - "chokidar": "chokidar@3.6.0", - "didyoumean": "didyoumean@1.2.2", - "dlv": "dlv@1.1.3", - "fast-glob": "fast-glob@3.3.2", - "glob-parent": "glob-parent@6.0.2", - "is-glob": "is-glob@4.0.3", - "jiti": "jiti@1.21.0", - "lilconfig": "lilconfig@2.1.0", - "micromatch": "micromatch@4.0.5", - "normalize-path": "normalize-path@3.0.0", - "object-hash": "object-hash@3.0.0", - "picocolors": "picocolors@1.0.0", - "postcss": "postcss@8.4.38", - "postcss-import": "postcss-import@15.1.0_postcss@8.4.38", - "postcss-js": "postcss-js@4.0.1_postcss@8.4.38", - "postcss-load-config": "postcss-load-config@4.0.2_postcss@8.4.38", - "postcss-nested": "postcss-nested@6.0.1_postcss@8.4.38", - "postcss-selector-parser": "postcss-selector-parser@6.0.16", - "resolve": "resolve@1.22.8", - "sucrase": "sucrase@3.35.0" - } - }, - "tailwindcss@3.4.3_postcss@8.4.38": { - "integrity": "sha512-U7sxQk/n397Bmx4JHbJx/iSOOv5G+II3f1kpLpY2QeUv5DcPdcTsYLlusZfq1NthHS1c1cZoyFmmkex1rzke0A==", - "dependencies": { - "@alloc/quick-lru": "@alloc/quick-lru@5.2.0", - "arg": "arg@5.0.2", - "chokidar": "chokidar@3.6.0", - "didyoumean": "didyoumean@1.2.2", - "dlv": "dlv@1.1.3", - "fast-glob": "fast-glob@3.3.2", - "glob-parent": "glob-parent@6.0.2", - "is-glob": "is-glob@4.0.3", - "jiti": "jiti@1.21.0", - "lilconfig": "lilconfig@2.1.0", - "micromatch": "micromatch@4.0.5", - "normalize-path": "normalize-path@3.0.0", - "object-hash": "object-hash@3.0.0", - "picocolors": "picocolors@1.0.0", - "postcss": "postcss@8.4.38", - "postcss-import": "postcss-import@15.1.0_postcss@8.4.38", - "postcss-js": "postcss-js@4.0.1_postcss@8.4.38", - "postcss-load-config": "postcss-load-config@4.0.2_postcss@8.4.38", - "postcss-nested": "postcss-nested@6.0.1_postcss@8.4.38", - "postcss-selector-parser": "postcss-selector-parser@6.0.16", - "resolve": "resolve@1.22.8", - "sucrase": "sucrase@3.35.0" - } - }, - "thenify-all@1.6.0": { - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "dependencies": { - "thenify": "thenify@3.3.1" - } - }, - "thenify@3.3.1": { - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dependencies": { - "any-promise": "any-promise@1.3.0" - } - }, - "to-regex-range@5.0.1": { - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dependencies": { - "is-number": "is-number@7.0.0" - } - }, - "ts-interface-checker@0.1.13": { - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", - "dependencies": {} - }, - "update-browserslist-db@1.0.13_browserslist@4.22.2": { - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", - "dependencies": { - "browserslist": "browserslist@4.22.2", - "escalade": "escalade@3.1.2", - "picocolors": "picocolors@1.0.0" - } - }, - "update-browserslist-db@1.0.13_browserslist@4.23.0": { - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", - "dependencies": { - "browserslist": "browserslist@4.23.0", - "escalade": "escalade@3.1.2", - "picocolors": "picocolors@1.0.0" - } - }, - "util-deprecate@1.0.2": { - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dependencies": {} - }, - "which@2.0.2": { - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dependencies": { - "isexe": "isexe@2.0.0" - } - }, - "wrap-ansi@7.0.0": { - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "ansi-styles@4.3.0", - "string-width": "string-width@4.2.3", - "strip-ansi": "strip-ansi@6.0.1" - } - }, - "wrap-ansi@8.1.0": { - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dependencies": { - "ansi-styles": "ansi-styles@6.2.1", - "string-width": "string-width@5.1.2", - "strip-ansi": "strip-ansi@7.1.0" - } - }, - "yaml@2.4.1": { - "integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==", - "dependencies": {} - } + "version": "4", + "specifiers": { + "jsr:@david/dax@0.40.1": "0.40.1", + "jsr:@david/which@0.3": "0.3.0", + "jsr:@deno/cache-dir@0.14": "0.14.0", + "jsr:@deno/graph@0.82": "0.82.0", + "jsr:@deno/graph@0.86": "0.86.3", + "jsr:@deno/graph@~0.82.3": "0.82.3", + "jsr:@std/assert@0.221": "0.221.0", + "jsr:@std/assert@0.223": "0.223.0", + "jsr:@std/bytes@0.221": "0.221.0", + "jsr:@std/bytes@^1.0.2": "1.0.4", + "jsr:@std/fmt@0.221": "0.221.0", + "jsr:@std/fmt@0.223": "0.223.0", + "jsr:@std/fmt@^1.0.3": "1.0.3", + "jsr:@std/fs@0.221.0": "0.221.0", + "jsr:@std/fs@^1.0.6": "1.0.6", + "jsr:@std/io@0.221": "0.221.0", + "jsr:@std/io@0.221.0": "0.221.0", + "jsr:@std/io@0.225": "0.225.0", + "jsr:@std/path@0.221": "0.221.0", + "jsr:@std/path@0.221.0": "0.221.0", + "jsr:@std/path@^1.0.8": "1.0.8", + "jsr:@std/streams@0.221.0": "0.221.0", + "npm:browserslist@4.23.0": "4.23.0", + "npm:lightningcss@*": "1.26.0", + "npm:lightningcss@^1.26.0": "1.26.0", + "npm:tailwindcss@3.4.3": "3.4.3_postcss@8.4.41" + }, + "jsr": { + "@david/dax@0.40.1": { + "integrity": "0c71d32a0484d3904f586417995f8ec26d45144f0eba95d3e5bb03b640b6df59", + "dependencies": [ + "jsr:@david/which", + "jsr:@std/fmt@0.221", + "jsr:@std/fs@0.221.0", + "jsr:@std/io@0.221.0", + "jsr:@std/path@0.221.0", + "jsr:@std/streams" + ] + }, + "@david/which@0.3.0": { + "integrity": "6bdb62c40ac90edcf328e854fa8103a8db21e7c326089cbe3c3a1cf7887d3204" + }, + "@deno/cache-dir@0.14.0": { + "integrity": "729f0b68e7fc96443c09c2c544b830ca70897bdd5168598446d752f7a4c731ad", + "dependencies": [ + "jsr:@deno/graph@0.86", + "jsr:@std/fmt@^1.0.3", + "jsr:@std/fs@^1.0.6", + "jsr:@std/io@0.225", + "jsr:@std/path@^1.0.8" + ] + }, + "@deno/graph@0.82.0": { + "integrity": "b39c8ca479116ad32c338f7a1ba99ffd21c63792b0242d6f66b2f053945e3729" + }, + "@deno/graph@0.82.3": { + "integrity": "5c1fe944368172a9c87588ac81b82eb027ca78002a57521567e6264be322637e" + }, + "@deno/graph@0.86.3": { + "integrity": "e7974e83aafb4b110c80bd0b2249491e53429b011c741939bcbd68ce74c3985d" + }, + "@std/assert@0.221.0": { + "integrity": "a5f1aa6e7909dbea271754fd4ab3f4e687aeff4873b4cef9a320af813adb489a" + }, + "@std/assert@0.223.0": { + "integrity": "eb8d6d879d76e1cc431205bd346ed4d88dc051c6366365b1af47034b0670be24", + "dependencies": [ + "jsr:@std/fmt@0.223" + ] + }, + "@std/bytes@0.221.0": { + "integrity": "64a047011cf833890a4a2ab7293ac55a1b4f5a050624ebc6a0159c357de91966" + }, + "@std/bytes@1.0.4": { + "integrity": "11a0debe522707c95c7b7ef89b478c13fb1583a7cfb9a85674cd2cc2e3a28abc" + }, + "@std/fmt@0.221.0": { + "integrity": "379fed69bdd9731110f26b9085aeb740606b20428ce6af31ef6bd45ef8efa62a" + }, + "@std/fmt@0.223.0": { + "integrity": "6deb37794127dfc7d7bded2586b9fc6f5d50e62a8134846608baf71ffc1a5208" + }, + "@std/fmt@1.0.3": { + "integrity": "97765c16aa32245ff4e2204ecf7d8562496a3cb8592340a80e7e554e0bb9149f" + }, + "@std/fs@0.221.0": { + "integrity": "028044450299de8ed5a716ade4e6d524399f035513b85913794f4e81f07da286", + "dependencies": [ + "jsr:@std/assert@0.221", + "jsr:@std/path@0.221" + ] + }, + "@std/fs@1.0.6": { + "integrity": "42b56e1e41b75583a21d5a37f6a6a27de9f510bcd36c0c85791d685ca0b85fa2" + }, + "@std/io@0.221.0": { + "integrity": "faf7f8700d46ab527fa05cc6167f4b97701a06c413024431c6b4d207caa010da", + "dependencies": [ + "jsr:@std/assert@0.221", + "jsr:@std/bytes@0.221" + ] + }, + "@std/io@0.225.0": { + "integrity": "c1db7c5e5a231629b32d64b9a53139445b2ca640d828c26bf23e1c55f8c079b3", + "dependencies": [ + "jsr:@std/bytes@^1.0.2" + ] + }, + "@std/path@0.221.0": { + "integrity": "0a36f6b17314ef653a3a1649740cc8db51b25a133ecfe838f20b79a56ebe0095", + "dependencies": [ + "jsr:@std/assert@0.221" + ] + }, + "@std/path@1.0.8": { + "integrity": "548fa456bb6a04d3c1a1e7477986b6cffbce95102d0bb447c67c4ee70e0364be" + }, + "@std/streams@0.221.0": { + "integrity": "47f2f74634b47449277c0ee79fe878da4424b66bd8975c032e3afdca88986e61", + "dependencies": [ + "jsr:@std/io@0.221" + ] + } + }, + "npm": { + "@alloc/quick-lru@5.2.0": { + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==" + }, + "@isaacs/cliui@8.0.2": { + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dependencies": [ + "string-width@5.1.2", + "string-width-cjs@npm:string-width@4.2.3", + "strip-ansi@7.1.0", + "strip-ansi-cjs@npm:strip-ansi@6.0.1", + "wrap-ansi@8.1.0", + "wrap-ansi-cjs@npm:wrap-ansi@7.0.0" + ] + }, + "@jridgewell/gen-mapping@0.3.5": { + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dependencies": [ + "@jridgewell/set-array", + "@jridgewell/sourcemap-codec", + "@jridgewell/trace-mapping" + ] + }, + "@jridgewell/resolve-uri@3.1.2": { + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==" + }, + "@jridgewell/set-array@1.2.1": { + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==" + }, + "@jridgewell/sourcemap-codec@1.5.0": { + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" + }, + "@jridgewell/trace-mapping@0.3.25": { + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dependencies": [ + "@jridgewell/resolve-uri", + "@jridgewell/sourcemap-codec" + ] + }, + "@nodelib/fs.scandir@2.1.5": { + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": [ + "@nodelib/fs.stat", + "run-parallel" + ] + }, + "@nodelib/fs.stat@2.0.5": { + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" + }, + "@nodelib/fs.walk@1.2.8": { + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": [ + "@nodelib/fs.scandir", + "fastq" + ] + }, + "@pkgjs/parseargs@0.11.0": { + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==" + }, + "ansi-regex@5.0.1": { + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "ansi-regex@6.0.1": { + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==" + }, + "ansi-styles@4.3.0": { + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": [ + "color-convert" + ] + }, + "ansi-styles@6.2.1": { + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==" + }, + "any-promise@1.3.0": { + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" + }, + "anymatch@3.1.3": { + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": [ + "normalize-path", + "picomatch" + ] + }, + "arg@5.0.2": { + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + }, + "balanced-match@1.0.2": { + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "binary-extensions@2.3.0": { + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==" + }, + "brace-expansion@2.0.1": { + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": [ + "balanced-match" + ] + }, + "braces@3.0.3": { + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dependencies": [ + "fill-range" + ] + }, + "browserslist@4.23.0": { + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "dependencies": [ + "caniuse-lite", + "electron-to-chromium", + "node-releases", + "update-browserslist-db" + ] + }, + "camelcase-css@2.0.1": { + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==" + }, + "caniuse-lite@1.0.30001653": { + "integrity": "sha512-XGWQVB8wFQ2+9NZwZ10GxTYC5hk0Fa+q8cSkr0tgvMhYhMHP/QC+WTgrePMDBWiWc/pV+1ik82Al20XOK25Gcw==" + }, + "chokidar@3.6.0": { + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dependencies": [ + "anymatch", + "braces", + "fsevents", + "glob-parent@5.1.2", + "is-binary-path", + "is-glob", + "normalize-path", + "readdirp" + ] + }, + "color-convert@2.0.1": { + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": [ + "color-name" + ] + }, + "color-name@1.1.4": { + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "commander@4.1.1": { + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==" + }, + "cross-spawn@7.0.3": { + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": [ + "path-key", + "shebang-command", + "which" + ] + }, + "cssesc@3.0.0": { + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" + }, + "detect-libc@1.0.3": { + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==" + }, + "didyoumean@1.2.2": { + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" + }, + "dlv@1.1.3": { + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" + }, + "eastasianwidth@0.2.0": { + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, + "electron-to-chromium@1.5.13": { + "integrity": "sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==" + }, + "emoji-regex@8.0.0": { + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "emoji-regex@9.2.2": { + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "escalade@3.1.2": { + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==" + }, + "fast-glob@3.3.2": { + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dependencies": [ + "@nodelib/fs.stat", + "@nodelib/fs.walk", + "glob-parent@5.1.2", + "merge2", + "micromatch" + ] + }, + "fastq@1.17.1": { + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dependencies": [ + "reusify" + ] + }, + "fill-range@7.1.1": { + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dependencies": [ + "to-regex-range" + ] + }, + "foreground-child@3.3.0": { + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "dependencies": [ + "cross-spawn", + "signal-exit" + ] + }, + "fsevents@2.3.3": { + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==" + }, + "function-bind@1.1.2": { + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "glob-parent@5.1.2": { + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": [ + "is-glob" + ] + }, + "glob-parent@6.0.2": { + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dependencies": [ + "is-glob" + ] + }, + "glob@10.4.5": { + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dependencies": [ + "foreground-child", + "jackspeak", + "minimatch", + "minipass", + "package-json-from-dist", + "path-scurry" + ] + }, + "hasown@2.0.2": { + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": [ + "function-bind" + ] + }, + "is-binary-path@2.1.0": { + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": [ + "binary-extensions" + ] + }, + "is-core-module@2.15.1": { + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "dependencies": [ + "hasown" + ] + }, + "is-extglob@2.1.1": { + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" + }, + "is-fullwidth-code-point@3.0.0": { + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "is-glob@4.0.3": { + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": [ + "is-extglob" + ] + }, + "is-number@7.0.0": { + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "isexe@2.0.0": { + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "jackspeak@3.4.3": { + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dependencies": [ + "@isaacs/cliui", + "@pkgjs/parseargs" + ] + }, + "jiti@1.21.6": { + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==" + }, + "lightningcss-darwin-arm64@1.26.0": { + "integrity": "sha512-n4TIvHO1NY1ondKFYpL2ZX0bcC2y6yjXMD6JfyizgR8BCFNEeArINDzEaeqlfX9bXz73Bpz/Ow0nu+1qiDrBKg==" + }, + "lightningcss-darwin-x64@1.26.0": { + "integrity": "sha512-Rf9HuHIDi1R6/zgBkJh25SiJHF+dm9axUZW/0UoYCW1/8HV0gMI0blARhH4z+REmWiU1yYT/KyNF3h7tHyRXUg==" + }, + "lightningcss-freebsd-x64@1.26.0": { + "integrity": "sha512-C/io7POAxp6sZxFSVGezjajMlCKQ8KSwISLLGRq8xLQpQMokYrUoqYEwmIX8mLmF6C/CZPk0gFmRSzd8biWM0g==" + }, + "lightningcss-linux-arm-gnueabihf@1.26.0": { + "integrity": "sha512-Aag9kqXqkyPSW+dXMgyWk66C984Nay2pY8Nws+67gHlDzV3cWh7TvFlzuaTaVFMVqdDTzN484LSK3u39zFBnzg==" + }, + "lightningcss-linux-arm64-gnu@1.26.0": { + "integrity": "sha512-iJmZM7fUyVjH+POtdiCtExG+67TtPUTer7K/5A8DIfmPfrmeGvzfRyBltGhQz13Wi15K1lf2cPYoRaRh6vcwNA==" + }, + "lightningcss-linux-arm64-musl@1.26.0": { + "integrity": "sha512-XxoEL++tTkyuvu+wq/QS8bwyTXZv2y5XYCMcWL45b8XwkiS8eEEEej9BkMGSRwxa5J4K+LDeIhLrS23CpQyfig==" + }, + "lightningcss-linux-x64-gnu@1.26.0": { + "integrity": "sha512-1dkTfZQAYLj8MUSkd6L/+TWTG8V6Kfrzfa0T1fSlXCXQHrt1HC1/UepXHtKHDt/9yFwyoeayivxXAsApVxn6zA==" + }, + "lightningcss-linux-x64-musl@1.26.0": { + "integrity": "sha512-yX3Rk9m00JGCUzuUhFEojY+jf/6zHs3XU8S8Vk+FRbnr4St7cjyMXdNjuA2LjiT8e7j8xHRCH8hyZ4H/btRE4A==" + }, + "lightningcss-win32-arm64-msvc@1.26.0": { + "integrity": "sha512-X/597/cFnCogy9VItj/+7Tgu5VLbAtDF7KZDPdSw0MaL6FL940th1y3HiOzFIlziVvAtbo0RB3NAae1Oofr+Tw==" + }, + "lightningcss-win32-x64-msvc@1.26.0": { + "integrity": "sha512-pYS3EyGP3JRhfqEFYmfFDiZ9/pVNfy8jVIYtrx9TVNusVyDK3gpW1w/rbvroQ4bDJi7grdUtyrYU6V2xkY/bBw==" + }, + "lightningcss@1.26.0": { + "integrity": "sha512-a/XZ5hdgifrofQJUArr5AiJjx26SwMam3SJUSMjgebZbESZ96i+6Qsl8tLi0kaUsdMzBWXh9sN1Oe6hp2/dkQw==", + "dependencies": [ + "detect-libc", + "lightningcss-darwin-arm64", + "lightningcss-darwin-x64", + "lightningcss-freebsd-x64", + "lightningcss-linux-arm-gnueabihf", + "lightningcss-linux-arm64-gnu", + "lightningcss-linux-arm64-musl", + "lightningcss-linux-x64-gnu", + "lightningcss-linux-x64-musl", + "lightningcss-win32-arm64-msvc", + "lightningcss-win32-x64-msvc" + ] + }, + "lilconfig@2.1.0": { + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==" + }, + "lilconfig@3.1.2": { + "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==" + }, + "lines-and-columns@1.2.4": { + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "lru-cache@10.4.3": { + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" + }, + "merge2@1.4.1": { + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" + }, + "micromatch@4.0.8": { + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dependencies": [ + "braces", + "picomatch" + ] + }, + "minimatch@9.0.5": { + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dependencies": [ + "brace-expansion" + ] + }, + "minipass@7.1.2": { + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==" + }, + "mz@2.7.0": { + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dependencies": [ + "any-promise", + "object-assign", + "thenify-all" + ] + }, + "nanoid@3.3.7": { + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==" + }, + "node-releases@2.0.18": { + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==" + }, + "normalize-path@3.0.0": { + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "object-assign@4.1.1": { + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" + }, + "object-hash@3.0.0": { + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==" + }, + "package-json-from-dist@1.0.0": { + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==" + }, + "path-key@3.1.1": { + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "path-parse@1.0.7": { + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "path-scurry@1.11.1": { + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dependencies": [ + "lru-cache", + "minipass" + ] + }, + "picocolors@1.0.1": { + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" + }, + "picomatch@2.3.1": { + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" + }, + "pify@2.3.0": { + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==" + }, + "pirates@4.0.6": { + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==" + }, + "postcss-import@15.1.0_postcss@8.4.41": { + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dependencies": [ + "postcss", + "postcss-value-parser", + "read-cache", + "resolve" + ] + }, + "postcss-js@4.0.1_postcss@8.4.41": { + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dependencies": [ + "camelcase-css", + "postcss" + ] + }, + "postcss-load-config@4.0.2_postcss@8.4.41": { + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "dependencies": [ + "lilconfig@3.1.2", + "postcss", + "yaml" + ] + }, + "postcss-nested@6.2.0_postcss@8.4.41": { + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "dependencies": [ + "postcss", + "postcss-selector-parser" + ] + }, + "postcss-selector-parser@6.1.2": { + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dependencies": [ + "cssesc", + "util-deprecate" + ] + }, + "postcss-value-parser@4.2.0": { + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + }, + "postcss@8.4.41": { + "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==", + "dependencies": [ + "nanoid", + "picocolors", + "source-map-js" + ] + }, + "queue-microtask@1.2.3": { + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" + }, + "read-cache@1.0.0": { + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dependencies": [ + "pify" + ] + }, + "readdirp@3.6.0": { + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": [ + "picomatch" + ] + }, + "resolve@1.22.8": { + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dependencies": [ + "is-core-module", + "path-parse", + "supports-preserve-symlinks-flag" + ] + }, + "reusify@1.0.4": { + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" + }, + "run-parallel@1.2.0": { + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dependencies": [ + "queue-microtask" + ] + }, + "shebang-command@2.0.0": { + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": [ + "shebang-regex" + ] + }, + "shebang-regex@3.0.0": { + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "signal-exit@4.1.0": { + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" + }, + "source-map-js@1.2.0": { + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==" + }, + "string-width@4.2.3": { + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": [ + "emoji-regex@8.0.0", + "is-fullwidth-code-point", + "strip-ansi@6.0.1" + ] + }, + "string-width@5.1.2": { + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dependencies": [ + "eastasianwidth", + "emoji-regex@9.2.2", + "strip-ansi@7.1.0" + ] + }, + "strip-ansi@6.0.1": { + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": [ + "ansi-regex@5.0.1" + ] + }, + "strip-ansi@7.1.0": { + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": [ + "ansi-regex@6.0.1" + ] + }, + "sucrase@3.35.0": { + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dependencies": [ + "@jridgewell/gen-mapping", + "commander", + "glob", + "lines-and-columns", + "mz", + "pirates", + "ts-interface-checker" + ] + }, + "supports-preserve-symlinks-flag@1.0.0": { + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + }, + "tailwindcss@3.4.3_postcss@8.4.41": { + "integrity": "sha512-U7sxQk/n397Bmx4JHbJx/iSOOv5G+II3f1kpLpY2QeUv5DcPdcTsYLlusZfq1NthHS1c1cZoyFmmkex1rzke0A==", + "dependencies": [ + "@alloc/quick-lru", + "arg", + "chokidar", + "didyoumean", + "dlv", + "fast-glob", + "glob-parent@6.0.2", + "is-glob", + "jiti", + "lilconfig@2.1.0", + "micromatch", + "normalize-path", + "object-hash", + "picocolors", + "postcss", + "postcss-import", + "postcss-js", + "postcss-load-config", + "postcss-nested", + "postcss-selector-parser", + "resolve", + "sucrase" + ] + }, + "thenify-all@1.6.0": { + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dependencies": [ + "thenify" + ] + }, + "thenify@3.3.1": { + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dependencies": [ + "any-promise" + ] + }, + "to-regex-range@5.0.1": { + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": [ + "is-number" + ] + }, + "ts-interface-checker@0.1.13": { + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" + }, + "update-browserslist-db@1.1.0_browserslist@4.23.0": { + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "dependencies": [ + "browserslist", + "escalade", + "picocolors" + ] + }, + "util-deprecate@1.0.2": { + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "which@2.0.2": { + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": [ + "isexe" + ] + }, + "wrap-ansi@7.0.0": { + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": [ + "ansi-styles@4.3.0", + "string-width@4.2.3", + "strip-ansi@6.0.1" + ] + }, + "wrap-ansi@8.1.0": { + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dependencies": [ + "ansi-styles@6.2.1", + "string-width@5.1.2", + "strip-ansi@7.1.0" + ] + }, + "yaml@2.5.0": { + "integrity": "sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==" } }, - "remote": { - "https://deno.land/std@0.209.0/assert/assert.ts": "e265ad50a9341f3b40e51dd4cb41ab253d976943ba78a977106950e52e0302ab", - "https://deno.land/std@0.209.0/assert/assertion_error.ts": "26ed1863d905005f00785c89750c001c3522c5417e4f58f95044b8143cfc1593", - "https://deno.land/std@0.209.0/bytes/copy.ts": "939d89e302a9761dcf1d9c937c7711174ed74c59eef40a1e4569a05c9de88219", - "https://deno.land/std@0.209.0/fmt/colors.ts": "34b3f77432925eb72cf0bfb351616949746768620b8e5ead66da532f93d10ba2", - "https://deno.land/std@0.209.0/fs/_util.ts": "b03c46be986540a23916918fe0c01e257909e34be371943812001792859e22be", - "https://deno.land/std@0.209.0/fs/copy.ts": "b6006efcf5643445dcd21c8d4c4d66fcc18e05aefffa08a92fc60d7751370926", - "https://deno.land/std@0.209.0/fs/empty_dir.ts": "7fba29ef2d03f3503cd512616efc0535984cf1bbe7ca9d098e8b4d0d88910120", - "https://deno.land/std@0.209.0/fs/ensure_dir.ts": "dc64c4c75c64721d4e3fb681f1382f803ff3d2868f08563ff923fdd20d071c40", - "https://deno.land/std@0.209.0/fs/ensure_file.ts": "d13c265aa80cc52d0006a02a42d73121c4e71fded0f315ffdf3625bf9ecfb4a0", - "https://deno.land/std@0.209.0/fs/ensure_link.ts": "c15e69c48556d78aae31b83e0c0ece04b7b8bc0951412f5b759aceb6fde7f0ac", - "https://deno.land/std@0.209.0/fs/ensure_symlink.ts": "b389c8568f0656d145ac7ece472afe710815cccbb2ebfd19da7978379ae143fe", - "https://deno.land/std@0.209.0/fs/eol.ts": "27516caa5b0f703bc67817493d07b9eb861b1a8bb8dfe52f73a011ae6e58e7d5", - "https://deno.land/std@0.209.0/fs/exists.ts": "da38bab3cd416131a2075c1a532c69b0b634c2ce8d75222355aa6d3d15995199", - "https://deno.land/std@0.209.0/fs/expand_glob.ts": "18f2cc51741afef3de4ee7f64b71a31cda1b9137e2bb7d2dc3b91dcd20e94412", - "https://deno.land/std@0.209.0/fs/mod.ts": "bc3d0acd488cc7b42627044caf47d72019846d459279544e1934418955ba4898", - "https://deno.land/std@0.209.0/fs/move.ts": "0c4b2651386dd7238e11830697a2592c7b86228039c132b5776810e9ea8abc2a", - "https://deno.land/std@0.209.0/fs/walk.ts": "999a272d5baa9d89d178d8099c88ea765e56da1e65f425f18dabca7c6fbd6821", - "https://deno.land/std@0.209.0/io/buf_reader.ts": "d0575c7786a5eb9b6f4ed560a400c987b5d1bac2724ad8c352a644b7baff9791", - "https://deno.land/std@0.209.0/io/buffer.ts": "b2ea4d33cd8d1f306d720a4768676382b9462fc0d0cf56b5f7bc2a33ea423b10", - "https://deno.land/std@0.209.0/path/_common/assert_path.ts": "061e4d093d4ba5aebceb2c4da3318bfe3289e868570e9d3a8e327d91c2958946", - "https://deno.land/std@0.209.0/path/_common/basename.ts": "0d978ff818f339cd3b1d09dc914881f4d15617432ae519c1b8fdc09ff8d3789a", - "https://deno.land/std@0.209.0/path/_common/common.ts": "9e4233b2eeb50f8b2ae10ecc2108f58583aea6fd3e8907827020282dc2b76143", - "https://deno.land/std@0.209.0/path/_common/constants.ts": "e49961f6f4f48039c0dfed3c3f93e963ca3d92791c9d478ac5b43183413136e0", - "https://deno.land/std@0.209.0/path/_common/dirname.ts": "2ba7fb4cc9fafb0f38028f434179579ce61d4d9e51296fad22b701c3d3cd7397", - "https://deno.land/std@0.209.0/path/_common/format.ts": "11aa62e316dfbf22c126917f5e03ea5fe2ee707386555a8f513d27ad5756cf96", - "https://deno.land/std@0.209.0/path/_common/from_file_url.ts": "ef1bf3197d2efbf0297a2bdbf3a61d804b18f2bcce45548ae112313ec5be3c22", - "https://deno.land/std@0.209.0/path/_common/glob_to_reg_exp.ts": "50386887d6041f15741d0013a703ee63ef673983d465d3a0c9c190e95f8da4fe", - "https://deno.land/std@0.209.0/path/_common/normalize.ts": "2ba7fb4cc9fafb0f38028f434179579ce61d4d9e51296fad22b701c3d3cd7397", - "https://deno.land/std@0.209.0/path/_common/normalize_string.ts": "88c472f28ae49525f9fe82de8c8816d93442d46a30d6bb5063b07ff8a89ff589", - "https://deno.land/std@0.209.0/path/_common/relative.ts": "1af19d787a2a84b8c534cc487424fe101f614982ae4851382c978ab2216186b4", - "https://deno.land/std@0.209.0/path/_common/strip_trailing_separators.ts": "7ffc7c287e97bdeeee31b155828686967f222cd73f9e5780bfe7dfb1b58c6c65", - "https://deno.land/std@0.209.0/path/_common/to_file_url.ts": "a8cdd1633bc9175b7eebd3613266d7c0b6ae0fb0cff24120b6092ac31662f9ae", - "https://deno.land/std@0.209.0/path/_interface.ts": "6471159dfbbc357e03882c2266d21ef9afdb1e4aa771b0545e90db58a0ba314b", - "https://deno.land/std@0.209.0/path/_os.ts": "30b0c2875f360c9296dbe6b7f2d528f0f9c741cecad2e97f803f5219e91b40a2", - "https://deno.land/std@0.209.0/path/basename.ts": "04bb5ef3e86bba8a35603b8f3b69537112cdd19ce64b77f2522006da2977a5f3", - "https://deno.land/std@0.209.0/path/common.ts": "f4d061c7d0b95a65c2a1a52439edec393e906b40f1caf4604c389fae7caa80f5", - "https://deno.land/std@0.209.0/path/dirname.ts": "88a0a71c21debafc4da7a4cd44fd32e899462df458fbca152390887d41c40361", - "https://deno.land/std@0.209.0/path/extname.ts": "2da4e2490f3b48b7121d19fb4c91681a5e11bd6bd99df4f6f47d7a71bb6ecdf2", - "https://deno.land/std@0.209.0/path/format.ts": "3457530cc85d1b4bab175f9ae73998b34fd456c830d01883169af0681b8894fb", - "https://deno.land/std@0.209.0/path/from_file_url.ts": "e7fa233ea1dff9641e8d566153a24d95010110185a6f418dd2e32320926043f8", - "https://deno.land/std@0.209.0/path/glob.ts": "a00a81a55c02bbe074ab21a50b6495c6f7795f54cd718c824adaa92c6c9b7419", - "https://deno.land/std@0.209.0/path/glob_to_regexp.ts": "74d7448c471e293d03f05ccb968df4365fed6aaa508506b6325a8efdc01d8271", - "https://deno.land/std@0.209.0/path/is_absolute.ts": "67232b41b860571c5b7537f4954c88d86ae2ba45e883ee37d3dec27b74909d13", - "https://deno.land/std@0.209.0/path/is_glob.ts": "567dce5c6656bdedfc6b3ee6c0833e1e4db2b8dff6e62148e94a917f289c06ad", - "https://deno.land/std@0.209.0/path/join.ts": "98d3d76c819af4a11a81d5ba2dbb319f1ce9d63fc2b615597d4bcfddd4a89a09", - "https://deno.land/std@0.209.0/path/join_globs.ts": "9b84d5103b63d3dbed4b2cf8b12477b2ad415c7d343f1488505162dc0e5f4db8", - "https://deno.land/std@0.209.0/path/mod.ts": "3defabebc98279e62b392fee7a6937adc932a8f4dcd2471441e36c15b97b00e0", - "https://deno.land/std@0.209.0/path/normalize.ts": "aa95be9a92c7bd4f9dc0ba51e942a1973e2b93d266cd74f5ca751c136d520b66", - "https://deno.land/std@0.209.0/path/normalize_glob.ts": "674baa82e1c00b6cb153bbca36e06f8e0337cb8062db6d905ab5de16076ca46b", - "https://deno.land/std@0.209.0/path/parse.ts": "d87ff0deef3fb495bc0d862278ff96da5a06acf0625ca27769fc52ac0d3d6ece", - "https://deno.land/std@0.209.0/path/posix/_util.ts": "ecf49560fedd7dd376c6156cc5565cad97c1abe9824f4417adebc7acc36c93e5", - "https://deno.land/std@0.209.0/path/posix/basename.ts": "a630aeb8fd8e27356b1823b9dedd505e30085015407caa3396332752f6b8406a", - "https://deno.land/std@0.209.0/path/posix/common.ts": "e781d395dc76f6282e3f7dd8de13194abb8b04a82d109593141abc6e95755c8b", - "https://deno.land/std@0.209.0/path/posix/dirname.ts": "f48c9c42cc670803b505478b7ef162c7cfa9d8e751b59d278b2ec59470531472", - "https://deno.land/std@0.209.0/path/posix/extname.ts": "ee7f6571a9c0a37f9218fbf510c440d1685a7c13082c348d701396cc795e0be0", - "https://deno.land/std@0.209.0/path/posix/format.ts": "b94876f77e61bfe1f147d5ccb46a920636cd3cef8be43df330f0052b03875968", - "https://deno.land/std@0.209.0/path/posix/from_file_url.ts": "b97287a83e6407ac27bdf3ab621db3fccbf1c27df0a1b1f20e1e1b5acf38a379", - "https://deno.land/std@0.209.0/path/posix/glob_to_regexp.ts": "6ed00c71fbfe0ccc35977c35444f94e82200b721905a60bd1278b1b768d68b1a", - "https://deno.land/std@0.209.0/path/posix/is_absolute.ts": "159900a3422d11069d48395568217eb7fc105ceda2683d03d9b7c0f0769e01b8", - "https://deno.land/std@0.209.0/path/posix/is_glob.ts": "ec4fbc604b9db8487f7b56ab0e759b24a971ab6a45f7b0b698bc39b8b9f9680f", - "https://deno.land/std@0.209.0/path/posix/join.ts": "0c0d84bdc344876930126640011ec1b888e6facf74153ffad9ef26813aa2a076", - "https://deno.land/std@0.209.0/path/posix/join_globs.ts": "f4838d54b1f60a34a40625a3293f6e583135348be1b2974341ac04743cb26121", - "https://deno.land/std@0.209.0/path/posix/mod.ts": "f1b08a7f64294b7de87fc37190d63b6ce5b02889af9290c9703afe01951360ae", - "https://deno.land/std@0.209.0/path/posix/normalize.ts": "11de90a94ab7148cc46e5a288f7d732aade1d616bc8c862f5560fa18ff987b4b", - "https://deno.land/std@0.209.0/path/posix/normalize_glob.ts": "10a1840c628ebbab679254d5fa1c20e59106102354fb648a1765aed72eb9f3f9", - "https://deno.land/std@0.209.0/path/posix/parse.ts": "199208f373dd93a792e9c585352bfc73a6293411bed6da6d3bc4f4ef90b04c8e", - "https://deno.land/std@0.209.0/path/posix/relative.ts": "e2f230608b0f083e6deaa06e063943e5accb3320c28aef8d87528fbb7fe6504c", - "https://deno.land/std@0.209.0/path/posix/resolve.ts": "51579d83159d5c719518c9ae50812a63959bbcb7561d79acbdb2c3682236e285", - "https://deno.land/std@0.209.0/path/posix/separator.ts": "0b6573b5f3269a3164d8edc9cefc33a02dd51003731c561008c8bb60220ebac1", - "https://deno.land/std@0.209.0/path/posix/to_file_url.ts": "08d43ea839ee75e9b8b1538376cfe95911070a655cd312bc9a00f88ef14967b6", - "https://deno.land/std@0.209.0/path/posix/to_namespaced_path.ts": "c9228a0e74fd37e76622cd7b142b8416663a9b87db643302fa0926b5a5c83bdc", - "https://deno.land/std@0.209.0/path/relative.ts": "23d45ede8b7ac464a8299663a43488aad6b561414e7cbbe4790775590db6349c", - "https://deno.land/std@0.209.0/path/resolve.ts": "5b184efc87155a0af9fa305ff68a109e28de9aee81fc3e77cd01380f19daf867", - "https://deno.land/std@0.209.0/path/separator.ts": "40a3e9a4ad10bef23bc2cd6c610291b6c502a06237c2c4cd034a15ca78dedc1f", - "https://deno.land/std@0.209.0/path/to_file_url.ts": "edaafa089e0bce386e1b2d47afe7c72e379ff93b28a5829a5885e4b6c626d864", - "https://deno.land/std@0.209.0/path/to_namespaced_path.ts": "cf8734848aac3c7527d1689d2adf82132b1618eff3cc523a775068847416b22a", - "https://deno.land/std@0.209.0/path/windows/_util.ts": "f32b9444554c8863b9b4814025c700492a2b57ff2369d015360970a1b1099d54", - "https://deno.land/std@0.209.0/path/windows/basename.ts": "8a9dbf7353d50afbc5b221af36c02a72c2d1b2b5b9f7c65bf6a5a2a0baf88ad3", - "https://deno.land/std@0.209.0/path/windows/common.ts": "e781d395dc76f6282e3f7dd8de13194abb8b04a82d109593141abc6e95755c8b", - "https://deno.land/std@0.209.0/path/windows/dirname.ts": "5c2aa541384bf0bd9aca821275d2a8690e8238fa846198ef5c7515ce31a01a94", - "https://deno.land/std@0.209.0/path/windows/extname.ts": "07f4fa1b40d06a827446b3e3bcc8d619c5546b079b8ed0c77040bbef716c7614", - "https://deno.land/std@0.209.0/path/windows/format.ts": "343019130d78f172a5c49fdc7e64686a7faf41553268961e7b6c92a6d6548edf", - "https://deno.land/std@0.209.0/path/windows/from_file_url.ts": "d53335c12b0725893d768be3ac6bf0112cc5b639d2deb0171b35988493b46199", - "https://deno.land/std@0.209.0/path/windows/glob_to_regexp.ts": "290755e18ec6c1a4f4d711c3390537358e8e3179581e66261a0cf348b1a13395", - "https://deno.land/std@0.209.0/path/windows/is_absolute.ts": "245b56b5f355ede8664bd7f080c910a97e2169972d23075554ae14d73722c53c", - "https://deno.land/std@0.209.0/path/windows/is_glob.ts": "ec4fbc604b9db8487f7b56ab0e759b24a971ab6a45f7b0b698bc39b8b9f9680f", - "https://deno.land/std@0.209.0/path/windows/join.ts": "e6600bf88edeeef4e2276e155b8de1d5dec0435fd526ba2dc4d37986b2882f16", - "https://deno.land/std@0.209.0/path/windows/join_globs.ts": "f4838d54b1f60a34a40625a3293f6e583135348be1b2974341ac04743cb26121", - "https://deno.land/std@0.209.0/path/windows/mod.ts": "d7040f461465c2c21c1c68fc988ef0bdddd499912138cde3abf6ad60c7fb3814", - "https://deno.land/std@0.209.0/path/windows/normalize.ts": "9deebbf40c81ef540b7b945d4ccd7a6a2c5a5992f791e6d3377043031e164e69", - "https://deno.land/std@0.209.0/path/windows/normalize_glob.ts": "344ff5ed45430495b9a3d695567291e50e00b1b3b04ea56712a2acf07ab5c128", - "https://deno.land/std@0.209.0/path/windows/parse.ts": "120faf778fe1f22056f33ded069b68e12447668fcfa19540c0129561428d3ae5", - "https://deno.land/std@0.209.0/path/windows/relative.ts": "026855cd2c36c8f28f1df3c6fbd8f2449a2aa21f48797a74700c5d872b86d649", - "https://deno.land/std@0.209.0/path/windows/resolve.ts": "5ff441ab18a2346abadf778121128ee71bda4d0898513d4639a6ca04edca366b", - "https://deno.land/std@0.209.0/path/windows/separator.ts": "ae21f27015f10510ed1ac4a0ba9c4c9c967cbdd9d9e776a3e4967553c397bd5d", - "https://deno.land/std@0.209.0/path/windows/to_file_url.ts": "8e9ea9e1ff364aa06fa72999204229952d0a279dbb876b7b838b2b2fea55cce3", - "https://deno.land/std@0.209.0/path/windows/to_namespaced_path.ts": "e0f4d4a5e77f28a5708c1a33ff24360f35637ba6d8f103d19661255ef7bfd50d", - "https://deno.land/std@0.209.0/streams/read_all.ts": "ce30cb93f0b7977f912d60a30f1766929c2891efdb44a2679cfbc25cf8c60184", - "https://deno.land/std@0.209.0/streams/reader_from_stream_reader.ts": "ac387c8826ee922a8e29afa9ba9add50dd9ac8ec6a21ba17dd52f43d369ee9b3", - "https://deno.land/std@0.209.0/streams/write_all.ts": "af86903af1ca8bc443bf615c2d3847afd2687ffc1b91c128e28461d5f4f86769", - "https://deno.land/x/dax@0.36.0/mod.ts": "b6d68abbf111cf1dac5f49d857ddfd97214954a00683d17c769b8cb9c8453f73", - "https://deno.land/x/dax@0.36.0/src/command.ts": "9741292cbdf1e0726e03ae868a8c8913166addef4e49ae7e9cb880b42014e36f", - "https://deno.land/x/dax@0.36.0/src/command_handler.ts": "56ee6893bf5ec829c370fe5a9367f60b3590e571f7b69153d48686779ab14d98", - "https://deno.land/x/dax@0.36.0/src/commands/args.ts": "a138aef24294e3cbf13cef08f4836d018e8dd99fd06ad82e7e7f08ef680bbc1d", - "https://deno.land/x/dax@0.36.0/src/commands/cat.ts": "bcfbd469c02fba13409d7a1d18c898118989ffa7e26d6579b84cac415f06f2c8", - "https://deno.land/x/dax@0.36.0/src/commands/cd.ts": "239fee1606881dbc3f778a761d1d4557c21a63063c15ab58883a32e7466b7177", - "https://deno.land/x/dax@0.36.0/src/commands/cp_mv.ts": "58205a82a9404e444c7c5caf98b5dd2b350c668c0b421546a038b76ea8b6a53d", - "https://deno.land/x/dax@0.36.0/src/commands/echo.ts": "247909de5b8ea20218daab419f3aad37b69763052272aca3633fe8e7f83148cd", - "https://deno.land/x/dax@0.36.0/src/commands/exit.ts": "c619e52d744dfa3e8fa954026f1c5302d8be991c775553efc85a0f224b77b6ff", - "https://deno.land/x/dax@0.36.0/src/commands/export.ts": "b6ecad1203cfe606d69da6c16736f31acf211e864e6822484d85cea1cb7d5528", - "https://deno.land/x/dax@0.36.0/src/commands/mkdir.ts": "9381ecdc0e0203d941f89027b6ef2865393bf0a66670bf5f5aaa6a49669244c7", - "https://deno.land/x/dax@0.36.0/src/commands/printenv.ts": "473c39b457cae91e9ca029ad420642b9a410257fb699674660c886c6ebe72ebc", - "https://deno.land/x/dax@0.36.0/src/commands/pwd.ts": "5438aea979027bfa5c64c2a7f1073389735ea986f6abe2174ec21bcb70a2156f", - "https://deno.land/x/dax@0.36.0/src/commands/rm.ts": "d911ff4e2e0b3d3c5d426c7b735313741ad762d9e25a743f101a1b05447eecf8", - "https://deno.land/x/dax@0.36.0/src/commands/sleep.ts": "d1183fa8e31ba85a7b88666e854c7aa6e53e1d4c65e39f20a05d8ea4b82efca3", - "https://deno.land/x/dax@0.36.0/src/commands/test.ts": "a221f82c209fd53756e9c02c475b9d5833284513853e90fdaaf0c1e1d9cfbf30", - "https://deno.land/x/dax@0.36.0/src/commands/touch.ts": "5953dbde8732da47ade9b7554a638ea06a8b67a59842e638fb79f7aebe392650", - "https://deno.land/x/dax@0.36.0/src/commands/unset.ts": "8d4abb29f53c3de0c10ba6d51e3d55bce745160f7430396ede58156e8f2b747c", - "https://deno.land/x/dax@0.36.0/src/common.ts": "7295d13ab0023bb09d4c97e3a131cedada6294a33474f136b652a145330c8e3e", - "https://deno.land/x/dax@0.36.0/src/console/confirm.ts": "d9128d10b77fcc0a8df2784f71c79df68f5c8e00a34b04547b9ba9ddf1c97f96", - "https://deno.land/x/dax@0.36.0/src/console/logger.ts": "e0ab5025915cef70df03681c756e211f25bb2e4331f82ed4256b17ddd9e794ea", - "https://deno.land/x/dax@0.36.0/src/console/mod.ts": "de8af7d646f6cb222eee6560171993690247941b13ed9d757789d16f019d73ee", - "https://deno.land/x/dax@0.36.0/src/console/multiSelect.ts": "31003744e58f45f720271bd034d8cfba1055c954ba02d77a2f2eb21e4c1ed55a", - "https://deno.land/x/dax@0.36.0/src/console/progress/format.ts": "15ddbb8051580f88ed499281e12ca6f881f875ab73268d7451d7113ee130bd7d", - "https://deno.land/x/dax@0.36.0/src/console/progress/interval.ts": "80188d980a27c2eb07c31324365118af549641442f0752fe7c3b0c91832e5046", - "https://deno.land/x/dax@0.36.0/src/console/progress/mod.ts": "dd9330c3edd1790d70808d043f417f0eaf80a4442a945545c38e47ce11e907b6", - "https://deno.land/x/dax@0.36.0/src/console/prompt.ts": "1ad65c8a5a27fb58ce6138f8ebefe2fca4cd12015fea550fbdc62f875d4b31f7", - "https://deno.land/x/dax@0.36.0/src/console/select.ts": "c9d7124d975bf34d52ea1ac88fd610ed39db8ee6505b9bb53f371cef2f56c6ab", - "https://deno.land/x/dax@0.36.0/src/console/utils.ts": "954c99397dcd2cb3f1ccf50055085f17c9ffb31b25b3c5719776de81e23935f4", - "https://deno.land/x/dax@0.36.0/src/deps.ts": "6a68786131224d34cb7aab557fd3f6f0295d2ec1247893d8bb7acc730a821720", - "https://deno.land/x/dax@0.36.0/src/lib/mod.ts": "c992db99c8259ae3bf2d35666585dfefda84cf7cf4e624e42ea2ac7367900fe0", - "https://deno.land/x/dax@0.36.0/src/lib/rs_lib.generated.js": "932a69348ce575e4a5c2398c896e9cd06cf287f6c18fb25dfdf23badca1c9f54", - "https://deno.land/x/dax@0.36.0/src/path.ts": "79bde2f690c43312e45afe1a19637b9c8be03d065f3faa66523ca882a8d64701", - "https://deno.land/x/dax@0.36.0/src/pipes.ts": "cf63e640857f0db398dc55d2d989d565812e4e71197d7f77a9c2cf1c9650637a", - "https://deno.land/x/dax@0.36.0/src/request.ts": "b4058af220fbf74dfcebf3642282991561a53bf55726318afaed7495680454c9", - "https://deno.land/x/dax@0.36.0/src/result.ts": "0908b69c16b25c3b258f6b2ada12e124686df5f7ea2b98daa27a83973c7b118c", - "https://deno.land/x/dax@0.36.0/src/shell.ts": "349c84a997998e1ff485354d54f154ec573499e17ac28d2eb742ea96faa753de", - "https://deno.land/x/outdent@v0.8.0/src/index.ts": "6dc3df4108d5d6fedcdb974844d321037ca81eaaa16be6073235ff3268841a22", - "https://deno.land/x/which@0.3.0/mod.ts": "3e10d07953c14e4ddc809742a3447cef14202cdfe9be6678a1dfc8769c4487e6" + "workspace": { + "dependencies": [ + "jsr:@david/dax@0.40.1", + "jsr:@deno/cache-dir@0.14", + "jsr:@deno/graph@~0.82.3", + "jsr:@std/assert@0.223", + "npm:browserslist@4.23.0", + "npm:lightningcss@^1.26.0", + "npm:tailwindcss@3.4.3" + ] } } diff --git a/examples/ddoc/main.rs b/examples/ddoc/main.rs index a63d179c..613b718f 100644 --- a/examples/ddoc/main.rs +++ b/examples/ddoc/main.rs @@ -3,9 +3,12 @@ use clap::App; use clap::Arg; use deno_doc::find_nodes_by_name_recursively; +use deno_doc::html::GenerateCtx; use deno_doc::html::HrefResolver; use deno_doc::html::UrlResolveKind; -use deno_doc::DocNodeKind; +use deno_doc::html::UsageComposer; +use deno_doc::html::UsageComposerEntry; +use deno_doc::node::DocNodeDef; use deno_doc::DocParser; use deno_doc::DocParserOptions; use deno_doc::DocPrinter; @@ -41,7 +44,9 @@ impl Loader for SourceFileLoader { content: content.into(), }) }) - .map_err(|err| err.into()) + .map_err(|err| { + deno_graph::source::LoadError::Other(std::sync::Arc::new(err)) + }) } else { Ok(None) }; @@ -57,6 +62,7 @@ async fn run() -> anyhow::Result<()> { .requires_all(&["output"]), ) .arg(Arg::with_name("name").long("name").takes_value(true)) + .arg(Arg::with_name("json").long("json").conflicts_with("html")) .arg( Arg::with_name("main_entrypoint") .long("main_entrypoint") @@ -73,6 +79,7 @@ async fn run() -> anyhow::Result<()> { .get_matches(); let source_files = matches.values_of("source_files").unwrap(); let html = matches.is_present("html"); + let json = matches.is_present("json"); let name = if html { matches.value_of("name").map(|name| name.to_string()) } else { @@ -118,23 +125,21 @@ async fn run() -> anyhow::Result<()> { ) .await; + let mut source_files = source_files.clone(); + source_files.sort(); + let parser = DocParser::new( &graph, &analyzer, + &source_files, DocParserOptions { diagnostics: false, private, }, )?; + let doc_nodes_by_url = parser.parse()?; if html { - let mut source_files = source_files.clone(); - source_files.sort(); - let mut doc_nodes_by_url = IndexMap::with_capacity(source_files.len()); - for source_file in source_files { - let nodes = parser.parse_with_reexports(&source_file)?; - doc_nodes_by_url.insert(source_file, nodes); - } generate_docs_directory( name, output_dir, @@ -144,19 +149,23 @@ async fn run() -> anyhow::Result<()> { return Ok(()); } - let mut doc_nodes = Vec::with_capacity(1024); - for source_file in source_files { - let nodes = parser.parse_with_reexports(&source_file)?; - doc_nodes.extend(nodes); - } + let mut doc_nodes = + parser.parse()?.into_values().flatten().collect::>(); - doc_nodes.retain(|doc_node| doc_node.kind != DocNodeKind::Import); + doc_nodes + .retain(|doc_node| !matches!(doc_node.def, DocNodeDef::Import { .. })); if let Some(filter) = maybe_filter { - doc_nodes = find_nodes_by_name_recursively(doc_nodes, filter.to_string()); + doc_nodes = find_nodes_by_name_recursively(doc_nodes, filter); + } + + if json { + serde_json::to_writer_pretty(std::io::stdout(), &doc_nodes)?; + println!(); + } else { + let result = DocPrinter::new(&doc_nodes, true, false); + println!("{}", result); } - let result = DocPrinter::new(&doc_nodes, true, false); - println!("{}", result); Ok(()) } @@ -171,7 +180,7 @@ fn main() { block_on(future); } -struct EmptyResolver(); +struct EmptyResolver; impl HrefResolver for EmptyResolver { fn resolve_path( @@ -194,14 +203,41 @@ impl HrefResolver for EmptyResolver { None } - fn resolve_usage(&self, current_resolve: UrlResolveKind) -> Option { - current_resolve - .get_file() - .map(|current_file| current_file.specifier.to_string()) + fn resolve_source(&self, location: &deno_doc::Location) -> Option { + Some(location.filename.to_string()) } - fn resolve_source(&self, location: &deno_doc::Location) -> Option { - Some(location.filename.clone()) + fn resolve_external_jsdoc_module( + &self, + _module: &str, + _symbol: Option<&str>, + ) -> Option<(String, String)> { + None + } +} + +impl UsageComposer for EmptyResolver { + fn is_single_mode(&self) -> bool { + true + } + + fn compose( + &self, + current_resolve: UrlResolveKind, + usage_to_md: deno_doc::html::UsageToMd, + ) -> IndexMap { + current_resolve + .get_file() + .map(|current_file| { + IndexMap::from([( + UsageComposerEntry { + name: "".to_string(), + icon: None, + }, + usage_to_md(current_file.specifier.as_str(), None), + )]) + }) + .unwrap_or_default() } } @@ -222,16 +258,26 @@ fn generate_docs_directory( let options = deno_doc::html::GenerateOptions { package_name, main_entrypoint, - href_resolver: Rc::new(EmptyResolver()), - usage_composer: None, + href_resolver: Rc::new(EmptyResolver), + usage_composer: Rc::new(EmptyResolver), rewrite_map: Some(index_map), - composable_output: false, category_docs: None, disable_search: false, symbol_redirect_map: None, default_symbol_map: None, + markdown_renderer: deno_doc::html::comrak::create_renderer( + None, None, None, + ), + markdown_stripper: Rc::new(deno_doc::html::comrak::strip), + head_inject: Some(Rc::new(|root| { + format!( + r#""#, + deno_doc::html::comrak::COMRAK_STYLESHEET_FILENAME + ) + })), }; - let html = deno_doc::html::generate(options, doc_nodes_by_url)?; + let ctx = GenerateCtx::create_basic(options, doc_nodes_by_url)?; + let html = deno_doc::html::generate(ctx)?; let path = &output_dir_resolved; let _ = std::fs::remove_dir_all(path); diff --git a/js/README.md b/js/README.md index fd80771c..ba114350 100644 --- a/js/README.md +++ b/js/README.md @@ -5,7 +5,7 @@ and exposes an interface which is available via the `mod.ts` and can be imported like this: ```ts -import { doc } from "https://deno.land/x/deno_doc@{VERSION}/mod.ts"; +import { doc } from "jsr:@deno/doc@{VERSION}"; ``` Where `{VERSION}` should be substituted with the specific version you want to @@ -21,7 +21,7 @@ A minimal example of using `doc()` and printing out some information about a function: ```ts -import { doc } from "https://deno.land/x/deno_doc@{VERSION}/mod.ts"; +import { doc } from "jsr:@deno/doc@{VERSION}"; const colorsDoc = await doc("https://deno.land/std/fmt/colors.ts"); diff --git a/js/allow_leak_test.ts b/js/allow_leak_test.ts new file mode 100644 index 00000000..af1baf6b --- /dev/null +++ b/js/allow_leak_test.ts @@ -0,0 +1,19 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +import { assertRejects } from "@std/assert"; +import { doc } from "./mod.ts"; + +Deno.test({ + name: "doc() - missing specifier", + // TODO(@kitsonk) - remove when new deno_graph crate published + sanitizeResources: false, + async fn() { + await assertRejects( + async () => { + await doc(["https://deno.land/x/bad.ts"]); + }, + Error, + `Module not found "https://deno.land/x/bad.ts".`, + ); + }, +}); diff --git a/js/deno.json b/js/deno.json index 076f3f56..601f8fe1 100644 --- a/js/deno.json +++ b/js/deno.json @@ -3,7 +3,8 @@ "version": "0.0.0", "exports": { ".": "./mod.ts", - "./types": "./types.d.ts" + "./types": "./types.d.ts", + "./html-types": "./html_types.d.ts" }, "exclude": [ "!**" diff --git a/js/html_types.d.ts b/js/html_types.d.ts new file mode 100644 index 00000000..fa38eab1 --- /dev/null +++ b/js/html_types.d.ts @@ -0,0 +1,374 @@ +// Copyright 2018-2025 the Deno authors. All rights reserved. MIT license. + +export interface HtmlHeadCtx { + title: string; + current_file: string; + stylesheet_url: string; + page_stylesheet_url: string; + reset_stylesheet_url: string; + url_search_index: string; + script_js: string; + fuse_js: string; + url_search: string; + head_inject: string | null; + disable_search: boolean; +} + +export interface CategoriesPanelCtx { + categories: CategoriesPanelCategoryCtx[]; + all_symbols_href: string; + total_symbols: number; +} + +export interface CategoriesPanelCategoryCtx { + name: string; + href: string; + active: boolean; +} + +export type Page = IndexCtx | AllSymbolsCtx | SymbolPageCtx | Redirect | Search; + +export interface PageBase { + kind: "IndexCtx" | "AllSymbolsCtx" | "SymbolPageCtx"; + html_head_ctx: HtmlHeadCtx; + disable_search: boolean; + categories_panel: CategoriesPanelCtx | null; + breadcrumbs_ctx: BreadcrumbsCtx; +} + +export interface IndexCtx extends PageBase { + kind: "IndexCtx"; + overview: SymbolContentCtx | null; + module_doc: ModuleDocCtx | null; + usage: UsagesCtx | null; + toc_ctx: ToCCtx; +} + +export interface AllSymbolsCtx extends PageBase { + kind: "AllSymbolsCtx"; + content: SymbolContentCtx; +} + +export interface SymbolPageCtx extends PageBase { + kind: "SymbolPageCtx"; + symbol_group_ctx: SymbolGroupCtx; + toc_ctx: ToCCtx; +} + +export interface Redirect { + kind: "redirect"; + path: string; +} + +export interface Search { + kind: "search"; + path: SearchIndexNode[]; +} + +export interface SlimKindCtx { + char: string; + kind: string; + title: string; +} + +export interface SearchIndexNode { + kind: SlimKindCtx[]; + name: string; + file: string; + doc: string; + url: string; + category?: string; + deprecated: boolean; +} + +export interface ToCCtx { + usages: UsagesCtx | null; + top_symbols: TopSymbolsCtx | null; + document_navigation_str: string | null; + document_navigation: ToCEntry[]; +} + +export interface ToCEntry { + level: number; + content: string; + anchor: string; +} + +export interface UsagesCtx { + usages: UsageCtx[]; + composed: boolean; +} + +export interface UsageCtx { + name: string; + content: string; + icon: string | null; + additional_css: string; +} + +export interface BreadcrumbsCtx { + parts: BreadcrumbCtx[]; +} + +export interface BreadcrumbCtx { + name: string; + href: string; + is_symbol: boolean; + is_first_symbol: boolean; +} + +export interface TopSymbolsCtx { + symbols: TopSymbolCtx[]; + total_symbols: number; + all_symbols_href: string; +} + +export interface TopSymbolCtx { + kind: DocNodeKindCtx[]; + name: string; + href: string; +} + +export interface ModuleDocCtx { + deprecated: string | null; + sections: SymbolContentCtx; +} + +export interface DocNodeKindCtx { + kind: string; + char: string; + title: string; + title_lowercase: string; + title_plural: string; +} + +export interface SymbolContentCtx { + id: string; + docs: string | null; + sections: SectionCtx[]; +} + +export interface SectionCtx { + header: SectionHeaderCtx | null; + content: SectionContentCtx; +} + +export interface SectionHeaderCtx { + title: string; + anchor: AnchorCtx; + href: string | null; + doc: string | null; +} + +export interface AnchorCtx { + id: string; +} + +export interface SymbolGroupCtx { + name: string; + symbols: SymbolCtx[]; +} + +export interface SymbolCtx { + kind: DocNodeKindCtx; + usage: UsagesCtx | null; + tags: Tag[]; + subtitle: DocBlockSubtitleCtx | null; + content: SymbolInnerCtx[]; + deprecated: string | null; + source_href: string | null; +} + +export type DocBlockSubtitleCtx = + | DocBlockSubtitleClassCtx + | DocBlockSubtitleInterfaceCtx; + +export interface DocBlockSubtitleClassCtx { + kind: "class"; + value: DocBlockSubtitleClassValueCtx; +} +export interface DocBlockSubtitleClassValueCtx { + implements: string[] | null; + extends: DocBlockClassSubtitleExtendsCtx | null; +} + +export interface DocBlockClassSubtitleExtendsCtx { + href: string | null; + symbol: string; + type_args: string; +} + +export interface DocBlockSubtitleInterfaceCtx { + kind: "interface"; + value: DocBlockSubtitleInterfaceValueCtx; +} + +export interface DocBlockSubtitleInterfaceValueCtx { + extends: string[]; +} + +export type SymbolInnerCtx = SymbolInnerFunctionCtx | SymbolInnerOtherCtx; + +export interface SymbolInnerFunctionCtx { + kind: "function"; + value: FunctionCtx; +} + +export interface SymbolInnerOtherCtx { + kind: "other"; + value: SymbolContentCtx; +} + +export interface FunctionCtx { + functions: OverloadRenderCtx[]; +} + +export interface OverloadRenderCtx { + id: string; + anchor: AnchorCtx; + name: string; + summary: string; + deprecated: string | null; + content: SymbolContentCtx; +} + +export type SectionContentCtx = + | SectionContentDocEntryCtx + | SectionContentExampleCtx + | SectionContentIndexSignatureCtx + | SectionContentNamespaceSectionCtx + | SectionContentNamespaceSeeCtx + | SectionContentEmptyCtx; + +export interface SectionContentDocEntryCtx { + kind: "doc_entry"; + content: DocEntryCtx[]; +} + +export interface SectionContentExampleCtx { + kind: "example"; + content: ExampleCtx[]; +} + +export interface SectionContentIndexSignatureCtx { + kind: "index_signature"; + content: IndexSignatureCtx[]; +} + +export interface SectionContentNamespaceSectionCtx { + kind: "namespace_section"; + content: NamespaceNodeCtx[]; +} + +export interface SectionContentNamespaceSeeCtx { + kind: "see"; + content: string[]; +} + +export interface SectionContentEmptyCtx { + kind: "empty"; +} + +export interface DocEntryCtx { + id: string; + name: string | null; + name_href: string | null; + content: string; + anchor: AnchorCtx; + tags: Tag[]; + js_doc: string | null; + source_href: string | null; +} + +export interface ExampleCtx { + anchor: AnchorCtx; + id: string; + title: string; + markdown_title: string; + markdown_body: string; +} + +export interface IndexSignatureCtx { + id: string; + anchor: AnchorCtx; + readonly: boolean; + params: string; + ts_type: string; + source_href: string | null; +} + +export interface NamespaceNodeCtx { + id: string; + anchor: AnchorCtx; + tags: Tag[]; + doc_node_kind_ctx: DocNodeKindCtx[]; + href: string; + name: string; + docs: string | null; + deprecated: boolean; + subitems: NamespaceNodeSubItemCtx[]; +} + +export interface NamespaceNodeSubItemCtx { + title: string; + href: string; +} + +export type Tag = + | TagNew + | TagAbstract + | TagDeprecated + | TagWriteonly + | TagReadonly + | TagProtected + | TagPrivate + | TagOptional + | TagUnstable + | TagPermissions + | TagOther; + +export interface TagNew { + kind: "new"; +} + +export interface TagAbstract { + kind: "abstract"; +} + +export interface TagDeprecated { + kind: "deprecated"; +} + +export interface TagWriteonly { + kind: "writeonly"; +} + +export interface TagReadonly { + kind: "readonly"; +} + +export interface TagProtected { + kind: "protected"; +} + +export interface TagPrivate { + kind: "private"; +} + +export interface TagOptional { + kind: "optional"; +} + +export interface TagUnstable { + kind: "unstable"; +} + +export interface TagPermissions { + kind: "permissions"; + value: string[]; +} + +export interface TagOther { + kind: "other"; + value: string; +} diff --git a/js/mod.ts b/js/mod.ts index 7172f799..7d146cea 100644 --- a/js/mod.ts +++ b/js/mod.ts @@ -1,12 +1,14 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. import { instantiate } from "./deno_doc_wasm.generated.js"; -import type { DocNode } from "./types.d.ts"; -import { createCache } from "jsr:@deno/cache-dir@0.8"; -import type { CacheSetting, LoadResponse } from "jsr:@deno/graph@0.73"; +import type { DocNode, Location } from "./types.d.ts"; +import type { Page } from "./html_types.d.ts"; +import { createCache } from "@deno/cache-dir"; +import type { CacheSetting, LoadResponse } from "@deno/graph"; -export type { CacheSetting, LoadResponse } from "jsr:@deno/graph@0.73"; +export type { CacheSetting, LoadResponse } from "@deno/graph"; export * from "./types.d.ts"; +export * from "./html_types.d.ts"; const encoder = new TextEncoder(); @@ -70,21 +72,21 @@ export interface DocOptions { * ```ts * import { doc } from "https://deno.land/x/deno_doc/mod.ts"; * - * const entries = await doc("https://deno.land/std/fmt/colors.ts"); + * const entries = await doc(["https://deno.land/std/fmt/colors.ts"]); * * for (const entry of entries) { * console.log(`name: ${entry.name} kind: ${entry.kind}`); * } * ``` * - * @param specifier The URL string of the specifier to document + * @param specifiers List of the URL strings of the specifiers to document * @param options A set of options for generating the documentation * @returns A promise that resolves with an array of documentation nodes */ export async function doc( - specifier: string, + specifiers: string[], options: DocOptions = {}, -): Promise> { +): Promise>> { const { load = createCache().load, includeAll = false, @@ -95,7 +97,7 @@ export async function doc( const wasm = await instantiate(); return wasm.doc( - specifier, + specifiers, includeAll, (specifier: string, options: { isDynamic: boolean; @@ -124,3 +126,249 @@ export async function doc( printImportMapDiagnostics, ); } + +export interface ShortPath { + /** Name identifier for the path. */ + path: string; + /** URL for the path. */ + specifier: string; + /** Whether the path is the main entrypoint. */ + isMain: boolean; +} + +export interface UrlResolveKindRoot { + kind: "root"; +} + +export interface UrlResolveKindAllSymbols { + kind: "allSymbols"; +} + +export interface UrlResolveKindCategory { + kind: "category"; + category: string; +} + +export interface UrlResolveKindFile { + kind: "file"; + file: ShortPath; +} + +export interface UrlResolveKindSymbol { + kind: "symbol"; + file: ShortPath; + symbol: string; +} + +export type UrlResolveKind = + | UrlResolveKindRoot + | UrlResolveKindAllSymbols + | UrlResolveKindCategory + | UrlResolveKindFile + | UrlResolveKindSymbol; + +export interface HrefResolver { + /** Resolver for how files should link to each other. */ + resolvePath?( + current: UrlResolveKind, + target: UrlResolveKind, + defaultResolve: () => string, + ): string; + /** Resolver for global symbols, like the Deno namespace or other built-ins */ + resolveGlobalSymbol?(symbol: string[]): string | undefined; + /** Resolver for symbols from non-relative imports */ + resolveImportHref?(symbol: string[], src: string): string | undefined; + /** Resolve the URL used in source code link buttons. */ + resolveSource?(location: Location): string | undefined; + /** + * Resolve external JSDoc module links. + * Returns a tuple with link and title. + */ + resolveExternalJsdocModule?( + module: string, + symbol?: string, + ): { link: string; title: string } | undefined; +} + +export interface UsageComposerEntry { + /** Name for the entry. Can be left blank in singleMode. */ + name: string; + /** Icon for the entry. */ + icon?: string; +} + +export type UsageToMd = ( + url: string, + customFileIdentifier: string | undefined, +) => string; + +export interface UsageComposer { + /** Whether the usage should only display a single item and not have a dropdown. */ + singleMode: boolean; + + /** + * Composer to generate usage. + * + * @param currentResolve The current resolve. + * @param usageToMd Callback to generate a usage import block. + */ + compose( + currentResolve: UrlResolveKind, + usageToMd: UsageToMd, + ): Map; +} + +export interface GenerateOptions { + /** The name of the package to use in the breadcrumbs. */ + packageName?: string; + /** The main entrypoint if one is present. */ + mainEntrypoint?: string; + /** Composer for generating the usage of a symbol of module. */ + usageComposer?: UsageComposer; + /** Resolver for how links should be resolved. */ + hrefResolver?: HrefResolver; + /** Map for remapping module names to a custom value. */ + rewriteMap?: Record; + /** + * Map of categories to their markdown description. + * Only usable in category mode (single d.ts file with categories declared). + */ + categoryDocs?: Record; + /** Whether to disable search. */ + disableSearch?: boolean; + /** + * Map of modules, where the value is a map of symbols with value of a link to + * where this symbol should redirect to. + */ + symbolRedirectMap?: Record>; + /** + * Map of modules, where the value is what the name of the default symbol should be. + */ + defaultSymbolMap?: Record; + /** + * Hook to inject content in the `head` tag. + * + * @param root the path to the root of the output. + */ + headInject?(root: string): string; + /** + * Function to render markdown. + * + * @param md The raw markdown that needs to be rendered. + * @param titleOnly Whether only the title should be rendered. Recommended syntax to keep is: + * - paragraph + * - heading + * - text + * - code + * - html inline + * - emph + * - strong + * - strikethrough + * - superscript + * - link + * - math + * - escaped + * - wiki link + * - underline + * - soft break + * @param filePath The filepath where the rendering is happening. + * @param anchorizer Anchorizer used to generate slugs and the sidebar. + * @return The rendered markdown. + */ + markdownRenderer( + md: string, + titleOnly: boolean, + filePath: ShortPath | undefined, + anchorizer: (content: string, depthLevel: number) => string, + ): string | undefined; + /** Function to strip markdown. */ + markdownStripper(md: string): string; +} + +const defaultUsageComposer: UsageComposer = { + singleMode: true, + compose(currentResolve, usageToMd) { + if ("file" in currentResolve) { + return new Map([[ + { name: "" }, + usageToMd(currentResolve.file.specifier, undefined), + ]]); + } else { + return new Map(); + } + }, +}; + +/** + * Generate HTML files for provided {@linkcode DocNode}s. + * @param docNodesByUrl DocNodes keyed by their absolute URL. + * @param options Options for the generation. + */ +export async function generateHtml( + docNodesByUrl: Record>, + options: GenerateOptions, +): Promise> { + const { + usageComposer = defaultUsageComposer, + } = options; + + const wasm = await instantiate(); + return wasm.generate_html( + options.packageName, + options.mainEntrypoint, + usageComposer.singleMode, + usageComposer.compose, + options.rewriteMap, + options.categoryDocs, + options.disableSearch ?? false, + options.symbolRedirectMap, + options.defaultSymbolMap, + options.hrefResolver?.resolvePath, + options.hrefResolver?.resolveGlobalSymbol || (() => undefined), + options.hrefResolver?.resolveImportHref || (() => undefined), + options.hrefResolver?.resolveSource || (() => undefined), + options.hrefResolver?.resolveExternalJsdocModule || (() => undefined), + options.markdownRenderer, + options.markdownStripper, + options.headInject, + docNodesByUrl, + false, + ); +} + +/** + * Generate JSON data equivalent to the HTML files generated by {@linkcode generateHtml}. + * @param docNodesByUrl DocNodes keyed by their absolute URL. + * @param options Options for the generation. + */ +export async function generateHtmlAsJSON( + docNodesByUrl: Record>, + options: GenerateOptions, +): Promise> { + const { + usageComposer = defaultUsageComposer, + } = options; + + const wasm = await instantiate(); + return wasm.generate_html( + options.packageName, + options.mainEntrypoint, + usageComposer.singleMode, + usageComposer.compose, + options.rewriteMap, + options.categoryDocs, + options.disableSearch ?? false, + options.symbolRedirectMap, + options.defaultSymbolMap, + options.hrefResolver?.resolvePath, + options.hrefResolver?.resolveGlobalSymbol || (() => undefined), + options.hrefResolver?.resolveImportHref || (() => undefined), + options.hrefResolver?.resolveSource || (() => undefined), + options.hrefResolver?.resolveExternalJsdocModule || (() => undefined), + options.markdownRenderer, + options.markdownStripper, + options.headInject, + docNodesByUrl, + true, + ); +} diff --git a/js/test.ts b/js/test.ts index 295cde16..634e3633 100644 --- a/js/test.ts +++ b/js/test.ts @@ -1,14 +1,15 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. import { assert, assertEquals, assertRejects } from "jsr:@std/assert@0.223"; -import { doc } from "./mod.ts"; +import { doc, generateHtml, generateHtmlAsJSON } from "./mod.ts"; Deno.test({ name: "doc()", async fn() { - const entries = await doc( - "https://deno.land/std@0.104.0/fmt/colors.ts", + const records = await doc( + ["https://deno.land/std@0.104.0/fmt/colors.ts"], ); + const entries = Object.values(records)[0]; assertEquals(entries.length, 49); const fnStripColor = entries.find((n) => n.kind === "function" && n.name === "stripColor" @@ -32,8 +33,8 @@ Deno.test({ Deno.test({ name: "doc() - timings", async fn() { - const fixture = new URL("../benches/fixtures/deno.d.ts", import.meta.url) - .toString(); + const fixture = [new URL("../benches/fixtures/deno.d.ts", import.meta.url) + .toString()]; const start = Date.now(); await doc(fixture); @@ -58,7 +59,7 @@ Deno.test({ Deno.test({ name: "doc() - with headers", async fn() { - const entries = await doc("https://example.com/a", { + const entries = await doc(["https://example.com/a"], { load(specifier) { return Promise.resolve({ kind: "module", @@ -72,22 +73,7 @@ Deno.test({ }); }, }); - assertEquals(entries.length, 1); - }, -}); - -Deno.test({ - name: "doc() - missing specifier", - // TODO(@kitsonk) - remove when new deno_graph crate published - sanitizeResources: false, - async fn() { - await assertRejects( - async () => { - await doc("https://deno.land/x/bad.ts"); - }, - Error, - `Module not found "https://deno.land/x/bad.ts".`, - ); + assertEquals(Object.values(entries)[0].length, 1); }, }); @@ -96,7 +82,7 @@ Deno.test({ async fn() { await assertRejects( async () => { - await doc("./bad.ts"); + await doc(["./bad.ts"]); }, Error, "relative URL without a base", @@ -107,7 +93,7 @@ Deno.test({ Deno.test({ name: "doc() - with import map", async fn() { - const entries = await doc("https://example.com/a.ts", { + const records = await doc(["https://example.com/a.ts"], { importMap: "https://example.com/import_map.json", load(specifier) { let content = ""; @@ -133,8 +119,63 @@ Deno.test({ }); }, }); + const entries = Object.values(records)[0]; assertEquals(entries.length, 1); assertEquals(entries[0].kind, "class"); assertEquals(entries[0].name, "B"); }, }); + +Deno.test({ + name: "generateHtml()", + async fn() { + const entries = await doc( + ["https://deno.land/std@0.104.0/fmt/colors.ts"], + ); + + const files = await generateHtml({ + ["file:///colors.ts"]: Object.values(entries)[0], + }, { + markdownRenderer( + md, + _titleOnly, + _filePath, + _anchorizer, + ) { + return md; + }, + markdownStripper(md: string) { + return md; + }, + }); + + assertEquals(Object.keys(files).length, 61); + }, +}); + +Deno.test({ + name: "generateHtmlAsJSON()", + async fn() { + const entries = await doc( + ["https://deno.land/std@0.104.0/fmt/colors.ts"], + ); + + const files = await generateHtmlAsJSON({ + ["file:///colors.ts"]: Object.values(entries)[0], + }, { + markdownRenderer( + md, + _titleOnly, + _filePath, + _anchorizer, + ) { + return md; + }, + markdownStripper(md: string) { + return md; + }, + }); + + assertEquals(Object.keys(files).length, 55); + }, +}); diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 5fc4dfb5..acd9624f 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -14,11 +14,13 @@ path = "lib.rs" crate-type = ["cdylib"] [dependencies] -anyhow = "1.0.43" -deno_graph = { workspace = true, features = ["wasm_executor"] } +anyhow = "1.0.86" +deno_graph = { workspace = true } deno_doc = { path = "../", default-features = false } import_map.workspace = true serde.workspace = true +indexmap = "2.6.0" +deno_error = { version = "0.5.3", features = ["url"] } console_error_panic_hook = "0.1.7" js-sys = "=0.3.69" @@ -27,4 +29,4 @@ wasm-bindgen = "=0.2.92" wasm-bindgen-futures = "=0.4.42" [dev-dependencies] -pretty_assertions = "1.0.0" +pretty_assertions = "1.4.0" diff --git a/lib/lib.rs b/lib/lib.rs index 7fa4f606..02b3c8bf 100644 --- a/lib/lib.rs +++ b/lib/lib.rs @@ -2,8 +2,12 @@ use anyhow::anyhow; use anyhow::Context; +use deno_doc::html::UrlResolveKind; +use deno_doc::html::UsageComposerEntry; +use deno_doc::html::UsageToMd; use deno_doc::DocParser; use deno_graph::source::CacheSetting; +use deno_graph::source::LoadError; use deno_graph::source::LoadFuture; use deno_graph::source::LoadOptions; use deno_graph::source::LoadResponse; @@ -18,7 +22,11 @@ use deno_graph::ModuleSpecifier; use deno_graph::Range; use import_map::ImportMap; use import_map::ImportMapOptions; +use indexmap::IndexMap; use serde::Serialize; +use std::ffi::c_void; +use std::rc::Rc; +use std::sync::Arc; use wasm_bindgen::prelude::*; use wasm_bindgen_futures::JsFuture; @@ -32,6 +40,11 @@ macro_rules! console_warn { ($($t:tt)*) => (warn(&format_args!($($t)*).to_string())) } +thread_local! { + static CURRENT: std::cell::RefCell<*const c_void> = const { std::cell::RefCell::new(std::ptr::null()) }; + static TARGET: std::cell::RefCell<*const c_void> = const { std::cell::RefCell::new(std::ptr::null()) }; +} + struct JsLoader { load: js_sys::Function, } @@ -72,7 +85,11 @@ impl Loader for JsLoader { }; response .map(|value| serde_wasm_bindgen::from_value(value).unwrap()) - .map_err(|_| anyhow!("load rejected or errored")) + .map_err(|_| { + LoadError::Other(Arc::new(deno_error::JsErrorBox::generic( + "load rejected or errored", + ))) + }) }; Box::pin(f) } @@ -92,12 +109,12 @@ impl Resolver for ImportMapResolver { &self, specifier: &str, referrer_range: &Range, - _mode: deno_graph::source::ResolutionMode, + _kind: deno_graph::source::ResolutionKind, ) -> Result { self .0 .resolve(specifier, &referrer_range.specifier) - .map_err(|err| ResolveError::Other(err.into())) + .map_err(|err| ResolveError::ImportMap(err)) } } @@ -117,7 +134,7 @@ impl Resolver for JsResolver { &self, specifier: &str, referrer_range: &Range, - _mode: deno_graph::source::ResolutionMode, + _kind: deno_graph::source::ResolutionKind, ) -> Result { use ResolveError::*; let this = JsValue::null(); @@ -126,18 +143,21 @@ impl Resolver for JsResolver { let value = match self.resolve.call2(&this, &arg0, &arg1) { Ok(value) => value, Err(_) => { - return Err(Other(anyhow!("JavaScript resolve() function threw."))) + return Err(Other(deno_error::JsErrorBox::generic( + "JavaScript resolve() function threw.", + ))) } }; let value: String = serde_wasm_bindgen::from_value(value) - .map_err(|err| anyhow!("{}", err))?; - ModuleSpecifier::parse(&value).map_err(|err| Other(err.into())) + .map_err(|err| deno_error::JsErrorBox::generic(err.to_string()))?; + ModuleSpecifier::parse(&value) + .map_err(|err| Other(deno_error::JsErrorBox::from_err(err))) } } #[wasm_bindgen] pub async fn doc( - root_specifier: String, + root_specifiers: Vec, include_all: bool, load: js_sys::Function, maybe_resolve: Option, @@ -146,7 +166,7 @@ pub async fn doc( ) -> anyhow::Result { console_error_panic_hook::set_once(); inner_doc( - root_specifier, + root_specifiers, include_all, load, maybe_resolve, @@ -158,14 +178,17 @@ pub async fn doc( } async fn inner_doc( - root_specifier: String, + root_specifiers: Vec, include_all: bool, load: js_sys::Function, maybe_resolve: Option, maybe_import_map: Option, print_import_map_diagnostics: bool, ) -> Result { - let root_specifier = ModuleSpecifier::parse(&root_specifier)?; + let root_specifiers = root_specifiers + .into_iter() + .map(|root_specifier| ModuleSpecifier::parse(&root_specifier)) + .collect::, _>>()?; let mut loader = JsLoader::new(load); let maybe_resolver: Option> = if let Some(import_map) = maybe_import_map @@ -181,6 +204,7 @@ async fn inner_doc( &import_map_specifier, LoadOptions { is_dynamic: false, + was_dynamic_root: false, cache_setting: CacheSetting::Use, maybe_checksum: None, }, @@ -220,7 +244,7 @@ async fn inner_doc( let mut graph = ModuleGraph::new(GraphKind::TypesOnly); graph .build( - vec![root_specifier.clone()], + root_specifiers.clone(), &mut loader, BuildOptions { module_analyzer: &analyzer, @@ -232,13 +256,413 @@ async fn inner_doc( let entries = DocParser::new( &graph, &analyzer, + &root_specifiers, deno_doc::DocParserOptions { diagnostics: false, private: include_all, }, )? - .parse_with_reexports(&root_specifier)?; + .parse()?; let serializer = serde_wasm_bindgen::Serializer::new().serialize_maps_as_objects(true); Ok(entries.serialize(&serializer).unwrap()) } + +#[allow(clippy::too_many_arguments)] +#[wasm_bindgen] +pub fn generate_html( + package_name: Option, + main_entrypoint: Option, + + usage_composer_single_mode: bool, + usage_composer_compose: js_sys::Function, + + rewrite_map: JsValue, + category_docs: JsValue, + disable_search: bool, + symbol_redirect_map: JsValue, + default_symbol_map: JsValue, + + resolve_path: Option, + resolve_global_symbol: js_sys::Function, + resolve_import_href: js_sys::Function, + resolve_source: js_sys::Function, + resolve_external_jsdoc_module: js_sys::Function, + + markdown_renderer: js_sys::Function, + markdown_stripper: js_sys::Function, + head_inject: Option, + + doc_nodes_by_url: JsValue, + + json: bool, +) -> Result { + console_error_panic_hook::set_once(); + + generate_html_inner( + package_name, + main_entrypoint, + usage_composer_single_mode, + usage_composer_compose, + rewrite_map, + category_docs, + disable_search, + symbol_redirect_map, + default_symbol_map, + resolve_path, + resolve_global_symbol, + resolve_import_href, + resolve_source, + resolve_external_jsdoc_module, + markdown_renderer, + markdown_stripper, + head_inject, + doc_nodes_by_url, + json, + ) + .map_err(|err| JsValue::from(js_sys::Error::new(&err.to_string()))) +} + +struct JsHrefResolver { + resolve_path: Option, + resolve_global_symbol: js_sys::Function, + resolve_import_href: js_sys::Function, + resolve_source: js_sys::Function, + resolve_external_jsdoc_module: js_sys::Function, +} + +impl deno_doc::html::HrefResolver for JsHrefResolver { + fn resolve_path( + &self, + current: UrlResolveKind, + target: UrlResolveKind, + ) -> String { + if let Some(resolve_path) = &self.resolve_path { + let this = JsValue::null(); + + let new_current = current.clone(); + let new_target = target.clone(); + + { + let current_ptr = + &new_current as *const UrlResolveKind as *const c_void; + CURRENT.set(current_ptr); + let target = &new_target as *const UrlResolveKind as *const c_void; + TARGET.set(target); + } + + let default_closure = Box::new(move || { + CURRENT.with(|current| { + let current_ptr = *current.borrow() as *const UrlResolveKind; + assert!(!current_ptr.is_null()); + // SAFETY: this pointer is valid until destroyed, which is done + // after compose is called + let current_val = unsafe { &*current_ptr }; + + let path = TARGET.with(|target| { + let target_ptr = *target.borrow() as *const UrlResolveKind; + assert!(!target_ptr.is_null()); + // SAFETY: this pointer is valid until destroyed, which is done + // after compose is called + let target_val = unsafe { &*target_ptr }; + + let path = + deno_doc::html::href_path_resolve(*current_val, *target_val); + + *target.borrow_mut() = + target_val as *const UrlResolveKind as *const c_void; + + path + }); + + *current.borrow_mut() = + current_val as *const UrlResolveKind as *const c_void; + + path + }) + }); + + let default_closure = + Closure::wrap(Box::new(default_closure) as Box String>); + let default_closure = + JsCast::unchecked_ref::(default_closure.as_ref()); + + let current = serde_wasm_bindgen::to_value(¤t).unwrap(); + let target = serde_wasm_bindgen::to_value(&target).unwrap(); + + let global_symbol = resolve_path + .call3(&this, ¤t, &target, default_closure) + .expect("resolve_path errored"); + + { + let current = + CURRENT.replace(std::ptr::null()) as *const UrlResolveKind; + // SAFETY: take the pointer and drop it + let _ = unsafe { &*current }; + + let target = TARGET.replace(std::ptr::null()) as *const UrlResolveKind; + // SAFETY: take the pointer and drop it + let _ = unsafe { &*target }; + } + + serde_wasm_bindgen::from_value(global_symbol) + .expect("resolve_path returned an invalid value") + } else { + deno_doc::html::href_path_resolve(current, target) + } + } + + fn resolve_global_symbol(&self, symbol: &[String]) -> Option { + let this = JsValue::null(); + + let symbol = serde_wasm_bindgen::to_value(&symbol).unwrap(); + + let global_symbol = self + .resolve_global_symbol + .call1(&this, &symbol) + .expect("resolve_global_symbol errored"); + + serde_wasm_bindgen::from_value(global_symbol) + .expect("resolve_global_symbol returned an invalid value") + } + + fn resolve_import_href( + &self, + symbol: &[String], + src: &str, + ) -> Option { + let this = JsValue::null(); + + let symbol = serde_wasm_bindgen::to_value(&symbol).unwrap(); + let src = serde_wasm_bindgen::to_value(&src).unwrap(); + + let global_symbol = self + .resolve_import_href + .call2(&this, &symbol, &src) + .expect("resolve_import_href errored"); + + serde_wasm_bindgen::from_value(global_symbol) + .expect("resolve_import_href returned an invalid value") + } + + fn resolve_source(&self, location: &deno_doc::Location) -> Option { + let this = JsValue::null(); + + let location = serde_wasm_bindgen::to_value(&location).unwrap(); + + let global_symbol = self + .resolve_source + .call1(&this, &location) + .expect("resolve_source errored"); + + serde_wasm_bindgen::from_value(global_symbol) + .expect("resolve_source returned an invalid value") + } + + fn resolve_external_jsdoc_module( + &self, + module: &str, + symbol: Option<&str>, + ) -> Option<(String, String)> { + let this = JsValue::null(); + + let module = serde_wasm_bindgen::to_value(&module).unwrap(); + let symbol = serde_wasm_bindgen::to_value(&symbol).unwrap(); + + let global_symbol = self + .resolve_external_jsdoc_module + .call2(&this, &module, &symbol) + .expect("resolve_external_jsdoc_module errored"); + + serde_wasm_bindgen::from_value(global_symbol) + .expect("resolve_external_jsdoc_module returned an invalid value") + } +} + +struct JsUsageComposer { + single_mode: bool, + compose: js_sys::Function, +} + +impl deno_doc::html::UsageComposer for JsUsageComposer { + fn is_single_mode(&self) -> bool { + self.single_mode + } + + fn compose( + &self, + current_resolve: UrlResolveKind, + usage_to_md: UsageToMd, + ) -> IndexMap { + let this = JsValue::null(); + + let current_resolve = + serde_wasm_bindgen::to_value(¤t_resolve).unwrap(); + + let global_symbol = self + .compose + .call2(&this, ¤t_resolve, &usage_to_md) + .expect("compose errored"); + + serde_wasm_bindgen::from_value(global_symbol) + .expect("compose returned an invalid value") + } +} + +#[allow(clippy::too_many_arguments)] +fn generate_html_inner( + package_name: Option, + main_entrypoint: Option, + + usage_composer_single_mode: bool, + usage_composer_compose: js_sys::Function, + + rewrite_map: JsValue, + category_docs: JsValue, + disable_search: bool, + symbol_redirect_map: JsValue, + default_symbol_map: JsValue, + + resolve_path: Option, + resolve_global_symbol: js_sys::Function, + resolve_import_href: js_sys::Function, + resolve_source: js_sys::Function, + resolve_external_jsdoc_module: js_sys::Function, + + markdown_renderer: js_sys::Function, + markdown_stripper: js_sys::Function, + head_inject: Option, + + doc_nodes_by_url: JsValue, + + json: bool, +) -> Result { + let main_entrypoint = main_entrypoint + .map(|s| ModuleSpecifier::parse(&s)) + .transpose() + .map_err(|e| anyhow::Error::from(e).context("mainEntrypoint"))?; + + let rewrite_map = serde_wasm_bindgen::from_value::< + Option>, + >(rewrite_map) + .map_err(|err| anyhow!("rewriteMap: {}", err))?; + + let category_docs = serde_wasm_bindgen::from_value::< + Option>>, + >(category_docs) + .map_err(|err| anyhow!("categoryDocs: {}", err))?; + + let symbol_redirect_map = serde_wasm_bindgen::from_value::< + Option>>, + >(symbol_redirect_map) + .map_err(|err| anyhow!("symbolRedirectMap: {}", err))?; + + let default_symbol_map = serde_wasm_bindgen::from_value::< + Option>, + >(default_symbol_map) + .map_err(|err| anyhow!("defaultSymbolMap: {}", err))?; + + let doc_nodes_by_url: IndexMap> = + serde_wasm_bindgen::from_value(doc_nodes_by_url) + .map_err(|err| anyhow!("docNodesByUrl: {}", err))?; + + let markdown_renderer = Rc::new( + move |md: &str, + title_only: bool, + file_path: Option, + anchorizer: deno_doc::html::jsdoc::Anchorizer| { + let this = JsValue::null(); + let md = serde_wasm_bindgen::to_value(md).unwrap(); + let title_only = serde_wasm_bindgen::to_value(&title_only).unwrap(); + let file_path = serde_wasm_bindgen::to_value(&file_path).unwrap(); + + let html = markdown_renderer + .apply( + &this, + &js_sys::Array::of4(&md, &title_only, &file_path, &anchorizer), + ) + .expect("markdown_renderer errored"); + + serde_wasm_bindgen::from_value(html) + .expect("markdown_renderer returned an invalid value") + }, + ); + + let markdown_stripper = Rc::new(move |md: &str| { + let this = JsValue::null(); + let md = serde_wasm_bindgen::to_value(md).unwrap(); + + let stripped = markdown_stripper + .call1(&this, &md) + .expect("markdown_stripper errored"); + + serde_wasm_bindgen::from_value(stripped) + .expect("markdown_stripper returned an invalid value") + }); + + let head_inject: Option String + 'static>> = + if let Some(head_inject) = head_inject { + let head_inject = Rc::new(move |root: &str| { + let this = JsValue::null(); + let root = serde_wasm_bindgen::to_value(root).unwrap(); + + let inject = head_inject + .call1(&this, &root) + .expect("head_inject errored"); + + serde_wasm_bindgen::from_value::(inject) + .expect("head_inject returned an invalid value") + }); + + Some(head_inject) + } else { + None + }; + + let ctx = deno_doc::html::GenerateCtx::create_basic( + deno_doc::html::GenerateOptions { + package_name, + main_entrypoint, + href_resolver: Rc::new(JsHrefResolver { + resolve_path, + resolve_global_symbol, + resolve_import_href, + resolve_source, + resolve_external_jsdoc_module, + }), + usage_composer: Rc::new(JsUsageComposer { + single_mode: usage_composer_single_mode, + compose: usage_composer_compose, + }), + rewrite_map, + category_docs, + disable_search, + symbol_redirect_map, + default_symbol_map, + markdown_renderer, + markdown_stripper, + head_inject, + }, + doc_nodes_by_url, + )?; + + if json { + let files = deno_doc::html::generate_json(ctx)?; + + let serializer = + serde_wasm_bindgen::Serializer::new().serialize_maps_as_objects(true); + + files + .serialize(&serializer) + .map_err(|err| anyhow!("{}", err)) + } else { + let files = deno_doc::html::generate(ctx)?; + + let serializer = + serde_wasm_bindgen::Serializer::new().serialize_maps_as_objects(true); + + files + .serialize(&serializer) + .map_err(|err| anyhow!("{}", err)) + } +} diff --git a/rust-toolchain.toml b/rust-toolchain.toml index a436857e..80afd2d3 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "1.76.0" +channel = "1.83.0" components = ["rustfmt", "clippy"] diff --git a/src/class.rs b/src/class.rs index 824a688b..f8dd4d70 100644 --- a/src/class.rs +++ b/src/class.rs @@ -1,7 +1,7 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -use deno_ast::ParsedSource; use deno_ast::SourceRangedForSpanned; +use deno_graph::symbols::EsModuleInfo; use serde::Deserialize; use serde::Serialize; @@ -32,7 +32,7 @@ use crate::ParamDef; cfg_if! { if #[cfg(feature = "rust")] { - use crate::colors; + use deno_terminal::colors; use crate::display::display_abstract; use crate::display::display_accessibility; use crate::display::display_async; @@ -113,14 +113,14 @@ pub struct ClassPropertyDef { pub ts_type: Option, pub readonly: bool, pub accessibility: Option, - #[serde(skip_serializing_if = "Vec::is_empty", default)] - pub decorators: Vec, + #[serde(skip_serializing_if = "<[_]>::is_empty", default)] + pub decorators: Box<[DecoratorDef]>, pub optional: bool, pub is_abstract: bool, pub is_static: bool, #[serde(skip_serializing_if = "is_false", default)] pub is_override: bool, - pub name: String, + pub name: Box, pub location: Location, } @@ -172,7 +172,7 @@ pub struct ClassMethodDef { pub is_static: bool, #[serde(skip_serializing_if = "is_false", default)] pub is_override: bool, - pub name: String, + pub name: Box, pub kind: deno_ast::swc::ast::MethodKind, pub function_def: FunctionDef, pub location: Location, @@ -220,24 +220,24 @@ impl Display for ClassMethodDef { pub struct ClassDef { #[serde(skip_serializing_if = "Option::is_none", default)] /// set when the class is a default export and has a name in its declaration - pub def_name: Option, + pub def_name: Option>, pub is_abstract: bool, - pub constructors: Vec, - pub properties: Vec, - pub index_signatures: Vec, - pub methods: Vec, - pub extends: Option, - pub implements: Vec, - pub type_params: Vec, - pub super_type_params: Vec, - #[serde(skip_serializing_if = "Vec::is_empty", default)] - pub decorators: Vec, + pub constructors: Box<[ClassConstructorDef]>, + pub properties: Box<[ClassPropertyDef]>, + pub index_signatures: Box<[IndexSignatureDef]>, + pub methods: Box<[ClassMethodDef]>, + pub extends: Option>, + pub implements: Box<[TsTypeDef]>, + pub type_params: Box<[TsTypeParamDef]>, + pub super_type_params: Box<[TsTypeDef]>, + #[serde(skip_serializing_if = "<[_]>::is_empty", default)] + pub decorators: Box<[DecoratorDef]>, } pub fn class_to_class_def( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, class: &deno_ast::swc::ast::Class, - def_name: Option, + def_name: Option>, ) -> (ClassDef, JsDoc) { use deno_ast::swc::ast::Expr; @@ -262,10 +262,10 @@ pub fn class_to_class_def( } } - let extends: Option = match &class.super_class { + let extends: Option> = match &class.super_class { Some(boxed) => { let expr: &Expr = boxed; - walk_class_extends(expr) + walk_class_extends(expr).map(|s| s.into_boxed_str()) } None => None, }; @@ -273,18 +273,17 @@ pub fn class_to_class_def( let implements = class .implements .iter() - .map(|expr| TsTypeDef::ts_expr_with_type_args(parsed_source, expr)) - .collect::>(); + .map(|expr| TsTypeDef::ts_expr_with_type_args(module_info, expr)) + .collect::>(); for member in &class.body { use deno_ast::swc::ast::ClassMember::*; match member { Constructor(ctor) => { - if let Some(ctor_js_doc) = - js_doc_for_range(parsed_source, &ctor.range()) + if let Some(ctor_js_doc) = js_doc_for_range(module_info, &ctor.range()) { - let constructor_name = prop_name_to_string(parsed_source, &ctor.key); + let constructor_name = prop_name_to_string(module_info, &ctor.key); let mut params = vec![]; @@ -295,7 +294,7 @@ pub fn class_to_class_def( Param(param) => ClassConstructorParamDef { accessibility: None, is_override: false, - param: param_to_param_def(parsed_source, param), + param: param_to_param_def(module_info, param), readonly: false, }, TsParamProp(ts_param_prop) => { @@ -303,10 +302,10 @@ pub fn class_to_class_def( let param = match &ts_param_prop.param { TsParamPropParam::Ident(ident) => { - ident_to_param_def(parsed_source, ident) + ident_to_param_def(module_info, ident) } TsParamPropParam::Assign(assign_pat) => { - assign_pat_to_param_def(parsed_source, assign_pat) + assign_pat_to_param_def(module_info, assign_pat) } }; @@ -328,22 +327,18 @@ pub fn class_to_class_def( has_body: ctor.body.is_some(), name: constructor_name, params, - location: get_location(parsed_source, ctor.start()), + location: get_location(module_info, ctor.start()), }; constructors.push(constructor_def); } } Method(class_method) => { if let Some(method_js_doc) = - js_doc_for_range(parsed_source, &class_method.range()) + js_doc_for_range(module_info, &class_method.range()) { - let method_name = - prop_name_to_string(parsed_source, &class_method.key); - let fn_def = function_to_function_def( - parsed_source, - &class_method.function, - None, - ); + let method_name = prop_name_to_string(module_info, &class_method.key); + let fn_def = + function_to_function_def(module_info, &class_method.function, None); let method_def = ClassMethodDef { js_doc: method_js_doc, accessibility: class_method.accessibility, @@ -351,33 +346,33 @@ pub fn class_to_class_def( is_abstract: class_method.is_abstract, is_static: class_method.is_static, is_override: class_method.is_override, - name: method_name, + name: method_name.into_boxed_str(), kind: class_method.kind, function_def: fn_def, - location: get_location(parsed_source, class_method.start()), + location: get_location(module_info, class_method.start()), }; methods.push(method_def); } } ClassProp(class_prop) => { if let Some(prop_js_doc) = - js_doc_for_range(parsed_source, &class_prop.range()) + js_doc_for_range(module_info, &class_prop.range()) { let ts_type = if let Some(type_ann) = &class_prop.type_ann { // if the property has a type annotation, use it - Some(TsTypeDef::new(parsed_source, &type_ann.type_ann)) + Some(TsTypeDef::new(module_info, &type_ann.type_ann)) } else if let Some(value) = &class_prop.value { // else, if it has an initializer, try to infer the type - infer_ts_type_from_expr(parsed_source, value, false) + infer_ts_type_from_expr(module_info, value, false) } else { // else, none None }; - let prop_name = prop_name_to_string(parsed_source, &class_prop.key); + let prop_name = prop_name_to_string(module_info, &class_prop.key); let decorators = - decorators_to_defs(parsed_source, &class_prop.decorators); + decorators_to_defs(module_info, &class_prop.decorators); let prop_def = ClassPropertyDef { js_doc: prop_js_doc, @@ -388,30 +383,30 @@ pub fn class_to_class_def( is_static: class_prop.is_static, is_override: class_prop.is_override, accessibility: class_prop.accessibility, - name: prop_name, + name: prop_name.into_boxed_str(), decorators, - location: get_location(parsed_source, class_prop.start()), + location: get_location(module_info, class_prop.start()), }; properties.push(prop_def); } } TsIndexSignature(ts_index_sig) => { if let Some(js_doc) = - js_doc_for_range(parsed_source, &ts_index_sig.range()) + js_doc_for_range(module_info, &ts_index_sig.range()) { let mut params = vec![]; for param in &ts_index_sig.params { - let param_def = ts_fn_param_to_param_def(parsed_source, param); + let param_def = ts_fn_param_to_param_def(module_info, param); params.push(param_def); } let ts_type = ts_index_sig .type_ann .as_ref() - .map(|rt| TsTypeDef::new(parsed_source, &rt.type_ann)); + .map(|rt| TsTypeDef::new(module_info, &rt.type_ann)); let index_sig_def = IndexSignatureDef { - location: get_location(parsed_source, ts_index_sig.start()), + location: get_location(module_info, ts_index_sig.start()), js_doc, readonly: ts_index_sig.readonly, params, @@ -428,21 +423,21 @@ pub fn class_to_class_def( } let type_params = maybe_type_param_decl_to_type_param_defs( - parsed_source, + module_info, class.type_params.as_deref(), ); let super_type_params = maybe_type_param_instantiation_to_type_defs( - parsed_source, + module_info, class.super_type_params.as_deref(), ); - let decorators = decorators_to_defs(parsed_source, &class.decorators); + let decorators = decorators_to_defs(module_info, &class.decorators); // JSDoc associated with the class may actually be a leading comment on a // decorator, and so we should parse out the JSDoc for the first decorator let js_doc = if !class.decorators.is_empty() { - js_doc_for_range(parsed_source, &class.decorators[0].range()).unwrap() + js_doc_for_range(module_info, &class.decorators[0].range()).unwrap() } else { JsDoc::default() }; @@ -453,10 +448,10 @@ pub fn class_to_class_def( is_abstract: class.is_abstract, extends, implements, - constructors, - properties, - index_signatures, - methods, + constructors: constructors.into_boxed_slice(), + properties: properties.into_boxed_slice(), + index_signatures: index_signatures.into_boxed_slice(), + methods: methods.into_boxed_slice(), type_params, super_type_params, decorators, @@ -466,12 +461,12 @@ pub fn class_to_class_def( } pub fn get_doc_for_class_decl( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, class_decl: &deno_ast::swc::ast::ClassDecl, ) -> (String, ClassDef, JsDoc) { let class_name = class_decl.ident.sym.to_string(); let (class_def, js_doc) = - class_to_class_def(parsed_source, &class_decl.class, None); + class_to_class_def(module_info, &class_decl.class, None); (class_name, class_def, js_doc) } diff --git a/src/colors.rs b/src/colors.rs deleted file mode 100644 index bcf4331a..00000000 --- a/src/colors.rs +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -use std::fmt; -use std::io::Write; -use std::sync::atomic::AtomicBool; -use std::sync::atomic::Ordering; -use termcolor::Ansi; -use termcolor::Color::Ansi256; -use termcolor::Color::Blue; -use termcolor::Color::Green; -use termcolor::Color::Magenta; -use termcolor::Color::Red; -use termcolor::ColorSpec; -use termcolor::WriteColor; - -lazy_static! { - static ref USE_COLOR: AtomicBool = AtomicBool::new(false); -} - -#[cfg(feature = "rust")] -pub fn enable_color() { - USE_COLOR.store(true, Ordering::Relaxed); -} - -#[cfg(feature = "rust")] -pub fn disable_color() { - USE_COLOR.store(false, Ordering::Relaxed); -} - -pub fn use_color() -> bool { - USE_COLOR.load(Ordering::Relaxed) -} - -fn style>(s: S, colorspec: ColorSpec) -> impl fmt::Display { - if !use_color() { - return String::from(s.as_ref()); - } - let mut v = Vec::new(); - let mut ansi_writer = Ansi::new(&mut v); - ansi_writer.set_color(&colorspec).unwrap(); - ansi_writer.write_all(s.as_ref().as_bytes()).unwrap(); - ansi_writer.reset().unwrap(); - String::from_utf8_lossy(&v).into_owned() -} - -pub fn yellow>(s: S) -> impl fmt::Display { - let mut style_spec = ColorSpec::new(); - style_spec.set_fg(Some(Ansi256(11))); - style(s, style_spec) -} - -pub fn cyan>(s: S) -> impl fmt::Display { - let mut style_spec = ColorSpec::new(); - style_spec.set_fg(Some(Ansi256(14))); - style(s, style_spec) -} - -pub fn red>(s: S) -> impl fmt::Display { - let mut style_spec = ColorSpec::new(); - style_spec.set_fg(Some(Red)); - style(s, style_spec) -} - -pub fn green>(s: S) -> impl fmt::Display { - let mut style_spec = ColorSpec::new(); - style_spec.set_fg(Some(Green)).set_intense(true); - style(s, style_spec) -} - -pub fn magenta>(s: S) -> impl fmt::Display { - let mut style_spec = ColorSpec::new(); - style_spec.set_fg(Some(Magenta)); - style(s, style_spec) -} - -pub fn bold>(s: S) -> impl fmt::Display { - let mut style_spec = ColorSpec::new(); - style_spec.set_bold(true); - style(s, style_spec) -} - -#[cfg(feature = "rust")] -pub fn gray>(s: S) -> impl fmt::Display { - let mut style_spec = ColorSpec::new(); - style_spec.set_fg(Some(Ansi256(8))); - style(s, style_spec) -} - -#[cfg(feature = "rust")] -pub fn italic_gray>(s: S) -> impl fmt::Display { - let mut style_spec = ColorSpec::new(); - style_spec.set_fg(Some(Ansi256(8))).set_italic(true); - style(s, style_spec) -} - -#[cfg(feature = "rust")] -pub fn italic_cyan>(s: S) -> impl fmt::Display { - let mut style_spec = ColorSpec::new(); - style_spec.set_fg(Some(Ansi256(14))).set_italic(true); - style(s, style_spec) -} - -pub fn intense_blue>(s: S) -> impl fmt::Display { - let mut style_spec = ColorSpec::new(); - style_spec.set_fg(Some(Blue)).set_intense(true); - style(s, style_spec) -} diff --git a/src/decorators.rs b/src/decorators.rs index f597e4ea..0240086d 100644 --- a/src/decorators.rs +++ b/src/decorators.rs @@ -1,13 +1,13 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -use crate::colors; use crate::node::Location; use crate::util::swc::get_location; use deno_ast::swc::ast::Decorator; use deno_ast::swc::ast::Expr; -use deno_ast::ParsedSource; use deno_ast::SourceRangedForSpanned; +use deno_graph::symbols::EsModuleInfo; +use deno_terminal::colors; use serde::Deserialize; use serde::Serialize; use std::fmt::Display; @@ -41,7 +41,7 @@ impl Display for DecoratorDef { impl DecoratorDef { fn from_ast_decorator( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, decorator: &Decorator, ) -> Self { match decorator.expr.as_ref() { @@ -51,41 +51,44 @@ impl DecoratorDef { let args = call_expr .args .iter() - .map(|a| a.text_fast(parsed_source.text_info_lazy()).to_string()) + .map(|a| { + a.text_fast(module_info.source().text_info_lazy()) + .to_string() + }) .collect(); return Self { name: ident.sym.to_string(), args, - location: get_location(parsed_source, ident.start()), + location: get_location(module_info, ident.start()), }; } } Self { name: "[UNSUPPORTED]".to_string(), args: vec![], - location: get_location(parsed_source, call_expr.start()), + location: get_location(module_info, call_expr.start()), } } Expr::Ident(ident) => Self { name: ident.sym.to_string(), args: vec![], - location: get_location(parsed_source, ident.start()), + location: get_location(module_info, ident.start()), }, _ => Self { name: "[UNSUPPORTED]".to_string(), args: vec![], - location: get_location(parsed_source, decorator.start()), + location: get_location(module_info, decorator.start()), }, } } } pub fn decorators_to_defs( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, decorators: &[Decorator], -) -> Vec { +) -> Box<[DecoratorDef]> { decorators .iter() - .map(|d| DecoratorDef::from_ast_decorator(parsed_source, d)) + .map(|d| DecoratorDef::from_ast_decorator(module_info, d)) .collect() } diff --git a/src/diagnostics.rs b/src/diagnostics.rs index f4d64033..1fc4a882 100644 --- a/src/diagnostics.rs +++ b/src/diagnostics.rs @@ -3,13 +3,13 @@ use crate::js_doc::JsDoc; use crate::node::DeclarationKind; use crate::node::DocNode; +use crate::node::DocNodeDef; use crate::node::NamespaceDef; use crate::ts_type::TsTypeDef; use crate::util::swc::get_text_info_location; use crate::util::swc::has_ignorable_js_doc_tag; use crate::util::symbol::symbol_has_ignorable_js_doc_tag; use crate::variable::VariableDef; -use crate::DocNodeKind; use crate::Location; use deno_ast::diagnostics::Diagnostic; @@ -110,13 +110,21 @@ impl Diagnostic for DocDiagnostic { } fn snippet(&self) -> Option> { + let start_byte_index = self.location.byte_index; + let start_char_len = &self.text_info.text()[start_byte_index..] + .chars() + .next() + .map(|ch| ch.len_utf8()) + .unwrap_or(1); Some(DiagnosticSnippet { source: Cow::Borrowed(&self.text_info), highlights: vec![DiagnosticSnippetHighlight { style: DiagnosticSnippetHighlightStyle::Error, range: DiagnosticSourceRange { - start: DiagnosticSourcePos::ByteIndex(self.location.byte_index), - end: DiagnosticSourcePos::ByteIndex(self.location.byte_index + 1), + start: DiagnosticSourcePos::ByteIndex(start_byte_index), + end: DiagnosticSourcePos::ByteIndex( + start_byte_index + start_char_len, + ), }, description: None, }], @@ -243,7 +251,10 @@ impl<'a> DiagnosticsCollector<'a> { }) // should never happen, but just in case .unwrap_or_else(|| Location { - filename: referenced_module.specifier().to_string(), + filename: referenced_module + .specifier() + .to_string() + .into_boxed_str(), line: 1, col: 0, byte_index: 0, @@ -352,7 +363,7 @@ struct DiagnosticDocNodeVisitor<'a, 'b> { diagnostics: &'a mut DiagnosticsCollector<'b>, } -impl<'a, 'b> DiagnosticDocNodeVisitor<'a, 'b> { +impl DiagnosticDocNodeVisitor<'_, '_> { pub fn visit_doc_nodes<'c, I>(&'c mut self, doc_nodes: I) where I: Iterator, @@ -364,8 +375,9 @@ impl<'a, 'b> DiagnosticDocNodeVisitor<'a, 'b> { } if let Some(last_node) = last_node { - if doc_node.name == last_node.name && last_node.function_def.is_some() { - if let Some(current_fn) = &doc_node.function_def { + if doc_node.name == last_node.name && last_node.function_def().is_some() + { + if let Some(current_fn) = &doc_node.function_def() { if current_fn.has_body { continue; // it's an overload. Ignore it } @@ -382,16 +394,18 @@ impl<'a, 'b> DiagnosticDocNodeVisitor<'a, 'b> { } fn visit_doc_node(&mut self, doc_node: &DocNode) { - fn is_js_docable_kind(kind: &DocNodeKind) -> bool { - match kind { - DocNodeKind::Class - | DocNodeKind::Enum - | DocNodeKind::Function - | DocNodeKind::Interface - | DocNodeKind::Namespace - | DocNodeKind::TypeAlias - | DocNodeKind::Variable => true, - DocNodeKind::Import | DocNodeKind::ModuleDoc => false, + fn is_js_docable_kind(node: &DocNode) -> bool { + match node.def { + DocNodeDef::Class { .. } + | DocNodeDef::Enum { .. } + | DocNodeDef::Function { .. } + | DocNodeDef::Interface { .. } + | DocNodeDef::Namespace { .. } + | DocNodeDef::TypeAlias { .. } + | DocNodeDef::Variable { .. } => true, + DocNodeDef::Import { .. } + | DocNodeDef::ModuleDoc { .. } + | DocNodeDef::Reference { .. } => false, } } @@ -399,29 +413,29 @@ impl<'a, 'b> DiagnosticDocNodeVisitor<'a, 'b> { return; // skip, we don't do these diagnostics above private nodes } - if is_js_docable_kind(&doc_node.kind) { + if is_js_docable_kind(doc_node) { self .diagnostics .check_missing_js_doc(&doc_node.js_doc, &doc_node.location); } - if let Some(def) = &doc_node.class_def { + if let Some(def) = &doc_node.class_def() { self.visit_class_def(def); } - if let Some(def) = &doc_node.function_def { + if let Some(def) = &doc_node.function_def() { self.visit_function_def(doc_node, def); } - if let Some(def) = &doc_node.interface_def { + if let Some(def) = &doc_node.interface_def() { self.visit_interface_def(def); } - if let Some(def) = &doc_node.namespace_def { + if let Some(def) = &doc_node.namespace_def() { self.visit_namespace_def(def); } - if let Some(def) = &doc_node.variable_def { + if let Some(def) = &doc_node.variable_def() { self.visit_variable_def(doc_node, def); } } @@ -439,7 +453,7 @@ impl<'a, 'b> DiagnosticDocNodeVisitor<'a, 'b> { } // properties - for prop in &def.properties { + for prop in def.properties.iter() { if prop.accessibility == Some(Accessibility::Private) { continue; // don't do diagnostics for private types } @@ -454,7 +468,7 @@ impl<'a, 'b> DiagnosticDocNodeVisitor<'a, 'b> { } // index signatures - for sig in &def.index_signatures { + for sig in def.index_signatures.iter() { self .diagnostics .check_missing_js_doc(&sig.js_doc, &sig.location); @@ -467,9 +481,9 @@ impl<'a, 'b> DiagnosticDocNodeVisitor<'a, 'b> { // methods let mut last_name: Option<&str> = None; - for method in &def.methods { + for method in def.methods.iter() { if let Some(last_name) = last_name { - if method.name == last_name && method.function_def.has_body { + if &*method.name == last_name && method.function_def.has_body { continue; // skip, it's the implementation signature } } diff --git a/src/display.rs b/src/display.rs index 7dfac3bc..aba3b559 100644 --- a/src/display.rs +++ b/src/display.rs @@ -1,20 +1,10 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -use crate::colors; + +use deno_terminal::colors; use std::fmt::Display; use std::fmt::Formatter; use std::fmt::Result; -pub(crate) struct Indent(pub i64); - -impl Display for Indent { - fn fmt(&self, f: &mut Formatter<'_>) -> Result { - for _ in 0..self.0 { - write!(f, " ")?; - } - Ok(()) - } -} - pub(crate) struct SliceDisplayer<'a, T: Display>(&'a [T], &'a str, bool); impl<'a, T: Display> SliceDisplayer<'a, T> { diff --git a/src/enum.rs b/src/enum.rs index dca38798..c73a4303 100644 --- a/src/enum.rs +++ b/src/enum.rs @@ -1,7 +1,7 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -use deno_ast::ParsedSource; use deno_ast::SourceRangedForSpanned; +use deno_graph::symbols::EsModuleInfo; use serde::Deserialize; use serde::Serialize; @@ -30,7 +30,7 @@ pub struct EnumDef { } pub fn get_doc_for_ts_enum_decl( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, enum_decl: &deno_ast::swc::ast::TsEnumDecl, ) -> (String, EnumDef) { let enum_name = enum_decl.id.sym.to_string(); @@ -39,14 +39,13 @@ pub fn get_doc_for_ts_enum_decl( for enum_member in &enum_decl.members { use deno_ast::swc::ast::TsEnumMemberId::*; - if let Some(js_doc) = js_doc_for_range(parsed_source, &enum_member.range()) - { + if let Some(js_doc) = js_doc_for_range(module_info, &enum_member.range()) { let name = match &enum_member.id { Ident(ident) => ident.sym.to_string(), Str(str_) => str_.value.to_string(), }; let init = if let Some(expr) = &enum_member.init { - infer_ts_type_from_expr(parsed_source, expr, true) + infer_ts_type_from_expr(module_info, expr, true) } else { None }; @@ -55,7 +54,7 @@ pub fn get_doc_for_ts_enum_decl( name, init, js_doc, - location: get_location(parsed_source, enum_member.start()), + location: get_location(module_info, enum_member.start()), }; members.push(member_def); } diff --git a/src/function.rs b/src/function.rs index 60378d56..25bb7c83 100644 --- a/src/function.rs +++ b/src/function.rs @@ -10,7 +10,7 @@ use crate::util::swc::is_false; use crate::ParamDef; use deno_ast::swc::ast::ReturnStmt; use deno_ast::swc::ast::Stmt; -use deno_ast::ParsedSource; +use deno_graph::symbols::EsModuleInfo; use serde::Deserialize; use serde::Serialize; @@ -26,26 +26,26 @@ pub struct FunctionDef { pub has_body: bool, pub is_async: bool, pub is_generator: bool, - pub type_params: Vec, - #[serde(skip_serializing_if = "Vec::is_empty", default)] - pub decorators: Vec, + pub type_params: Box<[TsTypeParamDef]>, + #[serde(skip_serializing_if = "<[_]>::is_empty", default)] + pub decorators: Box<[DecoratorDef]>, } pub fn function_to_function_def( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, function: &deno_ast::swc::ast::Function, def_name: Option, ) -> FunctionDef { let params = function .params .iter() - .map(|param| param_to_param_def(parsed_source, param)) + .map(|param| param_to_param_def(module_info, param)) .collect(); let maybe_return_type = match function .return_type .as_deref() - .map(|return_type| TsTypeDef::new(parsed_source, &return_type.type_ann)) + .map(|return_type| TsTypeDef::new(module_info, &return_type.type_ann)) { Some(return_type) => Some(return_type), None @@ -58,7 +58,7 @@ pub fn function_to_function_def( repr: "Promise".to_string(), kind: Some(crate::ts_type::TsTypeDefKind::TypeRef), type_ref: Some(crate::ts_type::TsTypeRefDef { - type_params: Some(vec![TsTypeDef::keyword("void")]), + type_params: Some(Box::new([TsTypeDef::keyword("void")])), type_name: "Promise".to_string(), }), ..Default::default() @@ -71,13 +71,13 @@ pub fn function_to_function_def( }; let type_params = maybe_type_param_decl_to_type_param_defs( - parsed_source, + module_info, function.type_params.as_deref(), ); let has_body = function.body.is_some(); - let decorators = decorators_to_defs(parsed_source, &function.decorators); + let decorators = decorators_to_defs(module_info, &function.decorators); FunctionDef { def_name, @@ -92,11 +92,11 @@ pub fn function_to_function_def( } pub fn get_doc_for_fn_decl( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, fn_decl: &deno_ast::swc::ast::FnDecl, ) -> (String, FunctionDef) { let name = fn_decl.ident.sym.to_string(); - let fn_def = function_to_function_def(parsed_source, &fn_decl.function, None); + let fn_def = function_to_function_def(module_info, &fn_decl.function, None); (name, fn_def) } diff --git a/src/html/comrak.rs b/src/html/comrak.rs new file mode 100644 index 00000000..33b9a3e5 --- /dev/null +++ b/src/html/comrak.rs @@ -0,0 +1,264 @@ +use crate::html::ShortPath; +use comrak::adapters::SyntaxHighlighterAdapter; +use comrak::nodes::AstNode; +use comrak::nodes::NodeValue; +use comrak::Arena; +use std::collections::HashMap; +use std::io::BufWriter; +use std::io::Write; +use std::rc::Rc; +use std::sync::Arc; + +pub const COMRAK_STYLESHEET: &str = include_str!("./templates/comrak.gen.css"); +pub const COMRAK_STYLESHEET_FILENAME: &str = "comrak.css"; + +pub type NodeHook = Box< + dyn for<'a> Fn( + &'a Arena>, + &'a AstNode<'a>, + &comrak::Options, + &comrak::Plugins, + ), +>; + +fn walk_node<'a>( + node_hook: &NodeHook, + arena: &'a Arena>, + node: &'a AstNode<'a>, + options: &comrak::Options, + plugins: &comrak::Plugins, +) { + for child in node.children() { + node_hook(arena, child, options, plugins); + walk_node(node_hook, arena, child, options, plugins); + } +} + +fn walk_node_title<'a>(node: &'a AstNode<'a>) { + for child in node.children() { + if matches!( + child.data.borrow().value, + NodeValue::Document + | NodeValue::Paragraph + | NodeValue::Heading(_) + | NodeValue::Text(_) + | NodeValue::Code(_) + | NodeValue::HtmlInline(_) + | NodeValue::Emph + | NodeValue::Strong + | NodeValue::Strikethrough + | NodeValue::Superscript + | NodeValue::Link(_) + | NodeValue::Math(_) + | NodeValue::Escaped + | NodeValue::WikiLink(_) + | NodeValue::Underline + | NodeValue::SoftBreak + ) { + walk_node_title(child); + } else { + // delete the node + child.detach(); + } + } +} + +pub fn render_node<'a>( + node: &'a AstNode<'a>, + options: &comrak::Options, + plugins: &comrak::Plugins, +) -> String { + let mut bw = BufWriter::new(Vec::new()); + comrak::format_html_with_plugins(node, options, &mut bw, plugins).unwrap(); + String::from_utf8(bw.into_inner().unwrap()).unwrap() +} + +pub fn strip(md: &str) -> String { + let mut options = comrak::Options::default(); + options.extension.autolink = true; + options.extension.description_lists = true; + options.extension.strikethrough = true; + options.extension.superscript = true; + options.extension.table = true; + options.extension.tagfilter = true; + options.extension.tasklist = true; + options.render.escape = true; + + let arena = Arena::new(); + let root = comrak::parse_document(&arena, md, &options); + + fn collect_text<'a>(node: &'a AstNode<'a>, output: &mut BufWriter>) { + match node.data.borrow().value { + NodeValue::Text(ref literal) + | NodeValue::Code(comrak::nodes::NodeCode { ref literal, .. }) => { + output.write_all(literal.as_bytes()).unwrap(); + } + NodeValue::LineBreak | NodeValue::SoftBreak => { + output.write_all(b" ").unwrap() + } + _ => { + for n in node.children() { + collect_text(n, output); + } + } + } + } + + let mut bw = BufWriter::new(Vec::new()); + collect_text(root, &mut bw); + String::from_utf8(bw.into_inner().unwrap()).unwrap() +} + +pub type HtmlClean = Box String>; + +pub fn create_renderer( + syntax_highlighter: Option>, + node_hook: Option, + clean: Option, +) -> super::jsdoc::MarkdownRenderer { + let mut options = comrak::Options::default(); + options.extension.autolink = true; + options.extension.description_lists = true; + options.extension.strikethrough = true; + options.extension.superscript = true; + options.extension.table = true; + options.extension.tagfilter = true; + options.extension.tasklist = true; + + options.render.escape = clean.is_none(); + options.render.unsafe_ = clean.is_some(); // its fine because we run the cleaner afterwards + + let renderer = move |md: &str, + title_only: bool, + _file_path: Option, + anchorizer: super::jsdoc::Anchorizer| + -> Option { + let mut plugins = comrak::Plugins::default(); + let heading_adapter = ComrakHeadingAdapter(anchorizer); + let highlight_adapter = + ComrakHighlightWrapperAdapter(syntax_highlighter.clone()); + + if !title_only { + plugins.render.codefence_syntax_highlighter = Some(&highlight_adapter); + plugins.render.heading_adapter = Some(&heading_adapter); + } + + let html = { + let arena = Arena::new(); + let root = comrak::parse_document(&arena, md, &options); + + if title_only { + walk_node_title(root); + + if let Some(child) = root.first_child() { + render_node(child, &options, &plugins) + } else { + return None; + } + } else { + if let Some(node_hook) = &node_hook { + walk_node(node_hook, &arena, root, &options, &plugins); + } + + render_node(root, &options, &plugins) + } + }; + + let class_name = if title_only { + "markdown_summary" + } else { + "markdown" + }; + + let html = format!( + r#"
{}
"#, + if let Some(clean) = &clean { + clean(html) + } else { + html + } + ); + + Some(html) + }; + + Rc::new(renderer) +} + +pub struct ComrakHeadingAdapter(super::jsdoc::Anchorizer); + +impl comrak::adapters::HeadingAdapter for ComrakHeadingAdapter { + fn enter( + &self, + output: &mut dyn Write, + heading: &comrak::adapters::HeadingMeta, + _sourcepos: Option, + ) -> std::io::Result<()> { + let anchor = self.0(heading.content.clone(), heading.level); + + writeln!(output, r#""#, heading.level) + } + + fn exit( + &self, + output: &mut dyn Write, + heading: &comrak::adapters::HeadingMeta, + ) -> std::io::Result<()> { + writeln!(output, "", heading.level)?; + Ok(()) + } +} + +pub struct ComrakHighlightWrapperAdapter( + pub Option>, +); + +impl SyntaxHighlighterAdapter for ComrakHighlightWrapperAdapter { + fn write_highlighted( + &self, + output: &mut dyn Write, + lang: Option<&str>, + code: &str, + ) -> std::io::Result<()> { + if let Some(adapter) = &self.0 { + adapter.write_highlighted(output, lang, code)?; + } else { + comrak::html::escape(output, code.as_bytes())?; + } + + write!(output, "")?; + write!( + output, + r#""#, + html_escape::encode_double_quoted_attribute(code), + include_str!("./templates/icons/copy.svg"), + include_str!("./templates/icons/check.svg"), + )?; + write!(output, "") + } + + fn write_pre_tag( + &self, + output: &mut dyn Write, + mut attributes: HashMap, + ) -> std::io::Result<()> { + attributes.insert("class".to_string(), "highlight".to_string()); + if let Some(adapter) = &self.0 { + adapter.write_pre_tag(output, attributes) + } else { + comrak::html::write_opening_tag(output, "pre", attributes) + } + } + + fn write_code_tag( + &self, + output: &mut dyn Write, + attributes: HashMap, + ) -> std::io::Result<()> { + if let Some(adapter) = &self.0 { + adapter.write_code_tag(output, attributes) + } else { + comrak::html::write_opening_tag(output, "code", attributes) + } + } +} diff --git a/src/html/comrak_adapters.rs b/src/html/comrak_adapters.rs deleted file mode 100644 index d4586f77..00000000 --- a/src/html/comrak_adapters.rs +++ /dev/null @@ -1,350 +0,0 @@ -// Copied and modified from https://github.com/kivikakk/comrak/blob/main/src/plugins/syntect.rs - -//! Adapter for the Syntect syntax highlighter plugin. - -use crate::html::ShortPath; -use comrak::adapters::HeadingAdapter; -use comrak::adapters::HeadingMeta; -use comrak::adapters::SyntaxHighlighterAdapter; -use comrak::nodes::Sourcepos; -use std::cmp::Ordering; -use std::collections::HashMap; -use std::io::Write; -use std::sync::Arc; -use std::sync::Mutex; - -#[derive(Debug)] -/// Syntect syntax highlighter plugin. -pub struct HighlightAdapter { - #[cfg(feature = "syntect")] - pub syntax_set: syntect::parsing::SyntaxSet, - #[cfg(feature = "syntect")] - pub theme_set: syntect::highlighting::ThemeSet, - #[cfg(feature = "tree-sitter")] - pub language_cb: - fn(&str) -> Option<&'static tree_sitter_highlight::HighlightConfiguration>, - pub show_line_numbers: bool, -} - -impl HighlightAdapter { - fn highlight_html<'a, I, H>( - &self, - iter: I, - mut highlighter: H, - ) -> Result - where - I: Iterator, - H: FnMut(&mut String, &str) -> Result<(), anyhow::Error>, - { - let mut line_numbers = String::new(); - let mut lines = String::new(); - - for (i, line) in iter.enumerate() { - let n = i + 1; - - if self.show_line_numbers { - line_numbers.push_str(&format!( - r##"{n}"##, - )); - - lines.push_str(&format!( - r#""# - )); - } - - highlighter(&mut lines, line)?; - - if self.show_line_numbers { - lines.push_str(""); - } - } - - if self.show_line_numbers { - Ok(format!( - r##"
{line_numbers}
{lines}
"## - )) - } else { - Ok(lines) - } - } - - fn write_button( - &self, - output: &mut dyn Write, - source: &str, - ) -> std::io::Result<()> { - write!(output, "
")?; - write!( - output, - r#""#, - html_escape::encode_double_quoted_attribute(source), - include_str!("./templates/icons/copy.svg") - )?; - write!(output, "") - } -} - -impl SyntaxHighlighterAdapter for HighlightAdapter { - #[cfg(any( - all(feature = "syntect", not(feature = "tree-sitter")), - all(feature = "syntect", feature = "tree-sitter") - ))] - fn write_highlighted( - &self, - output: &mut dyn Write, - lang: Option<&str>, - code: &str, - ) -> std::io::Result<()> { - let lang = match lang { - Some(l) if !l.is_empty() => l, - _ => "Plain Text", - }; - - let syntax = - self - .syntax_set - .find_syntax_by_token(lang) - .unwrap_or_else(|| { - self - .syntax_set - .find_syntax_by_first_line(code) - .unwrap_or_else(|| self.syntax_set.find_syntax_plain_text()) - }); - - let theme = &self.theme_set.themes["InspiredGitHub"]; - let mut highlighter = syntect::easy::HighlightLines::new(syntax, theme); - - match self.highlight_html( - syntect::util::LinesWithEndings::from(&code), - |lines, line| { - let regions = highlighter.highlight_line(line, &self.syntax_set)?; - syntect::html::append_highlighted_html_for_styled_line( - ®ions[..], - syntect::html::IncludeBackground::No, - lines, - )?; - - Ok(()) - }, - ) { - Ok(highlighted_code) => output.write_all(highlighted_code.as_bytes())?, - Err(_) => output.write_all(code.as_bytes())?, - } - - self.write_button(output, &code) - } - - #[cfg(all(feature = "tree-sitter", not(feature = "syntect")))] - fn write_highlighted( - &self, - output: &mut dyn Write, - lang: Option<&str>, - code: &str, - ) -> std::io::Result<()> { - let lang = lang.unwrap_or_default(); - let config = (self.language_cb)(lang); - let source = code.as_bytes(); - if let Some(config) = config { - let mut highlighter = tree_sitter_highlight::Highlighter::new(); - let res = highlighter.highlight(config, source, None, self.language_cb); - match res { - Ok(highlighter) => { - let mut renderer = tree_sitter_highlight::HtmlRenderer::new(); - match renderer.render(highlighter, source, &|highlight| { - crate::html::tree_sitter::classes(highlight) - }) { - Ok(()) => { - let html = self - .highlight_html(renderer.lines(), |lines, line| { - lines.push_str(line); - Ok(()) - }) - .unwrap(); - - output.write_all(html.as_bytes())?; - return self.write_button(output, &code); - } - Err(err) => { - eprintln!("Error rendering code: {}", err); - } - }; - } - Err(err) => { - eprintln!("Error highlighting code: {}", err); - } - } - } - comrak::html::escape(output, source)?; - self.write_button(output, &code) - } - - #[cfg(all(not(feature = "syntect"), not(feature = "tree-sitter")))] - fn write_highlighted( - &self, - output: &mut dyn Write, - _lang: Option<&str>, - code: &str, - ) -> std::io::Result<()> { - let code = html_escape::encode_text(code); - let html = self - .highlight_html(code.lines(), |lines, line| { - lines.push_str(&format!("{line}\n")); - - Ok(()) - }) - .unwrap(); - - output.write_all(html.as_bytes())?; - self.write_button(output, &code) - } - - fn write_pre_tag( - &self, - output: &mut dyn Write, - mut attributes: HashMap, - ) -> std::io::Result<()> { - attributes - .entry("class".into()) - .or_default() - .push_str(" highlight"); - comrak::html::write_opening_tag(output, "pre", attributes) - } - - fn write_code_tag( - &self, - output: &mut dyn Write, - mut attributes: HashMap, - ) -> std::io::Result<()> { - if self.show_line_numbers { - attributes - .entry("class".into()) - .or_default() - .push_str(" !flex gap-2"); - } - comrak::html::write_opening_tag(output, "code", attributes) - } -} - -#[derive(Debug)] -pub struct ToCEntry { - pub level: u8, - pub content: String, - pub anchor: String, -} - -#[derive(Clone)] -pub struct HeadingToCAdapter { - toc: Arc>>, - anchorizer: Arc>, - offset: Arc>, -} - -impl Default for HeadingToCAdapter { - fn default() -> Self { - Self { - toc: Arc::new(Mutex::new(vec![])), - anchorizer: Arc::new(Mutex::new(Default::default())), - offset: Arc::new(Mutex::new(0)), - } - } -} - -impl HeadingToCAdapter { - pub fn anchorize(&self, content: String) -> String { - let mut anchorizer = self.anchorizer.lock().unwrap(); - anchorizer.anchorize(content.clone()) - } - - pub fn add_entry( - &self, - level: u8, - content: String, - anchor: String, - ) -> String { - let mut toc = self.toc.lock().unwrap(); - let mut offset = self.offset.lock().unwrap(); - - *offset = level; - - if toc.last().map_or(true, |toc| toc.content != content) { - toc.push(ToCEntry { - level, - content, - anchor: anchor.clone(), - }); - } - - anchor - } - - pub fn render(self) -> Option { - let toc = Arc::into_inner(self.toc).unwrap().into_inner().unwrap(); - - if toc.is_empty() { - return None; - } - - let mut toc_content = vec!["
    ".to_string()]; - let mut current_level = toc.first().unwrap().level; - - for entry in toc { - match current_level.cmp(&entry.level) { - Ordering::Equal => {} - Ordering::Less => { - toc_content.push(r#"
    • "#.to_string()); - current_level = entry.level; - } - Ordering::Greater => { - toc_content.push("
  • ".to_string()); - current_level = entry.level; - } - } - - toc_content.push(format!( - r##"
  • {}
  • "##, - entry.anchor, entry.content, entry.content - )); - } - - toc_content.push(String::from("
")); - - Some(toc_content.join("")) - } -} - -impl HeadingAdapter for HeadingToCAdapter { - fn enter( - &self, - output: &mut dyn Write, - heading: &HeadingMeta, - _sourcepos: Option, - ) -> std::io::Result<()> { - let mut anchorizer = self.anchorizer.lock().unwrap(); - let offset = self.offset.lock().unwrap(); - - let anchor = anchorizer.anchorize(heading.content.clone()); - writeln!(output, r#""#, heading.level)?; - - let mut toc = self.toc.lock().unwrap(); - toc.push(ToCEntry { - level: heading.level + *offset, - content: heading.content.clone(), - anchor, - }); - - Ok(()) - } - - fn exit( - &self, - output: &mut dyn Write, - heading: &HeadingMeta, - ) -> std::io::Result<()> { - writeln!(output, "", heading.level)?; - Ok(()) - } -} - -#[cfg(feature = "ammonia")] -pub type URLRewriter = - Arc, &str) -> String) + Send + Sync>; diff --git a/src/html/default_newlines.packdump b/src/html/default_newlines.packdump deleted file mode 100644 index fd024eff..00000000 Binary files a/src/html/default_newlines.packdump and /dev/null differ diff --git a/src/html/jsdoc.rs b/src/html/jsdoc.rs index a0d44f7d..6311e78f 100644 --- a/src/html/jsdoc.rs +++ b/src/html/jsdoc.rs @@ -3,18 +3,10 @@ use super::util::*; use crate::html::ShortPath; use crate::js_doc::JsDoc; use crate::js_doc::JsDocTag; -use crate::DocNodeKind; -use comrak::nodes::Ast; -use comrak::nodes::AstNode; -use comrak::nodes::NodeHtmlBlock; -use comrak::nodes::NodeValue; -use comrak::Arena; +use crate::node::DocNodeDef; use serde::Serialize; use std::borrow::Cow; -use std::cell::RefCell; - -#[cfg(feature = "ammonia")] -use crate::html::comrak_adapters::URLRewriter; +use std::rc::Rc; lazy_static! { static ref JSDOC_LINK_RE: regex::Regex = regex::Regex::new( @@ -83,9 +75,17 @@ fn parse_links<'a>(md: &'a str, ctx: &RenderContext) -> Cow<'a, str> { short_path.as_resolve_kind(), ); if title.is_empty() { - title = short_path.display_name(); + title = short_path.display_name().to_string(); } } + } else if let Some((external_link, external_title)) = + ctx.ctx.href_resolver.resolve_external_jsdoc_module( + module_link, + symbol_match.map(|symbol_match| symbol_match.as_str()), + ) + { + link = external_link; + title = external_title; } link @@ -128,10 +128,7 @@ fn parse_links<'a>(md: &'a str, ctx: &RenderContext) -> Cow<'a, str> { }) } -fn split_markdown_title( - md: &str, - prefer_title: bool, -) -> (Option<&str>, Option<&str>) { +fn split_markdown_title(md: &str) -> (Option<&str>, Option<&str>) { let newline = md.find("\n\n").unwrap_or(usize::MAX); let codeblock = md.find("```").unwrap_or(usize::MAX); @@ -139,322 +136,80 @@ fn split_markdown_title( match md.split_at(index) { ("", body) => (None, Some(body)), - (title, "") if prefer_title => (Some(title), None), - (title, "") if !prefer_title => (None, Some(title)), + (title, "") => (None, Some(title)), (title, body) => (Some(title), Some(body)), } } -#[cfg(feature = "ammonia")] -struct AmmoniaRelativeUrlEvaluator { - current_file: Option, - url_rewriter: URLRewriter, -} - -#[cfg(feature = "ammonia")] -impl ammonia::UrlRelativeEvaluate for AmmoniaRelativeUrlEvaluator { - fn evaluate<'a>(&self, url: &'a str) -> Option> { - Some((self.url_rewriter)(self.current_file.as_ref(), url).into()) - } -} - -enum Alert { - Note, - Tip, - Important, - Warning, - Caution, +pub struct MarkdownToHTMLOptions { + pub title_only: bool, + pub no_toc: bool, } -fn match_node_value<'a>( - arena: &'a Arena>, - node: &'a AstNode<'a>, - options: &comrak::Options, - plugins: &comrak::Plugins, -) { - match &node.data.borrow().value { - NodeValue::BlockQuote => { - if let Some(paragraph_child) = node.first_child() { - if paragraph_child.data.borrow().value == NodeValue::Paragraph { - let alert = paragraph_child.first_child().and_then(|text_child| { - if let NodeValue::Text(text) = &text_child.data.borrow().value { - match text.as_str() { - "[!NOTE]" => Some(Alert::Note), - "[!TIP]" => Some(Alert::Tip), - "[!IMPORTANT]" => Some(Alert::Important), - "[!WARNING]" => Some(Alert::Warning), - "[!CAUTION]" => Some(Alert::Caution), - _ => None, - } - } else { - None - } - }); - - if let Some(alert) = alert { - let start_col = node.data.borrow().sourcepos.start; - - let document = arena.alloc(AstNode::new(RefCell::new(Ast::new( - NodeValue::Document, - start_col, - )))); - - let node_without_alert = arena.alloc(AstNode::new(RefCell::new( - Ast::new(NodeValue::Paragraph, start_col), - ))); +pub type MarkdownStripper = std::rc::Rc String)>; - for child_node in paragraph_child.children().skip(1) { - node_without_alert.append(child_node); - } - for child_node in node.children().skip(1) { - node_without_alert.append(child_node); - } - - document.append(node_without_alert); - - let html = render_node(document, options, plugins); - - let alert_title = match alert { - Alert::Note => format!( - "{}Note", - include_str!("./templates/icons/info-circle.svg") - ), - Alert::Tip => { - format!("{}Tip", include_str!("./templates/icons/bulb.svg")) - } - Alert::Important => format!( - "{}Important", - include_str!("./templates/icons/warning-message.svg") - ), - Alert::Warning => format!( - "{}Warning", - include_str!("./templates/icons/warning-triangle.svg") - ), - Alert::Caution => format!( - "{}Caution", - include_str!("./templates/icons/warning-octagon.svg") - ), - }; - - let html = format!( - r#"
{alert_title}
{html}
"#, - match alert { - Alert::Note => "note", - Alert::Tip => "tip", - Alert::Important => "important", - Alert::Warning => "warning", - Alert::Caution => "caution", - } - ); - - let alert_node = arena.alloc(AstNode::new(RefCell::new(Ast::new( - NodeValue::HtmlBlock(NodeHtmlBlock { - block_type: 6, - literal: html, - }), - start_col, - )))); - node.insert_before(alert_node); - node.detach(); - } - } - } - } - NodeValue::Link(link) => { - if link.url.ends_with(".mov") || link.url.ends_with(".mp4") { - let start_col = node.data.borrow().sourcepos.start; - - let html = format!(r#""#, link.url); - - let alert_node = arena.alloc(AstNode::new(RefCell::new(Ast::new( - NodeValue::HtmlBlock(NodeHtmlBlock { - block_type: 6, - literal: html, - }), - start_col, - )))); - node.insert_before(alert_node); - node.detach(); - } - } - _ => {} - } -} +pub fn strip(render_ctx: &RenderContext, md: &str) -> String { + let md = parse_links(md, render_ctx); -fn walk_node<'a>( - arena: &'a Arena>, - node: &'a AstNode<'a>, - options: &comrak::Options, - plugins: &comrak::Plugins, -) { - for child in node.children() { - match_node_value(arena, child, options, plugins); - walk_node(arena, child, options, plugins); - } + (render_ctx.ctx.markdown_stripper)(&md) } -fn render_node<'a>( - node: &'a AstNode<'a>, - options: &comrak::Options, - plugins: &comrak::Plugins, -) -> String { - let mut bw = std::io::BufWriter::new(Vec::new()); - comrak::format_html_with_plugins(node, options, &mut bw, plugins).unwrap(); - String::from_utf8(bw.into_inner().unwrap()).unwrap() -} +#[cfg(not(feature = "rust"))] +pub type Anchorizer<'a> = &'a js_sys::Function; +#[cfg(feature = "rust")] +pub type Anchorizer = + std::sync::Arc String + Send + Sync>; -pub struct MarkdownToHTMLOptions { - pub summary: bool, - pub summary_prefer_title: bool, - pub no_toc: bool, -} +pub type MarkdownRenderer = + Rc, Anchorizer) -> Option)>; pub fn markdown_to_html( render_ctx: &RenderContext, md: &str, render_options: MarkdownToHTMLOptions, ) -> Option { - // TODO(bartlomieju): this should be initialized only once - let mut options = comrak::Options::default(); - options.extension.autolink = true; - options.extension.description_lists = true; - options.extension.strikethrough = true; - options.extension.superscript = true; - options.extension.table = true; - options.extension.tagfilter = true; - options.extension.tasklist = true; - #[cfg(not(feature = "ammonia"))] - { - options.render.escape = true; - } - #[cfg(feature = "ammonia")] - { - options.render.unsafe_ = true; // its fine because we run ammonia afterwards - } - - let mut plugins = comrak::Plugins::default(); - plugins.render.codefence_syntax_highlighter = - Some(&render_ctx.ctx.highlight_adapter); - if !render_options.no_toc { - plugins.render.heading_adapter = Some(&render_ctx.toc); - } - - let md = parse_links(md, render_ctx); + let toc = render_ctx.toc.clone(); - let md = if render_options.summary { - let (title, _body) = - split_markdown_title(&md, render_options.summary_prefer_title); - title.unwrap_or_default() - } else { - md.as_ref() - }; - - if md.is_empty() { - return None; - } - - let class_name = if render_options.summary { - "markdown_summary" - } else { - "markdown" - }; + let anchorizer = move |content: String, level: u8| { + let mut anchorizer = toc.anchorizer.lock().unwrap(); + let offset = toc.offset.lock().unwrap(); - let mut html = { - let arena = Arena::new(); - let root = comrak::parse_document(&arena, md, &options); + let anchor = anchorizer.anchorize(&content); - walk_node(&arena, root, &options, &plugins); + if !render_options.no_toc { + let mut toc = toc.toc.lock().unwrap(); + toc.push(crate::html::render_context::ToCEntry { + level: level + *offset, + content, + anchor: anchor.clone(), + }); + } - render_node(root, &options, &plugins) + anchor }; - #[cfg(feature = "ammonia")] - { - let mut ammonia_builder = ammonia::Builder::default(); - - ammonia_builder - .add_tags(["video", "button", "svg", "path", "rect"]) - .add_generic_attributes(["id", "align"]) - .add_tag_attributes("button", ["data-copy"]) - .add_tag_attributes( - "svg", - [ - "width", - "height", - "viewBox", - "fill", - "xmlns", - "stroke", - "stroke-width", - "stroke-linecap", - "stroke-linejoin", - ], - ) - .add_tag_attributes( - "path", - [ - "d", - "fill", - "fill-rule", - "clip-rule", - "stroke", - "stroke-width", - "stroke-linecap", - "stroke-linejoin", - ], - ) - .add_tag_attributes("rect", ["x", "y", "width", "height", "fill"]) - .add_tag_attributes("video", ["src", "controls"]) - .add_allowed_classes("pre", ["highlight"]) - .add_allowed_classes("button", ["context_button"]) - .add_allowed_classes( - "div", - [ - "alert", - "alert-note", - "alert-tip", - "alert-important", - "alert-warning", - "alert-caution", - ], - ) - .link_rel(Some("nofollow")) - .url_relative(render_ctx.ctx.url_rewriter.as_ref().map_or( - ammonia::UrlRelative::PassThrough, - |url_rewriter| { - ammonia::UrlRelative::Custom(Box::new(AmmoniaRelativeUrlEvaluator { - current_file: render_ctx.get_current_resolve().get_file().cloned(), - url_rewriter: url_rewriter.clone(), - })) - }, - )); - - #[cfg(feature = "syntect")] - ammonia_builder.add_tag_attributes("span", ["style"]); + #[cfg(not(target_arch = "wasm32"))] + let anchorizer = std::sync::Arc::new(anchorizer); - #[cfg(feature = "tree-sitter")] - ammonia_builder.add_allowed_classes("span", super::tree_sitter::CLASSES); + #[cfg(target_arch = "wasm32")] + let anchorizer = wasm_bindgen::prelude::Closure::wrap( + Box::new(anchorizer) as Box String> + ); + #[cfg(target_arch = "wasm32")] + let anchorizer = wasm_bindgen::JsCast::unchecked_ref::( + anchorizer.as_ref(), + ); - html = ammonia_builder.clean(&html).to_string(); - } + let md = parse_links(md, render_ctx); - Some(format!(r#"
{html}
"#)) -} + let file = render_ctx.get_current_resolve().get_file().cloned(); -pub(crate) fn render_markdown_summary( - render_ctx: &RenderContext, - md: &str, -) -> String { - markdown_to_html( - render_ctx, - md, - MarkdownToHTMLOptions { - summary: true, - summary_prefer_title: true, - no_toc: false, - }, + (render_ctx.ctx.markdown_renderer)( + &md, + render_options.title_only, + file, + anchorizer, ) - .unwrap_or_default() } pub(crate) fn render_markdown( @@ -466,8 +221,7 @@ pub(crate) fn render_markdown( render_ctx, md, MarkdownToHTMLOptions { - summary: false, - summary_prefer_title: false, + title_only: false, no_toc, }, ) @@ -484,8 +238,7 @@ pub(crate) fn jsdoc_body_to_html( ctx, doc, MarkdownToHTMLOptions { - summary, - summary_prefer_title: true, + title_only: summary, no_toc: false, }, ) @@ -529,6 +282,7 @@ pub(crate) fn jsdoc_examples( pub struct ExampleCtx { pub anchor: AnchorCtx, pub id: String, + pub title: String, pub markdown_title: String, markdown_body: String, } @@ -539,20 +293,21 @@ impl ExampleCtx { pub fn new(render_ctx: &RenderContext, example: &str, i: usize) -> Self { let id = name_to_id("example", &i.to_string()); - let (maybe_title, body) = split_markdown_title(example, false); + let (maybe_title, body) = split_markdown_title(example); let title = if let Some(title) = maybe_title { title.to_string() } else { format!("Example {}", i + 1) }; - let markdown_title = render_markdown_summary(render_ctx, &title); + let markdown_title = render_markdown(render_ctx, &title, false); let markdown_body = render_markdown(render_ctx, body.unwrap_or_default(), true); ExampleCtx { anchor: AnchorCtx { id: id.to_string() }, id: id.to_string(), + title, markdown_title, markdown_body, } @@ -575,7 +330,7 @@ impl ModuleDocCtx { let (deprecated, html) = if let Some(node) = module_doc_nodes .iter() - .find(|n| n.kind == DocNodeKind::ModuleDoc) + .find(|n| matches!(n.def, DocNodeDef::ModuleDoc)) { let deprecated = node.js_doc.tags.iter().find_map(|tag| { if let JsDocTag::Deprecated { doc } = tag { @@ -601,25 +356,25 @@ impl ModuleDocCtx { }; if !short_path.is_main { - let partitions_by_kind = - super::partition::partition_nodes_by_kind(module_doc_nodes, true); + let partitions_by_kind = super::partition::partition_nodes_by_kind( + render_ctx.ctx, + module_doc_nodes.iter().map(Cow::Borrowed), + true, + ); sections.extend(super::namespace::render_namespace( - render_ctx, - partitions_by_kind - .into_iter() - .map(|(title, nodes)| { - ( - SectionHeaderCtx { - title: title.clone(), - anchor: AnchorCtx { id: title }, - href: None, - doc: None, - }, - nodes, - ) - }) - .collect(), + partitions_by_kind.into_iter().map(|(title, nodes)| { + ( + render_ctx.clone(), + Some(SectionHeaderCtx { + title: title.clone(), + anchor: AnchorCtx { id: title }, + href: None, + doc: None, + }), + nodes, + ) + }), )); } @@ -641,18 +396,22 @@ mod test { use crate::html::GenerateCtx; use crate::html::GenerateOptions; use crate::html::HrefResolver; + use crate::html::UsageComposer; + use crate::html::UsageComposerEntry; use crate::DocNode; use crate::Location; use deno_ast::ModuleSpecifier; use indexmap::IndexMap; + use std::rc::Rc; + use crate::html::usage::UsageToMd; use crate::html::RenderContext; use crate::html::UrlResolveKind; use crate::interface::InterfaceDef; use crate::js_doc::JsDoc; use crate::node::DeclarationKind; - struct EmptyResolver {} + struct EmptyResolver; impl HrefResolver for EmptyResolver { fn resolve_path( @@ -675,31 +434,62 @@ mod test { None } - fn resolve_usage(&self, current_resolve: UrlResolveKind) -> Option { - current_resolve - .get_file() - .map(|current_file| current_file.display_name()) + fn resolve_source(&self, _location: &Location) -> Option { + None } - fn resolve_source(&self, _location: &Location) -> Option { + fn resolve_external_jsdoc_module( + &self, + _module: &str, + _symbol: Option<&str>, + ) -> Option<(String, String)> { None } } + impl UsageComposer for EmptyResolver { + fn is_single_mode(&self) -> bool { + true + } + + fn compose( + &self, + current_resolve: UrlResolveKind, + usage_to_md: UsageToMd, + ) -> IndexMap { + current_resolve + .get_file() + .map(|current_file| { + IndexMap::from([( + UsageComposerEntry { + name: "".to_string(), + icon: None, + }, + usage_to_md(current_file.display_name(), None), + )]) + }) + .unwrap_or_default() + } + } + #[test] fn parse_links_test() { let ctx = GenerateCtx::new( GenerateOptions { package_name: None, main_entrypoint: None, - href_resolver: std::rc::Rc::new(EmptyResolver {}), - usage_composer: None, + href_resolver: Rc::new(EmptyResolver), + usage_composer: Rc::new(EmptyResolver), rewrite_map: None, - composable_output: false, category_docs: None, disable_search: false, symbol_redirect_map: None, default_symbol_map: None, + markdown_renderer: crate::html::comrak::create_renderer( + None, None, None, + ), + markdown_stripper: Rc::new(crate::html::comrak::strip), + head_inject: None, }, Default::default(), Default::default(), @@ -708,7 +498,7 @@ mod test { ModuleSpecifier::parse("file:///a.ts").unwrap(), vec![ DocNode::interface( - "foo".to_string(), + "foo".into(), false, Location::default(), DeclarationKind::Export, @@ -721,11 +511,11 @@ mod test { properties: vec![], call_signatures: vec![], index_signatures: vec![], - type_params: vec![], + type_params: Box::new([]), }, ), DocNode::interface( - "bar".to_string(), + "bar".into(), false, Location::default(), DeclarationKind::Export, @@ -738,7 +528,7 @@ mod test { properties: vec![], call_signatures: vec![], index_signatures: vec![], - type_params: vec![], + type_params: Box::new([]), }, ), ], @@ -746,7 +536,7 @@ mod test { ( ModuleSpecifier::parse("file:///b.ts").unwrap(), vec![DocNode::interface( - "baz".to_string(), + "baz".into(), false, Location::default(), DeclarationKind::Export, @@ -759,7 +549,7 @@ mod test { properties: vec![], call_signatures: vec![], index_signatures: vec![], - type_params: vec![], + type_params: Box::new([]), }, )], ), @@ -842,55 +632,4 @@ mod test { ); } } - - #[test] - fn markdown_alerts() { - let ctx = GenerateCtx::new( - GenerateOptions { - package_name: None, - main_entrypoint: None, - href_resolver: std::rc::Rc::new(EmptyResolver {}), - usage_composer: None, - rewrite_map: None, - composable_output: false, - category_docs: None, - disable_search: false, - symbol_redirect_map: None, - default_symbol_map: None, - }, - Default::default(), - Default::default(), - Default::default(), - ) - .unwrap(); - - let render_ctx = RenderContext::new(&ctx, &[], UrlResolveKind::AllSymbols); - - let md = super::render_markdown( - &render_ctx, - r#" - > [!NOTE] - > foo - > - > bar"#, - true, - ); - - assert!(md.contains("foo")); - assert!(md.contains("bar")); - - let md = super::render_markdown( - &render_ctx, - r#" - > [!NOTE] - > - > foo - > - > bar"#, - true, - ); - - assert!(md.contains("foo")); - assert!(md.contains("bar")); - } } diff --git a/src/html/mod.rs b/src/html/mod.rs index 47da3e49..e7f8d14a 100644 --- a/src/html/mod.rs +++ b/src/html/mod.rs @@ -1,16 +1,18 @@ +use crate::node::DocNodeDef; +use crate::DocNode; use deno_ast::ModuleSpecifier; use handlebars::handlebars_helper; use handlebars::Handlebars; use indexmap::IndexMap; +use serde::Deserialize; +use serde::Serialize; +use std::borrow::Cow; use std::cmp::Ordering; use std::collections::HashMap; use std::path::PathBuf; use std::rc::Rc; use std::sync::Arc; -use crate::DocNode; - -pub mod comrak_adapters; pub mod jsdoc; pub mod pages; mod parameters; @@ -18,11 +20,12 @@ pub mod partition; mod render_context; mod search; mod symbols; -#[cfg(feature = "tree-sitter")] -mod tree_sitter; mod types; mod usage; -mod util; +pub mod util; + +#[cfg(feature = "comrak")] +pub mod comrak; use crate::html::pages::SymbolPage; use crate::js_doc::JsDocTag; @@ -32,7 +35,9 @@ pub use search::generate_search_index; pub use symbols::namespace; pub use symbols::SymbolContentCtx; pub use symbols::SymbolGroupCtx; -pub use usage::usage_to_md; +pub use usage::UsageComposer; +pub use usage::UsageComposerEntry; +pub use usage::UsageToMd; pub use util::compute_namespaced_symbols; pub use util::href_path_resolve; pub use util::qualify_drilldown_name; @@ -67,20 +72,171 @@ const FUSE_FILENAME: &str = "fuse.js"; const SEARCH_JS: &str = include_str!("./templates/pages/search.js"); const SEARCH_FILENAME: &str = "search.js"; -pub type UsageComposer = Rc< - dyn Fn( - &RenderContext, - &[DocNodeWithContext], - String, - ) -> IndexMap, ->; - -#[derive(Eq, PartialEq, Hash)] -pub struct UsageComposerEntry { - pub name: String, - pub icon: Option>, +fn setup_hbs() -> Result, anyhow::Error> { + let mut reg = Handlebars::new(); + reg.register_escape_fn(|str| html_escape::encode_safe(str).into_owned()); + reg.set_strict_mode(true); + + #[cfg(debug_assertions)] + reg.set_dev_mode(true); + + handlebars_helper!(concat: |a: str, b: str| format!("{a}{b}")); + reg.register_helper("concat", Box::new(concat)); + + handlebars_helper!(print: |a: Json| println!("{a:#?}")); + reg.register_helper("print", Box::new(print)); + + reg.register_template_string( + ToCCtx::TEMPLATE, + include_str!("./templates/toc.hbs"), + )?; + reg.register_template_string( + util::DocEntryCtx::TEMPLATE, + include_str!("./templates/doc_entry.hbs"), + )?; + reg.register_template_string( + util::SectionCtx::TEMPLATE, + include_str!("./templates/section.hbs"), + )?; + reg.register_template_string( + "doc_node_kind_icon", + include_str!("./templates/doc_node_kind_icon.hbs"), + )?; + reg.register_template_string( + "namespace_section", + include_str!("./templates/namespace_section.hbs"), + )?; + reg.register_template_string( + symbols::DocBlockSubtitleCtx::TEMPLATE_CLASS, + include_str!("./templates/doc_block_subtitle_class.hbs"), + )?; + reg.register_template_string( + symbols::DocBlockSubtitleCtx::TEMPLATE_INTERFACE, + include_str!("./templates/doc_block_subtitle_interface.hbs"), + )?; + reg.register_template_string( + util::AnchorCtx::TEMPLATE, + include_str!("./templates/anchor.hbs"), + )?; + reg.register_template_string( + SymbolGroupCtx::TEMPLATE, + include_str!("./templates/symbol_group.hbs"), + )?; + reg.register_template_string( + SymbolContentCtx::TEMPLATE, + include_str!("./templates/symbol_content.hbs"), + )?; + reg.register_template_string( + jsdoc::ExampleCtx::TEMPLATE, + include_str!("./templates/example.hbs"), + )?; + reg.register_template_string( + symbols::function::FunctionCtx::TEMPLATE, + include_str!("./templates/function.hbs"), + )?; + reg.register_template_string( + jsdoc::ModuleDocCtx::TEMPLATE, + include_str!("./templates/module_doc.hbs"), + )?; + reg.register_template_string( + util::BreadcrumbsCtx::TEMPLATE, + include_str!("./templates/breadcrumbs.hbs"), + )?; + reg.register_template_string( + usage::UsagesCtx::TEMPLATE, + include_str!("./templates/usages.hbs"), + )?; + reg.register_template_string( + "usages_large", + include_str!("./templates/usages_large.hbs"), + )?; + reg.register_template_string( + util::Tag::TEMPLATE, + include_str!("./templates/tag.hbs"), + )?; + reg.register_template_string( + "source_button", + include_str!("./templates/source_button.hbs"), + )?; + reg.register_template_string( + "deprecated", + include_str!("./templates/deprecated.hbs"), + )?; + reg.register_template_string( + "index_signature", + include_str!("./templates/index_signature.hbs"), + )?; + reg.register_template_string( + pages::CategoriesPanelCtx::TEMPLATE, + include_str!("./templates/category_panel.hbs"), + )?; + reg.register_template_string("see", include_str!("./templates/see.hbs"))?; + + // pages + reg.register_template_string( + pages::HtmlHeadCtx::TEMPLATE, + include_str!("./templates/pages/html_head.hbs"), + )?; + reg.register_template_string( + pages::AllSymbolsCtx::TEMPLATE, + include_str!("./templates/pages/all_symbols.hbs"), + )?; + reg.register_template_string( + pages::SymbolPageCtx::TEMPLATE, + include_str!("./templates/pages/symbol.hbs"), + )?; + reg.register_template_string( + pages::IndexCtx::TEMPLATE, + include_str!("./templates/pages/index.hbs"), + )?; + reg.register_template_string( + "pages/top_nav", + include_str!("./templates/pages/top_nav.hbs"), + )?; + reg.register_template_string( + "pages/search_results", + include_str!("./templates/pages/search_results.hbs"), + )?; + reg.register_template_string( + "pages/redirect", + include_str!("./templates/pages/redirect.hbs"), + )?; + + // icons + reg.register_template_string( + "icons/arrow", + include_str!("./templates/icons/arrow.svg"), + )?; + reg.register_template_string( + "icons/copy", + include_str!("./templates/icons/copy.svg"), + )?; + reg.register_template_string( + "icons/check", + include_str!("./templates/icons/check.svg"), + )?; + reg.register_template_string( + "icons/link", + include_str!("./templates/icons/link.svg"), + )?; + reg.register_template_string( + "icons/source", + include_str!("./templates/icons/source.svg"), + )?; + reg.register_template_string( + "icons/menu", + include_str!("./templates/icons/menu.svg"), + )?; + + Ok(reg) +} + +lazy_static! { + pub static ref HANDLEBARS: Handlebars<'static> = setup_hbs().unwrap(); } +pub type HeadInject = Rc String>; + #[derive(Clone)] pub struct GenerateOptions { /// The name that is shown is the top-left corner, eg. "deno_std". @@ -90,26 +246,24 @@ pub struct GenerateOptions { /// default to that file. pub main_entrypoint: Option, pub href_resolver: Rc, - pub usage_composer: Option, + pub usage_composer: Rc, pub rewrite_map: Option>, - pub composable_output: bool, pub category_docs: Option>>, pub disable_search: bool, pub symbol_redirect_map: Option>>, pub default_symbol_map: Option>, + pub markdown_renderer: jsdoc::MarkdownRenderer, + pub markdown_stripper: jsdoc::MarkdownStripper, + pub head_inject: Option, } #[non_exhaustive] -pub struct GenerateCtx<'ctx> { +pub struct GenerateCtx { pub package_name: Option, pub common_ancestor: Option, pub doc_nodes: IndexMap, Vec>, - pub hbs: Handlebars<'ctx>, - pub highlight_adapter: comrak_adapters::HighlightAdapter, - #[cfg(feature = "ammonia")] - pub url_rewriter: Option, pub href_resolver: Rc, - pub usage_composer: Option, + pub usage_composer: Rc, pub rewrite_map: Option>, pub main_entrypoint: Option>, pub file_mode: FileMode, @@ -117,9 +271,12 @@ pub struct GenerateCtx<'ctx> { pub disable_search: bool, pub symbol_redirect_map: Option>>, pub default_symbol_map: Option>, + pub markdown_renderer: jsdoc::MarkdownRenderer, + pub markdown_stripper: jsdoc::MarkdownStripper, + pub head_inject: Option, } -impl<'ctx> GenerateCtx<'ctx> { +impl GenerateCtx { pub fn new( options: GenerateOptions, common_ancestor: Option, @@ -145,31 +302,30 @@ impl<'ctx> GenerateCtx<'ctx> { let nodes = nodes .into_iter() .map(|mut node| { - if node.name == "default" { + if &*node.name == "default" { if let Some(default_rename) = options.default_symbol_map.as_ref().and_then( |default_symbol_map| default_symbol_map.get(&short_path.path), ) { - node.name = default_rename.clone(); + node.name = default_rename.as_str().into(); } } + // TODO(@crowlKats): support this in namespaces let node = if node - .variable_def + .variable_def() .as_ref() .and_then(|def| def.ts_type.as_ref()) .and_then(|ts_type| ts_type.kind.as_ref()) .is_some_and(|kind| { kind == &crate::ts_type::TsTypeDefKind::FnOrConstructor }) { - let fn_or_constructor = node - .variable_def - .unwrap() - .ts_type - .unwrap() - .fn_or_constructor - .unwrap(); + let DocNodeDef::Variable { variable_def } = node.def else { + unreachable!() + }; + let fn_or_constructor = + variable_def.ts_type.unwrap().fn_or_constructor.unwrap(); let mut new_node = DocNode::function( node.name, @@ -185,7 +341,7 @@ impl<'ctx> GenerateCtx<'ctx> { is_async: false, is_generator: false, type_params: fn_or_constructor.type_params, - decorators: vec![], + decorators: Box::new([]), }, ); new_node.is_default = node.is_default; @@ -196,13 +352,42 @@ impl<'ctx> GenerateCtx<'ctx> { DocNodeWithContext { origin: short_path.clone(), - ns_qualifiers: Rc::new(vec![]), - drilldown_parent_kind: None, - kind_with_drilldown: DocNodeKindWithDrilldown::Other(node.kind), + ns_qualifiers: Rc::new([]), + kind: DocNodeKind::from_node(&node), inner: Arc::new(node), + drilldown_name: None, parent: None, + namespace_children: None, } }) + .map(|mut node| { + fn handle_node(node: &mut DocNodeWithContext) { + let children = if let Some(ns) = node.namespace_def() { + let subqualifier: Rc<[String]> = node.sub_qualifier().into(); + Some( + ns.elements + .iter() + .map(|subnode| { + let mut child_node = node.create_namespace_child( + subnode.clone(), + subqualifier.clone(), + ); + handle_node(&mut child_node); + child_node + }) + .collect::>(), + ) + } else { + None + }; + + node.namespace_children = children; + } + + handle_node(&mut node); + + node + }) .collect::>(); (short_path, nodes) @@ -213,10 +398,6 @@ impl<'ctx> GenerateCtx<'ctx> { package_name: options.package_name, common_ancestor, doc_nodes, - hbs: setup_hbs()?, - highlight_adapter: setup_highlighter(false), - #[cfg(feature = "ammonia")] - url_rewriter: None, href_resolver: options.href_resolver, usage_composer: options.usage_composer, rewrite_map: options.rewrite_map, @@ -226,15 +407,44 @@ impl<'ctx> GenerateCtx<'ctx> { disable_search: options.disable_search, symbol_redirect_map: options.symbol_redirect_map, default_symbol_map: options.default_symbol_map, + markdown_renderer: options.markdown_renderer, + markdown_stripper: options.markdown_stripper, + head_inject: options.head_inject, }) } + pub fn create_basic( + mut options: GenerateOptions, + doc_nodes_by_url: IndexMap>, + ) -> Result { + if doc_nodes_by_url.len() == 1 && options.main_entrypoint.is_none() { + options.main_entrypoint = + Some(doc_nodes_by_url.keys().next().unwrap().clone()); + } + + let file_mode = match ( + doc_nodes_by_url + .keys() + .all(|specifier| specifier.as_str().ends_with(".d.ts")), + doc_nodes_by_url.len(), + ) { + (false, 1) => FileMode::Single, + (false, _) => FileMode::Normal, + (true, 1) => FileMode::SingleDts, + (true, _) => FileMode::Dts, + }; + + let common_ancestor = find_common_ancestor(doc_nodes_by_url.keys(), true); + + GenerateCtx::new(options, common_ancestor, file_mode, doc_nodes_by_url) + } + pub fn render( &self, template: &str, data: &T, ) -> String { - self.hbs.render(template, data).unwrap() + HANDLEBARS.render(template, data).unwrap() } pub fn resolve_path( @@ -254,9 +464,97 @@ impl<'ctx> GenerateCtx<'ctx> { self.href_resolver.resolve_path(current, target) } + + // TODO(@crowlKats): don't reference to another node, but redirect to it instead + pub fn resolve_reference<'a>( + &'a self, + new_parent: Option<&'a DocNodeWithContext>, + reference: &'a crate::Location, + ) -> impl Iterator> + 'a { + fn handle_node<'a>( + node: &'a DocNodeWithContext, + reference: &'a crate::Location, + depth: usize, + ) -> Box> + 'a> { + if &node.location == reference { + let node = if depth > 0 { + fn strip_qualifiers(node: &mut DocNodeWithContext, depth: usize) { + let ns_qualifiers = node.ns_qualifiers.to_vec(); + node.ns_qualifiers = ns_qualifiers[depth..].to_vec().into(); + + if let Some(children) = &mut node.namespace_children { + for child in children { + strip_qualifiers(child, depth); + } + } + } + + let mut node = node.clone(); + strip_qualifiers(&mut node, depth); + Cow::Owned(node) + } else { + Cow::Borrowed(node) + }; + + return Box::new(std::iter::once(node)); + } + + if matches!(node.def, DocNodeDef::Namespace { .. }) { + if let Some(children) = &node.namespace_children { + return Box::new( + children + .iter() + .flat_map(move |child| handle_node(child, reference, depth + 1)), + ); + } + } + + Box::new(std::iter::empty()) + } + + self + .doc_nodes + .values() + .flat_map(move |nodes| { + nodes + .iter() + .flat_map(move |node| handle_node(node, reference, 0)) + }) + .map(move |node| { + if let Some(parent) = new_parent { + let mut node = node.into_owned(); + let mut ns_qualifiers = Vec::with_capacity( + parent.ns_qualifiers.len() + node.ns_qualifiers.len(), + ); + ns_qualifiers.extend(parent.sub_qualifier()); + + fn handle_node( + node: &mut DocNodeWithContext, + ns_qualifiers: Vec, + ) { + if let Some(children) = &mut node.namespace_children { + for node in children { + handle_node(node, ns_qualifiers.clone()); + } + } + + let mut new_ns_qualifiers = ns_qualifiers; + new_ns_qualifiers.extend(node.ns_qualifiers.iter().cloned()); + node.ns_qualifiers = new_ns_qualifiers.into(); + } + + handle_node(&mut node, ns_qualifiers); + + Cow::Owned(node) + } else { + node + } + }) + } } -#[derive(Clone, Debug, Eq, PartialEq, Hash)] +#[derive(Clone, Debug, Eq, PartialEq, Hash, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] pub struct ShortPath { pub path: String, pub specifier: ModuleSpecifier, @@ -288,7 +586,7 @@ impl ShortPath { }; } - let Ok(url_file_path) = specifier.to_file_path() else { + let Ok(url_file_path) = deno_path_util::url_to_file_path(&specifier) else { return ShortPath { path: specifier.to_string(), specifier, @@ -321,9 +619,9 @@ impl ShortPath { } } - pub fn display_name(&self) -> String { + pub fn display_name(&self) -> &str { if self.is_main { - "default".to_string() + "default" } else { self .path @@ -331,7 +629,6 @@ impl ShortPath { .unwrap_or(&self.path) .strip_prefix('/') .unwrap_or(&self.path) - .to_string() } } @@ -339,7 +636,7 @@ impl ShortPath { if self.is_main { UrlResolveKind::Root } else { - UrlResolveKind::File(self) + UrlResolveKind::File { file: self } } } } @@ -349,7 +646,7 @@ impl Ord for ShortPath { other .is_main .cmp(&self.is_main) - .then_with(|| self.display_name().cmp(&other.display_name())) + .then_with(|| self.display_name().cmp(other.display_name())) } } @@ -359,24 +656,91 @@ impl PartialOrd for ShortPath { } } -#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)] -pub enum DocNodeKindWithDrilldown { - Property, +#[derive( + Debug, + PartialEq, + Eq, + Hash, + Clone, + Copy, + Serialize, + Deserialize, + Ord, + PartialOrd, +)] +pub enum MethodKind { Method, - Other(crate::DocNodeKind), + Getter, + Setter, +} + +impl From for MethodKind { + fn from(value: deno_ast::swc::ast::MethodKind) -> Self { + match value { + deno_ast::swc::ast::MethodKind::Method => Self::Method, + deno_ast::swc::ast::MethodKind::Getter => Self::Getter, + deno_ast::swc::ast::MethodKind::Setter => Self::Setter, + } + } +} + +#[derive( + Debug, + PartialEq, + Eq, + Hash, + Clone, + Copy, + Serialize, + Deserialize, + Ord, + PartialOrd, +)] +pub enum DocNodeKind { + Property, + Method(MethodKind), + Class, + Enum, + Function, + Import, + Interface, + ModuleDoc, + Namespace, + Reference, + TypeAlias, + Variable, +} + +impl DocNodeKind { + fn from_node(node: &DocNode) -> Self { + match node.def { + DocNodeDef::Function { .. } => Self::Function, + DocNodeDef::Variable { .. } => Self::Variable, + DocNodeDef::Enum { .. } => Self::Enum, + DocNodeDef::Class { .. } => Self::Class, + DocNodeDef::TypeAlias { .. } => Self::TypeAlias, + DocNodeDef::Namespace { .. } => Self::Namespace, + DocNodeDef::Interface { .. } => Self::Interface, + DocNodeDef::Import { .. } => Self::Import, + DocNodeDef::ModuleDoc => Self::ModuleDoc, + DocNodeDef::Reference { .. } => Self::Reference, + } + } } /// A wrapper around [`DocNode`] with additional fields to track information /// about the inner [`DocNode`]. /// This is cheap to clone since all fields are [`Rc`]s. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] pub struct DocNodeWithContext { pub origin: Rc, - pub ns_qualifiers: Rc>, - pub drilldown_parent_kind: Option, - pub kind_with_drilldown: DocNodeKindWithDrilldown, + pub ns_qualifiers: Rc<[String]>, + pub kind: DocNodeKind, pub inner: Arc, + pub drilldown_name: Option>, pub parent: Option>, + pub namespace_children: Option>, } impl DocNodeWithContext { @@ -384,17 +748,18 @@ impl DocNodeWithContext { DocNodeWithContext { origin: self.origin.clone(), ns_qualifiers: self.ns_qualifiers.clone(), - drilldown_parent_kind: None, - kind_with_drilldown: DocNodeKindWithDrilldown::Other(doc_node.kind), + kind: DocNodeKind::from_node(&doc_node), inner: doc_node, + drilldown_name: None, parent: Some(Box::new(self.clone())), + namespace_children: None, } } pub fn create_namespace_child( &self, doc_node: Arc, - qualifiers: Rc>, + qualifiers: Rc<[String]>, ) -> Self { let mut child = self.create_child(doc_node); child.ns_qualifiers = qualifiers; @@ -405,14 +770,17 @@ impl DocNodeWithContext { &self, mut method_doc_node: DocNode, is_static: bool, + method_kind: deno_ast::swc::ast::MethodKind, ) -> Self { + let original_name = method_doc_node.name.clone(); method_doc_node.name = - qualify_drilldown_name(self.get_name(), &method_doc_node.name, is_static); + qualify_drilldown_name(self.get_name(), &method_doc_node.name, is_static) + .into_boxed_str(); method_doc_node.declaration_kind = self.declaration_kind; let mut new_node = self.create_child(Arc::new(method_doc_node)); - new_node.drilldown_parent_kind = Some(self.kind); - new_node.kind_with_drilldown = DocNodeKindWithDrilldown::Method; + new_node.drilldown_name = Some(original_name); + new_node.kind = DocNodeKind::Method(method_kind.into()); new_node } @@ -421,16 +789,18 @@ impl DocNodeWithContext { mut property_doc_node: DocNode, is_static: bool, ) -> Self { + let original_name = property_doc_node.name.clone(); property_doc_node.name = qualify_drilldown_name( self.get_name(), &property_doc_node.name, is_static, - ); + ) + .into_boxed_str(); property_doc_node.declaration_kind = self.declaration_kind; let mut new_node = self.create_child(Arc::new(property_doc_node)); - new_node.drilldown_parent_kind = Some(self.kind); - new_node.kind_with_drilldown = DocNodeKindWithDrilldown::Property; + new_node.drilldown_name = Some(original_name); + new_node.kind = DocNodeKind::Property; new_node } @@ -443,13 +813,14 @@ impl DocNodeWithContext { } pub fn sub_qualifier(&self) -> Vec { - let mut ns_qualifiers = (*self.ns_qualifiers).clone(); + let mut ns_qualifiers = Vec::from(&*self.ns_qualifiers); ns_qualifiers.push(self.get_name().to_string()); ns_qualifiers } - pub fn is_internal(&self) -> bool { - self.inner.declaration_kind == crate::node::DeclarationKind::Private + pub fn is_internal(&self, ctx: &GenerateCtx) -> bool { + (self.inner.declaration_kind == crate::node::DeclarationKind::Private + && !matches!(ctx.file_mode, FileMode::SingleDts | FileMode::Dts)) || self .js_doc .tags @@ -463,6 +834,109 @@ impl DocNodeWithContext { None => self, } } + + fn get_drilldown_symbols<'a>( + &'a self, + ) -> Option + 'a>> { + match &self.inner.def { + DocNodeDef::Class { class_def } => Some(Box::new( + class_def + .methods + .iter() + .map(|method| { + self.create_child_method( + DocNode::function( + method.name.clone(), + false, + method.location.clone(), + self.declaration_kind, + method.js_doc.clone(), + method.function_def.clone(), + ), + method.is_static, + method.kind, + ) + }) + .chain(class_def.properties.iter().map(|property| { + self.create_child_property( + DocNode::from(property.clone()), + property.is_static, + ) + })), + )), + DocNodeDef::Interface { interface_def } => Some(Box::new( + interface_def + .methods + .iter() + .map(|method| { + self.create_child_method( + DocNode::from(method.clone()), + true, + method.kind, + ) + }) + .chain(interface_def.properties.iter().map(|property| { + self.create_child_property(DocNode::from(property.clone()), true) + })), + )), + DocNodeDef::TypeAlias { type_alias_def } => { + if let Some(ts_type_literal) = + type_alias_def.ts_type.type_literal.as_ref() + { + Some(Box::new( + ts_type_literal + .methods + .iter() + .map(|method| { + self.create_child_method( + DocNode::from(method.clone()), + true, + method.kind, + ) + }) + .chain(ts_type_literal.properties.iter().map(|property| { + self + .create_child_property(DocNode::from(property.clone()), true) + })), + )) + } else { + None + } + } + DocNodeDef::Variable { variable_def } => { + if let Some(ts_type_literal) = variable_def + .ts_type + .as_ref() + .and_then(|ts_type| ts_type.type_literal.as_ref()) + { + Some(Box::new( + ts_type_literal + .methods + .iter() + .map(|method| { + self.create_child_method( + DocNode::from(method.clone()), + true, + method.kind, + ) + }) + .chain(ts_type_literal.properties.iter().map(|property| { + self + .create_child_property(DocNode::from(property.clone()), true) + })), + )) + } else { + None + } + } + DocNodeDef::Function { .. } => None, + DocNodeDef::Enum { .. } => None, + DocNodeDef::Namespace { .. } => None, + DocNodeDef::Import { .. } => None, + DocNodeDef::ModuleDoc => None, + DocNodeDef::Reference { .. } => None, + } + } } impl core::ops::Deref for DocNodeWithContext { @@ -473,212 +947,224 @@ impl core::ops::Deref for DocNodeWithContext { } } -pub fn setup_hbs<'t>() -> Result, anyhow::Error> { - let mut reg = Handlebars::new(); - reg.register_escape_fn(|str| html_escape::encode_safe(str).into_owned()); - reg.set_strict_mode(true); - - #[cfg(debug_assertions)] - reg.set_dev_mode(true); - - handlebars_helper!(concat: |a: str, b: str| format!("{a}{b}")); - reg.register_helper("concat", Box::new(concat)); +#[derive(Default, Debug, Eq, PartialEq)] +pub enum FileMode { + #[default] + Normal, + Dts, + Single, + SingleDts, +} - handlebars_helper!(print: |a: Json| println!("{a:#?}")); - reg.register_helper("print", Box::new(print)); +pub fn generate( + ctx: GenerateCtx, +) -> Result, anyhow::Error> { + let mut files = HashMap::new(); - reg.register_template_string( - ToCCtx::TEMPLATE, - include_str!("./templates/toc.hbs"), - )?; - reg.register_template_string( - util::DocEntryCtx::TEMPLATE, - include_str!("./templates/doc_entry.hbs"), - )?; - reg.register_template_string( - util::SectionCtx::TEMPLATE, - include_str!("./templates/section.hbs"), - )?; - reg.register_template_string( - "doc_node_kind_icon", - include_str!("./templates/doc_node_kind_icon.hbs"), - )?; - reg.register_template_string( - "namespace_section", - include_str!("./templates/namespace_section.hbs"), - )?; - reg.register_template_string( - symbols::DocBlockSubtitleCtx::TEMPLATE_CLASS, - include_str!("./templates/doc_block_subtitle_class.hbs"), - )?; - reg.register_template_string( - symbols::DocBlockSubtitleCtx::TEMPLATE_INTERFACE, - include_str!("./templates/doc_block_subtitle_interface.hbs"), - )?; - reg.register_template_string( - util::AnchorCtx::TEMPLATE, - include_str!("./templates/anchor.hbs"), - )?; - reg.register_template_string( - SymbolGroupCtx::TEMPLATE, - include_str!("./templates/symbol_group.hbs"), - )?; - reg.register_template_string( - SymbolContentCtx::TEMPLATE, - include_str!("./templates/symbol_content.hbs"), - )?; - reg.register_template_string( - jsdoc::ExampleCtx::TEMPLATE, - include_str!("./templates/example.hbs"), - )?; - reg.register_template_string( - symbols::function::FunctionCtx::TEMPLATE, - include_str!("./templates/function.hbs"), - )?; - reg.register_template_string( - jsdoc::ModuleDocCtx::TEMPLATE, - include_str!("./templates/module_doc.hbs"), - )?; - reg.register_template_string( - util::BreadcrumbsCtx::TEMPLATE, - include_str!("./templates/breadcrumbs.hbs"), - )?; - reg.register_template_string( - usage::UsagesCtx::TEMPLATE, - include_str!("./templates/usages.hbs"), - )?; - reg.register_template_string( - "usages_large", - include_str!("./templates/usages_large.hbs"), - )?; - reg.register_template_string( - util::Tag::TEMPLATE, - include_str!("./templates/tag.hbs"), - )?; - reg.register_template_string( - "source_button", - include_str!("./templates/source_button.hbs"), - )?; - reg.register_template_string( - "deprecated", - include_str!("./templates/deprecated.hbs"), - )?; - reg.register_template_string( - "index_signature", - include_str!("./templates/index_signature.hbs"), - )?; + // Index page + { + let (partitions_for_entrypoint_nodes, uses_categories) = + if let Some(entrypoint) = ctx.main_entrypoint.as_ref() { + let nodes = ctx.doc_nodes.get(entrypoint).unwrap(); + let categories = partition::partition_nodes_by_category( + &ctx, + nodes.iter().map(Cow::Borrowed), + ctx.file_mode == FileMode::SingleDts, + ); - // pages - reg.register_template_string( - pages::HtmlHeadCtx::TEMPLATE, - include_str!("./templates/pages/html_head.hbs"), - )?; - reg.register_template_string( - pages::CategoriesPanelCtx::TEMPLATE, - include_str!("./templates/pages/category_panel.hbs"), - )?; - reg.register_template_string( - pages::AllSymbolsCtx::TEMPLATE, - include_str!("./templates/pages/all_symbols.hbs"), - )?; - reg.register_template_string( - pages::SymbolPageCtx::TEMPLATE, - include_str!("./templates/pages/symbol.hbs"), - )?; - reg.register_template_string( - pages::IndexCtx::TEMPLATE, - include_str!("./templates/pages/index.hbs"), - )?; - reg.register_template_string( - "pages/top_nav", - include_str!("./templates/pages/top_nav.hbs"), - )?; - reg.register_template_string( - "pages/search_results", - include_str!("./templates/pages/search_results.hbs"), - )?; - reg.register_template_string( - "pages/redirect", - include_str!("./templates/pages/redirect.hbs"), - )?; + if categories.len() == 1 && categories.contains_key("Uncategorized") { + ( + partition::partition_nodes_by_kind( + &ctx, + nodes.iter().map(Cow::Borrowed), + ctx.file_mode == FileMode::SingleDts, + ), + false, + ) + } else { + (categories, true) + } + } else { + Default::default() + }; - // icons - reg.register_template_string( - "icons/arrow", - include_str!("./templates/icons/arrow.svg"), - )?; - reg.register_template_string( - "icons/copy", - include_str!("./templates/icons/copy.svg"), - )?; - reg.register_template_string( - "icons/link", - include_str!("./templates/icons/link.svg"), - )?; - reg.register_template_string( - "icons/source", - include_str!("./templates/icons/source.svg"), - )?; - reg.register_template_string( - "icons/menu", - include_str!("./templates/icons/menu.svg"), - )?; + let index = pages::IndexCtx::new( + &ctx, + ctx.main_entrypoint.clone(), + partitions_for_entrypoint_nodes, + uses_categories, + ); - Ok(reg) -} + files.insert( + "./index.html".to_string(), + ctx.render(pages::IndexCtx::TEMPLATE, &index), + ); + } -pub fn setup_highlighter( - show_line_numbers: bool, -) -> comrak_adapters::HighlightAdapter { - comrak_adapters::HighlightAdapter { - #[cfg(feature = "syntect")] - syntax_set: syntect::dumps::from_uncompressed_data(include_bytes!( - "./default_newlines.packdump" - )) - .unwrap(), - #[cfg(feature = "syntect")] - theme_set: syntect::highlighting::ThemeSet::load_defaults(), - #[cfg(feature = "tree-sitter")] - language_cb: tree_sitter::tree_sitter_language_cb, - show_line_numbers, + let all_doc_nodes = ctx + .doc_nodes + .values() + .flatten() + .cloned() + .collect::>(); + + // All symbols (list of all symbols in all files) + { + let partitions_by_kind = partition::partition_nodes_by_entrypoint( + &ctx, + all_doc_nodes.iter().map(Cow::Borrowed), + true, + ); + + let all_symbols = pages::AllSymbolsCtx::new(&ctx, partitions_by_kind); + + files.insert( + "./all_symbols.html".to_string(), + ctx.render(pages::AllSymbolsCtx::TEMPLATE, &all_symbols), + ); } -} -#[derive(Default, Debug, Eq, PartialEq)] -pub enum FileMode { - #[default] - Normal, - Dts, - Single, - SingleDts, -} + // Category pages + if ctx.file_mode == FileMode::SingleDts { + let categories = partition::partition_nodes_by_category( + &ctx, + all_doc_nodes.iter().map(Cow::Borrowed), + true, + ); -pub fn generate( - mut options: GenerateOptions, - doc_nodes_by_url: IndexMap>, -) -> Result, anyhow::Error> { - if doc_nodes_by_url.len() == 1 && options.main_entrypoint.is_none() { - options.main_entrypoint = - Some(doc_nodes_by_url.keys().next().unwrap().clone()); + if categories.len() != 1 { + for (category, nodes) in &categories { + let partitions = partition::partition_nodes_by_kind( + &ctx, + nodes.iter().map(Cow::Borrowed), + false, + ); + + let index = pages::IndexCtx::new_category( + &ctx, + category, + partitions, + &all_doc_nodes, + ); + files.insert( + format!("{}.html", util::slugify(category)), + ctx.render(pages::IndexCtx::TEMPLATE, &index), + ); + } + } } - let file_mode = match ( - doc_nodes_by_url - .keys() - .all(|specifier| specifier.as_str().ends_with(".d.ts")), - doc_nodes_by_url.len(), - ) { - (false, 1) => FileMode::Single, - (false, _) => FileMode::Normal, - (true, 1) => FileMode::SingleDts, - (true, _) => FileMode::Dts, - }; + // Pages for all discovered symbols + { + for (short_path, doc_nodes) in &ctx.doc_nodes { + let doc_nodes_by_kind = partition::partition_nodes_by_kind( + &ctx, + doc_nodes.iter().map(Cow::Borrowed), + ctx.file_mode == FileMode::SingleDts, + ); - let composable_output = options.composable_output; + let symbol_pages = + generate_symbol_pages_for_module(&ctx, short_path, doc_nodes); + + files.extend(symbol_pages.into_iter().flat_map(|symbol_page| { + match symbol_page { + SymbolPage::Symbol { + breadcrumbs_ctx, + symbol_group_ctx, + toc_ctx, + categories_panel, + } => { + let root = ctx.resolve_path( + UrlResolveKind::Symbol { + file: short_path, + symbol: &symbol_group_ctx.name, + }, + UrlResolveKind::Root, + ); + + let mut title_parts = breadcrumbs_ctx.to_strings(); + title_parts.reverse(); + // contains the package name, which we already render in the head + title_parts.pop(); - let common_ancestor = find_common_ancestor(doc_nodes_by_url.keys(), true); - let ctx = - GenerateCtx::new(options, common_ancestor, file_mode, doc_nodes_by_url)?; + let html_head_ctx = pages::HtmlHeadCtx::new( + &ctx, + &root, + Some(&title_parts.join(" - ")), + Some(short_path), + ); + + let file_name = + format!("{}/~/{}.html", short_path.path, symbol_group_ctx.name); + + let page_ctx = pages::SymbolPageCtx { + html_head_ctx, + symbol_group_ctx, + breadcrumbs_ctx, + toc_ctx, + disable_search: ctx.disable_search, + categories_panel, + }; + + let symbol_page = + ctx.render(pages::SymbolPageCtx::TEMPLATE, &page_ctx); + + vec![(file_name, symbol_page)] + } + SymbolPage::Redirect { + current_symbol, + href, + } => { + let redirect = + serde_json::json!({ "kind": "redirect", "path": href }); + + let file_name = + format!("{}/~/{}.html", short_path.path, current_symbol); + + vec![(file_name, ctx.render("pages/redirect", &redirect))] + } + } + })); + + if !short_path.is_main { + let index = pages::IndexCtx::new( + &ctx, + Some(short_path.clone()), + doc_nodes_by_kind, + false, + ); + + files.insert( + format!("{}/index.html", short_path.path), + ctx.render(pages::IndexCtx::TEMPLATE, &index), + ); + } + } + } + + files.insert(STYLESHEET_FILENAME.into(), STYLESHEET.into()); + files.insert( + SEARCH_INDEX_FILENAME.into(), + search::get_search_index_file(&ctx)?, + ); + files.insert(SCRIPT_FILENAME.into(), SCRIPT_JS.into()); + + files.insert(PAGE_STYLESHEET_FILENAME.into(), PAGE_STYLESHEET.into()); + files.insert(RESET_STYLESHEET_FILENAME.into(), RESET_STYLESHEET.into()); + files.insert(FUSE_FILENAME.into(), FUSE_JS.into()); + files.insert(SEARCH_FILENAME.into(), SEARCH_JS.into()); + #[cfg(feature = "comrak")] + files.insert( + comrak::COMRAK_STYLESHEET_FILENAME.into(), + comrak::COMRAK_STYLESHEET.into(), + ); + + Ok(files) +} + +pub fn generate_json( + ctx: GenerateCtx, +) -> Result, anyhow::Error> { let mut files = HashMap::new(); // Index page @@ -687,14 +1173,16 @@ pub fn generate( if let Some(entrypoint) = ctx.main_entrypoint.as_ref() { let nodes = ctx.doc_nodes.get(entrypoint).unwrap(); let categories = partition::partition_nodes_by_category( - nodes, + &ctx, + nodes.iter().map(Cow::Borrowed), ctx.file_mode == FileMode::SingleDts, ); if categories.len() == 1 && categories.contains_key("Uncategorized") { ( partition::partition_nodes_by_kind( - nodes, + &ctx, + nodes.iter().map(Cow::Borrowed), ctx.file_mode == FileMode::SingleDts, ), false, @@ -713,31 +1201,7 @@ pub fn generate( uses_categories, ); - if composable_output { - files.insert( - "./breadcrumbs.html".to_string(), - ctx.render(util::BreadcrumbsCtx::TEMPLATE, &index.breadcrumbs_ctx), - ); - - if index.module_doc.is_some() || index.overview.is_some() { - let mut out = String::new(); - - if let Some(module_doc) = index.module_doc { - out.push_str(&ctx.render(jsdoc::ModuleDocCtx::TEMPLATE, &module_doc)); - } - - if let Some(all_symbols) = index.overview { - out.push_str(&ctx.render(SymbolContentCtx::TEMPLATE, &all_symbols)); - } - - files.insert("./content.html".to_string(), out); - } - } else { - files.insert( - "./index.html".to_string(), - ctx.render(pages::IndexCtx::TEMPLATE, &index), - ); - } + files.insert("./index.json".to_string(), serde_json::to_value(index)?); } let all_doc_nodes = ctx @@ -749,37 +1213,35 @@ pub fn generate( // All symbols (list of all symbols in all files) { - let partitions_by_kind = - partition::partition_nodes_by_entrypoint(&all_doc_nodes, true); + let partitions_by_kind = partition::partition_nodes_by_entrypoint( + &ctx, + all_doc_nodes.iter().map(Cow::Borrowed), + true, + ); let all_symbols = pages::AllSymbolsCtx::new(&ctx, partitions_by_kind); - if composable_output { - files.insert( - "./all_symbols/content.html".to_string(), - ctx.render(SymbolContentCtx::TEMPLATE, &all_symbols.content), - ); - - files.insert( - "./all_symbols/breadcrumbs.html".to_string(), - ctx - .render(util::BreadcrumbsCtx::TEMPLATE, &all_symbols.breadcrumbs_ctx), - ); - } else { - files.insert( - "./all_symbols.html".to_string(), - ctx.render(pages::AllSymbolsCtx::TEMPLATE, &all_symbols), - ); - } + files.insert( + "./all_symbols.json".to_string(), + serde_json::to_value(all_symbols)?, + ); } + // Category pages if ctx.file_mode == FileMode::SingleDts { - let categories = - partition::partition_nodes_by_category(&all_doc_nodes, true); + let categories = partition::partition_nodes_by_category( + &ctx, + all_doc_nodes.iter().map(Cow::Borrowed), + true, + ); if categories.len() != 1 { for (category, nodes) in &categories { - let partitions = partition::partition_nodes_by_kind(nodes, false); + let partitions = partition::partition_nodes_by_kind( + &ctx, + nodes.iter().map(Cow::Borrowed), + false, + ); let index = pages::IndexCtx::new_category( &ctx, @@ -788,8 +1250,8 @@ pub fn generate( &all_doc_nodes, ); files.insert( - format!("{}.html", util::slugify(category)), - ctx.render(pages::IndexCtx::TEMPLATE, &index), + format!("{}.json", util::slugify(category)), + serde_json::to_value(index)?, ); } } @@ -799,7 +1261,8 @@ pub fn generate( { for (short_path, doc_nodes) in &ctx.doc_nodes { let doc_nodes_by_kind = partition::partition_nodes_by_kind( - doc_nodes, + &ctx, + doc_nodes.iter().map(Cow::Borrowed), ctx.file_mode == FileMode::SingleDts, ); @@ -822,46 +1285,31 @@ pub fn generate( UrlResolveKind::Root, ); + let mut title_parts = breadcrumbs_ctx.to_strings(); + title_parts.reverse(); + // contains the package name, which we already render in the head + title_parts.pop(); + let html_head_ctx = pages::HtmlHeadCtx::new( + &ctx, &root, - &symbol_group_ctx.name, - ctx.package_name.as_ref(), + Some(&title_parts.join(" - ")), Some(short_path), - ctx.disable_search, ); - if composable_output { - let dir_name = - format!("{}/~/{}", short_path.path, symbol_group_ctx.name); - - vec![ - ( - format!("{dir_name}/breadcrumbs.html"), - ctx.render(util::BreadcrumbsCtx::TEMPLATE, &breadcrumbs_ctx), - ), - ( - format!("{dir_name}/content.html"), - ctx.render(SymbolGroupCtx::TEMPLATE, &symbol_group_ctx), - ), - ] - } else { - let file_name = - format!("{}/~/{}.html", short_path.path, symbol_group_ctx.name); - - let page_ctx = pages::SymbolPageCtx { - html_head_ctx, - symbol_group_ctx, - breadcrumbs_ctx, - toc_ctx, - disable_search: ctx.disable_search, - categories_panel, - }; + let file_name = + format!("{}/~/{}.json", short_path.path, symbol_group_ctx.name); - let symbol_page = - ctx.render(pages::SymbolPageCtx::TEMPLATE, &page_ctx); + let page_ctx = pages::SymbolPageCtx { + html_head_ctx, + symbol_group_ctx, + breadcrumbs_ctx, + toc_ctx, + disable_search: ctx.disable_search, + categories_panel, + }; - vec![(file_name, symbol_page)] - } + vec![(file_name, serde_json::to_value(page_ctx).unwrap())] } SymbolPage::Redirect { current_symbol, @@ -869,19 +1317,10 @@ pub fn generate( } => { let redirect = serde_json::json!({ "path": href }); - if composable_output { - let file_name = format!( - "{}/~/{}/redirect.json", - short_path.path, current_symbol - ); + let file_name = + format!("{}/~/{}.json", short_path.path, current_symbol); - vec![(file_name, serde_json::to_string(&redirect).unwrap())] - } else { - let file_name = - format!("{}/~/{}.html", short_path.path, current_symbol); - - vec![(file_name, ctx.render("pages/redirect", &redirect))] - } + vec![(file_name, redirect)] } } })); @@ -894,52 +1333,15 @@ pub fn generate( false, ); - if composable_output { - files.insert( - format!("{}/breadcrumbs.html", short_path.path), - ctx.render(util::BreadcrumbsCtx::TEMPLATE, &index.breadcrumbs_ctx), - ); - - if index.module_doc.is_some() || index.overview.is_some() { - let mut out = String::new(); - - if let Some(module_doc) = index.module_doc { - out.push_str( - &ctx.render(jsdoc::ModuleDocCtx::TEMPLATE, &module_doc), - ); - } - - if let Some(all_symbols) = index.overview { - out.push_str( - &ctx.render(SymbolContentCtx::TEMPLATE, &all_symbols), - ); - } - - files.insert(format!("{}/content.html", short_path.path), out); - } - } else { - files.insert( - format!("{}/index.html", short_path.path), - ctx.render(pages::IndexCtx::TEMPLATE, &index), - ); - } + files.insert( + format!("{}/index.json", short_path.path), + serde_json::to_value(index)?, + ); } } } - files.insert(STYLESHEET_FILENAME.into(), STYLESHEET.into()); - files.insert( - SEARCH_INDEX_FILENAME.into(), - search::get_search_index_file(&ctx)?, - ); - files.insert(SCRIPT_FILENAME.into(), SCRIPT_JS.into()); - - if !composable_output { - files.insert(PAGE_STYLESHEET_FILENAME.into(), PAGE_STYLESHEET.into()); - files.insert(RESET_STYLESHEET_FILENAME.into(), RESET_STYLESHEET.into()); - files.insert(FUSE_FILENAME.into(), FUSE_JS.into()); - files.insert(SEARCH_FILENAME.into(), SEARCH_JS.into()); - } + files.insert("search.json".into(), generate_search_index(&ctx)); Ok(files) } @@ -951,7 +1353,7 @@ pub fn find_common_ancestor<'a>( let paths: Vec = urls .filter_map(|url| { if url.scheme() == "file" { - url.to_file_path().ok() + deno_path_util::url_to_file_path(url).ok() } else { None } diff --git a/src/html/pages.rs b/src/html/pages.rs index 844f7098..ea1b47ff 100644 --- a/src/html/pages.rs +++ b/src/html/pages.rs @@ -11,6 +11,8 @@ use super::RenderContext; use super::ShortPath; use super::SymbolGroupCtx; use super::UrlResolveKind; +use std::borrow::Cow; +use std::cmp::Ordering; use std::rc::Rc; use super::FUSE_FILENAME; @@ -23,8 +25,7 @@ use super::STYLESHEET_FILENAME; use crate::html::usage::UsagesCtx; use crate::js_doc::JsDocTag; -use crate::DocNode; -use crate::DocNodeKind; +use crate::node::DocNodeDef; use indexmap::IndexMap; use serde::Serialize; @@ -39,6 +40,7 @@ pub struct HtmlHeadCtx { script_js: String, fuse_js: String, url_search: String, + head_inject: Option, disable_search: bool, } @@ -46,16 +48,18 @@ impl HtmlHeadCtx { pub const TEMPLATE: &'static str = "pages/html_head"; pub fn new( + ctx: &GenerateCtx, root: &str, - page: &str, - package_name: Option<&String>, + page: Option<&str>, current_file: Option<&ShortPath>, - disable_search: bool, ) -> Self { Self { title: format!( - "{page} - {}documentation", - package_name + "{}{}documentation", + page.map(|page| format!("{page} - ")).unwrap_or_default(), + ctx + .package_name + .as_ref() .map(|package_name| format!("{package_name} ")) .unwrap_or_default() ), @@ -70,7 +74,8 @@ impl HtmlHeadCtx { script_js: format!("{root}{SCRIPT_FILENAME}"), fuse_js: format!("{root}{FUSE_FILENAME}"), url_search: format!("{root}{SEARCH_FILENAME}"), - disable_search, + head_inject: ctx.head_inject.clone().map(|head_inject| head_inject(root)), + disable_search: ctx.disable_search, } } } @@ -83,17 +88,23 @@ pub struct CategoriesPanelCtx { } impl CategoriesPanelCtx { - pub const TEMPLATE: &'static str = "pages/category_panel"; + pub const TEMPLATE: &'static str = "category_panel"; - pub fn new(ctx: &RenderContext) -> Option { + pub fn new(ctx: &RenderContext, current_path: Option<&str>) -> Option { match ctx.ctx.file_mode { FileMode::Dts => { let total_symbols = ctx .ctx .doc_nodes .values() - .flat_map(|nodes| partition::partition_nodes_by_name(nodes, true)) - .filter(|(_name, node)| !node[0].is_internal()) + .flat_map(|nodes| { + partition::partition_nodes_by_name( + ctx.ctx, + nodes.iter().map(Cow::Borrowed), + true, + ) + }) + .filter(|(_name, node)| !node[0].is_internal(ctx.ctx)) .count(); let mut categories = ctx @@ -101,11 +112,14 @@ impl CategoriesPanelCtx { .doc_nodes .keys() .map(|short_path| CategoriesPanelCategoryCtx { - name: short_path.display_name(), + name: short_path.display_name().to_string(), href: ctx.ctx.resolve_path( ctx.get_current_resolve(), - UrlResolveKind::File(short_path), + UrlResolveKind::File { file: short_path }, ), + active: current_path.is_some_and(|current_path| { + current_path == short_path.display_name() + }), }) .collect::>(); @@ -125,13 +139,20 @@ impl CategoriesPanelCtx { .ctx .doc_nodes .values() - .flat_map(|nodes| partition::partition_nodes_by_name(nodes, true)) - .filter(|(_name, node)| !node[0].is_internal()) + .flat_map(|nodes| { + partition::partition_nodes_by_name( + ctx.ctx, + nodes.iter().map(Cow::Borrowed), + true, + ) + }) + .filter(|(_name, node)| !node[0].is_internal(ctx.ctx)) .count(); let (_, nodes) = ctx.ctx.doc_nodes.first().unwrap(); let partitions = partition::partition_nodes_by_category( - nodes, + ctx.ctx, + nodes.iter().map(Cow::Borrowed), ctx.ctx.file_mode == FileMode::SingleDts, ); @@ -140,8 +161,10 @@ impl CategoriesPanelCtx { .map(|title| CategoriesPanelCategoryCtx { href: ctx.ctx.resolve_path( ctx.get_current_resolve(), - UrlResolveKind::Category(&title), + UrlResolveKind::Category { category: &title }, ), + active: current_path + .is_some_and(|current_path| current_path == title), name: title, }) .collect::>(); @@ -168,9 +191,11 @@ impl CategoriesPanelCtx { pub struct CategoriesPanelCategoryCtx { pub name: String, pub href: String, + pub active: bool, } #[derive(Debug, Serialize)] +#[serde(tag = "kind")] pub struct IndexCtx { pub html_head_ctx: HtmlHeadCtx, pub module_doc: Option, @@ -215,11 +240,16 @@ impl IndexCtx { ctx.resolve_path(render_ctx.get_current_resolve(), UrlResolveKind::Root); let html_head_ctx = HtmlHeadCtx::new( + ctx, &root, - "Index", - ctx.package_name.as_ref(), + short_path.as_ref().and_then(|short_path| { + if short_path.is_main { + None + } else { + Some(short_path.display_name()) + } + }), None, - ctx.disable_search, ); let overview = match ctx.file_mode { @@ -230,7 +260,7 @@ impl IndexCtx { .map(|(short_path, nodes)| { let doc = nodes .iter() - .find(|node| node.kind == DocNodeKind::ModuleDoc) + .find(|node| matches!(node.def, DocNodeDef::ModuleDoc)) .and_then(|node| { crate::html::jsdoc::jsdoc_body_to_html( &render_ctx, @@ -241,28 +271,30 @@ impl IndexCtx { let title = short_path.display_name(); - let anchor = render_ctx.toc.add_entry( - 1, - title.clone(), - render_ctx.toc.anchorize(title.clone()), - ); + let anchor = render_ctx.toc.anchorize(title); + render_ctx.toc.add_entry(1, title, &anchor); util::SectionCtx { - header: SectionHeaderCtx { + header: Some(SectionHeaderCtx { href: Some(ctx.resolve_path( UrlResolveKind::Root, short_path.as_resolve_kind(), )), - title, + title: title.to_string(), anchor: AnchorCtx { id: anchor }, doc, - }, + }), content: util::SectionContentCtx::Empty, } }) .collect::>(); - sections.sort_by(|a, b| a.header.title.cmp(&b.header.title)); + sections.sort_by(|a, b| match (&a.header, &b.header) { + (Some(x), Some(y)) => x.title.cmp(&y.title), + (None, Some(_)) => Ordering::Less, + (Some(_), None) => Ordering::Greater, + (None, None) => Ordering::Equal, + }); Some(SymbolContentCtx { id: String::new(), @@ -274,11 +306,8 @@ impl IndexCtx { let sections = partitions .into_keys() .map(|title| { - let anchor = render_ctx.toc.add_entry( - 1, - title.clone(), - render_ctx.toc.anchorize(title.clone()), - ); + let anchor = render_ctx.toc.anchorize(&title); + render_ctx.toc.add_entry(1, &title, &anchor); let doc = ctx .category_docs @@ -291,23 +320,22 @@ impl IndexCtx { &render_ctx, &doc, super::jsdoc::MarkdownToHTMLOptions { - summary: false, - summary_prefer_title: false, + title_only: false, no_toc: false, }, ) }); util::SectionCtx { - header: SectionHeaderCtx { + header: Some(SectionHeaderCtx { href: Some(render_ctx.ctx.resolve_path( render_ctx.get_current_resolve(), - UrlResolveKind::Category(&title), + UrlResolveKind::Category { category: &title }, )), title, anchor: AnchorCtx { id: anchor }, doc, - }, + }), content: util::SectionContentCtx::Empty, } }) @@ -326,7 +354,12 @@ impl IndexCtx { let dts_mode = matches!(ctx.file_mode, FileMode::SingleDts | FileMode::Dts); - let categories_panel = CategoriesPanelCtx::new(&render_ctx); + let categories_panel = CategoriesPanelCtx::new( + &render_ctx, + short_path + .as_ref() + .map(|short_path| short_path.display_name()), + ); let usage = dts_mode.then(|| UsagesCtx::new(&render_ctx, &[])).flatten(); let toc_ctx = util::ToCCtx::new( @@ -353,45 +386,41 @@ impl IndexCtx { partitions: partition::Partitions, all_doc_nodes: &[DocNodeWithContext], ) -> Self { - let render_ctx = - RenderContext::new(ctx, all_doc_nodes, UrlResolveKind::Category(name)); + let render_ctx = RenderContext::new( + ctx, + all_doc_nodes, + UrlResolveKind::Category { category: name }, + ); let sections = super::namespace::render_namespace( - &render_ctx, - partitions - .into_iter() - .map(|(title, nodes)| { - let doc = ctx.category_docs.as_ref().and_then(|category_docs| { - category_docs.get(&title).cloned().flatten() - }); - - ( - SectionHeaderCtx { - anchor: AnchorCtx { id: title.clone() }, - title, - href: None, - doc, - }, - nodes, - ) - }) - .collect(), + partitions.into_iter().map(|(title, nodes)| { + let doc = ctx.category_docs.as_ref().and_then(|category_docs| { + category_docs.get(&title).cloned().flatten() + }); + + ( + render_ctx.clone(), + Some(SectionHeaderCtx { + anchor: AnchorCtx { id: title.clone() }, + title, + href: None, + doc, + }), + nodes, + ) + }), ); - let root = - ctx.resolve_path(UrlResolveKind::Category(name), UrlResolveKind::Root); - - let html_head_ctx = HtmlHeadCtx::new( - &root, - name, - ctx.package_name.as_ref(), - None, - ctx.disable_search, + let root = ctx.resolve_path( + UrlResolveKind::Category { category: name }, + UrlResolveKind::Root, ); + let html_head_ctx = HtmlHeadCtx::new(ctx, &root, Some(name), None); + let breadcrumbs_ctx = render_ctx.get_breadcrumbs(); - let categories_panel = CategoriesPanelCtx::new(&render_ctx); + let categories_panel = CategoriesPanelCtx::new(&render_ctx, Some(name)); let usage = UsagesCtx::new(&render_ctx, &[]); let toc_ctx = util::ToCCtx::new( @@ -418,6 +447,7 @@ impl IndexCtx { } #[derive(Serialize)] +#[serde(tag = "kind")] pub struct AllSymbolsCtx { pub html_head_ctx: HtmlHeadCtx, pub content: SymbolContentCtx, @@ -433,31 +463,21 @@ impl AllSymbolsCtx { ctx: &GenerateCtx, partitions: partition::Partitions>, ) -> Self { - // TODO(@crowlKats): handle doc_nodes in all symbols page for each symbol let render_ctx = RenderContext::new(ctx, &[], UrlResolveKind::AllSymbols); let sections = super::namespace::render_namespace( - &render_ctx, - partitions - .into_iter() - .map(|(path, nodes)| { - ( - SectionHeaderCtx::new_for_namespace(&render_ctx, &path), - nodes, - ) - }) - .collect(), - ); + partitions.into_iter().map(|(path, nodes)| { + let render_ctx = + RenderContext::new(ctx, &nodes, UrlResolveKind::AllSymbols); + let header = SectionHeaderCtx::new_for_all_symbols(&render_ctx, &path); - let html_head_ctx = HtmlHeadCtx::new( - "./", - "All Symbols", - ctx.package_name.as_ref(), - None, - ctx.disable_search, + (render_ctx, header, nodes) + }), ); - let categories_panel = CategoriesPanelCtx::new(&render_ctx); + let html_head_ctx = HtmlHeadCtx::new(ctx, "./", Some("All Symbols"), None); + + let categories_panel = CategoriesPanelCtx::new(&render_ctx, None); AllSymbolsCtx { html_head_ctx, @@ -477,7 +497,7 @@ pub enum SymbolPage { Symbol { breadcrumbs_ctx: BreadcrumbsCtx, symbol_group_ctx: SymbolGroupCtx, - toc_ctx: util::ToCCtx, + toc_ctx: Box, categories_panel: Option, }, Redirect { @@ -491,174 +511,21 @@ pub fn generate_symbol_pages_for_module( short_path: &ShortPath, module_doc_nodes: &[DocNodeWithContext], ) -> Vec { - let mut name_partitions = - partition::partition_nodes_by_name(module_doc_nodes, true); + let mut name_partitions = partition::partition_nodes_by_name( + ctx, + module_doc_nodes.iter().map(Cow::Borrowed), + true, + ); let mut drilldown_partitions = IndexMap::new(); for doc_nodes in name_partitions.values() { - let has_class = - doc_nodes.iter().any(|node| node.kind == DocNodeKind::Class); for doc_node in doc_nodes { - match doc_node.kind { - DocNodeKind::Class => { - let class = doc_node.class_def.as_ref().unwrap(); - - let method_nodes = class - .methods - .iter() - .map(|method| { - doc_node.create_child_method( - DocNode::function( - method.name.clone(), - false, - method.location.clone(), - doc_node.declaration_kind, - method.js_doc.clone(), - method.function_def.clone(), - ), - method.is_static, - ) - }) - .collect::>(); - - drilldown_partitions - .extend(partition::partition_nodes_by_name(&method_nodes, false)); - - let property_nodes = class - .properties - .iter() - .map(|property| { - doc_node.create_child_property( - DocNode::from(property.clone()), - property.is_static, - ) - }) - .collect::>(); - - drilldown_partitions.extend( - super::partition::partition_nodes_by_name(&property_nodes, false), - ); - } - DocNodeKind::Interface => { - let interface = doc_node.interface_def.as_ref().unwrap(); - let method_nodes = interface - .methods - .iter() - .filter_map(|method| { - if has_class && method.name == "prototype" { - None - } else { - Some( - doc_node - .create_child_method(DocNode::from(method.clone()), true), - ) - } - }) - .collect::>(); - - drilldown_partitions - .extend(partition::partition_nodes_by_name(&method_nodes, false)); - - let property_nodes = - interface - .properties - .iter() - .filter_map(|property| { - if has_class && property.name == "prototype" { - None - } else { - Some(doc_node.create_child_property( - DocNode::from(property.clone()), - true, - )) - } - }) - .collect::>(); - - drilldown_partitions - .extend(partition::partition_nodes_by_name(&property_nodes, false)); - } - DocNodeKind::TypeAlias => { - let type_alias = doc_node.type_alias_def.as_ref().unwrap(); - - if let Some(ts_type_literal) = - type_alias.ts_type.type_literal.as_ref() - { - let method_nodes = ts_type_literal - .methods - .iter() - .filter_map(|method| { - if has_class && method.name == "prototype" { - None - } else { - Some( - doc_node - .create_child_method(DocNode::from(method.clone()), true), - ) - } - }) - .collect::>(); - - drilldown_partitions - .extend(partition::partition_nodes_by_name(&method_nodes, false)); - - let property_nodes = ts_type_literal - .properties - .iter() - .filter_map(|property| { - if has_class && property.name == "prototype" { - None - } else { - Some(doc_node.create_child_property( - DocNode::from(property.clone()), - true, - )) - } - }) - .collect::>(); - - drilldown_partitions.extend(partition::partition_nodes_by_name( - &property_nodes, - false, - )); - } - } - DocNodeKind::Variable => { - let variable = doc_node.variable_def.as_ref().unwrap(); - - if let Some(ts_type_literal) = variable - .ts_type - .as_ref() - .and_then(|ts_type| ts_type.type_literal.as_ref()) - { - let method_nodes = ts_type_literal - .methods - .iter() - .map(|method| { - doc_node - .create_child_method(DocNode::from(method.clone()), true) - }) - .collect::>(); - - drilldown_partitions - .extend(partition::partition_nodes_by_name(&method_nodes, false)); - - let property_nodes = ts_type_literal - .properties - .iter() - .map(|property| { - doc_node - .create_child_property(DocNode::from(property.clone()), true) - }) - .collect::>(); - - drilldown_partitions.extend(partition::partition_nodes_by_name( - &property_nodes, - false, - )); - } - } - _ => {} + if let Some(drilldown_symbols) = doc_node.get_drilldown_symbols() { + drilldown_partitions.extend(partition::partition_nodes_by_name( + ctx, + drilldown_symbols.map(Cow::Owned), + false, + )) } } } @@ -666,8 +533,11 @@ pub fn generate_symbol_pages_for_module( let mut generated_pages = Vec::with_capacity(name_partitions.values().len()); - let render_ctx = - RenderContext::new(ctx, module_doc_nodes, UrlResolveKind::File(short_path)); + let render_ctx = RenderContext::new( + ctx, + module_doc_nodes, + UrlResolveKind::File { file: short_path }, + ); for (name, doc_nodes) in name_partitions { let (breadcrumbs_ctx, symbol_group_ctx, toc_ctx, categories_panel) = @@ -676,13 +546,13 @@ pub fn generate_symbol_pages_for_module( generated_pages.push(SymbolPage::Symbol { breadcrumbs_ctx, symbol_group_ctx, - toc_ctx, + toc_ctx: Box::new(toc_ctx), categories_panel, }); if doc_nodes .iter() - .any(|doc_node| doc_node.kind == DocNodeKind::Class) + .any(|doc_node| matches!(doc_node.def, DocNodeDef::Class { .. })) { let prototype_name = format!("{name}.prototype"); generated_pages.push(SymbolPage::Redirect { @@ -705,11 +575,12 @@ pub fn generate_symbol_pages_for_module( } #[derive(Debug, Serialize)] +#[serde(tag = "kind")] pub struct SymbolPageCtx { pub html_head_ctx: HtmlHeadCtx, pub symbol_group_ctx: SymbolGroupCtx, pub breadcrumbs_ctx: BreadcrumbsCtx, - pub toc_ctx: util::ToCCtx, + pub toc_ctx: Box, pub disable_search: bool, pub categories_panel: Option, } @@ -735,13 +606,18 @@ pub fn render_symbol_page( symbol: namespaced_name, }) .with_category(if render_ctx.ctx.file_mode == FileMode::SingleDts { - doc_nodes[0].js_doc.tags.iter().find_map(|tag| { - if let JsDocTag::Category { doc } = tag { - Some(doc.as_ref()) - } else { - None - } - }) + doc_nodes[0] + .get_topmost_ancestor() + .js_doc + .tags + .iter() + .find_map(|tag| { + if let JsDocTag::Category { doc } = tag { + Some(doc.as_ref()) + } else { + None + } + }) } else { None }); @@ -754,7 +630,14 @@ pub fn render_symbol_page( let symbol_group_ctx = SymbolGroupCtx::new(&render_ctx, doc_nodes, namespaced_name); - let categories_panel = CategoriesPanelCtx::new(&render_ctx); + let categories_panel = CategoriesPanelCtx::new( + &render_ctx, + Some( + render_ctx + .category + .unwrap_or_else(|| short_path.display_name()), + ), + ); let toc_nodes = (!matches!( render_ctx.ctx.file_mode, diff --git a/src/html/partition.rs b/src/html/partition.rs index f9562475..d50e3dbc 100644 --- a/src/html/partition.rs +++ b/src/html/partition.rs @@ -1,75 +1,106 @@ use super::DocNodeWithContext; +use super::GenerateCtx; use super::ShortPath; use crate::js_doc::JsDocTag; -use crate::DocNodeKind; +use crate::node::DocNodeDef; use indexmap::IndexMap; +use std::borrow::Cow; use std::cmp::Ordering; use std::rc::Rc; pub type Partitions = IndexMap>; -fn create_partitioner( - doc_nodes: &[DocNodeWithContext], +fn create_partitioner<'a, T, F>( + ctx: &GenerateCtx, + doc_nodes: impl Iterator> + 'a, flatten_namespaces: bool, process: &F, ) -> Partitions where F: Fn(&mut IndexMap>, &DocNodeWithContext), { - fn partitioner_inner( + fn partitioner_inner<'a, T, F>( + ctx: &GenerateCtx, partitions: &mut Partitions, - doc_nodes: &[DocNodeWithContext], + parent_node: Option<&DocNodeWithContext>, + doc_nodes: Box> + 'a>, flatten_namespaces: bool, process: &F, ) where F: Fn(&mut IndexMap>, &DocNodeWithContext), { for node in doc_nodes { - if matches!(node.kind, DocNodeKind::ModuleDoc | DocNodeKind::Import) { + if matches!( + node.def, + DocNodeDef::ModuleDoc { .. } | DocNodeDef::Import { .. } + ) { continue; } - if flatten_namespaces && node.kind == DocNodeKind::Namespace { - let namespace_def = node.namespace_def.as_ref().unwrap(); - let ns_qualifiers = Rc::new(node.sub_qualifier()); - + if flatten_namespaces && matches!(node.def, DocNodeDef::Namespace { .. }) + { partitioner_inner( + ctx, partitions, - &namespace_def - .elements - .iter() - .map(|element| { - node - .create_namespace_child(element.clone(), ns_qualifiers.clone()) - }) - .collect::>(), + Some(&node), + Box::new( + node + .namespace_children + .as_ref() + .unwrap() + .iter() + .map(Cow::Borrowed), + ), true, process, ); } - process(partitions, node); + if let Some(reference) = node.reference_def() { + partitioner_inner( + ctx, + partitions, + parent_node, + Box::new(ctx.resolve_reference(parent_node, &reference.target)), + flatten_namespaces, + process, + ) + } else { + process(partitions, &node); + } } } let mut partitions = IndexMap::default(); - partitioner_inner(&mut partitions, doc_nodes, flatten_namespaces, process); + partitioner_inner( + ctx, + &mut partitions, + None, + Box::new(doc_nodes), + flatten_namespaces, + process, + ); partitions } -pub fn partition_nodes_by_name( - doc_nodes: &[DocNodeWithContext], +pub fn partition_nodes_by_name<'a>( + ctx: &GenerateCtx, + doc_nodes: impl Iterator> + 'a, flatten_namespaces: bool, ) -> Partitions { - let mut partitions = - create_partitioner(doc_nodes, flatten_namespaces, &|partitions, node| { + let mut partitions = create_partitioner( + ctx, + doc_nodes, + flatten_namespaces, + &|partitions, node| { partitions .entry(node.get_qualified_name()) .or_default() .push(node.clone()); - }); + }, + ); for val in partitions.values_mut() { val.sort_by_key(|n| n.kind); @@ -80,12 +111,16 @@ pub fn partition_nodes_by_name( partitions } -pub fn partition_nodes_by_kind( - doc_nodes: &[DocNodeWithContext], +pub fn partition_nodes_by_kind<'a>( + ctx: &GenerateCtx, + doc_nodes: impl Iterator> + 'a, flatten_namespaces: bool, ) -> Partitions { - let mut partitions = - create_partitioner(doc_nodes, flatten_namespaces, &|partitions, node| { + let mut partitions = create_partitioner( + ctx, + doc_nodes, + flatten_namespaces, + &|partitions, node| { let maybe_nodes = partitions.values_mut().find(|nodes| { nodes .iter() @@ -95,10 +130,11 @@ pub fn partition_nodes_by_kind( if let Some(nodes) = maybe_nodes { nodes.push(node.clone()); } else { - let entry = partitions.entry(node.kind_with_drilldown).or_default(); + let entry = partitions.entry(node.kind).or_default(); entry.push(node.clone()); } - }); + }, + ); for (_kind, nodes) in partitions.iter_mut() { nodes.sort_by(compare_node); @@ -115,12 +151,16 @@ pub fn partition_nodes_by_kind( .collect() } -pub fn partition_nodes_by_category( - doc_nodes: &[DocNodeWithContext], +pub fn partition_nodes_by_category<'a>( + ctx: &GenerateCtx, + doc_nodes: impl Iterator> + 'a, flatten_namespaces: bool, ) -> Partitions { - let mut partitions = - create_partitioner(doc_nodes, flatten_namespaces, &|partitions, node| { + let mut partitions = create_partitioner( + ctx, + doc_nodes, + flatten_namespaces, + &|partitions, node| { let category = node .js_doc .tags @@ -142,7 +182,8 @@ pub fn partition_nodes_by_category( }) { entry.push(node.clone()); } - }); + }, + ); for (_kind, nodes) in partitions.iter_mut() { nodes.sort_by(compare_node); @@ -163,16 +204,21 @@ pub fn partition_nodes_by_category( .collect() } -pub fn partition_nodes_by_entrypoint( - doc_nodes: &[DocNodeWithContext], +pub fn partition_nodes_by_entrypoint<'a>( + ctx: &GenerateCtx, + doc_nodes: impl Iterator> + 'a, flatten_namespaces: bool, ) -> Partitions> { - let mut partitions = - create_partitioner(doc_nodes, flatten_namespaces, &|partitions, node| { + let mut partitions = create_partitioner( + ctx, + doc_nodes, + flatten_namespaces, + &|partitions, node| { let entry = partitions.entry(node.origin.clone()).or_default(); entry.push(node.clone()); - }); + }, + ); for (_file, nodes) in partitions.iter_mut() { nodes.sort_by(compare_node); diff --git a/src/html/render_context.rs b/src/html/render_context.rs index 51717144..292725d5 100644 --- a/src/html/render_context.rs +++ b/src/html/render_context.rs @@ -4,39 +4,43 @@ use crate::html::util::NamespacedSymbols; use crate::html::DocNodeWithContext; use crate::html::GenerateCtx; use crate::html::UrlResolveKind; -use crate::DocNodeKind; +use crate::node::DocNodeDef; use deno_graph::ModuleSpecifier; +use serde::Serialize; +use std::cmp::Ordering; use std::collections::HashMap; use std::collections::HashSet; use std::rc::Rc; +use std::sync::Arc; +use std::sync::Mutex; #[derive(Clone)] pub struct RenderContext<'ctx> { - pub ctx: &'ctx GenerateCtx<'ctx>, + pub ctx: &'ctx GenerateCtx, scoped_symbols: NamespacedSymbols, current_imports: Rc>, current_type_params: Rc>, current_resolve: UrlResolveKind<'ctx>, /// A vector of parts of the current namespace, eg. `vec!["Deno", "errors"]`. - namespace_parts: Rc>, + namespace_parts: Rc<[String]>, /// Only some when in `FileMode::SingleDts` and using categories - category: Option<&'ctx str>, - pub toc: crate::html::comrak_adapters::HeadingToCAdapter, + pub category: Option<&'ctx str>, + pub toc: HeadingToCAdapter, } impl<'ctx> RenderContext<'ctx> { pub fn new( - ctx: &'ctx GenerateCtx<'ctx>, + ctx: &'ctx GenerateCtx, doc_nodes: &[DocNodeWithContext], current_resolve: UrlResolveKind<'ctx>, ) -> Self { Self { ctx, - scoped_symbols: NamespacedSymbols::new(doc_nodes), + scoped_symbols: NamespacedSymbols::new(ctx, doc_nodes), current_imports: Rc::new(get_current_imports(doc_nodes)), current_type_params: Default::default(), current_resolve, - namespace_parts: Rc::new(vec![]), + namespace_parts: Rc::new([]), category: None, toc: Default::default(), } @@ -52,7 +56,7 @@ impl<'ctx> RenderContext<'ctx> { } } - pub fn with_namespace(&self, namespace_parts: Rc>) -> Self { + pub fn with_namespace(&self, namespace_parts: Rc<[String]>) -> Self { Self { namespace_parts, ..self.clone() @@ -93,36 +97,43 @@ impl<'ctx> RenderContext<'ctx> { .collect::>(); if !self.namespace_parts.is_empty() { - let mut parts = (*self.namespace_parts).clone(); + // TODO: clean this up to not clone and to_vec + let mut parts = self.namespace_parts.to_vec(); while !parts.is_empty() { let mut current_parts = parts.clone(); current_parts.extend_from_slice(&target_symbol_parts); - if self.scoped_symbols.contains(¤t_parts) { - return Some(self.ctx.resolve_path( - self.get_current_resolve(), - UrlResolveKind::Symbol { - file: self.get_current_resolve().get_file().unwrap(), - symbol: ¤t_parts.join("."), - }, - )); + if let Some(origin) = self.scoped_symbols.get(¤t_parts) { + return Some( + self.ctx.resolve_path( + self.get_current_resolve(), + UrlResolveKind::Symbol { + file: self + .get_current_resolve() + .get_file() + .or_else(|| origin.as_ref().map(|origin| &**origin)) + .unwrap(), + symbol: ¤t_parts.join("."), + }, + ), + ); } parts.pop(); } } - if self.scoped_symbols.contains(&target_symbol_parts) { + if let Some(origin) = self.scoped_symbols.get(&target_symbol_parts) { return Some( self.ctx.resolve_path( self.get_current_resolve(), UrlResolveKind::Symbol { - file: &self + file: self .get_current_resolve() .get_file() - .cloned() + .or_else(|| origin.as_ref().map(|origin| &**origin)) .unwrap_or_else(|| { - (**self.ctx.main_entrypoint.as_ref().unwrap()).clone() + &(**self.ctx.main_entrypoint.as_ref().unwrap()) }), symbol: target_symbol, }, @@ -189,7 +200,7 @@ impl<'ctx> RenderContext<'ctx> { }, ] } - UrlResolveKind::Category(category) => { + UrlResolveKind::Category { category } => { vec![ BreadcrumbCtx { name: index_name, @@ -207,7 +218,7 @@ impl<'ctx> RenderContext<'ctx> { }, ] } - UrlResolveKind::File(file) => { + UrlResolveKind::File { file } => { if file.is_main { vec![BreadcrumbCtx { name: index_name, @@ -226,7 +237,7 @@ impl<'ctx> RenderContext<'ctx> { is_first_symbol: false, }, BreadcrumbCtx { - name: file.display_name(), + name: file.display_name().to_string(), href: "".to_string(), is_symbol: false, is_first_symbol: false, @@ -246,10 +257,11 @@ impl<'ctx> RenderContext<'ctx> { if !file.is_main { parts.push(BreadcrumbCtx { - name: file.display_name(), - href: self - .ctx - .resolve_path(self.current_resolve, UrlResolveKind::File(file)), + name: file.display_name().to_string(), + href: self.ctx.resolve_path( + self.current_resolve, + UrlResolveKind::File { file }, + ), is_symbol: false, is_first_symbol: false, }); @@ -258,7 +270,7 @@ impl<'ctx> RenderContext<'ctx> { name: category.to_string(), href: self.ctx.resolve_path( self.current_resolve, - UrlResolveKind::Category(category), + UrlResolveKind::Category { category }, ), is_symbol: false, is_first_symbol: false, @@ -298,6 +310,129 @@ impl<'ctx> RenderContext<'ctx> { } } +#[derive(Debug, Serialize)] +pub struct ToCEntry { + pub level: u8, + pub content: String, + pub anchor: String, +} + +#[derive(Default)] +pub struct Anchorizer { + map: HashMap, + itoa_buffer: itoa::Buffer, +} + +impl Anchorizer { + /// Returns a String that has been converted into an anchor using the GFM algorithm. + /// This replaces comrak's implementation to improve the performance. + /// @see https://docs.rs/comrak/latest/comrak/struct.Anchorizer.html#method.anchorize + pub fn anchorize(&mut self, s: &str) -> String { + let mut s = REJECTED_CHARS + .replace_all(&s.to_lowercase(), "") + .replace(' ', "-"); + + if let Some(count) = self.map.get_mut(&s) { + let a = self.itoa_buffer.format(*count); + s.push('-'); + s.push_str(a); + + *count += 1; + } else { + self.map.insert(s.clone(), 1); + } + + s + } +} + +#[derive(Clone)] +pub struct HeadingToCAdapter { + pub toc: Arc>>, + pub offset: Arc>, + pub anchorizer: Arc>, +} + +impl Default for HeadingToCAdapter { + fn default() -> Self { + Self { + toc: Arc::new(Mutex::new(vec![])), + anchorizer: Arc::new(Mutex::new(Default::default())), + offset: Arc::new(Mutex::new(0)), + } + } +} + +lazy_static! { + static ref REJECTED_CHARS: regex::Regex = + regex::Regex::new(r"[^\p{L}\p{M}\p{N}\p{Pc} -]").unwrap(); +} + +impl HeadingToCAdapter { + pub fn anchorize(&self, content: &str) -> String { + let mut anchorizer = self.anchorizer.lock().unwrap(); + anchorizer.anchorize(content) + } + + pub fn add_entry(&self, level: u8, content: &str, anchor: &str) { + let mut toc = self.toc.lock().unwrap(); + let mut offset = self.offset.lock().unwrap(); + + *offset = level; + + if toc.last().map_or(true, |toc| toc.content != content) { + toc.push(ToCEntry { + level, + content: content.to_owned(), + anchor: anchor.to_owned(), + }); + } + } + + pub fn render(&self) -> Option { + let toc = self.toc.lock().unwrap(); + + if toc.is_empty() { + return None; + } + + let mut toc_content = vec!["
    ".to_string()]; + let mut current_level = toc.iter().map(|entry| entry.level).min().unwrap(); + + let mut level_diff = 0; + for entry in toc.iter() { + match current_level.cmp(&entry.level) { + Ordering::Equal => {} + Ordering::Less => { + level_diff += 1; + toc_content.push(r#"
    • "#.to_string()); + current_level = entry.level; + } + Ordering::Greater => { + level_diff -= 1; + toc_content.push("
  • ".to_string()); + current_level = entry.level; + } + } + + toc_content.push(format!( + r##"
  • {}
  • "##, + entry.anchor, + html_escape::encode_double_quoted_attribute(&entry.content), + entry.content + )); + } + + for _ in 0..level_diff { + toc_content.push("
".to_string()); + } + + toc_content.push(String::from("")); + + Some(toc_content.join("")) + } +} + fn split_with_brackets(s: &str) -> Vec { let mut result = Vec::new(); let mut current = String::new(); @@ -339,8 +474,7 @@ fn get_current_imports( let mut imports = HashMap::new(); for doc_node in doc_nodes { - if doc_node.kind == DocNodeKind::Import { - let import_def = doc_node.import_def.as_ref().unwrap(); + if let DocNodeDef::Import { import_def } = &doc_node.def { // TODO: handle import aliasing if import_def.imported.as_deref() == Some(doc_node.get_name()) { imports.insert(doc_node.get_name().to_string(), import_def.src.clone()); @@ -354,14 +488,17 @@ fn get_current_imports( #[cfg(test)] mod test { use super::*; - use crate::html::GenerateOptions; use crate::html::HrefResolver; + use crate::html::{ + GenerateOptions, UsageComposer, UsageComposerEntry, UsageToMd, + }; use crate::node::DeclarationKind; use crate::node::ImportDef; use crate::DocNode; use crate::Location; + use indexmap::IndexMap; - struct TestResolver(); + struct TestResolver; impl HrefResolver for TestResolver { fn resolve_path( @@ -388,14 +525,41 @@ mod test { Some(format!("{src}/{}", symbol.join("."))) } - fn resolve_usage(&self, current_resolve: UrlResolveKind) -> Option { - current_resolve - .get_file() - .map(|current_file| current_file.specifier.to_string()) + fn resolve_source(&self, location: &Location) -> Option { + Some(location.filename.clone().into_string()) } - fn resolve_source(&self, location: &Location) -> Option { - Some(location.filename.clone()) + fn resolve_external_jsdoc_module( + &self, + _module: &str, + _symbol: Option<&str>, + ) -> Option<(String, String)> { + None + } + } + + impl UsageComposer for TestResolver { + fn is_single_mode(&self) -> bool { + true + } + + fn compose( + &self, + current_resolve: UrlResolveKind, + usage_to_md: UsageToMd, + ) -> IndexMap { + current_resolve + .get_file() + .map(|current_file| { + IndexMap::from([( + UsageComposerEntry { + name: "".to_string(), + icon: None, + }, + usage_to_md(current_file.specifier.as_str(), None), + )]) + }) + .unwrap_or_default() } } @@ -404,28 +568,22 @@ mod test { let doc_nodes_by_url = indexmap::IndexMap::from([( ModuleSpecifier::parse("file:///mod.ts").unwrap(), vec![DocNode { - kind: DocNodeKind::Import, - name: "foo".to_string(), + name: "foo".into(), is_default: None, location: Location { - filename: "a".to_string(), + filename: "a".into(), line: 0, col: 0, byte_index: 0, }, declaration_kind: DeclarationKind::Private, js_doc: Default::default(), - function_def: None, - variable_def: None, - enum_def: None, - class_def: None, - type_alias_def: None, - namespace_def: None, - interface_def: None, - import_def: Some(ImportDef { - src: "b".to_string(), - imported: Some("foo".to_string()), - }), + def: crate::node::DocNodeDef::Import { + import_def: ImportDef { + src: "b".to_string(), + imported: Some("foo".to_string()), + }, + }, }], )]); @@ -433,14 +591,18 @@ mod test { GenerateOptions { package_name: None, main_entrypoint: None, - href_resolver: Rc::new(TestResolver()), - usage_composer: None, + href_resolver: Rc::new(TestResolver), + usage_composer: Rc::new(TestResolver), rewrite_map: None, - composable_output: false, category_docs: None, disable_search: false, symbol_redirect_map: None, default_symbol_map: None, + markdown_renderer: crate::html::comrak::create_renderer( + None, None, None, + ), + markdown_stripper: Rc::new(crate::html::comrak::strip), + head_inject: None, }, None, Default::default(), @@ -458,8 +620,11 @@ mod test { let render_ctx = RenderContext::new(&ctx, doc_nodes, UrlResolveKind::Root); assert_eq!(render_ctx.lookup_symbol_href("foo").unwrap(), "b/foo"); - let render_ctx = - RenderContext::new(&ctx, doc_nodes, UrlResolveKind::File(short_path)); + let render_ctx = RenderContext::new( + &ctx, + doc_nodes, + UrlResolveKind::File { file: short_path }, + ); assert_eq!(render_ctx.lookup_symbol_href("foo").unwrap(), "b/foo"); } } diff --git a/src/html/search.rs b/src/html/search.rs index 5dded021..d78d8d73 100644 --- a/src/html/search.rs +++ b/src/html/search.rs @@ -1,47 +1,54 @@ +use super::DocNodeKindCtx; use super::DocNodeWithContext; use super::GenerateCtx; use crate::js_doc::JsDocTag; -use crate::node::Location; -use crate::DocNodeKind; -use deno_ast::ModuleSpecifier; use serde::Serialize; use serde_json::json; +#[derive(Clone, Debug, Serialize)] +#[serde(rename_all = "camelCase")] +struct SlimKindCtx { + char: char, + pub kind: &'static str, + pub title: &'static str, +} + #[derive(Clone, Debug, Serialize)] #[serde(rename_all = "camelCase")] struct SearchIndexNode { - kind: Vec, - name: String, - file: String, - doc: String, - location: Location, - url: String, - category: String, - declaration_kind: crate::node::DeclarationKind, + kind: Vec, + name: Box, + file: Box, + doc: Box, + url: Box, + #[serde(skip_serializing_if = "is_empty", default)] + category: Box, deprecated: bool, } +fn is_empty(s: &str) -> bool { + s.is_empty() +} + fn doc_nodes_into_search_index_node( ctx: &GenerateCtx, doc_nodes: Vec, name: String, -) -> SearchIndexNode { - let kinds = doc_nodes.iter().map(|node| node.kind).collect(); +) -> Vec { + let kinds = doc_nodes + .iter() + .map(|node| { + let kind = DocNodeKindCtx::from(node.kind); + SlimKindCtx { + char: kind.char, + kind: kind.kind, + title: kind.title, + } + }) + .collect(); let deprecated = super::util::all_deprecated(&doc_nodes.iter().collect::>()); - let mut location = doc_nodes[0].location.clone(); - let location_url = ModuleSpecifier::parse(&location.filename).unwrap(); - location.filename = if let Some(short_path) = ctx - .doc_nodes - .keys() - .find(|short_path| short_path.specifier == location_url) - { - html_escape::encode_text(&short_path.display_name()).into_owned() - } else { - String::new() - }; - let doc = doc_nodes[0].js_doc.doc.clone().unwrap_or_default(); let abs_url = ctx.resolve_path( @@ -65,20 +72,32 @@ fn doc_nodes_into_search_index_node( }) .unwrap_or_default(); - SearchIndexNode { + let mut out = vec![SearchIndexNode { kind: kinds, - name: html_escape::encode_text(&name).to_string(), + name: html_escape::encode_text(&name).into(), file: html_escape::encode_double_quoted_attribute( &doc_nodes[0].origin.path, ) - .into_owned(), + .into(), doc, - location, - url: abs_url, + url: abs_url.into_boxed_str(), category, - declaration_kind: doc_nodes[0].declaration_kind, deprecated, - } + }]; + + out.extend( + doc_nodes + .iter() + .filter_map(|node| node.get_drilldown_symbols()) + .flatten() + .flat_map(|drilldown_node| { + let name = drilldown_node.get_qualified_name(); + + doc_nodes_into_search_index_node(ctx, vec![drilldown_node], name) + }), + ); + + out } pub fn generate_search_index(ctx: &GenerateCtx) -> serde_json::Value { @@ -86,18 +105,21 @@ pub fn generate_search_index(ctx: &GenerateCtx) -> serde_json::Value { .doc_nodes .values() .flatten() - .cloned() - .collect::>(); - let partitions = super::partition::partition_nodes_by_name(&doc_nodes, true); + .map(std::borrow::Cow::Borrowed); + let partitions = + super::partition::partition_nodes_by_name(ctx, doc_nodes, true); let mut doc_nodes = partitions .into_iter() - .map(|(name, nodes)| doc_nodes_into_search_index_node(ctx, nodes, name)) + .flat_map(|(name, nodes)| { + doc_nodes_into_search_index_node(ctx, nodes, name) + }) .collect::>(); doc_nodes.sort_by(|a, b| a.file.cmp(&b.file)); let search_index = json!({ + "kind": "search", "nodes": doc_nodes }); diff --git a/src/html/symbols/class.rs b/src/html/symbols/class.rs index a46b3583..d71b8a30 100644 --- a/src/html/symbols/class.rs +++ b/src/html/symbols/class.rs @@ -11,14 +11,12 @@ use serde::Serialize; use std::collections::BTreeMap; use std::collections::HashSet; -// TODO: overrides - pub(crate) fn render_class( ctx: &RenderContext, doc_node: &DocNodeWithContext, name: &str, ) -> Vec { - let class_def = doc_node.class_def.as_ref().unwrap(); + let class_def = doc_node.class_def().unwrap(); let current_type_params = class_def .type_params @@ -136,7 +134,7 @@ fn render_constructors( Some(html_escape::encode_text(&name).into_owned()), None, &format!("({params})"), - HashSet::from([Tag::New]), + [Tag::New].into(), constructor.js_doc.doc.as_deref(), &constructor.location, ) @@ -258,20 +256,20 @@ fn property_or_method_cmp( struct ClassItems { properties: Vec, static_properties: Vec, - methods: BTreeMap>, - static_methods: BTreeMap>, + methods: BTreeMap, Vec>, + static_methods: BTreeMap, Vec>, } fn partition_properties_and_classes( - properties: Vec, - methods: Vec, + properties: Box<[ClassPropertyDef]>, + methods: Box<[ClassMethodDef]>, ) -> ClassItems { let mut out_properties = vec![]; let mut out_static_properties = vec![]; let mut out_methods = BTreeMap::new(); let mut out_static_methods = BTreeMap::new(); - for property in properties { + for property in properties.into_vec().into_iter() { if property.is_static { out_static_properties.push(PropertyOrMethod::Property(property)); } else { @@ -279,7 +277,7 @@ fn partition_properties_and_classes( } } - for method in methods { + for method in methods.into_vec().into_iter() { if matches!(method.kind, MethodKind::Getter | MethodKind::Setter) { if method.is_static { out_static_properties.push(PropertyOrMethod::Method(method)); @@ -381,7 +379,7 @@ fn render_class_method( tags.insert(Tag::Abstract); } if method.optional { - tags.insert(Tag::Abstract); + tags.insert(Tag::Optional); } Some(DocEntryCtx::new( @@ -493,7 +491,7 @@ fn render_class_properties( fn render_class_methods( ctx: &RenderContext, class_name: &str, - methods: BTreeMap>, + methods: BTreeMap, Vec>, ) -> Vec { methods .values() diff --git a/src/html/symbols/enum.rs b/src/html/symbols/enum.rs index 67595c05..a1084914 100644 --- a/src/html/symbols/enum.rs +++ b/src/html/symbols/enum.rs @@ -7,7 +7,7 @@ pub(crate) fn render_enum( render_ctx: &RenderContext, doc_node: &DocNodeWithContext, ) -> Vec { - let mut members = doc_node.enum_def.as_ref().unwrap().members.clone(); + let mut members = doc_node.enum_def().unwrap().members.clone(); members.sort_by(|a, b| a.name.cmp(&b.name)); diff --git a/src/html/symbols/function.rs b/src/html/symbols/function.rs index 0fd5f4f6..11d1f0a6 100644 --- a/src/html/symbols/function.rs +++ b/src/html/symbols/function.rs @@ -9,8 +9,10 @@ use crate::html::util::*; use crate::html::DocNodeWithContext; use crate::js_doc::JsDocTag; use crate::params::ParamPatternDef; +use indexmap::IndexSet; use serde::Serialize; use std::collections::HashSet; +use std::ops::Deref; #[derive(Debug, Serialize, Clone)] struct OverloadRenderCtx { @@ -40,14 +42,14 @@ impl FunctionCtx { .iter() .enumerate() .filter(|(i, doc_node)| { - let function_def = doc_node.function_def.as_ref().unwrap(); + let function_def = doc_node.function_def().unwrap(); !(function_def.has_body && *i != 0) }) .count(); for (i, doc_node) in doc_nodes.into_iter().enumerate() { - let function_def = doc_node.function_def.as_ref().unwrap(); + let function_def = doc_node.function_def().unwrap(); if function_def.has_body && i != 0 { continue; @@ -70,11 +72,9 @@ impl FunctionCtx { name_to_id("function", &format!("{}_{i}", doc_node.get_name())); if overloads_count > 1 { - ctx.toc.add_entry( - 0, - format!("Overload {}", i + 1), - overload_id.clone(), - ); + ctx + .toc + .add_entry(0, &format!("Overload {}", i + 1), &overload_id); } functions_content.push(OverloadRenderCtx { @@ -117,7 +117,7 @@ fn render_single_function( doc_node: &DocNodeWithContext, overload_id: &str, ) -> SymbolContentCtx { - let function_def = doc_node.function_def.as_ref().unwrap(); + let function_def = doc_node.function_def().unwrap(); let current_type_params = function_def .type_params @@ -126,29 +126,28 @@ fn render_single_function( .collect::>(); let ctx = &ctx.with_current_type_params(current_type_params); - let param_docs = - doc_node - .js_doc - .tags - .iter() - .filter_map(|tag| { - if let JsDocTag::Param { - name, - doc, - optional, - default, - .. - } = tag - { - Some((name.as_str(), (doc, *optional, default))) - } else { - None - } - }) - .collect::, bool, &Option), - >>(); + let param_docs = doc_node + .js_doc + .tags + .iter() + .filter_map(|tag| { + if let JsDocTag::Param { + name, + doc, + optional, + default, + .. + } = tag + { + Some((name.deref(), (doc, *optional, default))) + } else { + None + } + }) + .collect::>, bool, &Option>), + >>(); let params = function_def .params @@ -168,7 +167,7 @@ fn render_single_function( let ts_type = if let ParamPatternDef::Assign { left, right } = ¶m.pattern { - default = default.or(Some(right.to_string())); + default = default.or(Some(right.deref().into())); left.ts_type.as_ref() } else { param.ts_type.as_ref() @@ -179,7 +178,7 @@ fn render_single_function( .unwrap_or_default(); if let Some(default) = &default { - if default != "[UNSUPPORTED]" { + if default.deref() != "[UNSUPPORTED]" { ts_type = format!(r#"{ts_type} = {default}"#); } } @@ -193,9 +192,9 @@ fn render_single_function( ) || default.is_some() || optional { - HashSet::from([Tag::Optional]) + IndexSet::from([Tag::Optional]) } else { - HashSet::new() + IndexSet::new() }; let param_doc = param_docs @@ -251,6 +250,54 @@ fn render_single_function( ), )); + let throws = doc_node + .js_doc + .tags + .iter() + .filter_map(|tag| { + if let JsDocTag::Throws { type_ref, doc } = tag { + if type_ref.is_some() || doc.is_some() { + return Some((type_ref, doc)); + } + } + + None + }) + .enumerate() + .map(|(i, (type_ref, doc))| { + render_function_throws(ctx, doc_node, type_ref, doc, overload_id, i) + }) + .collect::>(); + + if !throws.is_empty() { + sections.push(SectionCtx::new( + ctx, + "Throws", + SectionContentCtx::DocEntry(throws), + )); + } + + let references = doc_node + .js_doc + .tags + .iter() + .filter_map(|tag| { + if let JsDocTag::See { doc } = tag { + Some(super::generate_see(ctx, doc)) + } else { + None + } + }) + .collect::>(); + + if !references.is_empty() { + sections.push(SectionCtx::new( + ctx, + "See", + SectionContentCtx::See(references), + )); + } + SymbolContentCtx { id: String::new(), sections, @@ -282,8 +329,33 @@ fn render_function_return_type( None, None, &render_type_def(render_ctx, return_type), - HashSet::new(), + IndexSet::new(), return_type_doc, &doc_node.location, )) } + +fn render_function_throws( + render_ctx: &RenderContext, + doc_node: &DocNodeWithContext, + type_ref: &Option>, + doc: &Option>, + overload_id: &str, + throws_id: usize, +) -> DocEntryCtx { + let id = name_to_id(overload_id, &format!("throws_{throws_id}")); + + DocEntryCtx::new( + render_ctx, + &id, + None, + None, + type_ref + .as_ref() + .map(|doc| doc.as_ref()) + .unwrap_or_default(), + IndexSet::new(), + doc.as_ref().map(|doc| doc.as_ref()), + &doc_node.location, + ) +} diff --git a/src/html/symbols/interface.rs b/src/html/symbols/interface.rs index a2540194..22207791 100644 --- a/src/html/symbols/interface.rs +++ b/src/html/symbols/interface.rs @@ -11,7 +11,7 @@ pub(crate) fn render_interface( doc_node: &DocNodeWithContext, name: &str, ) -> Vec { - let interface_def = doc_node.interface_def.as_ref().unwrap(); + let interface_def = doc_node.interface_def().unwrap(); let current_type_params = interface_def .type_params @@ -225,7 +225,7 @@ pub(crate) fn render_methods( .iter() .enumerate() .map(|(i, method)| { - let id = name_to_id("call_signature", &format!("{}_{i}", method.name)); + let id = name_to_id("methods", &format!("{}_{i}", method.name)); let name = if method.name == "new" { "new".to_string() diff --git a/src/html/symbols/mod.rs b/src/html/symbols/mod.rs index f832f97c..9d2ee7b8 100644 --- a/src/html/symbols/mod.rs +++ b/src/html/symbols/mod.rs @@ -1,15 +1,18 @@ use crate::html::types::render_type_def; use crate::html::usage::UsagesCtx; use crate::html::util::AnchorCtx; +use crate::html::util::SectionContentCtx; use crate::html::util::SectionCtx; use crate::html::util::Tag; -use crate::html::DocNodeKindWithDrilldown; +use crate::html::DocNodeKind; use crate::html::DocNodeWithContext; use crate::html::RenderContext; use crate::js_doc::JsDocTag; -use crate::DocNodeKind; +use crate::node::DocNodeDef; use indexmap::IndexMap; +use indexmap::IndexSet; use serde::Serialize; +use std::borrow::Cow; use std::collections::HashSet; pub mod class; @@ -24,7 +27,7 @@ pub mod variable; struct SymbolCtx { kind: super::util::DocNodeKindCtx, usage: Option, - tags: HashSet, + tags: IndexSet, subtitle: Option, content: Vec, deprecated: Option, @@ -46,15 +49,15 @@ impl SymbolGroupCtx { name: &str, ) -> Self { let mut split_nodes = - IndexMap::>::default(); + IndexMap::>::default(); for doc_node in doc_nodes { - if doc_node.kind == DocNodeKind::Import { + if matches!(doc_node.def, DocNodeDef::Import { .. }) { continue; } split_nodes - .entry(doc_node.kind_with_drilldown) + .entry(doc_node.kind) .or_insert(vec![]) .push(doc_node.clone()); } @@ -67,7 +70,7 @@ impl SymbolGroupCtx { let all_deprecated = super::util::all_deprecated(&doc_nodes.iter().collect::>()); - let mut tags = HashSet::new(); + let mut tags = indexmap::IndexSet::new(); if doc_nodes.iter().any(|node| { node @@ -79,7 +82,7 @@ impl SymbolGroupCtx { tags.insert(Tag::Unstable); } - let permissions = doc_nodes + let mut permissions = doc_nodes .iter() .flat_map(|node| { node @@ -101,18 +104,19 @@ impl SymbolGroupCtx { }) .flatten() }) - .collect::>(); + .collect::>(); if !permissions.is_empty() { - tags.insert(Tag::Permissions(permissions)); + permissions.sort(); + tags.insert(Tag::Permissions(permissions.into_iter().collect())); } - if doc_nodes[0].is_internal() { + if doc_nodes[0].is_internal(ctx.ctx) { tags.insert(Tag::Private); } let deprecated = if all_deprecated - && !(doc_nodes[0].kind == DocNodeKind::Function + && !(matches!(doc_nodes[0].def, DocNodeDef::Function { .. }) && doc_nodes.len() == 1) { doc_nodes[0].js_doc.tags.iter().find_map(|tag| { @@ -142,7 +146,7 @@ impl SymbolGroupCtx { SymbolCtx { tags, - kind: doc_nodes[0].kind_with_drilldown.into(), + kind: doc_nodes[0].kind.into(), subtitle: DocBlockSubtitleCtx::new(ctx, &doc_nodes[0]), content: SymbolInnerCtx::new(ctx, doc_nodes, name), source_href: ctx @@ -187,10 +191,8 @@ impl DocBlockSubtitleCtx { pub const TEMPLATE_INTERFACE: &'static str = "doc_block_subtitle_interface"; fn new(ctx: &RenderContext, doc_node: &DocNodeWithContext) -> Option { - match doc_node.kind { - DocNodeKind::Class => { - let class_def = doc_node.class_def.as_ref().unwrap(); - + match &doc_node.def { + DocNodeDef::Class { class_def } => { let current_type_params = class_def .type_params .iter() @@ -228,9 +230,7 @@ impl DocBlockSubtitleCtx { extends: class_extends, }) } - DocNodeKind::Interface => { - let interface_def = doc_node.interface_def.as_ref().unwrap(); - + DocNodeDef::Interface { interface_def } => { if interface_def.extends.is_empty() { return None; } @@ -287,64 +287,99 @@ impl SymbolInnerCtx { let docs = crate::html::jsdoc::jsdoc_body_to_html(ctx, &doc_node.js_doc, false); - if let Some(examples) = - crate::html::jsdoc::jsdoc_examples(ctx, &doc_node.js_doc) - { - sections.push(examples); + if !matches!(doc_node.def, DocNodeDef::Function { .. }) { + if let Some(examples) = + crate::html::jsdoc::jsdoc_examples(ctx, &doc_node.js_doc) + { + sections.push(examples); + } } - sections.extend(match doc_node.kind { - DocNodeKind::Function => { + sections.extend(match doc_node.def { + DocNodeDef::Function { .. } => { functions.push(doc_node); continue; } - DocNodeKind::Variable => variable::render_variable(ctx, doc_node, name), - DocNodeKind::Class => class::render_class(ctx, doc_node, name), - DocNodeKind::Enum => r#enum::render_enum(ctx, doc_node), - DocNodeKind::Interface => { + DocNodeDef::Variable { .. } => { + variable::render_variable(ctx, doc_node, name) + } + DocNodeDef::Class { .. } => class::render_class(ctx, doc_node, name), + DocNodeDef::Enum { .. } => r#enum::render_enum(ctx, doc_node), + DocNodeDef::Interface { .. } => { interface::render_interface(ctx, doc_node, name) } - DocNodeKind::TypeAlias => { + DocNodeDef::TypeAlias { .. } => { type_alias::render_type_alias(ctx, doc_node, name) } - DocNodeKind::Namespace => { - let namespace_def = doc_node.namespace_def.as_ref().unwrap(); - let ns_qualifiers = std::rc::Rc::new(doc_node.sub_qualifier()); - let namespace_nodes = namespace_def - .elements - .iter() - .map(|element| { - doc_node - .create_namespace_child(element.clone(), ns_qualifiers.clone()) - }) - .collect::>(); - - let partitions = - super::partition::partition_nodes_by_kind(&namespace_nodes, false); - - namespace::render_namespace( - &ctx.with_namespace(ns_qualifiers), - partitions - .into_iter() - .map(|(title, nodes)| { - ( - crate::html::util::SectionHeaderCtx { - title: title.clone(), - anchor: AnchorCtx { id: title }, - href: None, - doc: None, - }, - nodes, + DocNodeDef::Namespace { .. } => { + let namespace_nodes = doc_node.namespace_children.as_ref().unwrap(); + let ns_qualifiers = namespace_nodes + .first() + .map(|node| node.ns_qualifiers.clone()) + .unwrap_or_else(|| doc_node.sub_qualifier().into()); + + let partitions = super::partition::partition_nodes_by_kind( + ctx.ctx, + namespace_nodes.iter().flat_map(|node| { + if let Some(reference_def) = node.reference_def() { + Box::new( + ctx + .ctx + .resolve_reference(Some(doc_node), &reference_def.target), ) - }) - .collect(), - ) + as Box>> + } else { + Box::new(std::iter::once(Cow::Borrowed(node))) as _ + } + }), + false, + ); + + let ctx = ctx.with_namespace(ns_qualifiers); + + namespace::render_namespace(partitions.into_iter().map( + |(title, nodes)| { + ( + ctx.clone(), + Some(crate::html::util::SectionHeaderCtx { + title: title.clone(), + anchor: AnchorCtx { id: title }, + href: None, + doc: None, + }), + nodes, + ) + }, + )) } - DocNodeKind::ModuleDoc | DocNodeKind::Import => unreachable!(), + DocNodeDef::ModuleDoc { .. } + | DocNodeDef::Import { .. } + | DocNodeDef::Reference { .. } => unreachable!(), }); + let references = doc_node + .js_doc + .tags + .iter() + .filter_map(|tag| { + if let JsDocTag::See { doc } = tag { + Some(generate_see(ctx, doc)) + } else { + None + } + }) + .collect::>(); + + if !references.is_empty() { + sections.push(SectionCtx::new( + ctx, + "See", + SectionContentCtx::See(references), + )); + } + content_parts.push(SymbolInnerCtx::Other(SymbolContentCtx { id: String::new(), sections, @@ -361,3 +396,13 @@ impl SymbolInnerCtx { content_parts } } + +fn generate_see(ctx: &RenderContext, doc: &str) -> String { + let doc = if let Some(href) = ctx.lookup_symbol_href(doc) { + format!("[{doc}]({href})") + } else { + doc.to_string() + }; + + crate::html::jsdoc::render_markdown(ctx, &doc, true) +} diff --git a/src/html/symbols/namespace.rs b/src/html/symbols/namespace.rs index a02080ad..3ae1a065 100644 --- a/src/html/symbols/namespace.rs +++ b/src/html/symbols/namespace.rs @@ -1,26 +1,32 @@ use crate::html::render_context::RenderContext; use crate::html::util::*; +use crate::html::DocNodeKind; use crate::html::DocNodeWithContext; +use crate::html::MethodKind; use indexmap::IndexMap; use indexmap::IndexSet; use serde::Serialize; -use std::collections::HashSet; +use std::cmp::Ordering; -pub fn render_namespace( - ctx: &RenderContext, - partitions: IndexMap>, +pub fn render_namespace<'a>( + partitions: impl Iterator< + Item = ( + RenderContext<'a>, + Option, + Vec, + ), + >, ) -> Vec { partitions - .into_iter() - .map(|(header, doc_nodes)| { - get_namespace_section_render_ctx(ctx, header, doc_nodes) + .map(|(ctx, header, doc_nodes)| { + get_namespace_section_render_ctx(&ctx, header, doc_nodes) }) .collect() } fn get_namespace_section_render_ctx( ctx: &RenderContext, - header: SectionHeaderCtx, + header: Option, doc_nodes: Vec, ) -> SectionCtx { let mut grouped_nodes = IndexMap::new(); @@ -35,7 +41,7 @@ fn get_namespace_section_render_ctx( let nodes = grouped_nodes .into_iter() .filter_map(|(name, nodes)| { - if nodes[0].is_internal() { + if nodes[0].is_internal(ctx.ctx) { None } else { Some(NamespaceNodeCtx::new(ctx, name, nodes)) @@ -45,23 +51,59 @@ fn get_namespace_section_render_ctx( let mut section = SectionCtx::new( ctx, - &header.title, + header + .as_ref() + .map(|header| header.title.as_str()) + .unwrap_or_default(), SectionContentCtx::NamespaceSection(nodes), ); section.header = header; section } +#[derive(Debug, Serialize, Clone)] +pub struct NamespaceNodeSubItemCtx { + title: String, + href: String, +} + +impl std::hash::Hash for NamespaceNodeSubItemCtx { + fn hash(&self, state: &mut H) { + self.title.hash(state) + } +} + +impl PartialOrd for NamespaceNodeSubItemCtx { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.title.cmp(&other.title)) + } +} + +impl Ord for NamespaceNodeSubItemCtx { + fn cmp(&self, other: &Self) -> Ordering { + self.title.cmp(&other.title) + } +} + +impl PartialEq for NamespaceNodeSubItemCtx { + fn eq(&self, other: &Self) -> bool { + self.title.eq(&other.title) + } +} + +impl Eq for NamespaceNodeSubItemCtx {} + #[derive(Debug, Serialize, Clone)] pub struct NamespaceNodeCtx { pub id: String, pub anchor: AnchorCtx, - pub tags: HashSet, + pub tags: IndexSet, pub doc_node_kind_ctx: IndexSet, pub href: String, pub name: String, pub docs: Option, pub deprecated: bool, + pub subitems: IndexSet, } impl NamespaceNodeCtx { @@ -77,24 +119,69 @@ impl NamespaceNodeCtx { let tags = Tag::from_js_doc(&nodes[0].js_doc); + let mut subitems = IndexSet::new(); + + let href = ctx.ctx.resolve_path( + ctx.get_current_resolve(), + UrlResolveKind::Symbol { + file: &nodes[0].origin, + symbol: &name, + }, + ); + + for node in &nodes { + if let Some(drilldown_symbols) = node.get_drilldown_symbols() { + subitems.extend( + drilldown_symbols + .filter(|symbol| { + !symbol.drilldown_name.as_ref().unwrap().starts_with('[') + }) + .map(|symbol| { + let id = match symbol.kind { + DocNodeKind::Property => name_to_id( + "property", + &symbol.drilldown_name.as_ref().unwrap().to_lowercase(), + ), + DocNodeKind::Method(kind) => { + if matches!(kind, MethodKind::Getter | MethodKind::Setter) { + name_to_id( + "accessor", + &symbol.drilldown_name.as_ref().unwrap().to_lowercase(), + ) + } else { + name_to_id( + "method", + &format!( + "{}_0", + symbol.drilldown_name.as_ref().unwrap().to_lowercase() + ), + ) + } + } + _ => unreachable!(), + }; + + NamespaceNodeSubItemCtx { + title: symbol.drilldown_name.as_ref().unwrap().to_string(), + href: format!("{href}#{id}"), + } + }), + ); + } + } + + subitems.sort(); + NamespaceNodeCtx { id: id.clone(), anchor: AnchorCtx { id }, tags, - doc_node_kind_ctx: nodes - .iter() - .map(|node| node.kind_with_drilldown.into()) - .collect(), - href: ctx.ctx.resolve_path( - ctx.get_current_resolve(), - UrlResolveKind::Symbol { - file: &nodes[0].origin, - symbol: &name, - }, - ), + doc_node_kind_ctx: nodes.iter().map(|node| node.kind.into()).collect(), + href, name, docs, deprecated: all_deprecated(&nodes.iter().collect::>()), + subitems, } } } diff --git a/src/html/symbols/type_alias.rs b/src/html/symbols/type_alias.rs index a25a00d8..e38018b7 100644 --- a/src/html/symbols/type_alias.rs +++ b/src/html/symbols/type_alias.rs @@ -13,7 +13,7 @@ pub(crate) fn render_type_alias( doc_node: &DocNodeWithContext, name: &str, ) -> Vec { - let type_alias_def = doc_node.type_alias_def.as_ref().unwrap(); + let type_alias_def = doc_node.type_alias_def().unwrap(); let current_type_params = type_alias_def .type_params @@ -24,8 +24,6 @@ pub(crate) fn render_type_alias( let id = name_to_id("typeAlias", name); - // TODO: tags - let mut sections = vec![]; if let Some(type_params) = crate::html::types::render_type_params( @@ -69,7 +67,7 @@ pub(crate) fn render_type_alias( None, None, &render_type_def(ctx, &type_alias_def.ts_type), - HashSet::new(), + Default::default(), None, &doc_node.location, )]), diff --git a/src/html/symbols/variable.rs b/src/html/symbols/variable.rs index 32406a1e..86df4d4e 100644 --- a/src/html/symbols/variable.rs +++ b/src/html/symbols/variable.rs @@ -6,14 +6,13 @@ use crate::html::symbols::interface::render_properties; use crate::html::types::render_type_def; use crate::html::util::*; use crate::html::DocNodeWithContext; -use std::collections::HashSet; pub(crate) fn render_variable( ctx: &RenderContext, doc_node: &DocNodeWithContext, name: &str, ) -> Vec { - let variable_def = doc_node.variable_def.as_ref().unwrap(); + let variable_def = doc_node.variable_def().unwrap(); let Some(ts_type) = &variable_def.ts_type else { return vec![]; @@ -55,7 +54,7 @@ pub(crate) fn render_variable( None, None, &render_type_def(ctx, ts_type), - HashSet::new(), + Default::default(), None, &doc_node.location, )]), diff --git a/src/html/templates/category_panel.hbs b/src/html/templates/category_panel.hbs new file mode 100644 index 00000000..02b1285a --- /dev/null +++ b/src/html/templates/category_panel.hbs @@ -0,0 +1,16 @@ +{{#if this}} +
+ +
+{{/if}} diff --git a/src/html/templates/comrak.css b/src/html/templates/comrak.css new file mode 100644 index 00000000..517c1524 --- /dev/null +++ b/src/html/templates/comrak.css @@ -0,0 +1,196 @@ +.link { + @apply text-blue-600 transition duration-75; +} + +.link:hover { + @apply text-blue-400; +} + +.markdown_summary, .markdown { + a:not(.no_color) { + @apply link; + } +} + +.markdown_summary { + @apply inline text-stone-600; + + p { + @apply inline-block line-clamp-4; + } + + :not(pre) > code { + @apply font-mono text-sm py-0.5 px-1.5 rounded bg-stone-200; + } +} + +.markdown { + @apply space-y-3 shrink min-w-0 max-w-[40ch] sm:max-w-screen-sm + md:max-w-screen-md lg:max-w-[75ch]; + + h1 { + @apply text-xl md:text-2xl lg:text-3xl border-b border-stone-300 pb-1; + } + + h2 { + @apply text-lg md:text-xl lg:text-2xl border-b border-stone-300 pb-1; + } + + h3 { + @apply font-bold md:text-lg md:font-normal lg:text-xl lg:font-normal; + } + + h4 { + @apply font-semibold md:font-bold lg:text-lg lg:font-normal; + } + + h5 { + @apply italic md:font-semibold lg:font-bold; + } + + h6 { + @apply md:italic lg:font-semibold; + } + + hr { + @apply m-2 border-stone-500; + } + + ol, ul { + @apply list-outside ml-4; + } + + ol { + @apply list-decimal; + } + + ul { + @apply list-disc; + } + + /* Inline code */ + :not(pre) > code { + @apply font-mono text-sm py-0.5 px-1.5 rounded-md bg-stone-200; + } + + h1, h2, h3, h4, h5, h6 { + & > code { + font-size: inherit !important; + } + } + + pre { + @apply font-mono text-sm text-black bg-slate-50 border-t-1.5 border-b-1.5 + border-slate-300 -mx-4 rounded-none md:rounded-md md:border-1.5 md:mx-0; + + & > code:first-child { + @apply overflow-x-auto px-6 py-4 block; + } + } + + p { + @apply my-1 mx-0; + } + + table { + @apply block table-auto overflow-auto w-max max-w-full; + } + + td { + @apply p-2; + } + + th { + @apply font-bold text-center py-1.5; + } + + th, td { + @apply border-1.5 border-slate-300; + } + + tr:nth-child(2n) { + @apply bg-slate-50; + } + + img { + display: inline-block; + } + + .alert { + @apply py-4 px-6 border-2 space-y-2 rounded-lg; + + div:first-child { + @apply font-medium flex items-center gap-1.5; + + svg { + @apply size-5; + } + } + } + + .alert-note { + @apply border-blue-600 bg-blue-600/5; + + div:first-child { + @apply text-blue-600 stroke-blue-600; + } + } + + .alert-tip { + @apply border-green-600 bg-green-600/5; + + div:first-child { + @apply text-green-600 stroke-green-600; + } + } + + .alert-important { + @apply border-purple-600 bg-purple-600/5; + + div:first-child { + @apply text-purple-600 stroke-purple-600; + } + } + + .alert-warning { + @apply border-yellow-600 bg-yellow-600/5; + + div:first-child { + @apply text-yellow-600 stroke-yellow-600; + } + } + + .alert-caution { + @apply border-red-600 bg-red-600/5; + + div:first-child { + @apply text-red-600 stroke-red-600; + } + } +} + +.markdown .highlight { + @apply relative; + + .lineNumbers { + @apply border-r-2 border-stone-300 pr-1 text-right flex-none; + } + + .context_button { + @apply absolute top-3 right-4 opacity-60 hover:opacity-100; + + svg.check { + @apply hidden; + } + + &.copied { + svg.copy { + @apply hidden; + } + + svg.check { + @apply block; + } + } + } +} diff --git a/src/html/templates/comrak.gen.css b/src/html/templates/comrak.gen.css new file mode 100644 index 00000000..5b6e6dcf --- /dev/null +++ b/src/html/templates/comrak.gen.css @@ -0,0 +1 @@ +.link{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity));transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter,backdrop-filter,-webkit-backdrop-filter;transition-duration:75ms;transition-timing-function:cubic-bezier(.4,0,.2,1)}.link:hover{--tw-text-opacity:1;color:rgb(96 165 250/var(--tw-text-opacity))}:is(.markdown_summary,.markdown) a:not(.no_color){--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity));transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter,backdrop-filter,-webkit-backdrop-filter;transition-duration:75ms;transition-timing-function:cubic-bezier(.4,0,.2,1)}:is(.markdown_summary,.markdown) a:not(.no_color):hover{--tw-text-opacity:1;color:rgb(96 165 250/var(--tw-text-opacity))}.markdown_summary{--tw-text-opacity:1;color:rgb(87 83 78/var(--tw-text-opacity));display:inline}.markdown_summary p{-webkit-line-clamp:4;-webkit-box-orient:vertical;display:inline-block;overflow:hidden}.markdown_summary :not(pre)>code{--tw-bg-opacity:1;background-color:rgb(231 229 228/var(--tw-bg-opacity));border-radius:.25rem;padding:.125rem .375rem;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:.875rem;line-height:1.25rem}.markdown{flex-shrink:1;min-width:0;max-width:40ch}.markdown>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.75rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem*var(--tw-space-y-reverse))}@media (min-width:640px){.markdown{max-width:640px}}@media (min-width:768px){.markdown{max-width:768px}}@media (min-width:1024px){.markdown{max-width:75ch}}.markdown h1{--tw-border-opacity:1;border-bottom-width:1px;border-color:rgb(214 211 209/var(--tw-border-opacity));padding-bottom:.25rem;font-size:1.25rem;line-height:1.75rem}@media (min-width:768px){.markdown h1{font-size:1.5rem;line-height:2rem}}@media (min-width:1024px){.markdown h1{font-size:1.875rem;line-height:2.25rem}}.markdown h2{--tw-border-opacity:1;border-bottom-width:1px;border-color:rgb(214 211 209/var(--tw-border-opacity));padding-bottom:.25rem;font-size:1.125rem;line-height:1.75rem}@media (min-width:768px){.markdown h2{font-size:1.25rem;line-height:1.75rem}}@media (min-width:1024px){.markdown h2{font-size:1.5rem;line-height:2rem}}.markdown h3{font-weight:700}@media (min-width:768px){.markdown h3{font-size:1.125rem;font-weight:400;line-height:1.75rem}}@media (min-width:1024px){.markdown h3{font-size:1.25rem;font-weight:400;line-height:1.75rem}}.markdown h4{font-weight:600}@media (min-width:768px){.markdown h4{font-weight:700}}@media (min-width:1024px){.markdown h4{font-size:1.125rem;font-weight:400;line-height:1.75rem}}.markdown h5{font-style:italic}@media (min-width:768px){.markdown h5{font-weight:600}}@media (min-width:1024px){.markdown h5{font-weight:700}}@media (min-width:768px){.markdown h6{font-style:italic}}@media (min-width:1024px){.markdown h6{font-weight:600}}.markdown hr{--tw-border-opacity:1;border-color:rgb(120 113 108/var(--tw-border-opacity));margin:.5rem}.markdown ol,.markdown ul{margin-left:1rem;list-style-position:outside}.markdown ol{list-style-type:decimal}.markdown ul{list-style-type:disc}.markdown :not(pre)>code{--tw-bg-opacity:1;background-color:rgb(231 229 228/var(--tw-bg-opacity));border-radius:.375rem;padding:.125rem .375rem;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:.875rem;line-height:1.25rem}:is(.markdown h1,.markdown h2,.markdown h3,.markdown h4,.markdown h5,.markdown h6)>code{font-size:inherit!important}.markdown pre{--tw-border-opacity:1;border-top-width:1.5px;border-bottom-width:1.5px;border-color:rgb(203 213 225/var(--tw-border-opacity));--tw-bg-opacity:1;background-color:rgb(248 250 252/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(0 0 0/var(--tw-text-opacity));border-radius:0;margin-left:-1rem;margin-right:-1rem;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:.875rem;line-height:1.25rem}@media (min-width:768px){.markdown pre{border-width:1.5px;border-radius:.375rem;margin-left:0;margin-right:0}}.markdown pre>code:first-child{padding:1rem 1.5rem;display:block;overflow-x:auto}.markdown p{margin:.25rem 0}.markdown table{table-layout:auto;width:max-content;max-width:100%;display:block;overflow:auto}.markdown td{padding:.5rem}.markdown th{text-align:center;padding-top:.375rem;padding-bottom:.375rem;font-weight:700}.markdown th,.markdown td{--tw-border-opacity:1;border-width:1.5px;border-color:rgb(203 213 225/var(--tw-border-opacity))}.markdown tr:nth-child(2n){--tw-bg-opacity:1;background-color:rgb(248 250 252/var(--tw-bg-opacity))}.markdown img{display:inline-block}.markdown .alert>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem*var(--tw-space-y-reverse))}.markdown .alert{border-width:2px;border-radius:.5rem;padding:1rem 1.5rem}.markdown .alert div:first-child{align-items:center;gap:.375rem;font-weight:500;display:flex}.markdown .alert div:first-child svg{width:1.25rem;height:1.25rem}.markdown .alert-note{--tw-border-opacity:1;border-color:rgb(37 99 235/var(--tw-border-opacity));background-color:#2563eb0d}.markdown .alert-note div:first-child{stroke:#2563eb;--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity))}.markdown .alert-tip{--tw-border-opacity:1;border-color:rgb(22 163 74/var(--tw-border-opacity));background-color:#16a34a0d}.markdown .alert-tip div:first-child{stroke:#16a34a;--tw-text-opacity:1;color:rgb(22 163 74/var(--tw-text-opacity))}.markdown .alert-important{--tw-border-opacity:1;border-color:rgb(147 51 234/var(--tw-border-opacity));background-color:#9333ea0d}.markdown .alert-important div:first-child{stroke:#9333ea;--tw-text-opacity:1;color:rgb(147 51 234/var(--tw-text-opacity))}.markdown .alert-warning{--tw-border-opacity:1;border-color:rgb(202 138 4/var(--tw-border-opacity));background-color:#ca8a040d}.markdown .alert-warning div:first-child{stroke:#ca8a04;--tw-text-opacity:1;color:rgb(202 138 4/var(--tw-text-opacity))}.markdown .alert-caution{--tw-border-opacity:1;border-color:rgb(220 38 38/var(--tw-border-opacity));background-color:#dc26260d}.markdown .alert-caution div:first-child{stroke:#dc2626;--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity))}.markdown .highlight{position:relative}.markdown .highlight .lineNumbers{--tw-border-opacity:1;border-right-width:2px;border-color:rgb(214 211 209/var(--tw-border-opacity));text-align:right;flex:none;padding-right:.25rem}.markdown .highlight .context_button{opacity:.6;position:absolute;top:.75rem;right:1rem}.markdown .highlight .context_button:hover{opacity:1}.markdown .highlight .context_button svg.check{display:none}.markdown .highlight .context_button.copied svg.copy{display:none}.markdown .highlight .context_button.copied svg.check{display:block} \ No newline at end of file diff --git a/src/html/templates/example.hbs b/src/html/templates/example.hbs index 62660369..39ec7f1c 100644 --- a/src/html/templates/example.hbs +++ b/src/html/templates/example.hbs @@ -1,13 +1,10 @@ -
+
{{~> anchor anchor ~}} -
- -
- {{{~markdown_title~}}} {{! markdown rendering }} -
-
- {{{~markdown_body~}}} {{! markdown rendering }} -
-
+

+ {{{~markdown_title~}}} {{! markdown rendering }} +

+
+ {{{~markdown_body~}}} {{! markdown rendering }} +
diff --git a/src/html/templates/icons/bulb.svg b/src/html/templates/icons/bulb.svg deleted file mode 100644 index ce97591b..00000000 --- a/src/html/templates/icons/bulb.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/src/html/templates/icons/check.svg b/src/html/templates/icons/check.svg new file mode 100644 index 00000000..12b32174 --- /dev/null +++ b/src/html/templates/icons/check.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/html/templates/icons/copy.svg b/src/html/templates/icons/copy.svg index bb24d4e6..dceaaa6f 100644 --- a/src/html/templates/icons/copy.svg +++ b/src/html/templates/icons/copy.svg @@ -1,4 +1,4 @@ - + diff --git a/src/html/templates/icons/info-circle.svg b/src/html/templates/icons/info-circle.svg deleted file mode 100644 index d5c57db7..00000000 --- a/src/html/templates/icons/info-circle.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/src/html/templates/icons/warning-message.svg b/src/html/templates/icons/warning-message.svg deleted file mode 100644 index 7c3348ed..00000000 --- a/src/html/templates/icons/warning-message.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/src/html/templates/icons/warning-octagon.svg b/src/html/templates/icons/warning-octagon.svg deleted file mode 100644 index 83fe5b8c..00000000 --- a/src/html/templates/icons/warning-octagon.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/src/html/templates/icons/warning-triangle.svg b/src/html/templates/icons/warning-triangle.svg deleted file mode 100644 index 0a16825d..00000000 --- a/src/html/templates/icons/warning-triangle.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/src/html/templates/module_doc.hbs b/src/html/templates/module_doc.hbs index da4a9593..d33ad6bc 100644 --- a/src/html/templates/module_doc.hbs +++ b/src/html/templates/module_doc.hbs @@ -1,5 +1,5 @@ -
-
+
+
{{~> deprecated deprecated ~}} {{~> symbol_content sections ~}} diff --git a/src/html/templates/namespace_section.hbs b/src/html/templates/namespace_section.hbs index 274a736e..7ad10b52 100644 --- a/src/html/templates/namespace_section.hbs +++ b/src/html/templates/namespace_section.hbs @@ -8,13 +8,21 @@ {{~this.name~}} -
+
{{~#if this.docs~}} {{{~this.docs~}}} {{! markdown rendering }} {{~else~}} No documentation available {{~/if~}}
+ + {{~#if this.subitems~}} + + {{~/if~}}
{{~/each~}} diff --git a/src/html/templates/pages/all_symbols.hbs b/src/html/templates/pages/all_symbols.hbs index f3d872a0..a41eb3ec 100644 --- a/src/html/templates/pages/all_symbols.hbs +++ b/src/html/templates/pages/all_symbols.hbs @@ -1,14 +1,14 @@ {{~> pages/html_head html_head_ctx ~}} -{{~> pages/category_panel categories_panel ~}} +{{~> category_panel categories_panel ~}}
{{~> pages/top_nav ~}} + {{~> pages/search_results ~}} +
{{~> symbol_content content ~}}
- - {{~> pages/search_results ~}}
diff --git a/src/html/templates/pages/category_panel.hbs b/src/html/templates/pages/category_panel.hbs deleted file mode 100644 index c63173d7..00000000 --- a/src/html/templates/pages/category_panel.hbs +++ /dev/null @@ -1,22 +0,0 @@ -{{#if this}} -
-
- -
-
-{{/if}} diff --git a/src/html/templates/pages/html_head.hbs b/src/html/templates/pages/html_head.hbs index ad14fa20..0f2070ef 100644 --- a/src/html/templates/pages/html_head.hbs +++ b/src/html/templates/pages/html_head.hbs @@ -8,13 +8,14 @@ + {{{~head_inject~}}} - {{#if (not disable_search)}} + {{~#if (not disable_search)~}} - {{/if}} + {{~/if~}}
diff --git a/src/html/templates/pages/index.hbs b/src/html/templates/pages/index.hbs index 86eddfe8..f4f7536a 100644 --- a/src/html/templates/pages/index.hbs +++ b/src/html/templates/pages/index.hbs @@ -1,8 +1,10 @@ {{~> pages/html_head html_head_ctx ~}} -{{~> pages/category_panel categories_panel ~}} +{{~> category_panel categories_panel ~}}
{{~> pages/top_nav ~}} + {{~> pages/search_results ~}} +
{{~#if usage~}} @@ -19,8 +21,6 @@
{{~> toc toc_ctx ~}} - - {{~> pages/search_results ~}}
diff --git a/src/html/templates/pages/page.css b/src/html/templates/pages/page.css index b09e4d1e..8cc6e549 100644 --- a/src/html/templates/pages/page.css +++ b/src/html/templates/pages/page.css @@ -2,60 +2,69 @@ @tailwind utilities; .ddoc { - @apply flex h-screen items-start gap-6 p-4 pt-2 lg:p-2 lg:pt-0 max-lg:pt-4; + /* keep spacing in sync with #topnav in various places further down */ + @apply flex min-h-fit items-start gap-6 p-4; - /* doesn't have categories panel */ - &:not(:has(> div.toc)) { - @apply lg:pt-4; - } - - /* Has categories panel, target non-categories panel content */ - &:has(> div.toc) > div:not(.toc) { - @apply lg:pt-4; - } + &:has(#categoryPanel) { + @apply lg:p-2; - /* Categories panel */ - & > .toc { - @apply max-lg:hidden md:flex md:flex-col -mt-0 pt-0 h-full max-h-screen; - @apply w-[290px] flex-shrink-0; + & > div:not(#categoryPanel) { + @apply lg:pt-4; + } - h3 { - @apply pt-3 !important; + #topnav { + @apply lg:-ml-6 lg:pl-6 !important; } } - /* Non-categories panel content */ - & > div:not(.toc) { + &:not(:has(#categoryPanel)), + &:has(#categoryPanel) > div:not(#categoryPanel) { + @apply pt-1 px-6; + } + + & > div:not(#categoryPanel) { @apply flex flex-col flex-grow; } } +#categoryPanel { + @apply max-lg:hidden -mt-0 pt-0 w-[250px] flex-shrink-0 top-0 sticky h-screen + box-border; + + > ul { + @apply max-h-full overflow-y-auto; + } +} + #content { @apply mt-4; - & > main { - @apply min-w-0 col-span-full pb-0 md:pb-8 lg:pb-12 flex flex-col gap-3 flex-grow; + > main { + @apply min-w-0 col-span-full pb-0 md:pb-8 lg:pb-12 flex flex-col gap-3 + flex-grow; } &:has(.toc) > main { @apply lg:col-span-3 lg:row-start-1; } +} - .toc { - @apply max-md:hidden xl:flex xl:flex-col; - } +#topnav { + @apply -ml-4 pl-4; } #content, #topnav > div { @apply flex flex-row justify-between gap-6 gap-8 lg:gap-12; } -#content .toc, #searchbar { +.toc, #searchbar { @apply flex-shrink-0 min-w-[250px] max-w-[300px]; } .toc { - @apply max-lg:row-start-1 lg:col-[span_1_/_-1] lg:top-0 lg:sticky lg:max-h-screen lg:h-fit flex flex-col box-border gap-y-4 -mt-14 pt-14; + @apply max-sm:hidden sm:flex sm:flex-col max-lg:row-start-1 + lg:col-[span_1_/_-1] top-0 sticky max-h-screen h-fit box-border gap-y-4 + -mt-14 pt-14; > div { @apply max-h-full lg:overflow-y-auto; @@ -65,7 +74,3 @@ } } } - -#searchResults { - @apply absolute bg-white inset-0 hidden; -} diff --git a/src/html/templates/pages/page.gen.css b/src/html/templates/pages/page.gen.css index 07b7e6f0..f5dece88 100644 --- a/src/html/templates/pages/page.gen.css +++ b/src/html/templates/pages/page.gen.css @@ -1 +1 @@ -.sticky{position:sticky}.top-0{top:0}.z-50{z-index:50}.block{display:block}.\!flex{display:flex!important}.flex{display:flex}.h-14{height:3.5rem}.h-full{height:100%}.items-center{align-items:center}.justify-between{justify-content:space-between}.gap-0{gap:0}.gap-0\.5{gap:.125rem}.gap-2{gap:.5rem}.gap-2\.5{gap:.625rem}.gap-4{gap:1rem}.overflow-hidden{overflow:hidden}.text-ellipsis{text-overflow:ellipsis}.whitespace-nowrap{white-space:nowrap}.rounded{border-radius:.25rem}.rounded-lg{border-radius:.5rem}.border{border-width:1px}.border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity))}.bg-transparent{background-color:#0000}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.italic{font-style:italic}.leading-none{line-height:1}.text-stone-400{--tw-text-opacity:1;color:rgb(168 162 158/var(--tw-text-opacity))}.blur{--tw-blur:blur(8px);filter:var(--tw-blur)var(--tw-brightness)var(--tw-contrast)var(--tw-grayscale)var(--tw-hue-rotate)var(--tw-invert)var(--tw-saturate)var(--tw-sepia)var(--tw-drop-shadow)}.ddoc{align-items:flex-start;gap:1.5rem;height:100vh;padding:.5rem 1rem 1rem;display:flex}@media not all and (min-width:1024px){.ddoc{padding-top:1rem}}@media (min-width:1024px){.ddoc{padding:0 .5rem .5rem}}@media (min-width:1024px){.ddoc:not(:has(>div.toc)),.ddoc:has(>div.toc)>div:not(.toc){padding-top:1rem}}.ddoc>.toc{height:100%;max-height:100vh;margin-top:0;padding-top:0}@media not all and (min-width:1024px){.ddoc>.toc{display:none}}@media (min-width:768px){.ddoc>.toc{flex-direction:column;display:flex}}.ddoc>.toc{flex-shrink:0;width:290px}.ddoc>.toc h3{padding-top:.75rem!important}.ddoc>div:not(.toc){flex-direction:column;flex-grow:1;display:flex}#content{margin-top:1rem}#content>main{flex-direction:column;flex-grow:1;grid-column:1/-1;gap:.75rem;min-width:0;padding-bottom:0;display:flex}@media (min-width:768px){#content>main{padding-bottom:2rem}}@media (min-width:1024px){#content>main{padding-bottom:3rem}#content:has(.toc)>main{grid-column:span 3/span 3;grid-row-start:1}}@media not all and (min-width:768px){#content .toc{display:none}}@media (min-width:1280px){#content .toc{flex-direction:column;display:flex}}#content,#topnav>div{flex-direction:row;justify-content:space-between;gap:2rem;display:flex}@media (min-width:1024px){#content,#topnav>div{gap:3rem}}#content .toc,#searchbar{flex-shrink:0;min-width:250px;max-width:300px}.toc{box-sizing:border-box;flex-direction:column;row-gap:1rem;margin-top:-3.5rem;padding-top:3.5rem;display:flex}@media not all and (min-width:1024px){.toc{grid-row-start:1}}@media (min-width:1024px){.toc{grid-column:span 1/-1;height:-moz-fit-content;height:fit-content;max-height:100vh;position:sticky;top:0}}.toc>div{max-height:100%}@media (min-width:1024px){.toc>div{overflow-y:auto}}.toc>div>:last-child{padding-bottom:1rem}#searchResults{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));display:none;position:absolute;inset:0}.hover\:bg-stone-100:hover{--tw-bg-opacity:1;background-color:rgb(245 245 244/var(--tw-bg-opacity))} \ No newline at end of file +.sticky{position:sticky}.top-0{top:0}.z-50{z-index:50}.block{display:block}.flex{display:flex}.h-14{height:3.5rem}.h-full{height:100%}.items-center{align-items:center}.justify-between{justify-content:space-between}.gap-2{gap:.5rem}.gap-2\.5{gap:.625rem}.gap-4{gap:1rem}.rounded{border-radius:.25rem}.rounded-lg{border-radius:.5rem}.border{border-width:1px}.border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity))}.bg-transparent{background-color:#0000}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.leading-none{line-height:1}.blur{--tw-blur:blur(8px);filter:var(--tw-blur)var(--tw-brightness)var(--tw-contrast)var(--tw-grayscale)var(--tw-hue-rotate)var(--tw-invert)var(--tw-saturate)var(--tw-sepia)var(--tw-drop-shadow)}.ddoc{align-items:flex-start;gap:1.5rem;min-height:fit-content;padding:1rem;display:flex}@media (min-width:1024px){.ddoc:has(#categoryPanel){padding:.5rem}}@media (min-width:1024px){.ddoc:has(#categoryPanel)>div:not(#categoryPanel){padding-top:1rem}.ddoc:has(#categoryPanel) #topnav{margin-left:-1.5rem!important;padding-left:1.5rem!important}}.ddoc:not(:has(#categoryPanel)),.ddoc:has(#categoryPanel)>div:not(#categoryPanel){padding-top:.25rem;padding-left:1.5rem;padding-right:1.5rem}.ddoc>div:not(#categoryPanel){flex-direction:column;flex-grow:1;display:flex}#categoryPanel{box-sizing:border-box;flex-shrink:0;width:250px;height:100vh;margin-top:0;padding-top:0;position:sticky;top:0}@media not all and (min-width:1024px){#categoryPanel{display:none}}#categoryPanel>ul{max-height:100%;overflow-y:auto}#content{margin-top:1rem}#content>main{flex-direction:column;flex-grow:1;grid-column:1/-1;gap:.75rem;min-width:0;padding-bottom:0;display:flex}@media (min-width:768px){#content>main{padding-bottom:2rem}}@media (min-width:1024px){#content>main{padding-bottom:3rem}#content:has(.toc)>main{grid-column:span 3/span 3;grid-row-start:1}}#topnav{margin-left:-1rem;padding-left:1rem}#content,#topnav>div{flex-direction:row;justify-content:space-between;gap:2rem;display:flex}@media (min-width:1024px){#content,#topnav>div{gap:3rem}}.toc,#searchbar{flex-shrink:0;min-width:250px;max-width:300px}.toc{box-sizing:border-box;row-gap:1rem;height:fit-content;max-height:100vh;margin-top:-3.5rem;padding-top:3.5rem;position:sticky;top:0}@media not all and (min-width:1024px){.toc{grid-row-start:1}}@media not all and (min-width:640px){.toc{display:none}}@media (min-width:640px){.toc{flex-direction:column;display:flex}}@media (min-width:1024px){.toc{grid-column:span 1/-1}}.toc>div{max-height:100%}@media (min-width:1024px){.toc>div{overflow-y:auto}}.toc>div>:last-child{padding-bottom:1rem}.hover\:bg-stone-100:hover{--tw-bg-opacity:1;background-color:rgb(245 245 244/var(--tw-bg-opacity))} \ No newline at end of file diff --git a/src/html/templates/pages/search.js b/src/html/templates/pages/search.js index c1495058..062b618c 100644 --- a/src/html/templates/pages/search.js +++ b/src/html/templates/pages/search.js @@ -1,7 +1,7 @@ const Fuse = window.Fuse; const searchInput = document.querySelector("#searchbar"); -const mainContentTags = document.getElementsByTagName("main"); +const contentDiv = document.querySelector("#content"); const searchResultsDiv = document.querySelector("#searchResults"); const currentFile = document.querySelector("meta[name='doc-current-file']").attributes @@ -98,16 +98,12 @@ function updateCurrentLocation(val) { } function showPage() { - for (const mainTag of mainContentTags) { - mainTag.style.display = "block"; - } + contentDiv.style.display = "flex"; searchResultsDiv.style.display = "none"; } function showSearchResults() { - for (const mainTag of mainContentTags) { - mainTag.style.display = "none"; - } + contentDiv.style.display = "none"; searchResultsDiv.style.display = "block"; } @@ -121,8 +117,7 @@ function renderResults(results) { for (const result of results) { const kind = result.kind.map((kind) => { - const [rustKind, title, symbol] = docNodeKindToStringVariants(kind); - return `
${symbol}
`; + return `
${kind.char}
`; }).join(""); html += `
  • @@ -133,7 +128,6 @@ function renderResults(results) {
  • ${result.name} -
    ${result.location.filename}:${result.location.line}
    `; } @@ -145,24 +139,3 @@ function renderResults(results) { function searchInIndex(val) { return fuse.search(val).map((result) => result.item); } - -function docNodeKindToStringVariants(kind) { - switch (kind) { - case "function": - return ["Function", "Function", "f"]; - case "variable": - return ["Variable", "Variable", "v"]; - case "class": - return ["Class", "Class", "c"]; - case "enum": - return ["Enum", "Enum", "E"]; - case "interface": - return ["Interface", "Interface", "I"]; - case "typeAlias": - return ["TypeAlias", "Type Alias", "T"]; - case "namespace": - return ["Namespace", "Namespace", "N"]; - default: - return []; - } -} diff --git a/src/html/templates/pages/symbol.hbs b/src/html/templates/pages/symbol.hbs index dac9b5b3..b81e983f 100644 --- a/src/html/templates/pages/symbol.hbs +++ b/src/html/templates/pages/symbol.hbs @@ -1,14 +1,14 @@ {{~> pages/html_head html_head_ctx ~}} -{{~> pages/category_panel categories_panel ~}} +{{~> category_panel categories_panel ~}}
    {{~> pages/top_nav ~}} + {{~> pages/search_results ~}} +
    {{~> symbol_group symbol_group_ctx ~}} {{~> toc toc_ctx ~}} - - {{~> pages/search_results ~}}
    diff --git a/src/html/templates/script.js b/src/html/templates/script.js index 15032006..16570fb7 100644 --- a/src/html/templates/script.js +++ b/src/html/templates/script.js @@ -13,6 +13,8 @@ document.addEventListener("click", (e) => { ); if (target) { navigator?.clipboard?.writeText(target.dataset["copy"]); + target.classList.add("copied"); + setTimeout(() => target.classList.remove("copied"), 1000); } }); diff --git a/src/html/templates/section.hbs b/src/html/templates/section.hbs index 69a093dc..585b353c 100644 --- a/src/html/templates/section.hbs +++ b/src/html/templates/section.hbs @@ -1,27 +1,33 @@ -
    -
    -

    - {{~> anchor header.anchor ~}} +
    + {{~#if header~}} +
    +

    + {{~> anchor header.anchor ~}} - {{~#if header.href~}} - {{header.title}} - {{~else~}} - {{header.title}} - {{~/if~}} -

    + {{~#if header.href~}} + {{header.title}} + {{~else~}} + {{header.title}} + {{~/if~}} +

    - {{~#if header.doc~}} - {{{header.doc}}} {{! markdown }} - {{~/if~}} -
    + {{~#if header.doc~}} + {{{header.doc}}} {{! markdown }} + {{~/if~}} + + {{~/if~}} {{~#if (ne content.kind "empty")~}} - {{~#if (eq content.kind "namespace_section")~}} - {{~> namespace_section content.content ~}} + {{~#if (or (eq content.kind "namespace_section") (eq content.kind "see"))~}} + {{~> (lookup ../content "kind") content.content ~}} {{~else~}}
    {{~#each content.content~}} {{~> (lookup ../content "kind") this ~}} + + {{~#if (and (eq (lookup ../content "kind") "example") (not @last))~}} +
    + {{~/if~}} {{~/each~}}
    {{~/if~}} diff --git a/src/html/templates/see.hbs b/src/html/templates/see.hbs new file mode 100644 index 00000000..0a562874 --- /dev/null +++ b/src/html/templates/see.hbs @@ -0,0 +1,5 @@ +
      + {{~#each this~}} +
    • {{{this}}}
    • {{! markdown }} + {{~/each~}} +
    diff --git a/src/html/templates/styles.css b/src/html/templates/styles.css index a66cd627..88d77a16 100644 --- a/src/html/templates/styles.css +++ b/src/html/templates/styles.css @@ -11,9 +11,9 @@ a { & { --ddoc-selection-border-width: 2px; - --ddoc-selection-border-color-default: #D6D3D1; - --ddoc-selection-selected-border-color: #2564EB; - --ddoc-selection-selected-bg: #056CF00C; + --ddoc-selection-border-color-default: #d6d3d1; + --ddoc-selection-selected-border-color: #2564eb; + --ddoc-selection-selected-bg: #056cf00c; --ddoc-selection-padding: 9px 15px; } @@ -26,7 +26,8 @@ a { } .anchor { - @apply hidden float-left leading-none text-stone-600 ml-[-24px] p-1 pr-1 pt-1 top-0 bottom-0; + @apply hidden float-left leading-none text-stone-600 ml-[-24px] p-1 pr-1 pt-1 + top-0 bottom-0; } .anchorable { @@ -72,26 +73,27 @@ a { } .section { - @apply space-y-2 mb-2 scroll-mt-16; + @apply space-y-2 mb-2 scroll-mt-16 max-w-prose; > div:first-child { - @apply space-y-8; + @apply space-y-2; > h2 { - @apply text-xl leading-6 font-semibold py-1; + @apply text-xl leading-6 font-semibold py-1 mb-0; } - > .markdown_summary { + /* markdown */ + > div { @apply text-base max-w-[75ch]; } } } .namespaceSection { - @apply grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-y-6 gap-x-10 md:gap-x-8 md:gap-y-8; + @apply space-y-4 mt-4 max-w-prose; .namespaceItem { - @apply flex gap-x-2.5 md:min-h-[4rem] lg:pr-4; + @apply flex gap-x-2.5 md:min-h-[4rem] lg:pr-4 min-h-0; .docNodeKindIcon { @apply w-auto flex-col justify-start; @@ -109,14 +111,29 @@ a { } .namespaceItemContent { - @apply space-y-1.5; + > a, .namespaceItemContentSubItems a { + @apply underline decoration-stone-300; + + &:hover { + @apply no-underline; + } + } > a { @apply block leading-tight break-all font-medium; } - > div { - @apply text-sm leading-5 text-stone-600; + .namespaceItemContentDoc { + @apply mt-2 text-sm leading-5 text-stone-600; + } + + .namespaceItemContentSubItems { + @apply mt-1.5 flex flex-wrap gap-y-1 text-sm; + + > li:not(:last-child):after { + content: "|"; + @apply mx-2 text-gray-300 select-none; + } } } } @@ -142,7 +159,8 @@ a { @apply inline-flex justify-end shrink-0; div { - @apply rounded-full size-5 font-medium text-xs leading-5 text-center align-middle shrink-0 select-none font-mono; + @apply rounded-full size-5 font-medium text-xs leading-5 text-center + align-middle shrink-0 select-none font-mono; } > * + * { @@ -150,18 +168,8 @@ a { } } -.example details { - summary { - @apply list-none flex items-center gap-2 py-2 rounded-lg w-full leading-6 cursor-pointer; - - > div:first-child { - @apply text-stone-600 select-none; - } - } - - &[open] summary > div:first-child { - @apply rotate-90; - } +.example-header { + @apply font-bold text-lg mb-3; } .toc { @@ -186,7 +194,8 @@ a { @apply flex items-center gap-2; > span { - @apply block w-full overflow-hidden whitespace-nowrap text-ellipsis -my-0.5 -ml-1 py-0.5 pl-1 rounded; + @apply block w-full overflow-hidden whitespace-nowrap text-ellipsis + -my-0.5 -ml-1 py-0.5 pl-1 rounded; } } } @@ -198,7 +207,7 @@ a { } .documentNavigation { - @apply max-lg:hidden text-sm space-y-3; + @apply max-sm:hidden text-sm space-y-3; > ul { @apply space-y-2 block overflow-y-auto flex-grow; @@ -218,7 +227,7 @@ a { } ul { - @apply ml-3.5 space-y-2 text-gray-1 text-[.8rem] leading-none; + @apply ml-3.5 space-y-2 text-gray-1 text-[0.8rem] leading-none; li { @apply mt-1 !important; @@ -231,7 +240,8 @@ a { } a { - @apply hover:underline block overflow-hidden whitespace-nowrap text-ellipsis; + @apply hover:underline block overflow-hidden whitespace-nowrap + text-ellipsis; } } } @@ -242,17 +252,20 @@ a { details { > summary { - @apply flex gap-1 select-none cursor-pointer rounded border border-gray-300 py-2 px-3; + @apply flex gap-1 select-none cursor-pointer rounded border + border-gray-300 py-2 px-3; } > div { @apply md:relative; > div { - @apply absolute max-md:inset-x-0 mt-1.5 p-2 block z-30 md:w-48 bg-white md:rounded border max-md:border-x-0 border-gray-300; + @apply absolute max-md:inset-x-0 mt-1.5 p-2 block z-30 md:w-48 + bg-white md:rounded border max-md:border-x-0 border-gray-300; label { - @apply flex items-center gap-2 cursor-pointer select-none px-2 py-1 leading-normal rounded-sm hover:bg-gray-50; + @apply flex items-center gap-2 cursor-pointer select-none px-2 py-1 + leading-normal rounded-sm hover:bg-gray-50; } } } @@ -261,11 +274,12 @@ a { } .usageContent { - :not(.markdown) h3 { + > h3 { @apply font-bold text-lg mb-3; } - .markdown { + /* markdown */ + > div { @apply text-xs text-[#686868]; p { @@ -296,9 +310,28 @@ a { } } +#categoryPanel { + @apply pt-3 text-sm; + + ul { + @apply space-y-2 overflow-y-auto; + + li { + @apply ml-1 mr-3; + + a { + @apply hover:underline block overflow-hidden whitespace-nowrap + text-ellipsis py-1.5 px-3.5; + } + } + } +} + .contextLink { - @apply text-contextLink/80 underline decoration-[1.5px] decoration-contextLink/50 underline-offset-[0.15em] hover:text-contextLink hover:decoration-contextLink; - text-decoration-skip-ink: auto + @apply text-contextLink/80 underline decoration-[1.5px] + decoration-contextLink/50 underline-offset-[0.15em] hover:text-contextLink + hover:decoration-contextLink; + text-decoration-skip-ink: auto; } .breadcrumbs { @@ -314,315 +347,14 @@ a { } .context_button { - @apply z-10 rounded p-1.5 cursor-pointer border bg-inherit hover:bg-stone-200 leading-[0]; + @apply z-10 rounded p-1.5 cursor-pointer border bg-inherit hover:bg-stone-200 + leading-[0]; } -/* markdown */ -.markdown_border { - @apply ml-1 pl-2.5 border-l-2 border-stone-300/40; -} - -.markdown_summary { - @apply inline text-stone-600; - - p { - @apply inline-block line-clamp-4; - } - - :not(pre) > code { - @apply font-mono text-sm py-0.5 px-1.5 rounded bg-stone-200; - } -} - -.markdown { - @apply space-y-3 shrink min-w-0 max-w-[40ch] sm:max-w-screen-sm md:max-w-screen-md lg:max-w-[75ch]; - - a:not(.no_color) { - @apply link; - } - - h1 { - @apply text-xl md:text-2xl lg:text-3xl border-b border-stone-300 pb-1; - } - - h2 { - @apply text-lg md:text-xl lg:text-2xl border-b border-stone-300 pb-1; - } - - h3 { - @apply font-bold md:text-lg md:font-normal lg:text-xl lg:font-normal; - } - - h4 { - @apply font-semibold md:font-bold lg:text-lg lg:font-normal; - } - - h5 { - @apply italic md:font-semibold lg:font-bold; - } - - h6 { - @apply md:italic lg:font-semibold; - } - - hr { - @apply m-2 border-stone-500; - } - - ol, ul { - @apply list-outside ml-4; - } - - ol { - @apply list-decimal; - } - - ul { - @apply list-disc; - } - - /* Inline code */ - - :not(pre) > code { - @apply font-mono text-sm py-0.5 px-1.5 rounded-md bg-stone-200; - } - - h1, h2, h3, h4, h5, h6 { - & > code { - font-size: inherit !important; - } - } - - pre { - @apply font-mono text-sm text-black bg-slate-50 border-t-1.5 border-b-1.5 border-slate-300 -mx-4 rounded-none md:rounded-md md:border-1.5 md:mx-0; - - & > code:first-child { - @apply overflow-x-auto px-6 py-4 block; - } - } - - p { - @apply my-1 mx-0; - } - - table { - @apply block table-auto overflow-auto w-max max-w-full; - } - - td { - @apply p-2; - } - - th { - @apply font-bold text-center py-1.5; - } - - th, td { - @apply border-1.5 border-slate-300; - } - - tr:nth-child(2n) { - @apply bg-slate-50; - } +.see { + @apply list-disc list-inside; - img { + > li * { display: inline-block; } - - .alert { - @apply py-2 px-4 border-l-4 space-y-2; - - div:first-child { - @apply font-medium flex items-center gap-1.5; - - svg { - @apply size-5; - } - } - } - - .alert-note { - @apply border-blue-600; - - div:first-child { - @apply text-blue-600 stroke-blue-600; - } - } - - .alert-tip { - @apply border-green-600; - - div:first-child { - @apply text-green-600 stroke-green-600; - } - } - - .alert-important { - @apply border-purple-600; - - div:first-child { - @apply text-purple-600 stroke-purple-600; - } - } - - .alert-warning { - @apply border-yellow-600; - - div:first-child { - @apply text-yellow-600 stroke-yellow-600; - } - } - - .alert-caution { - @apply border-red-600; - - div:first-child { - @apply text-red-600 stroke-red-600; - } - } -} - -.markdown .highlight { - @apply relative; - - .lineNumbers { - @apply border-r-2 border-stone-300 pr-1 text-right flex-none; - } - - .context_button { - @apply absolute top-3 right-4 opacity-60 hover:opacity-100; - } - - /*! - * GitHub Light v0.5.0 - * Copyright (c) 2012 - 2017 GitHub, Inc. - * Licensed under MIT (https://github.com/primer/github-syntax-theme-generator/blob/master/LICENSE) - */ - - .pl-c /* comment, punctuation.definition.comment, string.comment */ - { - color: #6A737D; - } - - .pl-c1 /* constant, entity.name.constant, variable.other.constant, variable.language, support, meta.property-name, support.constant, support.variable, meta.module-reference, markup.raw, meta.diff.header, meta.output */, - .pl-s .pl-v /* string variable */ - { - color: #005CC5; - } - - .pl-e /* entity */, - .pl-en /* entity.name */ - { - color: #6F42C1; - } - - .pl-smi /* variable.parameter.function, storage.modifier.package, storage.modifier.import, storage.type.java, variable.other */, - .pl-s .pl-s1 /* string source */ - { - color: #24292E; - } - - .pl-ent /* entity.name.tag, markup.quote */ - { - color: #22863A; - } - - .pl-k /* keyword, storage, storage.type */ - { - color: #D73A49; - } - - .pl-s /* string */, - .pl-pds /* punctuation.definition.string, source.regexp, string.regexp.character-class */, - .pl-s .pl-pse .pl-s1 /* string punctuation.section.embedded source */, - .pl-sr /* string.regexp */, - .pl-sr .pl-cce /* string.regexp constant.character.escape */, - .pl-sr .pl-sre /* string.regexp source.ruby.embedded */, - .pl-sr .pl-sra /* string.regexp string.regexp.arbitrary-repitition */ - { - color: #032F62; - } - - .pl-v /* variable */, - .pl-smw /* sublimelinter.mark.warning */ - { - color: #E36209; - } - - .pl-bu /* invalid.broken, invalid.deprecated, invalid.unimplemented, message.error, brackethighlighter.unmatched, sublimelinter.mark.error */ - { - color: #B31D28; - } - - .pl-ii /* invalid.illegal */ - { - color: #FAFBFC; - background-color: #B31D28; - } - - .pl-c2 /* carriage-return */ - { - color: #FAFBFC; - background-color: #D73A49; - } - - .pl-c2::before /* carriage-return */ - { - content: "^M"; - } - - .pl-sr .pl-cce /* string.regexp constant.character.escape */ - { - font-weight: bold; - color: #22863A; - } - - .pl-ml /* markup.list */ - { - color: #735C0F; - } - - .pl-mh /* markup.heading */, - .pl-mh .pl-en /* markup.heading entity.name */, - .pl-ms /* meta.separator */ - { - font-weight: bold; - color: #005CC5; - } - - .pl-mi /* markup.italic */ - { - font-style: italic; - color: #24292E; - } - - .pl-mb /* markup.bold */ - { - font-weight: bold; - color: #24292E; - } - - .pl-md /* markup.deleted, meta.diff.header.from-file, punctuation.definition.deleted */ - { - color: #B31D28; - background-color: #FFEEF0; - } - - .pl-mi1 /* markup.inserted, meta.diff.header.to-file, punctuation.definition.inserted */ - { - color: #22863A; - background-color: #F0FFF4; - } - - .pl-mc /* markup.changed, punctuation.definition.changed */ - { - color: #E36209; - background-color: #FFEBDA; - } - - .pl-mi2 /* markup.ignored, markup.untracked */ - { - color: #F6F8FA; - background-color: #005CC5; - } } diff --git a/src/html/templates/styles.gen.css b/src/html/templates/styles.gen.css index a582af54..619c6ead 100644 --- a/src/html/templates/styles.gen.css +++ b/src/html/templates/styles.gen.css @@ -1 +1 @@ -.ddoc .container{width:100%}@media (min-width:640px){.ddoc .container{max-width:640px}}@media (min-width:768px){.ddoc .container{max-width:768px}}@media (min-width:1024px){.ddoc .container{max-width:1024px}}@media (min-width:1280px){.ddoc .container{max-width:1280px}}@media (min-width:1536px){.ddoc .container{max-width:1536px}}.ddoc .static{position:static}.ddoc .relative{position:relative}.ddoc .\!mb-0{margin-bottom:0!important}.ddoc .\!mt-2{margin-top:.5rem!important}.ddoc .mb-1{margin-bottom:.25rem}.ddoc .ml-4{margin-left:1rem}.ddoc .ml-indent{margin-left:2ch}.ddoc .mr-2{margin-right:.5rem}.ddoc .mt-3{margin-top:.75rem}.ddoc .block{display:block}.ddoc .inline{display:inline}.ddoc .\!flex{display:flex!important}.ddoc .flex{display:flex}.ddoc .inline-flex{display:inline-flex}.ddoc .table{display:table}.ddoc .contents{display:contents}.ddoc .hidden{display:none}.ddoc .h-4{height:1rem}.ddoc .h-5{height:1.25rem}.ddoc .min-w-0{min-width:0}.ddoc .max-w-\[75ch\]{max-width:75ch}.ddoc .flex-1{flex:1}.ddoc .flex-none{flex:none}.ddoc .grow{flex-grow:1}.ddoc .rotate-90{--tw-rotate:90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y))rotate(var(--tw-rotate))skewX(var(--tw-skew-x))skewY(var(--tw-skew-y))scaleX(var(--tw-scale-x))scaleY(var(--tw-scale-y))}.ddoc .scroll-mt-16{scroll-margin-top:4rem}.ddoc .items-center{align-items:center}.ddoc .gap-0{gap:0}.ddoc .gap-0\.5{gap:.125rem}.ddoc .gap-1{gap:.25rem}.ddoc .gap-2{gap:.5rem}.ddoc .space-x-1>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(.25rem*var(--tw-space-x-reverse));margin-left:calc(.25rem*calc(1 - var(--tw-space-x-reverse)))}.ddoc .space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(.5rem*var(--tw-space-x-reverse));margin-left:calc(.5rem*calc(1 - var(--tw-space-x-reverse)))}.ddoc .space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem*var(--tw-space-y-reverse))}.ddoc .space-y-7>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1.75rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.75rem*var(--tw-space-y-reverse))}.ddoc .space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(2rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem*var(--tw-space-y-reverse))}.ddoc .overflow-x-auto{overflow-x:auto}.ddoc .break-words{overflow-wrap:break-word}.ddoc .break-all{word-break:break-all}.ddoc .rounded{border-radius:.25rem}.ddoc .rounded-md{border-radius:.375rem}.ddoc .border{border-width:1px}.ddoc .border-b{border-bottom-width:1px}.ddoc .border-l-2{border-left-width:2px}.ddoc .border-Class\/50{border-color:#20b44b80}.ddoc .border-Enum\/50{border-color:#22abb080}.ddoc .border-Function\/50{border-color:#056cf080}.ddoc .border-Interface\/50{border-color:#d2a06480}.ddoc .border-Method\/50{border-color:#056cf080}.ddoc .border-Namespace\/50{border-color:#d2564680}.ddoc .border-Property\/50{border-color:#7e57c080}.ddoc .border-TypeAlias\/50{border-color:#a4478c80}.ddoc .border-Variable\/50{border-color:#7e57c080}.ddoc .border-abstract\/50{border-color:#0cafc680}.ddoc .border-deprecated\/50{border-color:#dc262680}.ddoc .border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity))}.ddoc .border-new\/50{border-color:#7b61ff80}.ddoc .border-optional\/50{border-color:#0cafc680}.ddoc .border-other\/50{border-color:#57534e80}.ddoc .border-permissions\/50,.ddoc .border-private\/50{border-color:#0cafc680}.ddoc .border-protected\/50,.ddoc .border-readonly\/50{border-color:#7b61ff80}.ddoc .border-stone-300{--tw-border-opacity:1;border-color:rgb(214 211 209/var(--tw-border-opacity))}.ddoc .border-unstable\/50,.ddoc .border-writeonly\/50{border-color:#7b61ff80}.ddoc .bg-Class\/15{background-color:#20b44b26}.ddoc .bg-Class\/5{background-color:#20b44b0d}.ddoc .bg-Enum\/15{background-color:#22abb026}.ddoc .bg-Enum\/5{background-color:#22abb00d}.ddoc .bg-Function\/15{background-color:#056cf026}.ddoc .bg-Function\/5{background-color:#056cf00d}.ddoc .bg-Interface\/15{background-color:#d2a06426}.ddoc .bg-Interface\/5{background-color:#d2a0640d}.ddoc .bg-Method\/15{background-color:#056cf026}.ddoc .bg-Method\/5{background-color:#056cf00d}.ddoc .bg-Namespace\/15{background-color:#d2564626}.ddoc .bg-Namespace\/5{background-color:#d256460d}.ddoc .bg-Property\/15{background-color:#7e57c026}.ddoc .bg-Property\/5{background-color:#7e57c00d}.ddoc .bg-TypeAlias\/15{background-color:#a4478c26}.ddoc .bg-TypeAlias\/5{background-color:#a4478c0d}.ddoc .bg-Variable\/15{background-color:#7e57c026}.ddoc .bg-Variable\/5{background-color:#7e57c00d}.ddoc .bg-abstract\/15{background-color:#0cafc626}.ddoc .bg-abstract\/5{background-color:#0cafc60d}.ddoc .bg-deprecated\/15{background-color:#dc262626}.ddoc .bg-deprecated\/5{background-color:#dc26260d}.ddoc .bg-new\/15{background-color:#7b61ff26}.ddoc .bg-new\/5{background-color:#7b61ff0d}.ddoc .bg-optional\/15{background-color:#0cafc626}.ddoc .bg-optional\/5{background-color:#0cafc60d}.ddoc .bg-other\/15{background-color:#57534e26}.ddoc .bg-other\/5{background-color:#57534e0d}.ddoc .bg-permissions\/15{background-color:#0cafc626}.ddoc .bg-permissions\/5{background-color:#0cafc60d}.ddoc .bg-private\/15{background-color:#0cafc626}.ddoc .bg-private\/5{background-color:#0cafc60d}.ddoc .bg-protected\/15{background-color:#7b61ff26}.ddoc .bg-protected\/5{background-color:#7b61ff0d}.ddoc .bg-readonly\/15{background-color:#7b61ff26}.ddoc .bg-readonly\/5{background-color:#7b61ff0d}.ddoc .bg-stone-100{--tw-bg-opacity:1;background-color:rgb(245 245 244/var(--tw-bg-opacity))}.ddoc .bg-unstable\/15{background-color:#7b61ff26}.ddoc .bg-unstable\/5{background-color:#7b61ff0d}.ddoc .bg-writeonly\/15{background-color:#7b61ff26}.ddoc .bg-writeonly\/5{background-color:#7b61ff0d}.ddoc .px-2{padding-left:.5rem;padding-right:.5rem}.ddoc .px-3{padding-left:.75rem;padding-right:.75rem}.ddoc .px-4{padding-left:1rem;padding-right:1rem}.ddoc .py-1{padding-top:.25rem;padding-bottom:.25rem}.ddoc .py-2{padding-top:.5rem;padding-bottom:.5rem}.ddoc .pb-5{padding-bottom:1.25rem}.ddoc .pt-4{padding-top:1rem}.ddoc .text-2xl{font-size:1.5rem;line-height:2rem}.ddoc .text-base{font-size:1rem;line-height:1.5rem}.ddoc .text-sm{font-size:.875rem;line-height:1.25rem}.ddoc .font-bold{font-weight:700}.ddoc .font-medium{font-weight:500}.ddoc .font-normal{font-weight:400}.ddoc .italic{font-style:italic}.ddoc .leading-none{line-height:1}.ddoc .text-Class{--tw-text-opacity:1;color:rgb(32 180 75/var(--tw-text-opacity))}.ddoc .text-Enum{--tw-text-opacity:1;color:rgb(34 171 176/var(--tw-text-opacity))}.ddoc .text-Function{--tw-text-opacity:1;color:rgb(5 108 240/var(--tw-text-opacity))}.ddoc .text-Interface{--tw-text-opacity:1;color:rgb(210 160 100/var(--tw-text-opacity))}.ddoc .text-Method{--tw-text-opacity:1;color:rgb(5 108 240/var(--tw-text-opacity))}.ddoc .text-Namespace{--tw-text-opacity:1;color:rgb(210 86 70/var(--tw-text-opacity))}.ddoc .text-Property{--tw-text-opacity:1;color:rgb(126 87 192/var(--tw-text-opacity))}.ddoc .text-TypeAlias{--tw-text-opacity:1;color:rgb(164 71 140/var(--tw-text-opacity))}.ddoc .text-Variable{--tw-text-opacity:1;color:rgb(126 87 192/var(--tw-text-opacity))}.ddoc .text-\[\#0F172A\]{--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity))}.ddoc .text-abstract{--tw-text-opacity:1;color:rgb(12 175 198/var(--tw-text-opacity))}.ddoc .text-deprecated{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity))}.ddoc .text-new{--tw-text-opacity:1;color:rgb(123 97 255/var(--tw-text-opacity))}.ddoc .text-optional{--tw-text-opacity:1;color:rgb(12 175 198/var(--tw-text-opacity))}.ddoc .text-other{--tw-text-opacity:1;color:rgb(87 83 78/var(--tw-text-opacity))}.ddoc .text-permissions,.ddoc .text-private{--tw-text-opacity:1;color:rgb(12 175 198/var(--tw-text-opacity))}.ddoc .text-protected,.ddoc .text-readonly{--tw-text-opacity:1;color:rgb(123 97 255/var(--tw-text-opacity))}.ddoc .text-stone-500{--tw-text-opacity:1;color:rgb(120 113 108/var(--tw-text-opacity))}.ddoc .text-unstable,.ddoc .text-writeonly{--tw-text-opacity:1;color:rgb(123 97 255/var(--tw-text-opacity))}.ddoc .filter{filter:var(--tw-blur)var(--tw-brightness)var(--tw-contrast)var(--tw-grayscale)var(--tw-hue-rotate)var(--tw-invert)var(--tw-saturate)var(--tw-sepia)var(--tw-drop-shadow)}.ddoc summary::-webkit-details-marker{display:none}.ddoc a{word-wrap:break-word}.ddoc{--ddoc-selection-border-width:2px;--ddoc-selection-border-color-default:#d6d3d1;--ddoc-selection-selected-border-color:#2564eb;--ddoc-selection-selected-bg:#056cf00c;--ddoc-selection-padding:9px 15px}.ddoc .link{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity));transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter,backdrop-filter,-webkit-backdrop-filter;transition-duration:75ms;transition-timing-function:cubic-bezier(.4,0,.2,1)}.ddoc .link:hover{--tw-text-opacity:1;color:rgb(96 165 250/var(--tw-text-opacity))}.ddoc .anchor{float:left;--tw-text-opacity:1;color:rgb(87 83 78/var(--tw-text-opacity));margin-left:-24px;padding:.25rem;line-height:1;display:none;top:0;bottom:0}.ddoc .anchorable{scroll-margin-top:4rem;position:relative}.ddoc .anchorable:hover .anchor{display:block}.ddoc .deprecated>div:first-child{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity));align-items:center;gap:.25rem;padding-top:.25rem;padding-bottom:.25rem;display:flex}.ddoc .deprecated>div:first-child>span{font-weight:600;line-height:1.5rem}.ddoc .deprecated>div:nth-child(2){--tw-border-opacity:1;border-left-width:4px;border-color:rgb(252 165 165/var(--tw-border-opacity));margin-left:.25rem;padding-left:.5rem}.ddoc .symbolSubtitle>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.125rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.125rem*var(--tw-space-y-reverse))}.ddoc .symbolSubtitle{font-size:.875rem;line-height:1rem}.ddoc .symbolSubtitle .type{--tw-text-opacity:1;color:rgb(168 162 158/var(--tw-text-opacity));font-style:italic}.ddoc .docEntry{margin-bottom:1rem}.ddoc .docEntry>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem*var(--tw-space-y-reverse))}.ddoc .docEntry .docEntryHeader{justify-content:space-between;align-items:flex-start;display:flex}@media (min-width:768px){.ddoc .docEntry .docEntryHeader{font-size:1rem;line-height:1.5rem}}.ddoc .docEntry .docEntryHeader>div{overflow-wrap:break-word}.ddoc .section{margin-bottom:.5rem;scroll-margin-top:4rem}.ddoc .section>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem*var(--tw-space-y-reverse))}.ddoc .section>div:first-child>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(2rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem*var(--tw-space-y-reverse))}.ddoc .section>div:first-child>h2{padding-top:.25rem;padding-bottom:.25rem;font-size:1.25rem;font-weight:600;line-height:1.5rem}.ddoc .section>div:first-child>.markdown_summary{max-width:75ch;font-size:1rem;line-height:1.5rem}.ddoc .namespaceSection{-moz-column-gap:2.5rem;grid-template-columns:repeat(1,minmax(0,1fr));gap:1.5rem 2.5rem;display:grid}@media (min-width:768px){.ddoc .namespaceSection{-moz-column-gap:2rem;grid-template-columns:repeat(2,minmax(0,1fr));gap:2rem}}@media (min-width:1024px){.ddoc .namespaceSection{grid-template-columns:repeat(3,minmax(0,1fr))}}.ddoc .namespaceSection .namespaceItem{-moz-column-gap:.625rem;column-gap:.625rem;display:flex}@media (min-width:768px){.ddoc .namespaceSection .namespaceItem{min-height:4rem}}@media (min-width:1024px){.ddoc .namespaceSection .namespaceItem{padding-right:1rem}}.ddoc .namespaceSection .namespaceItem .docNodeKindIcon{flex-direction:column;justify-content:flex-start;width:auto}.ddoc .namespaceSection .namespaceItem .docNodeKindIcon>*+*{margin-top:-.125rem;margin-left:0}.ddoc .namespaceSection .namespaceItem[aria-label=deprecated]{opacity:.6}.ddoc .namespaceSection .namespaceItem[aria-label=deprecated] .namespaceItemContent>a{--tw-text-opacity:1;color:rgb(120 113 108/var(--tw-text-opacity));text-decoration-line:line-through;text-decoration-color:#78716cb3;text-decoration-thickness:2px}.ddoc .namespaceSection .namespaceItem .namespaceItemContent>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.375rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem*var(--tw-space-y-reverse))}.ddoc .namespaceSection .namespaceItem .namespaceItemContent>a{word-break:break-all;font-weight:500;line-height:1.25;display:block}.ddoc .namespaceSection .namespaceItem .namespaceItemContent>div{--tw-text-opacity:1;color:rgb(87 83 78/var(--tw-text-opacity));font-size:.875rem;line-height:1.25rem}.ddoc .symbolGroup>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(3rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(3rem*var(--tw-space-y-reverse))}.ddoc .symbolGroup article>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1.25rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.25rem*var(--tw-space-y-reverse))}.ddoc .symbolGroup article>div:first-child{justify-content:space-between;align-items:flex-start;display:flex}.ddoc .symbolGroup article>div:first-child>div:first-child>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.25rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem*var(--tw-space-y-reverse))}.ddoc .symbolGroup article>div:first-child>div:first-child{font-weight:500}.ddoc .docNodeKindIcon{flex-shrink:0;justify-content:flex-end;display:inline-flex}.ddoc .docNodeKindIcon div{-webkit-user-select:none;user-select:none;text-align:center;vertical-align:middle;border-radius:9999px;flex-shrink:0;width:1.25rem;height:1.25rem;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:.75rem;font-weight:500;line-height:1.25rem}.ddoc .docNodeKindIcon>*+*{margin-left:-.375rem}.ddoc .example details summary{cursor:pointer;border-radius:.5rem;align-items:center;gap:.5rem;width:100%;padding-top:.5rem;padding-bottom:.5rem;line-height:1.5rem;list-style-type:none;display:flex}.ddoc .example details summary>div:first-child{-webkit-user-select:none;user-select:none;--tw-text-opacity:1;color:rgb(87 83 78/var(--tw-text-opacity))}.ddoc .example details[open] summary>div:first-child{--tw-rotate:90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y))rotate(var(--tw-rotate))skewX(var(--tw-skew-x))skewY(var(--tw-skew-y))scaleX(var(--tw-scale-x))scaleY(var(--tw-scale-y))}.ddoc .toc h3{margin-bottom:.75rem;font-size:1.125rem;font-weight:700;line-height:1.75rem}.ddoc .toc>div>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1.25rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.25rem*var(--tw-space-y-reverse))}.ddoc .toc .topSymbols>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.75rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem*var(--tw-space-y-reverse))}.ddoc .toc .topSymbols{font-size:.875rem;line-height:1.25rem}.ddoc .toc .topSymbols ul{list-style-type:none}.ddoc .toc .topSymbols ul>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.625rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.625rem*var(--tw-space-y-reverse))}.ddoc .toc .topSymbols ul li{display:block}.ddoc .toc .topSymbols ul li a{align-items:center;gap:.5rem;display:flex}.ddoc .toc .topSymbols ul li a>span{text-overflow:ellipsis;white-space:nowrap;border-radius:.25rem;width:100%;margin-top:-.125rem;margin-bottom:-.125rem;margin-left:-.25rem;padding-top:.125rem;padding-bottom:.125rem;padding-left:.25rem;display:block;overflow:hidden}.ddoc .toc .topSymbols>a:hover{text-decoration-line:underline}.ddoc .toc .documentNavigation>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.75rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem*var(--tw-space-y-reverse))}.ddoc .toc .documentNavigation{font-size:.875rem;line-height:1.25rem}@media not all and (min-width:1024px){.ddoc .toc .documentNavigation{display:none}}.ddoc .toc .documentNavigation>ul{flex-grow:1;display:block}.ddoc .toc .documentNavigation>ul>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem*var(--tw-space-y-reverse))}.ddoc .toc .documentNavigation>ul{overflow-y:auto}.ddoc .toc .documentNavigation>ul>li{margin-top:.125rem;margin-left:.75rem;margin-right:.75rem}.ddoc .toc .documentNavigation>ul li:has(>ul){margin-top:0!important}.ddoc .toc .documentNavigation>ul li:has(>a){padding-bottom:0!important}.ddoc .toc .documentNavigation>ul ul{margin-left:.875rem}.ddoc .toc .documentNavigation>ul ul>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem*var(--tw-space-y-reverse))}.ddoc .toc .documentNavigation>ul ul{--tw-text-opacity:1;color:rgb(134 135 137/var(--tw-text-opacity));font-size:.8rem;line-height:1}.ddoc .toc .documentNavigation>ul ul li{margin-top:.25rem!important}.ddoc .toc .documentNavigation>ul ul li a{padding:.25rem}.ddoc .toc .documentNavigation>ul ul li a:hover{--tw-text-opacity:1;color:rgb(0 0 0/var(--tw-text-opacity))}.ddoc .toc .documentNavigation a{text-overflow:ellipsis;white-space:nowrap;display:block;overflow:hidden}.ddoc .toc .documentNavigation a:hover{text-decoration-line:underline}.ddoc .usages nav{flex-direction:row;align-items:center;gap:.5rem;margin-bottom:.75rem;font-weight:600;display:flex}.ddoc .usages nav details>summary{cursor:pointer;-webkit-user-select:none;user-select:none;--tw-border-opacity:1;border-width:1px;border-color:rgb(209 213 219/var(--tw-border-opacity));border-radius:.25rem;gap:.25rem;padding:.5rem .75rem;display:flex}@media (min-width:768px){.ddoc .usages nav details>div{position:relative}}.ddoc .usages nav details>div>div{z-index:30;--tw-border-opacity:1;border-width:1px;border-color:rgb(209 213 219/var(--tw-border-opacity));--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));margin-top:.375rem;padding:.5rem;display:block;position:absolute}@media not all and (min-width:768px){.ddoc .usages nav details>div>div{border-left-width:0;border-right-width:0;left:0;right:0}}@media (min-width:768px){.ddoc .usages nav details>div>div{border-radius:.25rem;width:12rem}}.ddoc .usages nav details>div>div label{cursor:pointer;-webkit-user-select:none;user-select:none;border-radius:.125rem;align-items:center;gap:.5rem;padding:.25rem .5rem;line-height:1.5;display:flex}.ddoc .usages nav details>div>div label:hover{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity))}.ddoc .usageContent :not(.markdown) h3{margin-bottom:.75rem;font-size:1.125rem;font-weight:700;line-height:1.75rem}.ddoc .usageContent .markdown{--tw-text-opacity:1;color:rgb(104 104 104/var(--tw-text-opacity));font-size:.75rem;line-height:1rem}.ddoc .usageContent .markdown p{margin:0}.ddoc .usageContent pre.highlight{--tw-border-opacity:1;border-width:1px;border-color:rgb(209 213 219/var(--tw-border-opacity));--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}@media not all and (min-width:768px){.ddoc .usageContent pre.highlight{border-left-width:0;border-right-width:0}}.ddoc .usageContent pre.highlight{margin-top:.25rem!important}.ddoc .usageContent pre.highlight>code:first-child{scrollbar-width:thin;padding:.5rem .75rem}.ddoc .usageContent pre.highlight .context_button{border-width:0;display:none;top:.25rem;right:.5rem}.ddoc .usageContent pre.highlight .context_button svg rect{fill:#fff}.ddoc .usageContent pre.highlight:hover .context_button{opacity:1;display:block}.ddoc .contextLink{color:#0e6590cc;text-underline-offset:.15em;text-decoration-line:underline;text-decoration-color:#0e659080;text-decoration-thickness:1.5px}.ddoc .contextLink:hover{--tw-text-opacity:1;color:rgb(14 101 144/var(--tw-text-opacity));text-decoration-color:#0e6590}.ddoc .contextLink{-webkit-text-decoration-skip:ink;-webkit-text-decoration-skip-ink:auto;text-decoration-skip-ink:auto}.ddoc .breadcrumbs{word-break:break-all;flex-wrap:wrap;align-items:center;gap:.25rem;display:inline-flex}.ddoc .breadcrumbs>li:first-child{font-size:1.5rem;font-weight:700;line-height:1}.ddoc .breadcrumbs li{font-size:1.125rem;line-height:.9em;display:inline}@media (min-width:1024px){.ddoc .breadcrumbs li{font-size:1.25rem;line-height:1.75rem}}.ddoc .context_button{z-index:10;cursor:pointer;background-color:inherit;border-width:1px;border-radius:.25rem;padding:.375rem;line-height:0}.ddoc .context_button:hover{--tw-bg-opacity:1;background-color:rgb(231 229 228/var(--tw-bg-opacity))}.ddoc .markdown_border{border-color:#d6d3d166;border-left-width:2px;margin-left:.25rem;padding-left:.625rem}.ddoc .markdown_summary{--tw-text-opacity:1;color:rgb(87 83 78/var(--tw-text-opacity));display:inline}.ddoc .markdown_summary p{-webkit-line-clamp:4;-webkit-box-orient:vertical;display:inline-block;overflow:hidden}.ddoc .markdown_summary :not(pre)>code{--tw-bg-opacity:1;background-color:rgb(231 229 228/var(--tw-bg-opacity));border-radius:.25rem;padding:.125rem .375rem;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:.875rem;line-height:1.25rem}.ddoc .markdown{flex-shrink:1;min-width:0;max-width:40ch}.ddoc .markdown>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.75rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem*var(--tw-space-y-reverse))}@media (min-width:640px){.ddoc .markdown{max-width:640px}}@media (min-width:768px){.ddoc .markdown{max-width:768px}}@media (min-width:1024px){.ddoc .markdown{max-width:75ch}}.ddoc .markdown a:not(.no_color){--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity));transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter,backdrop-filter,-webkit-backdrop-filter;transition-duration:75ms;transition-timing-function:cubic-bezier(.4,0,.2,1)}.ddoc .markdown a:not(.no_color):hover{--tw-text-opacity:1;color:rgb(96 165 250/var(--tw-text-opacity))}.ddoc .markdown h1{--tw-border-opacity:1;border-bottom-width:1px;border-color:rgb(214 211 209/var(--tw-border-opacity));padding-bottom:.25rem;font-size:1.25rem;line-height:1.75rem}@media (min-width:768px){.ddoc .markdown h1{font-size:1.5rem;line-height:2rem}}@media (min-width:1024px){.ddoc .markdown h1{font-size:1.875rem;line-height:2.25rem}}.ddoc .markdown h2{--tw-border-opacity:1;border-bottom-width:1px;border-color:rgb(214 211 209/var(--tw-border-opacity));padding-bottom:.25rem;font-size:1.125rem;line-height:1.75rem}@media (min-width:768px){.ddoc .markdown h2{font-size:1.25rem;line-height:1.75rem}}@media (min-width:1024px){.ddoc .markdown h2{font-size:1.5rem;line-height:2rem}}.ddoc .markdown h3{font-weight:700}@media (min-width:768px){.ddoc .markdown h3{font-size:1.125rem;font-weight:400;line-height:1.75rem}}@media (min-width:1024px){.ddoc .markdown h3{font-size:1.25rem;font-weight:400;line-height:1.75rem}}.ddoc .markdown h4{font-weight:600}@media (min-width:768px){.ddoc .markdown h4{font-weight:700}}@media (min-width:1024px){.ddoc .markdown h4{font-size:1.125rem;font-weight:400;line-height:1.75rem}}.ddoc .markdown h5{font-style:italic}@media (min-width:768px){.ddoc .markdown h5{font-weight:600}}@media (min-width:1024px){.ddoc .markdown h5{font-weight:700}}@media (min-width:768px){.ddoc .markdown h6{font-style:italic}}@media (min-width:1024px){.ddoc .markdown h6{font-weight:600}}.ddoc .markdown hr{--tw-border-opacity:1;border-color:rgb(120 113 108/var(--tw-border-opacity));margin:.5rem}.ddoc .markdown ol,.ddoc .markdown ul{margin-left:1rem;list-style-position:outside}.ddoc .markdown ol{list-style-type:decimal}.ddoc .markdown ul{list-style-type:disc}.ddoc .markdown :not(pre)>code{--tw-bg-opacity:1;background-color:rgb(231 229 228/var(--tw-bg-opacity));border-radius:.375rem;padding:.125rem .375rem;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:.875rem;line-height:1.25rem}:is(.ddoc .markdown h1,.ddoc .markdown h2,.ddoc .markdown h3,.ddoc .markdown h4,.ddoc .markdown h5,.ddoc .markdown h6)>code{font-size:inherit!important}.ddoc .markdown pre{--tw-border-opacity:1;border-top-width:1.5px;border-bottom-width:1.5px;border-color:rgb(203 213 225/var(--tw-border-opacity));--tw-bg-opacity:1;background-color:rgb(248 250 252/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(0 0 0/var(--tw-text-opacity));border-radius:0;margin-left:-1rem;margin-right:-1rem;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:.875rem;line-height:1.25rem}@media (min-width:768px){.ddoc .markdown pre{border-width:1.5px;border-radius:.375rem;margin-left:0;margin-right:0}}.ddoc .markdown pre>code:first-child{padding:1rem 1.5rem;display:block;overflow-x:auto}.ddoc .markdown p{margin:.25rem 0}.ddoc .markdown table{table-layout:auto;width:max-content;max-width:100%;display:block;overflow:auto}.ddoc .markdown td{padding:.5rem}.ddoc .markdown th{text-align:center;padding-top:.375rem;padding-bottom:.375rem;font-weight:700}.ddoc .markdown th,.ddoc .markdown td{--tw-border-opacity:1;border-width:1.5px;border-color:rgb(203 213 225/var(--tw-border-opacity))}.ddoc .markdown tr:nth-child(2n){--tw-bg-opacity:1;background-color:rgb(248 250 252/var(--tw-bg-opacity))}.ddoc .markdown img{display:inline-block}.ddoc .markdown .alert>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem*var(--tw-space-y-reverse))}.ddoc .markdown .alert{border-left-width:4px;padding:.5rem 1rem}.ddoc .markdown .alert div:first-child{align-items:center;gap:.375rem;font-weight:500;display:flex}.ddoc .markdown .alert div:first-child svg{width:1.25rem;height:1.25rem}.ddoc .markdown .alert-note{--tw-border-opacity:1;border-color:rgb(37 99 235/var(--tw-border-opacity))}.ddoc .markdown .alert-note div:first-child{stroke:#2563eb;--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity))}.ddoc .markdown .alert-tip{--tw-border-opacity:1;border-color:rgb(22 163 74/var(--tw-border-opacity))}.ddoc .markdown .alert-tip div:first-child{stroke:#16a34a;--tw-text-opacity:1;color:rgb(22 163 74/var(--tw-text-opacity))}.ddoc .markdown .alert-important{--tw-border-opacity:1;border-color:rgb(147 51 234/var(--tw-border-opacity))}.ddoc .markdown .alert-important div:first-child{stroke:#9333ea;--tw-text-opacity:1;color:rgb(147 51 234/var(--tw-text-opacity))}.ddoc .markdown .alert-warning{--tw-border-opacity:1;border-color:rgb(202 138 4/var(--tw-border-opacity))}.ddoc .markdown .alert-warning div:first-child{stroke:#ca8a04;--tw-text-opacity:1;color:rgb(202 138 4/var(--tw-text-opacity))}.ddoc .markdown .alert-caution{--tw-border-opacity:1;border-color:rgb(220 38 38/var(--tw-border-opacity))}.ddoc .markdown .alert-caution div:first-child{stroke:#dc2626;--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity))}.ddoc .markdown .highlight{position:relative}.ddoc .markdown .highlight .lineNumbers{--tw-border-opacity:1;border-right-width:2px;border-color:rgb(214 211 209/var(--tw-border-opacity));text-align:right;flex:none;padding-right:.25rem}.ddoc .markdown .highlight .context_button{opacity:.6;position:absolute;top:.75rem;right:1rem}.ddoc .markdown .highlight .context_button:hover{opacity:1}.ddoc .markdown .highlight .pl-c{color:#6a737d}.ddoc .markdown .highlight .pl-c1,.ddoc .markdown .highlight .pl-s .pl-v{color:#005cc5}.ddoc .markdown .highlight .pl-e,.ddoc .markdown .highlight .pl-en{color:#6f42c1}.ddoc .markdown .highlight .pl-smi,.ddoc .markdown .highlight .pl-s .pl-s1{color:#24292e}.ddoc .markdown .highlight .pl-ent{color:#22863a}.ddoc .markdown .highlight .pl-k{color:#d73a49}.ddoc .markdown .highlight .pl-s,.ddoc .markdown .highlight .pl-pds,.ddoc .markdown .highlight .pl-s .pl-pse .pl-s1,.ddoc .markdown .highlight .pl-sr,.ddoc .markdown .highlight .pl-sr .pl-cce,.ddoc .markdown .highlight .pl-sr .pl-sre,.ddoc .markdown .highlight .pl-sr .pl-sra{color:#032f62}.ddoc .markdown .highlight .pl-v,.ddoc .markdown .highlight .pl-smw{color:#e36209}.ddoc .markdown .highlight .pl-bu{color:#b31d28}.ddoc .markdown .highlight .pl-ii{color:#fafbfc;background-color:#b31d28}.ddoc .markdown .highlight .pl-c2{color:#fafbfc;background-color:#d73a49}.ddoc .markdown .highlight .pl-c2:before{content:"^M"}.ddoc .markdown .highlight .pl-sr .pl-cce{color:#22863a;font-weight:700}.ddoc .markdown .highlight .pl-ml{color:#735c0f}.ddoc .markdown .highlight .pl-mh,.ddoc .markdown .highlight .pl-mh .pl-en,.ddoc .markdown .highlight .pl-ms{color:#005cc5;font-weight:700}.ddoc .markdown .highlight .pl-mi{color:#24292e;font-style:italic}.ddoc .markdown .highlight .pl-mb{color:#24292e;font-weight:700}.ddoc .markdown .highlight .pl-md{color:#b31d28;background-color:#ffeef0}.ddoc .markdown .highlight .pl-mi1{color:#22863a;background-color:#f0fff4}.ddoc .markdown .highlight .pl-mc{color:#e36209;background-color:#ffebda}.ddoc .markdown .highlight .pl-mi2{color:#f6f8fa;background-color:#005cc5}.ddoc .\*\:h-4>*{height:1rem}.ddoc .\*\:h-5>*{height:1.25rem}.ddoc .\*\:w-auto>*{width:auto}.ddoc .\*\:flex-none>*{flex:none}.ddoc .target\:bg-yellow-200:target{--tw-bg-opacity:1;background-color:rgb(254 240 138/var(--tw-bg-opacity))}.ddoc .hover\:bg-Class\/15:hover{background-color:#20b44b26}.ddoc .hover\:bg-Class\/5:hover{background-color:#20b44b0d}.ddoc .hover\:bg-Enum\/15:hover{background-color:#22abb026}.ddoc .hover\:bg-Enum\/5:hover{background-color:#22abb00d}.ddoc .hover\:bg-Function\/15:hover{background-color:#056cf026}.ddoc .hover\:bg-Function\/5:hover{background-color:#056cf00d}.ddoc .hover\:bg-Interface\/15:hover{background-color:#d2a06426}.ddoc .hover\:bg-Interface\/5:hover{background-color:#d2a0640d}.ddoc .hover\:bg-Method\/15:hover{background-color:#056cf026}.ddoc .hover\:bg-Method\/5:hover{background-color:#056cf00d}.ddoc .hover\:bg-Namespace\/15:hover{background-color:#d2564626}.ddoc .hover\:bg-Namespace\/5:hover{background-color:#d256460d}.ddoc .hover\:bg-Property\/15:hover{background-color:#7e57c026}.ddoc .hover\:bg-Property\/5:hover{background-color:#7e57c00d}.ddoc .hover\:bg-TypeAlias\/15:hover{background-color:#a4478c26}.ddoc .hover\:bg-TypeAlias\/5:hover{background-color:#a4478c0d}.ddoc .hover\:bg-Variable\/15:hover{background-color:#7e57c026}.ddoc .hover\:bg-Variable\/5:hover{background-color:#7e57c00d}.ddoc .hover\:bg-abstract\/15:hover{background-color:#0cafc626}.ddoc .hover\:bg-abstract\/5:hover{background-color:#0cafc60d}.ddoc .hover\:bg-deprecated\/15:hover{background-color:#dc262626}.ddoc .hover\:bg-deprecated\/5:hover{background-color:#dc26260d}.ddoc .hover\:bg-new\/15:hover{background-color:#7b61ff26}.ddoc .hover\:bg-new\/5:hover{background-color:#7b61ff0d}.ddoc .hover\:bg-optional\/15:hover{background-color:#0cafc626}.ddoc .hover\:bg-optional\/5:hover{background-color:#0cafc60d}.ddoc .hover\:bg-other\/15:hover{background-color:#57534e26}.ddoc .hover\:bg-other\/5:hover{background-color:#57534e0d}.ddoc .hover\:bg-permissions\/15:hover{background-color:#0cafc626}.ddoc .hover\:bg-permissions\/5:hover{background-color:#0cafc60d}.ddoc .hover\:bg-private\/15:hover{background-color:#0cafc626}.ddoc .hover\:bg-private\/5:hover{background-color:#0cafc60d}.ddoc .hover\:bg-protected\/15:hover{background-color:#7b61ff26}.ddoc .hover\:bg-protected\/5:hover{background-color:#7b61ff0d}.ddoc .hover\:bg-readonly\/15:hover{background-color:#7b61ff26}.ddoc .hover\:bg-readonly\/5:hover{background-color:#7b61ff0d}.ddoc .hover\:bg-unstable\/15:hover{background-color:#7b61ff26}.ddoc .hover\:bg-unstable\/5:hover{background-color:#7b61ff0d}.ddoc .hover\:bg-writeonly\/15:hover{background-color:#7b61ff26}.ddoc .hover\:bg-writeonly\/5:hover{background-color:#7b61ff0d} \ No newline at end of file +.ddoc .container{width:100%}@media (min-width:640px){.ddoc .container{max-width:640px}}@media (min-width:768px){.ddoc .container{max-width:768px}}@media (min-width:1024px){.ddoc .container{max-width:1024px}}@media (min-width:1280px){.ddoc .container{max-width:1280px}}@media (min-width:1536px){.ddoc .container{max-width:1536px}}.ddoc .static{position:static}.ddoc .relative{position:relative}.ddoc .\!mb-0{margin-bottom:0!important}.ddoc .\!mt-2{margin-top:.5rem!important}.ddoc .mb-1{margin-bottom:.25rem}.ddoc .ml-4{margin-left:1rem}.ddoc .ml-indent{margin-left:2ch}.ddoc .mr-2{margin-right:.5rem}.ddoc .mt-3{margin-top:.75rem}.ddoc .inline{display:inline}.ddoc .\!flex{display:flex!important}.ddoc .flex{display:flex}.ddoc .inline-flex{display:inline-flex}.ddoc .table{display:table}.ddoc .contents{display:contents}.ddoc .hidden{display:none}.ddoc .h-4{height:1rem}.ddoc .h-5{height:1.25rem}.ddoc .max-w-\[75ch\]{max-width:75ch}.ddoc .flex-1{flex:1}.ddoc .flex-none{flex:none}.ddoc .rotate-90{--tw-rotate:90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y))rotate(var(--tw-rotate))skewX(var(--tw-skew-x))skewY(var(--tw-skew-y))scaleX(var(--tw-scale-x))scaleY(var(--tw-scale-y))}.ddoc .scroll-mt-16{scroll-margin-top:4rem}.ddoc .items-center{align-items:center}.ddoc .gap-0{gap:0}.ddoc .gap-0\.5{gap:.125rem}.ddoc .gap-1{gap:.25rem}.ddoc .space-x-1>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(.25rem*var(--tw-space-x-reverse));margin-left:calc(.25rem*calc(1 - var(--tw-space-x-reverse)))}.ddoc .space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(.5rem*var(--tw-space-x-reverse));margin-left:calc(.5rem*calc(1 - var(--tw-space-x-reverse)))}.ddoc .space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem*var(--tw-space-y-reverse))}.ddoc .space-y-7>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1.75rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.75rem*var(--tw-space-y-reverse))}.ddoc .space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(2rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem*var(--tw-space-y-reverse))}.ddoc .break-words{overflow-wrap:break-word}.ddoc .break-all{word-break:break-all}.ddoc .rounded{border-radius:.25rem}.ddoc .rounded-md{border-radius:.375rem}.ddoc .border{border-width:1px}.ddoc .border-b{border-bottom-width:1px}.ddoc .border-l-2{border-left-width:2px}.ddoc .border-Class\/50{border-color:#20b44b80}.ddoc .border-Enum\/50{border-color:#22abb080}.ddoc .border-Function\/50{border-color:#056cf080}.ddoc .border-Interface\/50{border-color:#d2a06480}.ddoc .border-Method\/50{border-color:#056cf080}.ddoc .border-Namespace\/50{border-color:#d2564680}.ddoc .border-Property\/50{border-color:#7e57c080}.ddoc .border-TypeAlias\/50{border-color:#a4478c80}.ddoc .border-Variable\/50{border-color:#7e57c080}.ddoc .border-abstract\/50{border-color:#0cafc680}.ddoc .border-deprecated\/50{border-color:#dc262680}.ddoc .border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity))}.ddoc .border-new\/50{border-color:#7b61ff80}.ddoc .border-optional\/50{border-color:#0cafc680}.ddoc .border-other\/50{border-color:#57534e80}.ddoc .border-permissions\/50,.ddoc .border-private\/50{border-color:#0cafc680}.ddoc .border-protected\/50,.ddoc .border-readonly\/50{border-color:#7b61ff80}.ddoc .border-stone-300{--tw-border-opacity:1;border-color:rgb(214 211 209/var(--tw-border-opacity))}.ddoc .border-unstable\/50,.ddoc .border-writeonly\/50{border-color:#7b61ff80}.ddoc .bg-Class\/15{background-color:#20b44b26}.ddoc .bg-Class\/5{background-color:#20b44b0d}.ddoc .bg-Enum\/15{background-color:#22abb026}.ddoc .bg-Enum\/5{background-color:#22abb00d}.ddoc .bg-Function\/15{background-color:#056cf026}.ddoc .bg-Function\/5{background-color:#056cf00d}.ddoc .bg-Interface\/15{background-color:#d2a06426}.ddoc .bg-Interface\/5{background-color:#d2a0640d}.ddoc .bg-Method\/15{background-color:#056cf026}.ddoc .bg-Method\/5{background-color:#056cf00d}.ddoc .bg-Namespace\/15{background-color:#d2564626}.ddoc .bg-Namespace\/5{background-color:#d256460d}.ddoc .bg-Property\/15{background-color:#7e57c026}.ddoc .bg-Property\/5{background-color:#7e57c00d}.ddoc .bg-TypeAlias\/15{background-color:#a4478c26}.ddoc .bg-TypeAlias\/5{background-color:#a4478c0d}.ddoc .bg-Variable\/15{background-color:#7e57c026}.ddoc .bg-Variable\/5{background-color:#7e57c00d}.ddoc .bg-abstract\/15{background-color:#0cafc626}.ddoc .bg-abstract\/5{background-color:#0cafc60d}.ddoc .bg-deprecated\/15{background-color:#dc262626}.ddoc .bg-deprecated\/5{background-color:#dc26260d}.ddoc .bg-new\/15{background-color:#7b61ff26}.ddoc .bg-new\/5{background-color:#7b61ff0d}.ddoc .bg-optional\/15{background-color:#0cafc626}.ddoc .bg-optional\/5{background-color:#0cafc60d}.ddoc .bg-other\/15{background-color:#57534e26}.ddoc .bg-other\/5{background-color:#57534e0d}.ddoc .bg-permissions\/15{background-color:#0cafc626}.ddoc .bg-permissions\/5{background-color:#0cafc60d}.ddoc .bg-private\/15{background-color:#0cafc626}.ddoc .bg-private\/5{background-color:#0cafc60d}.ddoc .bg-protected\/15{background-color:#7b61ff26}.ddoc .bg-protected\/5{background-color:#7b61ff0d}.ddoc .bg-readonly\/15{background-color:#7b61ff26}.ddoc .bg-readonly\/5{background-color:#7b61ff0d}.ddoc .bg-stone-100{--tw-bg-opacity:1;background-color:rgb(245 245 244/var(--tw-bg-opacity))}.ddoc .bg-unstable\/15{background-color:#7b61ff26}.ddoc .bg-unstable\/5{background-color:#7b61ff0d}.ddoc .bg-writeonly\/15{background-color:#7b61ff26}.ddoc .bg-writeonly\/5{background-color:#7b61ff0d}.ddoc .px-2{padding-left:.5rem;padding-right:.5rem}.ddoc .px-3{padding-left:.75rem;padding-right:.75rem}.ddoc .px-4{padding-left:1rem;padding-right:1rem}.ddoc .py-1{padding-top:.25rem;padding-bottom:.25rem}.ddoc .py-2{padding-top:.5rem;padding-bottom:.5rem}.ddoc .pb-5{padding-bottom:1.25rem}.ddoc .pt-4{padding-top:1rem}.ddoc .text-2xl{font-size:1.5rem;line-height:2rem}.ddoc .text-base{font-size:1rem;line-height:1.5rem}.ddoc .text-sm{font-size:.875rem;line-height:1.25rem}.ddoc .font-bold{font-weight:700}.ddoc .font-medium{font-weight:500}.ddoc .font-normal{font-weight:400}.ddoc .italic{font-style:italic}.ddoc .leading-none{line-height:1}.ddoc .text-Class{--tw-text-opacity:1;color:rgb(32 180 75/var(--tw-text-opacity))}.ddoc .text-Enum{--tw-text-opacity:1;color:rgb(34 171 176/var(--tw-text-opacity))}.ddoc .text-Function{--tw-text-opacity:1;color:rgb(5 108 240/var(--tw-text-opacity))}.ddoc .text-Interface{--tw-text-opacity:1;color:rgb(210 160 100/var(--tw-text-opacity))}.ddoc .text-Method{--tw-text-opacity:1;color:rgb(5 108 240/var(--tw-text-opacity))}.ddoc .text-Namespace{--tw-text-opacity:1;color:rgb(210 86 70/var(--tw-text-opacity))}.ddoc .text-Property{--tw-text-opacity:1;color:rgb(126 87 192/var(--tw-text-opacity))}.ddoc .text-TypeAlias{--tw-text-opacity:1;color:rgb(164 71 140/var(--tw-text-opacity))}.ddoc .text-Variable{--tw-text-opacity:1;color:rgb(126 87 192/var(--tw-text-opacity))}.ddoc .text-\[\#0F172A\]{--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity))}.ddoc .text-abstract{--tw-text-opacity:1;color:rgb(12 175 198/var(--tw-text-opacity))}.ddoc .text-deprecated{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity))}.ddoc .text-new{--tw-text-opacity:1;color:rgb(123 97 255/var(--tw-text-opacity))}.ddoc .text-optional{--tw-text-opacity:1;color:rgb(12 175 198/var(--tw-text-opacity))}.ddoc .text-other{--tw-text-opacity:1;color:rgb(87 83 78/var(--tw-text-opacity))}.ddoc .text-permissions,.ddoc .text-private{--tw-text-opacity:1;color:rgb(12 175 198/var(--tw-text-opacity))}.ddoc .text-protected,.ddoc .text-readonly{--tw-text-opacity:1;color:rgb(123 97 255/var(--tw-text-opacity))}.ddoc .text-stone-500{--tw-text-opacity:1;color:rgb(120 113 108/var(--tw-text-opacity))}.ddoc .text-unstable,.ddoc .text-writeonly{--tw-text-opacity:1;color:rgb(123 97 255/var(--tw-text-opacity))}.ddoc .filter{filter:var(--tw-blur)var(--tw-brightness)var(--tw-contrast)var(--tw-grayscale)var(--tw-hue-rotate)var(--tw-invert)var(--tw-saturate)var(--tw-sepia)var(--tw-drop-shadow)}.ddoc summary::-webkit-details-marker{display:none}.ddoc a{word-wrap:break-word}.ddoc{--ddoc-selection-border-width:2px;--ddoc-selection-border-color-default:#d6d3d1;--ddoc-selection-selected-border-color:#2564eb;--ddoc-selection-selected-bg:#056cf00c;--ddoc-selection-padding:9px 15px}.ddoc .link{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity));transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter,backdrop-filter,-webkit-backdrop-filter;transition-duration:75ms;transition-timing-function:cubic-bezier(.4,0,.2,1)}.ddoc .link:hover{--tw-text-opacity:1;color:rgb(96 165 250/var(--tw-text-opacity))}.ddoc .anchor{float:left;--tw-text-opacity:1;color:rgb(87 83 78/var(--tw-text-opacity));margin-left:-24px;padding:.25rem;line-height:1;display:none;top:0;bottom:0}.ddoc .anchorable{scroll-margin-top:4rem;position:relative}.ddoc .anchorable:hover .anchor{display:block}.ddoc .deprecated>div:first-child{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity));align-items:center;gap:.25rem;padding-top:.25rem;padding-bottom:.25rem;display:flex}.ddoc .deprecated>div:first-child>span{font-weight:600;line-height:1.5rem}.ddoc .deprecated>div:nth-child(2){--tw-border-opacity:1;border-left-width:4px;border-color:rgb(252 165 165/var(--tw-border-opacity));margin-left:.25rem;padding-left:.5rem}.ddoc .symbolSubtitle>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.125rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.125rem*var(--tw-space-y-reverse))}.ddoc .symbolSubtitle{font-size:.875rem;line-height:1rem}.ddoc .symbolSubtitle .type{--tw-text-opacity:1;color:rgb(168 162 158/var(--tw-text-opacity));font-style:italic}.ddoc .docEntry{margin-bottom:1rem}.ddoc .docEntry>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem*var(--tw-space-y-reverse))}.ddoc .docEntry .docEntryHeader{justify-content:space-between;align-items:flex-start;display:flex}@media (min-width:768px){.ddoc .docEntry .docEntryHeader{font-size:1rem;line-height:1.5rem}}.ddoc .docEntry .docEntryHeader>div{overflow-wrap:break-word}.ddoc .section{max-width:75ch;margin-bottom:.5rem;scroll-margin-top:4rem}.ddoc .section>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem*var(--tw-space-y-reverse))}.ddoc .section>div:first-child>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem*var(--tw-space-y-reverse))}.ddoc .section>div:first-child>h2{margin-bottom:0;padding-top:.25rem;padding-bottom:.25rem;font-size:1.25rem;font-weight:600;line-height:1.5rem}.ddoc .section>div:first-child>div{max-width:75ch;font-size:1rem;line-height:1.5rem}.ddoc .namespaceSection{max-width:75ch;margin-top:1rem}.ddoc .namespaceSection>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem*var(--tw-space-y-reverse))}.ddoc .namespaceSection .namespaceItem{-moz-column-gap:.625rem;column-gap:.625rem;min-height:0;display:flex}@media (min-width:768px){.ddoc .namespaceSection .namespaceItem{min-height:4rem}}@media (min-width:1024px){.ddoc .namespaceSection .namespaceItem{padding-right:1rem}}.ddoc .namespaceSection .namespaceItem .docNodeKindIcon{flex-direction:column;justify-content:flex-start;width:auto}.ddoc .namespaceSection .namespaceItem .docNodeKindIcon>*+*{margin-top:-.125rem;margin-left:0}.ddoc .namespaceSection .namespaceItem[aria-label=deprecated]{opacity:.6}.ddoc .namespaceSection .namespaceItem[aria-label=deprecated] .namespaceItemContent>a{--tw-text-opacity:1;color:rgb(120 113 108/var(--tw-text-opacity));text-decoration-line:line-through;text-decoration-color:#78716cb3;text-decoration-thickness:2px}.ddoc .namespaceSection .namespaceItem .namespaceItemContent>a,.ddoc .namespaceSection .namespaceItem .namespaceItemContent .namespaceItemContentSubItems a{text-decoration-line:underline;text-decoration-color:#d6d3d1}:is(.ddoc .namespaceSection .namespaceItem .namespaceItemContent>a,.ddoc .namespaceSection .namespaceItem .namespaceItemContent .namespaceItemContentSubItems a):hover{text-decoration-line:none}.ddoc .namespaceSection .namespaceItem .namespaceItemContent>a{word-break:break-all;font-weight:500;line-height:1.25;display:block}.ddoc .namespaceSection .namespaceItem .namespaceItemContent .namespaceItemContentDoc{--tw-text-opacity:1;color:rgb(87 83 78/var(--tw-text-opacity));margin-top:.5rem;font-size:.875rem;line-height:1.25rem}.ddoc .namespaceSection .namespaceItem .namespaceItemContent .namespaceItemContentSubItems{flex-wrap:wrap;row-gap:.25rem;margin-top:.375rem;font-size:.875rem;line-height:1.25rem;display:flex}.ddoc .namespaceSection .namespaceItem .namespaceItemContent .namespaceItemContentSubItems>li:not(:last-child):after{content:"|";-webkit-user-select:none;user-select:none;--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity));margin-left:.5rem;margin-right:.5rem}.ddoc .symbolGroup>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(3rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(3rem*var(--tw-space-y-reverse))}.ddoc .symbolGroup article>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1.25rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.25rem*var(--tw-space-y-reverse))}.ddoc .symbolGroup article>div:first-child{justify-content:space-between;align-items:flex-start;display:flex}.ddoc .symbolGroup article>div:first-child>div:first-child>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.25rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem*var(--tw-space-y-reverse))}.ddoc .symbolGroup article>div:first-child>div:first-child{font-weight:500}.ddoc .docNodeKindIcon{flex-shrink:0;justify-content:flex-end;display:inline-flex}.ddoc .docNodeKindIcon div{-webkit-user-select:none;user-select:none;text-align:center;vertical-align:middle;border-radius:9999px;flex-shrink:0;width:1.25rem;height:1.25rem;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:.75rem;font-weight:500;line-height:1.25rem}.ddoc .docNodeKindIcon>*+*{margin-left:-.375rem}.ddoc .example-header{margin-bottom:.75rem;font-size:1.125rem;font-weight:700;line-height:1.75rem}.ddoc .toc h3{margin-bottom:.75rem;font-size:1.125rem;font-weight:700;line-height:1.75rem}.ddoc .toc>div>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1.25rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.25rem*var(--tw-space-y-reverse))}.ddoc .toc .topSymbols>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.75rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem*var(--tw-space-y-reverse))}.ddoc .toc .topSymbols{font-size:.875rem;line-height:1.25rem}.ddoc .toc .topSymbols ul{list-style-type:none}.ddoc .toc .topSymbols ul>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.625rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.625rem*var(--tw-space-y-reverse))}.ddoc .toc .topSymbols ul li{display:block}.ddoc .toc .topSymbols ul li a{align-items:center;gap:.5rem;display:flex}.ddoc .toc .topSymbols ul li a>span{text-overflow:ellipsis;white-space:nowrap;border-radius:.25rem;width:100%;margin-top:-.125rem;margin-bottom:-.125rem;margin-left:-.25rem;padding-top:.125rem;padding-bottom:.125rem;padding-left:.25rem;display:block;overflow:hidden}.ddoc .toc .topSymbols>a:hover{text-decoration-line:underline}.ddoc .toc .documentNavigation>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.75rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem*var(--tw-space-y-reverse))}.ddoc .toc .documentNavigation{font-size:.875rem;line-height:1.25rem}@media not all and (min-width:640px){.ddoc .toc .documentNavigation{display:none}}.ddoc .toc .documentNavigation>ul{flex-grow:1;display:block}.ddoc .toc .documentNavigation>ul>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem*var(--tw-space-y-reverse))}.ddoc .toc .documentNavigation>ul{overflow-y:auto}.ddoc .toc .documentNavigation>ul>li{margin-top:.125rem;margin-left:.75rem;margin-right:.75rem}.ddoc .toc .documentNavigation>ul li:has(>ul){margin-top:0!important}.ddoc .toc .documentNavigation>ul li:has(>a){padding-bottom:0!important}.ddoc .toc .documentNavigation>ul ul{margin-left:.875rem}.ddoc .toc .documentNavigation>ul ul>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem*var(--tw-space-y-reverse))}.ddoc .toc .documentNavigation>ul ul{--tw-text-opacity:1;color:rgb(134 135 137/var(--tw-text-opacity));font-size:.8rem;line-height:1}.ddoc .toc .documentNavigation>ul ul li{margin-top:.25rem!important}.ddoc .toc .documentNavigation>ul ul li a{padding:.25rem}.ddoc .toc .documentNavigation>ul ul li a:hover{--tw-text-opacity:1;color:rgb(0 0 0/var(--tw-text-opacity))}.ddoc .toc .documentNavigation a{text-overflow:ellipsis;white-space:nowrap;display:block;overflow:hidden}.ddoc .toc .documentNavigation a:hover{text-decoration-line:underline}.ddoc .usages nav{flex-direction:row;align-items:center;gap:.5rem;margin-bottom:.75rem;font-weight:600;display:flex}.ddoc .usages nav details>summary{cursor:pointer;-webkit-user-select:none;user-select:none;--tw-border-opacity:1;border-width:1px;border-color:rgb(209 213 219/var(--tw-border-opacity));border-radius:.25rem;gap:.25rem;padding:.5rem .75rem;display:flex}@media (min-width:768px){.ddoc .usages nav details>div{position:relative}}.ddoc .usages nav details>div>div{z-index:30;--tw-border-opacity:1;border-width:1px;border-color:rgb(209 213 219/var(--tw-border-opacity));--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));margin-top:.375rem;padding:.5rem;display:block;position:absolute}@media not all and (min-width:768px){.ddoc .usages nav details>div>div{border-left-width:0;border-right-width:0;left:0;right:0}}@media (min-width:768px){.ddoc .usages nav details>div>div{border-radius:.25rem;width:12rem}}.ddoc .usages nav details>div>div label{cursor:pointer;-webkit-user-select:none;user-select:none;border-radius:.125rem;align-items:center;gap:.5rem;padding:.25rem .5rem;line-height:1.5;display:flex}.ddoc .usages nav details>div>div label:hover{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity))}.ddoc .usageContent>h3{margin-bottom:.75rem;font-size:1.125rem;font-weight:700;line-height:1.75rem}.ddoc .usageContent>div{--tw-text-opacity:1;color:rgb(104 104 104/var(--tw-text-opacity));font-size:.75rem;line-height:1rem}.ddoc .usageContent>div p{margin:0}.ddoc .usageContent pre.highlight{--tw-border-opacity:1;border-width:1px;border-color:rgb(209 213 219/var(--tw-border-opacity));--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}@media not all and (min-width:768px){.ddoc .usageContent pre.highlight{border-left-width:0;border-right-width:0}}.ddoc .usageContent pre.highlight{margin-top:.25rem!important}.ddoc .usageContent pre.highlight>code:first-child{scrollbar-width:thin;padding:.5rem .75rem}.ddoc .usageContent pre.highlight .context_button{border-width:0;display:none;top:.25rem;right:.5rem}.ddoc .usageContent pre.highlight .context_button svg rect{fill:#fff}.ddoc .usageContent pre.highlight:hover .context_button{opacity:1;display:block}.ddoc #categoryPanel{padding-top:.75rem;font-size:.875rem;line-height:1.25rem}.ddoc #categoryPanel ul>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem*calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem*var(--tw-space-y-reverse))}.ddoc #categoryPanel ul{overflow-y:auto}.ddoc #categoryPanel ul li{margin-left:.25rem;margin-right:.75rem}.ddoc #categoryPanel ul li a{text-overflow:ellipsis;white-space:nowrap;padding:.375rem .875rem;display:block;overflow:hidden}.ddoc #categoryPanel ul li a:hover{text-decoration-line:underline}.ddoc .contextLink{color:#0e6590cc;text-underline-offset:.15em;text-decoration-line:underline;text-decoration-color:#0e659080;text-decoration-thickness:1.5px}.ddoc .contextLink:hover{--tw-text-opacity:1;color:rgb(14 101 144/var(--tw-text-opacity));text-decoration-color:#0e6590}.ddoc .contextLink{-webkit-text-decoration-skip:ink;-webkit-text-decoration-skip-ink:auto;text-decoration-skip-ink:auto}.ddoc .breadcrumbs{word-break:break-all;flex-wrap:wrap;align-items:center;gap:.25rem;display:inline-flex}.ddoc .breadcrumbs>li:first-child{font-size:1.5rem;font-weight:700;line-height:1}.ddoc .breadcrumbs li{font-size:1.125rem;line-height:.9em;display:inline}@media (min-width:1024px){.ddoc .breadcrumbs li{font-size:1.25rem;line-height:1.75rem}}.ddoc .context_button{z-index:10;cursor:pointer;background-color:inherit;border-width:1px;border-radius:.25rem;padding:.375rem;line-height:0}.ddoc .context_button:hover{--tw-bg-opacity:1;background-color:rgb(231 229 228/var(--tw-bg-opacity))}.ddoc .see{list-style-type:disc;list-style-position:inside}.ddoc .see>li *{display:inline-block}.ddoc .\*\:h-4>*{height:1rem}.ddoc .\*\:h-5>*{height:1.25rem}.ddoc .\*\:w-auto>*{width:auto}.ddoc .\*\:flex-none>*{flex:none}.ddoc .hover\:bg-Class\/15:hover{background-color:#20b44b26}.ddoc .hover\:bg-Class\/5:hover{background-color:#20b44b0d}.ddoc .hover\:bg-Enum\/15:hover{background-color:#22abb026}.ddoc .hover\:bg-Enum\/5:hover{background-color:#22abb00d}.ddoc .hover\:bg-Function\/15:hover{background-color:#056cf026}.ddoc .hover\:bg-Function\/5:hover{background-color:#056cf00d}.ddoc .hover\:bg-Interface\/15:hover{background-color:#d2a06426}.ddoc .hover\:bg-Interface\/5:hover{background-color:#d2a0640d}.ddoc .hover\:bg-Method\/15:hover{background-color:#056cf026}.ddoc .hover\:bg-Method\/5:hover{background-color:#056cf00d}.ddoc .hover\:bg-Namespace\/15:hover{background-color:#d2564626}.ddoc .hover\:bg-Namespace\/5:hover{background-color:#d256460d}.ddoc .hover\:bg-Property\/15:hover{background-color:#7e57c026}.ddoc .hover\:bg-Property\/5:hover{background-color:#7e57c00d}.ddoc .hover\:bg-TypeAlias\/15:hover{background-color:#a4478c26}.ddoc .hover\:bg-TypeAlias\/5:hover{background-color:#a4478c0d}.ddoc .hover\:bg-Variable\/15:hover{background-color:#7e57c026}.ddoc .hover\:bg-Variable\/5:hover{background-color:#7e57c00d}.ddoc .hover\:bg-abstract\/15:hover{background-color:#0cafc626}.ddoc .hover\:bg-abstract\/5:hover{background-color:#0cafc60d}.ddoc .hover\:bg-deprecated\/15:hover{background-color:#dc262626}.ddoc .hover\:bg-deprecated\/5:hover{background-color:#dc26260d}.ddoc .hover\:bg-new\/15:hover{background-color:#7b61ff26}.ddoc .hover\:bg-new\/5:hover{background-color:#7b61ff0d}.ddoc .hover\:bg-optional\/15:hover{background-color:#0cafc626}.ddoc .hover\:bg-optional\/5:hover{background-color:#0cafc60d}.ddoc .hover\:bg-other\/15:hover{background-color:#57534e26}.ddoc .hover\:bg-other\/5:hover{background-color:#57534e0d}.ddoc .hover\:bg-permissions\/15:hover{background-color:#0cafc626}.ddoc .hover\:bg-permissions\/5:hover{background-color:#0cafc60d}.ddoc .hover\:bg-private\/15:hover{background-color:#0cafc626}.ddoc .hover\:bg-private\/5:hover{background-color:#0cafc60d}.ddoc .hover\:bg-protected\/15:hover{background-color:#7b61ff26}.ddoc .hover\:bg-protected\/5:hover{background-color:#7b61ff0d}.ddoc .hover\:bg-readonly\/15:hover{background-color:#7b61ff26}.ddoc .hover\:bg-readonly\/5:hover{background-color:#7b61ff0d}.ddoc .hover\:bg-unstable\/15:hover{background-color:#7b61ff26}.ddoc .hover\:bg-unstable\/5:hover{background-color:#7b61ff0d}.ddoc .hover\:bg-writeonly\/15:hover{background-color:#7b61ff26}.ddoc .hover\:bg-writeonly\/5:hover{background-color:#7b61ff0d} \ No newline at end of file diff --git a/src/html/templates/toc.hbs b/src/html/templates/toc.hbs index ab1322a9..d314fafd 100644 --- a/src/html/templates/toc.hbs +++ b/src/html/templates/toc.hbs @@ -1,4 +1,4 @@ -{{~#if (or usages (or top_symbols document_navigation))~}} +{{~#if (or usages (or top_symbols document_navigation_str))~}}
    {{~#if usages~}} @@ -27,10 +27,10 @@ {{~/if~}} - {{~#if document_navigation~}} + {{~#if document_navigation_str~}} {{~/if~}}
    diff --git a/src/html/tree_sitter.rs b/src/html/tree_sitter.rs deleted file mode 100644 index 553c3794..00000000 --- a/src/html/tree_sitter.rs +++ /dev/null @@ -1,266 +0,0 @@ -use std::sync::OnceLock; - -use tree_sitter_highlight::Highlight; -use tree_sitter_highlight::HighlightConfiguration; - -macro_rules! highlighter { - [$($name:literal -> $class:literal,)*] => { - /// The capture names to configure on the highlighter. If this is not - /// configured correctly, the highlighter will not work. - pub const CAPTURE_NAMES: &[&str] = &[$($name),*]; - const CLASSES_ATTRIBUTES: &[&str] = &[$(concat!("class=\"", $class, "\"")),*]; - pub const CLASSES: &[&str] = &[$($class),*]; - }; -} - -highlighter! [ - "attribute" -> "pl-c1", - "comment" -> "pl-c", - "constant.builtin" -> "pl-c1", - "constant" -> "pl-c1", - "constructor" -> "pl-v", - "embedded" -> "pl-s1", - "function" -> "pl-en", - "keyword" -> "pl-k", - "number" -> "pl-c1", - "operator" -> "pl-c1", - "property" -> "pl-c1", - "string" -> "pl-s", - "tag" -> "pl-ent", - "type" -> "pl-smi", - "variable.builtin" -> "pl-smi", -]; - -pub(crate) fn classes(highlight: Highlight) -> &'static [u8] { - CLASSES_ATTRIBUTES[highlight.0].as_bytes() -} - -pub fn tree_sitter_language_cb( - lang: &str, -) -> Option<&'static HighlightConfiguration> { - for lang in lang.split(',') { - let cfg = match lang.trim() { - "js" | "javascript" => tree_sitter_language_javascript(), - "jsx" => tree_sitter_language_jsx(), - "ts" | "typescript" => tree_sitter_language_typescript(), - "tsx" => tree_sitter_language_tsx(), - "json" | "jsonc" => tree_sitter_language_json(), - "css" => tree_sitter_language_css(), - "md" | "markdown" => tree_sitter_language_markdown(), - "toml" => tree_sitter_language_toml(), - "regex" => tree_sitter_language_regex(), - "rs" | "rust" => tree_sitter_language_rust(), - "html" => tree_sitter_language_html(), - "sh" | "bash" => tree_sitter_language_bash(), - _ => continue, - }; - return Some(cfg); - } - None -} - -pub fn tree_sitter_language_javascript() -> &'static HighlightConfiguration { - static CONFIG: OnceLock = OnceLock::new(); - CONFIG.get_or_init(|| { - let mut config = HighlightConfiguration::new( - tree_sitter_javascript::language(), - tree_sitter_javascript::HIGHLIGHT_QUERY, - tree_sitter_javascript::INJECTION_QUERY, - tree_sitter_javascript::LOCALS_QUERY, - ) - .expect("failed to initialize tree_sitter_javascript highlighter"); - config.configure(CAPTURE_NAMES); - config - }) -} - -pub fn tree_sitter_language_jsx() -> &'static HighlightConfiguration { - static CONFIG: OnceLock = OnceLock::new(); - CONFIG.get_or_init(|| { - let mut config = HighlightConfiguration::new( - tree_sitter_javascript::language(), - format!( - "{} {}", - tree_sitter_javascript::HIGHLIGHT_QUERY, - tree_sitter_javascript::JSX_HIGHLIGHT_QUERY - ) - .leak(), - tree_sitter_javascript::INJECTION_QUERY, - tree_sitter_javascript::LOCALS_QUERY, - ) - .expect("failed to initialize tree_sitter_javascript highlighter"); - config.configure(CAPTURE_NAMES); - config - }) -} - -pub fn tree_sitter_language_typescript() -> &'static HighlightConfiguration { - static CONFIG: OnceLock = OnceLock::new(); - CONFIG.get_or_init(|| { - let mut config = HighlightConfiguration::new( - tree_sitter_typescript::language_typescript(), - format!( - "{} {}", - tree_sitter_javascript::HIGHLIGHT_QUERY, - tree_sitter_typescript::HIGHLIGHT_QUERY - ) - .leak(), - tree_sitter_javascript::INJECTION_QUERY, - format!( - "{} {}", - tree_sitter_javascript::LOCALS_QUERY, - tree_sitter_typescript::LOCALS_QUERY - ) - .leak(), - ) - .expect("failed to initialize tree_sitter_typescript highlighter"); - config.configure(CAPTURE_NAMES); - config - }) -} - -pub fn tree_sitter_language_tsx() -> &'static HighlightConfiguration { - static CONFIG: OnceLock = OnceLock::new(); - CONFIG.get_or_init(|| { - let mut config = HighlightConfiguration::new( - tree_sitter_typescript::language_tsx(), - format!( - "{} {} {}", - tree_sitter_javascript::HIGHLIGHT_QUERY, - tree_sitter_javascript::JSX_HIGHLIGHT_QUERY, - tree_sitter_typescript::HIGHLIGHT_QUERY, - ) - .leak(), - tree_sitter_javascript::INJECTION_QUERY, - format!( - "{} {}", - tree_sitter_javascript::LOCALS_QUERY, - tree_sitter_typescript::LOCALS_QUERY - ) - .leak(), - ) - .expect("failed to initialize tree_sitter_typescript highlighter"); - config.configure(CAPTURE_NAMES); - config - }) -} - -fn tree_sitter_language_json() -> &'static HighlightConfiguration { - static CONFIG: OnceLock = OnceLock::new(); - CONFIG.get_or_init(|| { - let mut config = HighlightConfiguration::new( - tree_sitter_json::language(), - tree_sitter_json::HIGHLIGHT_QUERY, - "", - "", - ) - .expect("failed to initialize tree_sitter_json highlighter"); - config.configure(CAPTURE_NAMES); - config - }) -} - -fn tree_sitter_language_css() -> &'static HighlightConfiguration { - static CONFIG: OnceLock = OnceLock::new(); - CONFIG.get_or_init(|| { - let mut config = HighlightConfiguration::new( - tree_sitter_css::language(), - tree_sitter_css::HIGHLIGHTS_QUERY, - "", - "", - ) - .expect("failed to initialize tree_sitter_css highlighter"); - config.configure(CAPTURE_NAMES); - config - }) -} - -fn tree_sitter_language_markdown() -> &'static HighlightConfiguration { - static CONFIG: OnceLock = OnceLock::new(); - CONFIG.get_or_init(|| { - let mut config = HighlightConfiguration::new( - tree_sitter_md::language(), - tree_sitter_md::HIGHLIGHT_QUERY_BLOCK, - tree_sitter_md::INJECTION_QUERY_BLOCK, - "", - ) - .expect("failed to initialize tree_sitter_md highlighter"); - config.configure(CAPTURE_NAMES); - config - }) -} - -fn tree_sitter_language_toml() -> &'static HighlightConfiguration { - static CONFIG: OnceLock = OnceLock::new(); - CONFIG.get_or_init(|| { - let mut config = HighlightConfiguration::new( - tree_sitter_toml::language(), - tree_sitter_toml::HIGHLIGHT_QUERY, - "", - "", - ) - .expect("failed to initialize tree_sitter_toml highlighter"); - config.configure(CAPTURE_NAMES); - config - }) -} - -fn tree_sitter_language_regex() -> &'static HighlightConfiguration { - static CONFIG: OnceLock = OnceLock::new(); - CONFIG.get_or_init(|| { - let mut config = HighlightConfiguration::new( - tree_sitter_regex::language(), - tree_sitter_regex::HIGHLIGHTS_QUERY, - "", - "", - ) - .expect("failed to initialize tree_sitter_regex highlighter"); - config.configure(CAPTURE_NAMES); - config - }) -} - -fn tree_sitter_language_rust() -> &'static HighlightConfiguration { - static CONFIG: OnceLock = OnceLock::new(); - CONFIG.get_or_init(|| { - let mut config = HighlightConfiguration::new( - tree_sitter_rust::language(), - tree_sitter_rust::HIGHLIGHT_QUERY, - tree_sitter_rust::INJECTIONS_QUERY, - "", - ) - .expect("failed to initialize tree_sitter_rust highlighter"); - config.configure(CAPTURE_NAMES); - config - }) -} - -fn tree_sitter_language_html() -> &'static HighlightConfiguration { - static CONFIG: OnceLock = OnceLock::new(); - CONFIG.get_or_init(|| { - let mut config = HighlightConfiguration::new( - tree_sitter_html::language(), - tree_sitter_html::HIGHLIGHTS_QUERY, - tree_sitter_html::INJECTIONS_QUERY, - "", - ) - .expect("failed to initialize tree_sitter_html highlighter"); - config.configure(CAPTURE_NAMES); - config - }) -} - -fn tree_sitter_language_bash() -> &'static HighlightConfiguration { - static CONFIG: OnceLock = OnceLock::new(); - CONFIG.get_or_init(|| { - let mut config = HighlightConfiguration::new( - tree_sitter_bash::language(), - tree_sitter_bash::HIGHLIGHT_QUERY, - "", - "", - ) - .expect("failed to initialize tree_sitter_bash highlighter"); - config.configure(CAPTURE_NAMES); - config - }) -} diff --git a/src/html/types.rs b/src/html/types.rs index 6f0009fb..99edc1de 100644 --- a/src/html/types.rs +++ b/src/html/types.rs @@ -1,7 +1,6 @@ use super::parameters::render_params; use super::render_context::RenderContext; use super::util::*; -use std::collections::HashSet; use crate::js_doc::JsDoc; use crate::js_doc::JsDocTag; @@ -559,7 +558,7 @@ pub(crate) fn render_type_params( .iter() .filter_map(|tag| { if let JsDocTag::Template { name, doc } = tag { - doc.as_ref().map(|doc| (name.as_str(), doc.as_str())) + doc.as_ref().map(|doc| (&**name, &**doc)) } else { None } @@ -597,7 +596,7 @@ pub(crate) fn render_type_params( Some(html_escape::encode_text(&type_param.name).into_owned()), None, &format!("{constraint}{default}"), - HashSet::new(), + Default::default(), type_param_docs.get(type_param.name.as_str()).cloned(), location, ); diff --git a/src/html/usage.rs b/src/html/usage.rs index 9b59fcab..5ea89472 100644 --- a/src/html/usage.rs +++ b/src/html/usage.rs @@ -1,8 +1,28 @@ +use super::DocNodeWithContext; +use super::FileMode; use super::RenderContext; use super::UrlResolveKind; -use super::{DocNodeWithContext, FileMode}; -use crate::DocNodeKind; +use crate::js_doc::JsDocTag; +use crate::node::DocNodeDef; +use indexmap::IndexMap; +use regex::Regex; use serde::Serialize; +use std::borrow::Cow; + +#[cfg(target_arch = "wasm32")] +use std::cell::RefCell; +#[cfg(target_arch = "wasm32")] +use std::ffi::c_void; + +#[cfg(target_arch = "wasm32")] +thread_local! { + static RENDER_CONTEXT: RefCell<*const c_void> = const { RefCell::new(std::ptr::null()) }; + static DOC_NODES: RefCell<(*const c_void, usize)> = const { RefCell::new((std::ptr::null(), 0)) }; +} + +lazy_static! { + static ref IDENTIFIER_RE: Regex = Regex::new(r"[^a-zA-Z$_]").unwrap(); +} fn render_css_for_usage(name: &str) -> String { format!( @@ -21,56 +41,76 @@ fn render_css_for_usage(name: &str) -> String { ) } -pub fn usage_to_md( +fn usage_to_md( ctx: &RenderContext, doc_nodes: &[DocNodeWithContext], url: &str, + custom_file_identifier: Option<&str>, ) -> String { let usage = if let UrlResolveKind::Symbol { symbol, .. } = ctx.get_current_resolve() { - let mut parts = symbol.split('.').collect::>(); + let mut parts = symbol.split('.'); let top_node = doc_nodes[0].get_topmost_ancestor(); let is_default = top_node.is_default.is_some_and(|is_default| is_default) - || top_node.name == "default"; + || &*top_node.name == "default"; - let import_symbol = if is_default { + let import_symbol: Box = if is_default { if top_node.is_default.is_some_and(|is_default| is_default) { - top_node.name.clone() + let default_name = top_node.get_name(); + if default_name == "default" { + get_identifier_for_file(ctx, custom_file_identifier).into() + } else { + default_name.into() + } } else { - "module".to_string() + "module".into() } } else { - parts[0].to_string() + parts.clone().next().unwrap().into() }; - let usage_symbol = if doc_nodes - .iter() - .all(|node| node.drilldown_parent_kind.is_some()) - { + let usage_symbol = if doc_nodes.iter().all(|node| node.parent.is_some()) { None - } else if parts.len() > 1 { - parts.pop().map(|usage_symbol| { - ( - usage_symbol, - // if it is namespaces within namespaces, we simply re-join them together - // instead of trying to figure out some sort of nested restructuring - if is_default { - import_symbol.clone() - } else { - parts.join(".") - }, - ) - }) } else { - None + let last = parts.next_back(); + if let Some(usage_symbol) = last { + if usage_symbol == symbol { + None + } else { + Some(( + usage_symbol, + // if it is namespaces within namespaces, we simply re-join them together + // instead of trying to figure out some sort of nested restructuring + if is_default { + import_symbol.clone() + } else { + let capacity = symbol.len() - usage_symbol.len() - 1; + let mut joined = String::with_capacity(capacity); + for part in parts { + if !joined.is_empty() { + joined.push('.'); + } + joined.push_str(part); + } + joined.into_boxed_str() + }, + )) + } + } else { + None + } }; let is_type = doc_nodes.iter().all(|doc_node| { matches!( - doc_node.drilldown_parent_kind.unwrap_or(doc_node.kind), - DocNodeKind::TypeAlias | DocNodeKind::Interface + doc_node + .parent + .as_ref() + .map_or_else(|| &doc_node.inner, |parent| &parent.inner) + .def, + DocNodeDef::TypeAlias { .. } | DocNodeDef::Interface { .. } ) }); @@ -98,21 +138,61 @@ pub fn usage_to_md( usage_statement } else { - // when the imported symbol is a namespace import, we try to guess at an - // intelligent camelized name for the import based on the package name. - let import_symbol = "mod"; + let module_import_symbol = + get_identifier_for_file(ctx, custom_file_identifier); - format!(r#"import * as {import_symbol} from "{url}";"#) + format!(r#"import * as {module_import_symbol} from "{url}";"#) }; format!("```typescript\n{usage}\n```") } +fn get_identifier_for_file( + ctx: &RenderContext, + custom_file_identifier: Option<&str>, +) -> String { + let maybe_identifier = + if let Some(file) = ctx.get_current_resolve().get_file() { + ctx + .ctx + .doc_nodes + .get(file) + .and_then(|nodes| { + nodes + .iter() + .find(|node| matches!(node.def, DocNodeDef::ModuleDoc)) + }) + .and_then(|node| { + node.js_doc.tags.iter().find_map(|tag| { + if let JsDocTag::Module { name } = tag { + name.as_ref().map(|name| name.to_string()) + } else { + None + } + }) + }) + } else if let Some(context_name) = custom_file_identifier { + Some(context_name.to_string()) + } else { + ctx.ctx.package_name.clone() + }; + + maybe_identifier.as_ref().map_or_else( + || "mod".to_string(), + |identifier| IDENTIFIER_RE.replace_all(identifier, "_").to_string(), + ) +} + +#[cfg(not(feature = "rust"))] +pub type UsageToMd<'a> = &'a js_sys::Function; +#[cfg(feature = "rust")] +pub type UsageToMd<'a> = &'a dyn Fn(&str, Option<&str>) -> String; + #[derive(Clone, Debug, Serialize)] struct UsageCtx { name: String, content: String, - icon: Option>, + icon: Option>, additional_css: String, } @@ -129,52 +209,138 @@ impl UsagesCtx { ctx: &RenderContext, doc_nodes: &[DocNodeWithContext], ) -> Option { - if ctx.ctx.usage_composer.is_none() - && ctx.ctx.file_mode == FileMode::SingleDts - { + let is_single_mode = ctx.ctx.usage_composer.is_single_mode(); + + if is_single_mode && ctx.ctx.file_mode == FileMode::SingleDts { return None; } - let url = ctx + #[cfg(not(target_arch = "wasm32"))] + let usage_to_md_closure = + move |url: &str, custom_file_identifier: Option<&str>| { + usage_to_md(ctx, doc_nodes, url, custom_file_identifier) + }; + + #[cfg(target_arch = "wasm32")] + { + let ctx_ptr = ctx as *const RenderContext as *const c_void; + RENDER_CONTEXT.set(ctx_ptr); + let nodes_ptr = doc_nodes as *const [DocNodeWithContext] as *const c_void; + DOC_NODES.set((nodes_ptr, doc_nodes.len())); + } + + #[cfg(target_arch = "wasm32")] + let usage_to_md_closure = + move |url: String, custom_file_identifier: Option| { + RENDER_CONTEXT.with(|ctx| { + let render_ctx_ptr = *ctx.borrow() as *const RenderContext; + assert!(!render_ctx_ptr.is_null()); + // SAFETY: this pointer is valid until destroyed, which is done + // after compose is called + let render_ctx = unsafe { &*render_ctx_ptr }; + + let usage = DOC_NODES.with(|nodes| { + let (nodes_ptr, nodes_ptr_len) = *nodes.borrow(); + assert!(!nodes_ptr.is_null()); + // SAFETY: the pointers are valid until destroyed, which is done + // after compose is called + let doc_nodes = unsafe { + std::slice::from_raw_parts( + nodes_ptr as *const DocNodeWithContext, + nodes_ptr_len, + ) + }; + + let usage = usage_to_md( + &render_ctx, + doc_nodes, + &url, + custom_file_identifier.as_deref(), + ); + + *nodes.borrow_mut() = ( + doc_nodes as *const [DocNodeWithContext] as *const c_void, + doc_nodes.len(), + ); + + usage + }); + + *ctx.borrow_mut() = + render_ctx as *const RenderContext as *const c_void; + usage + }) + }; + + #[cfg(target_arch = "wasm32")] + let usage_to_md_closure = + wasm_bindgen::prelude::Closure::wrap(Box::new(usage_to_md_closure) + as Box) -> String>); + #[cfg(target_arch = "wasm32")] + let usage_to_md_closure = &wasm_bindgen::JsCast::unchecked_ref::< + js_sys::Function, + >(usage_to_md_closure.as_ref()); + + let usages = ctx .ctx - .href_resolver - .resolve_usage(ctx.get_current_resolve())?; + .usage_composer + .compose(ctx.get_current_resolve(), &usage_to_md_closure); - if let Some(usage_composer) = &ctx.ctx.usage_composer { - let usages = usage_composer(ctx, doc_nodes, url); + #[cfg(target_arch = "wasm32")] + { + let render_ctx = + RENDER_CONTEXT.replace(std::ptr::null()) as *const RenderContext; + // SAFETY: take the pointer and drop it + let _ = unsafe { &*render_ctx }; + let (doc_nodes_ptr, doc_nodes_ptr_len) = + DOC_NODES.replace((std::ptr::null(), 0)); + // SAFETY: take the pointer and drop it + let _ = unsafe { + std::slice::from_raw_parts( + doc_nodes_ptr as *const DocNodeWithContext, + doc_nodes_ptr_len, + ) + }; + }; + + if usages.is_empty() { + None + } else { let usages = usages .into_iter() .map(|(entry, content)| UsageCtx { - additional_css: render_css_for_usage(&entry.name), + additional_css: if is_single_mode { + String::new() + } else { + render_css_for_usage(&entry.name) + }, name: entry.name, icon: entry.icon, content: crate::html::jsdoc::render_markdown(ctx, &content, true), }) .collect::>(); - if usages.is_empty() { - None - } else { - Some(UsagesCtx { - usages, - composed: true, - }) - } - } else { - let import_statement = usage_to_md(ctx, doc_nodes, &url); - let rendered_import_statement = - crate::html::jsdoc::render_markdown(ctx, &import_statement, true); - Some(UsagesCtx { - usages: vec![UsageCtx { - name: "".to_string(), - content: rendered_import_statement, - icon: None, - additional_css: "".to_string(), - }], - composed: false, + usages, + composed: !is_single_mode, }) } } } + +#[derive(Eq, PartialEq, Hash, serde::Deserialize)] +pub struct UsageComposerEntry { + pub name: String, + pub icon: Option>, +} + +pub trait UsageComposer { + fn is_single_mode(&self) -> bool; + + fn compose( + &self, + current_resolve: UrlResolveKind, + usage_to_md: UsageToMd, + ) -> IndexMap; +} diff --git a/src/html/util.rs b/src/html/util.rs index 51975898..2b2795fd 100644 --- a/src/html/util.rs +++ b/src/html/util.rs @@ -1,26 +1,27 @@ use crate::html::jsdoc::markdown_to_html; use crate::html::jsdoc::MarkdownToHTMLOptions; +use crate::html::render_context::ToCEntry; use crate::html::usage::UsagesCtx; -use crate::html::DocNodeKindWithDrilldown; +use crate::html::DocNodeKind; use crate::html::DocNodeWithContext; use crate::html::FileMode; +use crate::html::GenerateCtx; use crate::html::RenderContext; use crate::html::ShortPath; use crate::js_doc::JsDoc; use crate::js_doc::JsDocTag; -use crate::DocNodeKind; +use crate::node::DocNodeDef; use deno_ast::swc::ast::Accessibility; use deno_ast::swc::atoms::once_cell::sync::Lazy; use indexmap::IndexSet; use regex::Regex; use serde::Serialize; +use std::borrow::Cow; use std::collections::HashMap; -use std::collections::HashSet; use std::rc::Rc; lazy_static! { - static ref TARGET_RE: regex::Regex = - regex::Regex::new(r"\s*\* ?|\.").unwrap(); + static ref TARGET_RE: Regex = Regex::new(r"\s*\* ?|\.").unwrap(); } pub(crate) fn name_to_id(kind: &str, name: &str) -> String { @@ -37,40 +38,50 @@ pub(crate) fn name_to_id(kind: &str, name: &str) -> String { /// ["Deno", "errors"] /// ["Deno", "errors", "HttpError"] #[derive(Clone, Debug)] -pub(crate) struct NamespacedSymbols(Rc>>); +pub(crate) struct NamespacedSymbols( + Rc, Option>>>, +); impl NamespacedSymbols { - pub(crate) fn new(doc_nodes: &[DocNodeWithContext]) -> Self { - let symbols = compute_namespaced_symbols(doc_nodes); + pub(crate) fn new( + ctx: &GenerateCtx, + doc_nodes: &[DocNodeWithContext], + ) -> Self { + let symbols = compute_namespaced_symbols( + ctx, + Box::new(doc_nodes.iter().map(Cow::Borrowed)), + ); Self(Rc::new(symbols)) } - pub(crate) fn contains(&self, path: &[String]) -> bool { - self.0.contains(path) + pub(crate) fn get(&self, path: &[String]) -> Option<&Option>> { + self.0.get(path) } } -pub fn compute_namespaced_symbols( - doc_nodes: &[DocNodeWithContext], -) -> HashSet> { - let mut namespaced_symbols = HashSet::new(); +pub fn compute_namespaced_symbols<'a>( + ctx: &'a GenerateCtx, + doc_nodes: Box> + 'a>, +) -> HashMap, Option>> { + let mut namespaced_symbols = + HashMap::, Option>>::new(); for doc_node in doc_nodes { - if doc_node.kind == DocNodeKind::ModuleDoc - || doc_node.kind == DocNodeKind::Import - { + if matches!( + doc_node.def, + DocNodeDef::ModuleDoc | DocNodeDef::Import { .. } + ) { continue; } - // TODO: handle export aliasing - let name_path = Rc::new(doc_node.sub_qualifier()); + // TODO: handle export aliasing - match doc_node.kind { - DocNodeKind::Class => { - let class_def = doc_node.class_def.as_ref().unwrap(); + let name_path: Rc<[String]> = doc_node.sub_qualifier().into(); + match &doc_node.def { + DocNodeDef::Class { class_def } => { namespaced_symbols.extend(class_def.methods.iter().map(|method| { - let mut method_path = (*doc_node.ns_qualifiers).clone(); + let mut method_path = doc_node.ns_qualifiers.to_vec(); method_path.extend( qualify_drilldown_name( doc_node.get_name(), @@ -80,12 +91,12 @@ pub fn compute_namespaced_symbols( .split('.') .map(|part| part.to_string()), ); - method_path + (method_path, Some(doc_node.origin.clone())) })); namespaced_symbols.extend(class_def.properties.iter().map( |property| { - let mut method_path = (*doc_node.ns_qualifiers).clone(); + let mut method_path = doc_node.ns_qualifiers.to_vec(); method_path.extend( qualify_drilldown_name( doc_node.get_name(), @@ -95,55 +106,51 @@ pub fn compute_namespaced_symbols( .split('.') .map(|part| part.to_string()), ); - method_path + (method_path, Some(doc_node.origin.clone())) }, )); } - DocNodeKind::Interface => { - let interface_def = doc_node.interface_def.as_ref().unwrap(); - + DocNodeDef::Interface { interface_def } => { namespaced_symbols.extend(interface_def.methods.iter().map(|method| { - let mut method_path = (*doc_node.ns_qualifiers).clone(); + let mut method_path = doc_node.ns_qualifiers.to_vec(); method_path.extend( qualify_drilldown_name(doc_node.get_name(), &method.name, true) .split('.') .map(|part| part.to_string()), ); - method_path + (method_path, Some(doc_node.origin.clone())) })); namespaced_symbols.extend(interface_def.properties.iter().map( |property| { - let mut method_path = (*doc_node.ns_qualifiers).clone(); + let mut method_path = doc_node.ns_qualifiers.to_vec(); method_path.extend( qualify_drilldown_name(doc_node.get_name(), &property.name, true) .split('.') .map(|part| part.to_string()), ); - method_path + (method_path, Some(doc_node.origin.clone())) }, )); } - DocNodeKind::TypeAlias => { - let type_alias_def = doc_node.type_alias_def.as_ref().unwrap(); - + DocNodeDef::TypeAlias { type_alias_def } => { if let Some(type_literal) = type_alias_def.ts_type.type_literal.as_ref() { namespaced_symbols.extend(type_literal.methods.iter().map( |method| { - let mut method_path = (*doc_node.ns_qualifiers).clone(); + let mut method_path = doc_node.ns_qualifiers.to_vec(); method_path.extend( qualify_drilldown_name(doc_node.get_name(), &method.name, true) .split('.') .map(|part| part.to_string()), ); - method_path + (method_path, Some(doc_node.origin.clone())) }, )); namespaced_symbols.extend(type_literal.properties.iter().map( |property| { - let mut method_path = (*doc_node.ns_qualifiers).clone(); + let mut method_path = doc_node.ns_qualifiers.to_vec(); method_path.extend( qualify_drilldown_name( doc_node.get_name(), @@ -153,34 +160,32 @@ pub fn compute_namespaced_symbols( .split('.') .map(|part| part.to_string()), ); - method_path + (method_path, Some(doc_node.origin.clone())) }, )); } } - DocNodeKind::Variable => { - let variable = doc_node.variable_def.as_ref().unwrap(); - - if let Some(type_literal) = variable + DocNodeDef::Variable { variable_def } => { + if let Some(type_literal) = variable_def .ts_type .as_ref() .and_then(|ts_type| ts_type.type_literal.as_ref()) { namespaced_symbols.extend(type_literal.methods.iter().map( |method| { - let mut method_path = (*doc_node.ns_qualifiers).clone(); + let mut method_path = doc_node.ns_qualifiers.to_vec(); method_path.extend( qualify_drilldown_name(doc_node.get_name(), &method.name, true) .split('.') .map(|part| part.to_string()), ); - method_path + (method_path, Some(doc_node.origin.clone())) }, )); namespaced_symbols.extend(type_literal.properties.iter().map( |property| { - let mut method_path = (*doc_node.ns_qualifiers).clone(); + let mut method_path = doc_node.ns_qualifiers.to_vec(); method_path.extend( qualify_drilldown_name( doc_node.get_name(), @@ -190,7 +195,7 @@ pub fn compute_namespaced_symbols( .split('.') .map(|part| part.to_string()), ); - method_path + (method_path, Some(doc_node.origin.clone())) }, )); } @@ -198,19 +203,27 @@ pub fn compute_namespaced_symbols( _ => {} } - namespaced_symbols.insert((*name_path).clone()); - - if doc_node.kind == DocNodeKind::Namespace { - let namespace_def = doc_node.namespace_def.as_ref().unwrap(); - namespaced_symbols.extend(compute_namespaced_symbols( - &namespace_def - .elements - .iter() - .map(|element| { - doc_node.create_namespace_child(element.clone(), name_path.clone()) - }) - .collect::>(), - )) + namespaced_symbols + .insert(name_path.to_vec(), Some(doc_node.origin.clone())); + + if matches!(doc_node.def, DocNodeDef::Namespace { .. }) { + let children = doc_node + .namespace_children + .as_ref() + .unwrap() + .iter() + .flat_map(|element| { + if let Some(reference_def) = element.reference_def() { + Box::new( + ctx.resolve_reference(Some(&doc_node), &reference_def.target), + ) as Box>> + } else { + Box::new(std::iter::once(Cow::Borrowed(element))) as _ + } + }); + + namespaced_symbols + .extend(compute_namespaced_symbols(ctx, Box::new(children))) } } @@ -231,12 +244,17 @@ impl NamespacedGlobalSymbols { } /// Different current and target locations -#[derive(Debug, Clone, Copy, Eq, PartialEq)] +#[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize)] +#[serde(tag = "kind", rename_all = "camelCase")] pub enum UrlResolveKind<'a> { Root, AllSymbols, - Category(&'a str), - File(&'a ShortPath), + Category { + category: &'a str, + }, + File { + file: &'a ShortPath, + }, Symbol { file: &'a ShortPath, symbol: &'a str, @@ -248,8 +266,8 @@ impl UrlResolveKind<'_> { match self { UrlResolveKind::Root => None, UrlResolveKind::AllSymbols => None, - UrlResolveKind::Category(_) => None, - UrlResolveKind::File(file) => Some(file), + UrlResolveKind::Category { .. } => None, + UrlResolveKind::File { file } => Some(file), UrlResolveKind::Symbol { file, .. } => Some(file), } } @@ -260,7 +278,7 @@ pub fn href_path_resolve( target: UrlResolveKind, ) -> String { let backs = match current { - UrlResolveKind::File(file) => "../".repeat(if file.is_main { + UrlResolveKind::File { file } => "../".repeat(if file.is_main { 1 } else { file.path.split('/').count() @@ -272,12 +290,12 @@ pub fn href_path_resolve( }), UrlResolveKind::Root => String::new(), UrlResolveKind::AllSymbols => String::from("./"), - UrlResolveKind::Category(_) => String::from("./"), + UrlResolveKind::Category { .. } => String::from("./"), }; match target { UrlResolveKind::Root => backs, - UrlResolveKind::File(target_file) if target_file.is_main => backs, + UrlResolveKind::File { file: target_file } if target_file.is_main => backs, UrlResolveKind::AllSymbols => format!("{backs}./all_symbols.html"), UrlResolveKind::Symbol { file: target_file, @@ -286,10 +304,10 @@ pub fn href_path_resolve( } => { format!("{backs}./{}/~/{target_symbol}.html", target_file.path) } - UrlResolveKind::File(target_file) => { + UrlResolveKind::File { file: target_file } => { format!("{backs}./{}/index.html", target_file.path) } - UrlResolveKind::Category(category) => { + UrlResolveKind::Category { category } => { format!("{backs}./{}.html", slugify(category)) } } @@ -310,11 +328,16 @@ pub trait HrefResolver { fn resolve_import_href(&self, symbol: &[String], src: &str) -> Option; - /// Resolve the URL used in "usage" blocks. - fn resolve_usage(&self, current_resolve: UrlResolveKind) -> Option; - /// Resolve the URL used in source code link buttons. fn resolve_source(&self, location: &crate::Location) -> Option; + + /// Resolve external JSDoc module links. + /// Returns a tuple with link and title. + fn resolve_external_jsdoc_module( + &self, + module: &str, + symbol: Option<&str>, + ) -> Option<(String, String)>; } #[derive(Debug, Serialize, Clone)] @@ -332,6 +355,22 @@ pub struct BreadcrumbsCtx { impl BreadcrumbsCtx { pub const TEMPLATE: &'static str = "breadcrumbs"; + + pub fn to_strings(&self) -> Vec> { + let mut title_parts = vec![]; + let mut symbol_parts = vec![]; + + for breadcrumb in self.parts.iter() { + if breadcrumb.is_symbol { + symbol_parts.push(breadcrumb.name.as_str()); + } else { + title_parts.push(Cow::Borrowed(breadcrumb.name.as_str())); + } + } + title_parts.push(Cow::Owned(symbol_parts.join("."))); + + title_parts + } } #[derive(Debug, Serialize, Clone, Eq, PartialEq, Hash)] @@ -343,39 +382,32 @@ pub struct DocNodeKindCtx { pub title_plural: &'static str, } -impl From for DocNodeKindCtx { - fn from(kind: DocNodeKindWithDrilldown) -> Self { +impl From for DocNodeKindCtx { + fn from(kind: DocNodeKind) -> Self { let (char, kind, title, title_lowercase, title_plural) = match kind { - DocNodeKindWithDrilldown::Property => { - (' ', "Property", "Property", "property", "Properties") - } - DocNodeKindWithDrilldown::Method => { - (' ', "Method", "Method", "method", "Methods") + DocNodeKind::Property => { + ('p', "Property", "Property", "property", "Properties") } - DocNodeKindWithDrilldown::Other(DocNodeKind::Function) => { + DocNodeKind::Method(_) => ('m', "Method", "Method", "method", "Methods"), + DocNodeKind::Function => { ('f', "Function", "Function", "function", "Functions") } - DocNodeKindWithDrilldown::Other(DocNodeKind::Variable) => { + DocNodeKind::Variable => { ('v', "Variable", "Variable", "variable", "Variables") } - DocNodeKindWithDrilldown::Other(DocNodeKind::Class) => { - ('c', "Class", "Class", "class", "Classes") - } - DocNodeKindWithDrilldown::Other(DocNodeKind::Enum) => { - ('E', "Enum", "Enum", "enum", "Enums") - } - DocNodeKindWithDrilldown::Other(DocNodeKind::Interface) => { + DocNodeKind::Class => ('c', "Class", "Class", "class", "Classes"), + DocNodeKind::Enum => ('E', "Enum", "Enum", "enum", "Enums"), + DocNodeKind::Interface => { ('I', "Interface", "Interface", "interface", "Interfaces") } - DocNodeKindWithDrilldown::Other(DocNodeKind::TypeAlias) => { + DocNodeKind::TypeAlias => { ('T', "TypeAlias", "Type Alias", "type alias", "Type Aliases") } - DocNodeKindWithDrilldown::Other(DocNodeKind::Namespace) => { + DocNodeKind::Namespace => { ('N', "Namespace", "Namespace", "namespace", "Namespaces") } - DocNodeKindWithDrilldown::Other(DocNodeKind::ModuleDoc) - | DocNodeKindWithDrilldown::Other(DocNodeKind::Import) => { - unimplemented!() + DocNodeKind::ModuleDoc | DocNodeKind::Import | DocNodeKind::Reference => { + unreachable!() } }; @@ -405,6 +437,7 @@ pub enum SectionContentCtx { Example(Vec), IndexSignature(Vec), NamespaceSection(Vec), + See(Vec), Empty, } @@ -417,23 +450,26 @@ pub struct SectionHeaderCtx { } impl SectionHeaderCtx { - pub fn new_for_namespace( + pub fn new_for_all_symbols( render_ctx: &RenderContext, path: &ShortPath, - ) -> Self { + ) -> Option { + if render_ctx.ctx.file_mode == FileMode::SingleDts { + return None; + } + let module_doc_nodes = render_ctx.ctx.doc_nodes.get(path).unwrap(); let doc = module_doc_nodes .iter() - .find(|n| n.kind == DocNodeKind::ModuleDoc) + .find(|n| matches!(n.def, DocNodeDef::ModuleDoc)) .and_then(|node| node.js_doc.doc.as_ref()) .and_then(|doc| { markdown_to_html( render_ctx, doc, MarkdownToHTMLOptions { - summary: true, - summary_prefer_title: true, + title_only: true, no_toc: false, }, ) @@ -441,21 +477,23 @@ impl SectionHeaderCtx { let title = path.display_name(); - SectionHeaderCtx { - title: title.clone(), - anchor: AnchorCtx { id: title }, + Some(SectionHeaderCtx { + title: title.to_string(), + anchor: AnchorCtx { + id: title.to_string(), + }, href: Some(render_ctx.ctx.resolve_path( render_ctx.get_current_resolve(), path.as_resolve_kind(), )), doc, - } + }) } } #[derive(Debug, Serialize, Clone)] pub struct SectionCtx { - pub header: SectionHeaderCtx, + pub header: Option, pub content: SectionContentCtx, } @@ -467,11 +505,19 @@ impl SectionCtx { title: &str, mut content: SectionContentCtx, ) -> Self { - let anchor = render_context.toc.add_entry( - 1, - title.to_owned(), - render_context.toc.anchorize(title.to_owned()), - ); + let header = if !title.is_empty() { + let anchor = render_context.toc.anchorize(title); + render_context.toc.add_entry(1, title, &anchor); + + Some(SectionHeaderCtx { + title: title.to_string(), + anchor: AnchorCtx { id: anchor }, + href: None, + doc: None, + }) + } else { + None + }; match &mut content { SectionContentCtx::DocEntry(entries) => { @@ -480,38 +526,44 @@ impl SectionCtx { continue; }; - let anchor = render_context.toc.anchorize(entry.id.to_owned()); + let anchor = render_context.toc.anchorize(&entry.id); + + render_context.toc.add_entry(2, name, &anchor); entry.id = anchor.clone(); - entry.anchor.id = anchor.clone(); + entry.anchor.id = anchor; + } + } + SectionContentCtx::Example(examples) => { + for example in examples { + let anchor = render_context.toc.anchorize(&example.id); + + render_context.toc.add_entry( + 2, + &super::jsdoc::strip(render_context, &example.title), + &anchor, + ); - render_context.toc.add_entry(2, name.clone(), anchor); + example.id = anchor.clone(); + example.anchor.id = anchor; } } - SectionContentCtx::Example(_) => {} SectionContentCtx::IndexSignature(_) => {} SectionContentCtx::NamespaceSection(nodes) => { for node in nodes { - let anchor = render_context.toc.anchorize(node.id.to_owned()); + let anchor = render_context.toc.anchorize(&node.id); - node.id = anchor.clone(); - node.anchor.id = anchor.clone(); + render_context.toc.add_entry(2, &node.name, &anchor); - render_context.toc.add_entry(2, node.name.clone(), anchor); + node.id = anchor.clone(); + node.anchor.id = anchor; } } + SectionContentCtx::See(_) => {} SectionContentCtx::Empty => {} } - Self { - header: SectionHeaderCtx { - title: title.to_string(), - anchor: AnchorCtx { id: anchor }, - href: None, - doc: None, - }, - content, - } + Self { header, content } } } @@ -527,8 +579,8 @@ pub enum Tag { Private, Optional, Unstable, - Permissions(Vec), - Other(String), + Permissions(Box<[Box]>), + Other(Box), } impl Tag { @@ -544,7 +596,7 @@ impl Tag { } } - pub fn from_js_doc(js_doc: &JsDoc) -> HashSet { + pub fn from_js_doc(js_doc: &JsDoc) -> IndexSet { js_doc .tags .iter() @@ -563,7 +615,7 @@ pub struct DocEntryCtx { name_href: Option, content: String, anchor: AnchorCtx, - tags: HashSet, + tags: IndexSet, js_doc: Option, source_href: Option, } @@ -578,7 +630,7 @@ impl DocEntryCtx { name: Option, name_href: Option, content: &str, - tags: HashSet, + tags: IndexSet, jsdoc: Option<&str>, location: &crate::Location, ) -> Self { @@ -640,8 +692,14 @@ impl TopSymbolsCtx { .ctx .doc_nodes .values() - .flat_map(|nodes| super::partition::partition_nodes_by_name(nodes, true)) - .filter(|(_name, node)| !node[0].is_internal()) + .flat_map(|nodes| { + super::partition::partition_nodes_by_name( + ctx.ctx, + nodes.iter().map(Cow::Borrowed), + true, + ) + }) + .filter(|(_name, node)| !node[0].is_internal(ctx.ctx)) .collect::>(); if partitions.is_empty() { @@ -654,10 +712,7 @@ impl TopSymbolsCtx { .into_iter() .take(5) .map(|(name, nodes)| TopSymbolCtx { - kind: nodes - .iter() - .map(|node| node.kind_with_drilldown.into()) - .collect(), + kind: nodes.iter().map(|node| node.kind.into()).collect(), href: ctx.ctx.resolve_path( ctx.get_current_resolve(), UrlResolveKind::Symbol { @@ -683,7 +738,8 @@ impl TopSymbolsCtx { pub struct ToCCtx { pub usages: Option, pub top_symbols: Option, - pub document_navigation: Option, + pub document_navigation_str: Option, + pub document_navigation: Vec, } impl ToCCtx { @@ -700,7 +756,8 @@ impl ToCCtx { return Self { usages: None, top_symbols: None, - document_navigation: None, + document_navigation_str: None, + document_navigation: vec![], }; } @@ -718,7 +775,11 @@ impl ToCCtx { } else { None }, - document_navigation: ctx.toc.render(), + document_navigation_str: ctx.toc.render(), + document_navigation: std::sync::Arc::into_inner(ctx.toc.toc) + .unwrap() + .into_inner() + .unwrap(), } } } diff --git a/src/interface.rs b/src/interface.rs index e8062050..53221b09 100644 --- a/src/interface.rs +++ b/src/interface.rs @@ -1,7 +1,7 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -use deno_ast::ParsedSource; use deno_ast::SourceRangedForSpanned; +use deno_graph::symbols::EsModuleInfo; use serde::Deserialize; use serde::Serialize; @@ -30,7 +30,7 @@ pub struct InterfaceDef { pub properties: Vec, pub call_signatures: Vec, pub index_signatures: Vec, - pub type_params: Vec, + pub type_params: Box<[TsTypeParamDef]>, } pub fn expr_to_name(expr: &deno_ast::swc::ast::Expr) -> String { @@ -75,7 +75,7 @@ pub fn expr_to_name(expr: &deno_ast::swc::ast::Expr) -> String { } pub fn get_doc_for_ts_interface_decl( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, interface_decl: &deno_ast::swc::ast::TsInterfaceDecl, def_name: Option, ) -> (String, InterfaceDef) { @@ -93,12 +93,12 @@ pub fn get_doc_for_ts_interface_decl( match &type_element { TsMethodSignature(ts_method_sig) => { if let Some(method_js_doc) = - js_doc_for_range(parsed_source, &ts_method_sig.range()) + js_doc_for_range(module_info, &ts_method_sig.range()) { let mut params = vec![]; for param in &ts_method_sig.params { - let param_def = ts_fn_param_to_param_def(parsed_source, param); + let param_def = ts_fn_param_to_param_def(module_info, param); params.push(param_def); } @@ -107,10 +107,10 @@ pub fn get_doc_for_ts_interface_decl( let maybe_return_type = ts_method_sig .type_ann .as_deref() - .map(|type_ann| TsTypeDef::new(parsed_source, &type_ann.type_ann)); + .map(|type_ann| TsTypeDef::new(module_info, &type_ann.type_ann)); let type_params = maybe_type_param_decl_to_type_param_defs( - parsed_source, + module_info, ts_method_sig.type_params.as_deref(), ); @@ -118,7 +118,7 @@ pub fn get_doc_for_ts_interface_decl( name, kind: deno_ast::swc::ast::MethodKind::Method, js_doc: method_js_doc, - location: get_location(parsed_source, ts_method_sig.start()), + location: get_location(module_info, ts_method_sig.start()), computed: ts_method_sig.computed, optional: ts_method_sig.optional, params, @@ -130,71 +130,71 @@ pub fn get_doc_for_ts_interface_decl( } TsGetterSignature(ts_getter_sig) => { if let Some(method_js_doc) = - js_doc_for_range(parsed_source, &ts_getter_sig.range()) + js_doc_for_range(module_info, &ts_getter_sig.range()) { let name = expr_to_name(&ts_getter_sig.key); let maybe_return_type = ts_getter_sig .type_ann .as_deref() - .map(|type_ann| TsTypeDef::new(parsed_source, &type_ann.type_ann)); + .map(|type_ann| TsTypeDef::new(module_info, &type_ann.type_ann)); let method_def = MethodDef { name, kind: deno_ast::swc::ast::MethodKind::Getter, js_doc: method_js_doc, - location: get_location(parsed_source, ts_getter_sig.start()), + location: get_location(module_info, ts_getter_sig.start()), computed: ts_getter_sig.computed, optional: false, params: vec![], return_type: maybe_return_type, - type_params: vec![], + type_params: Box::new([]), }; methods.push(method_def); } } TsSetterSignature(ts_setter_sig) => { if let Some(method_js_doc) = - js_doc_for_range(parsed_source, &ts_setter_sig.range()) + js_doc_for_range(module_info, &ts_setter_sig.range()) { let name = expr_to_name(&ts_setter_sig.key); let param_def = - ts_fn_param_to_param_def(parsed_source, &ts_setter_sig.param); + ts_fn_param_to_param_def(module_info, &ts_setter_sig.param); let params = vec![param_def]; let method_def = MethodDef { name, kind: deno_ast::swc::ast::MethodKind::Setter, js_doc: method_js_doc, - location: get_location(parsed_source, ts_setter_sig.start()), + location: get_location(module_info, ts_setter_sig.start()), computed: ts_setter_sig.computed, optional: false, params, return_type: None, - type_params: vec![], + type_params: Box::new([]), }; methods.push(method_def); } } TsPropertySignature(ts_prop_sig) => { if let Some(prop_js_doc) = - js_doc_for_range(parsed_source, &ts_prop_sig.range()) + js_doc_for_range(module_info, &ts_prop_sig.range()) { let name = expr_to_name(&ts_prop_sig.key); let ts_type = ts_prop_sig .type_ann .as_deref() - .map(|type_ann| TsTypeDef::new(parsed_source, &type_ann.type_ann)); + .map(|type_ann| TsTypeDef::new(module_info, &type_ann.type_ann)); let type_params = - maybe_type_param_decl_to_type_param_defs(parsed_source, None); + maybe_type_param_decl_to_type_param_defs(module_info, None); let prop_def = PropertyDef { name, js_doc: prop_js_doc, - location: get_location(parsed_source, ts_prop_sig.start()), + location: get_location(module_info, ts_prop_sig.start()), params: vec![], ts_type, readonly: ts_prop_sig.readonly, @@ -207,27 +207,27 @@ pub fn get_doc_for_ts_interface_decl( } TsCallSignatureDecl(ts_call_sig) => { if let Some(call_sig_js_doc) = - js_doc_for_range(parsed_source, &ts_call_sig.range()) + js_doc_for_range(module_info, &ts_call_sig.range()) { let mut params = vec![]; for param in &ts_call_sig.params { - let param_def = ts_fn_param_to_param_def(parsed_source, param); + let param_def = ts_fn_param_to_param_def(module_info, param); params.push(param_def); } let ts_type = ts_call_sig .type_ann .as_deref() - .map(|type_ann| TsTypeDef::new(parsed_source, &type_ann.type_ann)); + .map(|type_ann| TsTypeDef::new(module_info, &type_ann.type_ann)); let type_params = maybe_type_param_decl_to_type_param_defs( - parsed_source, + module_info, ts_call_sig.type_params.as_deref(), ); let call_sig_def = CallSignatureDef { js_doc: call_sig_js_doc, - location: get_location(parsed_source, ts_call_sig.start()), + location: get_location(module_info, ts_call_sig.start()), params, ts_type, type_params, @@ -237,21 +237,21 @@ pub fn get_doc_for_ts_interface_decl( } TsIndexSignature(ts_index_sig) => { if let Some(js_doc) = - js_doc_for_range(parsed_source, &ts_index_sig.range()) + js_doc_for_range(module_info, &ts_index_sig.range()) { let mut params = vec![]; for param in &ts_index_sig.params { - let param_def = ts_fn_param_to_param_def(parsed_source, param); + let param_def = ts_fn_param_to_param_def(module_info, param); params.push(param_def); } let ts_type = ts_index_sig .type_ann .as_ref() - .map(|rt| TsTypeDef::new(parsed_source, &rt.type_ann)); + .map(|rt| TsTypeDef::new(module_info, &rt.type_ann)); let index_sig_def = IndexSignatureDef { - location: get_location(parsed_source, ts_index_sig.start()), + location: get_location(module_info, ts_index_sig.start()), js_doc, readonly: ts_index_sig.readonly, params, @@ -262,28 +262,28 @@ pub fn get_doc_for_ts_interface_decl( } TsConstructSignatureDecl(ts_construct_sig) => { if let Some(js_doc) = - js_doc_for_range(parsed_source, &ts_construct_sig.range()) + js_doc_for_range(module_info, &ts_construct_sig.range()) { let mut params = vec![]; for param in &ts_construct_sig.params { - let param_def = ts_fn_param_to_param_def(parsed_source, param); + let param_def = ts_fn_param_to_param_def(module_info, param); params.push(param_def); } let type_params = maybe_type_param_decl_to_type_param_defs( - parsed_source, + module_info, ts_construct_sig.type_params.as_deref(), ); let maybe_return_type = ts_construct_sig .type_ann .as_ref() - .map(|rt| TsTypeDef::new(parsed_source, &rt.type_ann)); + .map(|rt| TsTypeDef::new(module_info, &rt.type_ann)); let construct_sig_def = ConstructorDef { js_doc, - location: get_location(parsed_source, ts_construct_sig.start()), + location: get_location(module_info, ts_construct_sig.start()), params, return_type: maybe_return_type, type_params, @@ -296,14 +296,14 @@ pub fn get_doc_for_ts_interface_decl( } let type_params = maybe_type_param_decl_to_type_param_defs( - parsed_source, + module_info, interface_decl.type_params.as_deref(), ); let extends = interface_decl .extends .iter() - .map(|expr| TsTypeDef::ts_expr_with_type_args(parsed_source, expr)) + .map(|expr| TsTypeDef::ts_expr_with_type_args(module_info, expr)) .collect::>(); let interface_def = InterfaceDef { diff --git a/src/js_doc.rs b/src/js_doc.rs index 5ce816b1..135d9d1c 100644 --- a/src/js_doc.rs +++ b/src/js_doc.rs @@ -5,26 +5,36 @@ use serde::Deserialize; use serde::Serialize; lazy_static! { - static ref JS_DOC_TAG_MAYBE_DOC_RE: Regex = Regex::new(r"(?s)^\s*@(deprecated)(?:\s+(.+))?").unwrap(); - static ref JS_DOC_TAG_DOC_RE: Regex = Regex::new(r"(?s)^\s*@(category|see|example|tags|since)(?:\s+(.+))").unwrap(); - static ref JS_DOC_TAG_NAMED_RE: Regex = Regex::new(r"(?s)^\s*@(callback|template|typeparam|typeParam)\s+([a-zA-Z_$]\S*)(?:\s+(.+))?").unwrap(); + static ref JS_DOC_TAG_RE: Regex = Regex::new(r"(?s)^\s*@(\S+)").unwrap(); + /// @tag + static ref JS_DOC_TAG_WITHOUT_VALUE_RE: Regex = Regex::new(r"^\s*@(constructor|class|ignore|internal|public|private|protected|readonly|experimental)").unwrap(); + /// @tag maybe_value + static ref JS_DOC_TAG_WITH_MAYBE_VALUE_RE: Regex = Regex::new(r"(?s)^\s*@(deprecated|module)(?:\s+(.+))?").unwrap(); + /// @tag value + static ref JS_DOC_TAG_WITH_VALUE_RE: Regex = Regex::new(r"(?s)^\s*@(category|group|see|example|tags|since)(?:\s+(.+))").unwrap(); + /// @tag name maybe_value + static ref JS_DOC_TAG_NAMED_WITH_MAYBE_VALUE_RE: Regex = Regex::new(r"(?s)^\s*@(callback|template|typeparam|typeParam)\s+([a-zA-Z_$]\S*)(?:\s+(.+))?").unwrap(); + /// @tag {type} name maybe_value static ref JS_DOC_TAG_NAMED_TYPED_RE: Regex = Regex::new(r"(?s)^\s*@(prop(?:erty)?|typedef)\s+\{([^}]+)\}\s+([a-zA-Z_$]\S*)(?:\s+(.+))?").unwrap(); - static ref JS_DOC_TAG_ONLY_RE: Regex = Regex::new(r"^\s*@(constructor|class|ignore|internal|module|public|private|protected|readonly|experimental)").unwrap(); + /// @tag {type} name maybe_value + /// @tag {type} [name] maybe_value + /// @tag {type} [name=default] maybe_value static ref JS_DOC_TAG_PARAM_RE: Regex = Regex::new( r"(?s)^\s*@(?:param|arg(?:ument)?)(?:\s+\{(?P[^}]+)\})?\s+(?:(?:\[(?P[a-zA-Z_$]\S*?)(?:\s*=\s*(?P[^]]+))?\])|(?P[a-zA-Z_$]\S*))(?:\s+(?P.+))?" ) .unwrap(); - static ref JS_DOC_TAG_RE: Regex = Regex::new(r"(?s)^\s*@(\S+)").unwrap(); - static ref JS_DOC_TAG_OPTIONAL_TYPE_AND_DOC_RE: Regex = Regex::new(r"(?s)^\s*@(returns?|throws|exception)(?:\s+\{([^}]+)\})?(?:\s+(.+))?").unwrap(); - static ref JS_DOC_TAG_TYPED_RE: Regex = Regex::new(r"(?s)^\s*@(enum|extends|augments|this|type|default)\s+\{([^}]+)\}(?:\s+(.+))?").unwrap(); + /// @tag {maybe_type} maybe_value + static ref JS_DOC_TAG_WITH_MAYBE_TYPE_AND_MAYBE_VALUE_RE: Regex = Regex::new(r"(?s)^\s*@(returns?|throws|exception)(?:\s+\{([^}]+)\})?(?:\s+(.+))?").unwrap(); + /// @tag {maybe_type} value + static ref JS_DOC_TAG_WITH_TYPE_AND_MAYBE_VALUE_RE: Regex = Regex::new(r"(?s)^\s*@(enum|extends|augments|this|type|default)\s+\{([^}]+)\}(?:\s+(.+))?").unwrap(); } #[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq)] pub struct JsDoc { #[serde(skip_serializing_if = "Option::is_none", default)] - pub doc: Option, - #[serde(skip_serializing_if = "Vec::is_empty", default)] - pub tags: Vec, + pub doc: Option>, + #[serde(skip_serializing_if = "<[_]>::is_empty", default)] + pub tags: Box<[JsDocTag]>, } impl JsDoc { @@ -33,46 +43,88 @@ impl JsDoc { } } +fn handle_codeblock<'a>( + line: &'a str, + is_codeblock: &mut bool, +) -> Option<&'a str> { + if *is_codeblock && line.starts_with("# ") { + if line.contains("```") { + *is_codeblock = !*is_codeblock; + Some("```") + } else { + None + } + } else { + if line.contains("```") { + *is_codeblock = !*is_codeblock; + } + Some(line) + } +} + impl From for JsDoc { fn from(value: String) -> Self { let mut tags = Vec::new(); - let mut doc_lines = Vec::new(); + let mut doc_lines: Option = None; let mut is_tag = false; - let mut current_tag: Vec<&str> = Vec::new(); + let mut is_codeblock = false; + let mut tag_is_codeblock = false; + let mut current_tag: Option = None; let mut current_tag_name = ""; for line in value.lines() { let caps = JS_DOC_TAG_RE.captures(line); if is_tag || caps.is_some() { if !is_tag { is_tag = true; - assert!(current_tag.is_empty()); + assert!(current_tag.is_none()); } - if caps.is_some() && !current_tag.is_empty() { - tags.push(current_tag.join("\n").into()); - current_tag.clear(); + if caps.is_some() { + tag_is_codeblock = false; + let current_tag = std::mem::take(&mut current_tag); + if let Some(current_tag) = current_tag { + tags.push(current_tag.into()); + } } if let Some(caps) = caps { current_tag_name = caps.get(1).unwrap().as_str(); } - // certain tags, we want to preserve any leading whitespace - if matches!(current_tag_name, "example") { - current_tag.push(line.trim_end()); - } else { - current_tag.push(line.trim()); + if let Some(line) = handle_codeblock(line, &mut tag_is_codeblock) { + let current_tag = if let Some(current_tag) = &mut current_tag { + current_tag.push('\n'); + current_tag + } else { + current_tag = Some(String::new()); + current_tag.as_mut().unwrap() + }; + + // certain tags, we want to preserve any leading whitespace + if matches!(current_tag_name, "example") { + current_tag.push_str(line.trim_end()); + } else { + current_tag.push_str(line.trim()); + } + } + } else if let Some(doc_lines) = &mut doc_lines { + if let Some(line) = handle_codeblock(line, &mut is_codeblock) { + doc_lines.push('\n'); + doc_lines.push_str(line); } } else { - doc_lines.push(line); + doc_lines = Some(String::new()); + doc_lines.as_mut().unwrap().push_str(line); + if line.contains("```") { + is_codeblock = !is_codeblock; + } } } - if !current_tag.is_empty() { - tags.push(current_tag.join("\n").into()); + if let Some(current_tag) = current_tag { + tags.push(current_tag.into()); + } + let doc = doc_lines.map(|doc_lines| doc_lines.into_boxed_str()); + Self { + doc, + tags: tags.into_boxed_slice(), } - let doc = if doc_lines.is_empty() { - None - } else { - Some(doc_lines.join("\n")) - }; - Self { doc, tags } } } @@ -81,68 +133,73 @@ impl From for JsDoc { pub enum JsDocTag { /// `@callback Predicate comment` Callback { - name: String, + name: Box, #[serde(skip_serializing_if = "Option::is_none", default)] - doc: Option, + doc: Option>, }, /// `@category comment` + /// `@group comment` Category { #[serde(default)] - doc: String, + doc: Box, }, /// `@constructor` or `@class` Constructor, /// `@default {value} comment` Default { - value: String, + value: Box, #[serde(skip_serializing_if = "Option::is_none", default)] - doc: Option, + doc: Option>, }, /// `@deprecated comment` Deprecated { #[serde(skip_serializing_if = "Option::is_none", default)] - doc: Option, + doc: Option>, }, /// `@enum {type} comment` Enum { #[serde(rename = "type")] - type_ref: String, + type_ref: Box, #[serde(skip_serializing_if = "Option::is_none", default)] - doc: Option, + doc: Option>, }, /// `@example comment` Example { #[serde(default)] - doc: String, + doc: Box, }, /// `@experimental` Experimental, /// `@extends {type} comment` Extends { #[serde(rename = "type")] - type_ref: String, + type_ref: Box, #[serde(skip_serializing_if = "Option::is_none", default)] - doc: Option, + doc: Option>, }, /// `@ignore` Ignore, /// `@internal` Internal, /// `@module` - Module, + /// `@module name` + Module { + #[serde(skip_serializing_if = "Option::is_none", default)] + name: Option>, + }, /// `@param`, `@arg` or `argument`, in format of `@param {type} name comment` /// or `@param {type} [name=default] comment` /// or `@param {type} [name] comment` Param { - name: String, + name: Box, #[serde(rename = "type", skip_serializing_if = "Option::is_none", default)] - type_ref: Option, + type_ref: Option>, #[serde(skip_serializing_if = "core::ops::Not::not", default)] optional: bool, #[serde(skip_serializing_if = "Option::is_none", default)] - default: Option, + default: Option>, #[serde(skip_serializing_if = "Option::is_none", default)] - doc: Option, + doc: Option>, }, /// `@public` Public, @@ -150,11 +207,11 @@ pub enum JsDocTag { Private, /// `@property {type} name comment` or `@prop {type} name comment` Property { - name: String, + name: Box, #[serde(rename = "type", default)] - type_ref: String, + type_ref: Box, #[serde(skip_serializing_if = "Option::is_none", default)] - doc: Option, + doc: Option>, }, /// `@protected` Protected, @@ -163,94 +220,97 @@ pub enum JsDocTag { /// `@return {type} comment` or `@returns {type} comment` Return { #[serde(rename = "type", skip_serializing_if = "Option::is_none", default)] - type_ref: Option, + type_ref: Option>, #[serde(skip_serializing_if = "Option::is_none", default)] - doc: Option, + doc: Option>, }, /// `@tags allow-read, allow-write` Tags { - tags: Vec, + tags: Box<[Box]>, }, /// `@template T comment` /// `@typeparam T comment` /// `@typeParam T comment` Template { - name: String, + name: Box, #[serde(skip_serializing_if = "Option::is_none", default)] - doc: Option, + doc: Option>, }, /// `@this {type} comment` This { #[serde(rename = "type")] - type_ref: String, + type_ref: Box, #[serde(skip_serializing_if = "Option::is_none", default)] - doc: Option, + doc: Option>, }, /// `@throws {type} comment` or `@exception {type} comment` Throws { #[serde(rename = "type")] - type_ref: Option, + type_ref: Option>, #[serde(skip_serializing_if = "Option::is_none", default)] - doc: Option, + doc: Option>, }, /// `@typedef {type} name comment` TypeDef { - name: String, + name: Box, #[serde(rename = "type")] - type_ref: String, + type_ref: Box, #[serde(skip_serializing_if = "Option::is_none", default)] - doc: Option, + doc: Option>, }, /// `@type {type} comment` #[serde(rename = "type")] TypeRef { #[serde(rename = "type")] - type_ref: String, + type_ref: Box, #[serde(skip_serializing_if = "Option::is_none", default)] - doc: Option, + doc: Option>, }, /// `@see comment` See { - doc: String, + doc: Box, }, /// `@since version` Since { - doc: String, + doc: Box, }, Unsupported { - value: String, + value: Box, }, } impl From for JsDocTag { fn from(value: String) -> Self { - if let Some(caps) = JS_DOC_TAG_ONLY_RE.captures(&value) { + if let Some(caps) = JS_DOC_TAG_WITHOUT_VALUE_RE.captures(&value) { let kind = caps.get(1).unwrap().as_str(); match kind { "constructor" | "class" => Self::Constructor, "experimental" => Self::Experimental, "ignore" => Self::Ignore, "internal" => Self::Internal, - "module" => Self::Module, "public" => Self::Public, "private" => Self::Private, "protected" => Self::Protected, "readonly" => Self::ReadOnly, _ => unreachable!("kind unexpected: {}", kind), } - } else if let Some(caps) = JS_DOC_TAG_NAMED_RE.captures(&value) { + } else if let Some(caps) = + JS_DOC_TAG_NAMED_WITH_MAYBE_VALUE_RE.captures(&value) + { let kind = caps.get(1).unwrap().as_str(); - let name = caps.get(2).unwrap().as_str().to_string(); - let doc = caps.get(3).map(|m| m.as_str().to_string()); + let name = caps.get(2).unwrap().as_str().into(); + let doc = caps.get(3).map(|m| m.as_str().into()); match kind { "callback" => Self::Callback { name, doc }, "template" | "typeparam" | "typeParam" => Self::Template { name, doc }, _ => unreachable!("kind unexpected: {}", kind), } - } else if let Some(caps) = JS_DOC_TAG_TYPED_RE.captures(&value) { + } else if let Some(caps) = + JS_DOC_TAG_WITH_TYPE_AND_MAYBE_VALUE_RE.captures(&value) + { let kind = caps.get(1).unwrap().as_str(); - let type_ref = caps.get(2).unwrap().as_str().to_string(); - let doc = caps.get(3).map(|m| m.as_str().to_string()); + let type_ref = caps.get(2).unwrap().as_str().into(); + let doc = caps.get(3).map(|m| m.as_str().into()); match kind { "enum" => Self::Enum { type_ref, doc }, "extends" | "augments" => Self::Extends { type_ref, doc }, @@ -264,9 +324,9 @@ impl From for JsDocTag { } } else if let Some(caps) = JS_DOC_TAG_NAMED_TYPED_RE.captures(&value) { let kind = caps.get(1).unwrap().as_str(); - let type_ref = caps.get(2).unwrap().as_str().to_string(); - let name = caps.get(3).unwrap().as_str().to_string(); - let doc = caps.get(4).map(|m| m.as_str().to_string()); + let type_ref = caps.get(2).unwrap().as_str().into(); + let name = caps.get(3).unwrap().as_str().into(); + let doc = caps.get(4).map(|m| m.as_str().into()); match kind { "prop" | "property" => Self::Property { name, @@ -280,21 +340,22 @@ impl From for JsDocTag { }, _ => unreachable!("kind unexpected: {}", kind), } - } else if let Some(caps) = JS_DOC_TAG_MAYBE_DOC_RE.captures(&value) { + } else if let Some(caps) = JS_DOC_TAG_WITH_MAYBE_VALUE_RE.captures(&value) { let kind = caps.get(1).unwrap().as_str(); - let doc = caps.get(2).map(|m| m.as_str().to_string()); + let doc = caps.get(2).map(|m| m.as_str().into()); match kind { "deprecated" => Self::Deprecated { doc }, + "module" => Self::Module { name: doc }, _ => unreachable!("kind unexpected: {}", kind), } - } else if let Some(caps) = JS_DOC_TAG_DOC_RE.captures(&value) { + } else if let Some(caps) = JS_DOC_TAG_WITH_VALUE_RE.captures(&value) { let kind = caps.get(1).unwrap().as_str(); - let doc = caps.get(2).unwrap().as_str().to_string(); + let doc = caps.get(2).unwrap().as_str().into(); match kind { - "category" => Self::Category { doc }, + "category" | "group" => Self::Category { doc }, "example" => Self::Example { doc }, "tags" => Self::Tags { - tags: doc.split(',').map(|i| i.trim().to_string()).collect(), + tags: doc.split(',').map(|i| i.trim().into()).collect(), }, "see" => Self::See { doc }, "since" => Self::Since { doc }, @@ -307,10 +368,10 @@ impl From for JsDocTag { .or(name_with_maybe_default) .unwrap() .as_str() - .to_string(); - let type_ref = caps.name("type").map(|m| m.as_str().to_string()); - let default = caps.name("default").map(|m| m.as_str().to_string()); - let doc = caps.name("doc").map(|m| m.as_str().to_string()); + .into(); + let type_ref = caps.name("type").map(|m| m.as_str().into()); + let default = caps.name("default").map(|m| m.as_str().into()); + let doc = caps.name("doc").map(|m| m.as_str().into()); Self::Param { name, type_ref, @@ -319,18 +380,20 @@ impl From for JsDocTag { doc, } } else if let Some(caps) = - JS_DOC_TAG_OPTIONAL_TYPE_AND_DOC_RE.captures(&value) + JS_DOC_TAG_WITH_MAYBE_TYPE_AND_MAYBE_VALUE_RE.captures(&value) { let kind = caps.get(1).unwrap().as_str(); - let type_ref = caps.get(2).map(|m| m.as_str().to_string()); - let doc = caps.get(3).map(|m| m.as_str().to_string()); + let type_ref = caps.get(2).map(|m| m.as_str().into()); + let doc = caps.get(3).map(|m| m.as_str().into()); match kind { "return" | "returns" => Self::Return { type_ref, doc }, "throws" | "exception" => Self::Throws { type_ref, doc }, _ => unreachable!("kind unexpected: {}", kind), } } else { - Self::Unsupported { value } + Self::Unsupported { + value: value.into(), + } } } } @@ -359,10 +422,6 @@ mod tests { serde_json::to_value(JsDoc::from("@ignore more".to_string())).unwrap(), json!({ "tags": [ { "kind": "ignore" } ] }), ); - assert_eq!( - serde_json::to_value(JsDoc::from("@module more".to_string())).unwrap(), - json!({ "tags": [ { "kind": "module" } ] }), - ); assert_eq!( serde_json::to_value(JsDoc::from("@public more".to_string())).unwrap(), json!({ "tags": [ { "kind": "public" } ] }), @@ -610,6 +669,26 @@ if (true) { }] }) ); + assert_eq!( + serde_json::to_value(JsDoc::from("@module".to_string())).unwrap(), + json!({ + "tags": [{ + "kind": "module", + }] + }) + ); + assert_eq!( + serde_json::to_value(JsDoc::from( + "@module maybe doc\n\nnew paragraph".to_string() + )) + .unwrap(), + json!({ + "tags": [{ + "kind": "module", + "name": "maybe doc\n\nnew paragraph", + }] + }) + ); } #[test] @@ -626,6 +705,18 @@ if (true) { }] }) ); + assert_eq!( + serde_json::to_value(JsDoc::from( + "@group Functional Components".to_string() + )) + .unwrap(), + json!({ + "tags": [{ + "kind": "category", + "doc": "Functional Components", + }] + }) + ); assert_eq!( serde_json::to_value(JsDoc::from( "@example\n\nconst a = \"a\";\n".to_string() @@ -928,7 +1019,7 @@ multi-line fn test_js_doc_tag_serialization() { assert_eq!( serde_json::to_value(JsDocTag::Callback { - name: "Predicate".to_string(), + name: "Predicate".into(), doc: None, }) .unwrap(), @@ -945,7 +1036,7 @@ multi-line ); assert_eq!( serde_json::to_value(JsDocTag::Default { - value: "true".to_string(), + value: "true".into(), doc: None, }) .unwrap(), @@ -956,7 +1047,7 @@ multi-line ); assert_eq!( serde_json::to_value(JsDocTag::Deprecated { - doc: Some("comment".to_string()), + doc: Some("comment".into()), }) .unwrap(), json!({ @@ -966,7 +1057,7 @@ multi-line ); assert_eq!( serde_json::to_value(JsDocTag::Enum { - type_ref: "number".to_string(), + type_ref: "number".into(), doc: None, }) .unwrap(), @@ -977,7 +1068,7 @@ multi-line ); assert_eq!( serde_json::to_value(JsDocTag::Extends { - type_ref: "OtherType".to_string(), + type_ref: "OtherType".into(), doc: None, }) .unwrap(), @@ -988,11 +1079,11 @@ multi-line ); assert_eq!( serde_json::to_value(JsDocTag::Param { - name: "arg".to_string(), - type_ref: Some("number".to_string()), + name: "arg".into(), + type_ref: Some("number".into()), optional: false, - default: Some("1".to_string()), - doc: Some("comment".to_string()), + default: Some("1".into()), + doc: Some("comment".into()), }) .unwrap(), json!({ @@ -1005,11 +1096,11 @@ multi-line ); assert_eq!( serde_json::to_value(JsDocTag::Param { - name: "arg".to_string(), + name: "arg".into(), type_ref: None, optional: false, default: None, - doc: Some("comment".to_string()), + doc: Some("comment".into()), }) .unwrap(), json!({ @@ -1028,8 +1119,8 @@ multi-line ); assert_eq!( serde_json::to_value(JsDocTag::Property { - name: "prop".to_string(), - type_ref: "string".to_string(), + name: "prop".into(), + type_ref: "string".into(), doc: None, }) .unwrap(), @@ -1049,8 +1140,8 @@ multi-line ); assert_eq!( serde_json::to_value(JsDocTag::Return { - type_ref: Some("string".to_string()), - doc: Some("comment".to_string()), + type_ref: Some("string".into()), + doc: Some("comment".into()), }) .unwrap(), json!({ @@ -1061,7 +1152,7 @@ multi-line ); assert_eq!( serde_json::to_value(JsDocTag::Template { - name: "T".to_string(), + name: "T".into(), doc: None, }) .unwrap(), @@ -1072,7 +1163,7 @@ multi-line ); assert_eq!( serde_json::to_value(JsDocTag::This { - type_ref: "Record".to_string(), + type_ref: "Record".into(), doc: None, }) .unwrap(), @@ -1083,8 +1174,8 @@ multi-line ); assert_eq!( serde_json::to_value(JsDocTag::TypeDef { - name: "Interface".to_string(), - type_ref: "object".to_string(), + name: "Interface".into(), + type_ref: "object".into(), doc: None, }) .unwrap(), @@ -1096,7 +1187,7 @@ multi-line ); assert_eq!( serde_json::to_value(JsDocTag::TypeRef { - type_ref: "Map".to_string(), + type_ref: "Map".into(), doc: None, }) .unwrap(), @@ -1107,7 +1198,7 @@ multi-line ); assert_eq!( serde_json::to_value(JsDocTag::Unsupported { - value: "unsupported".to_string() + value: "unsupported".into() }) .unwrap(), json!({ diff --git a/src/lib.rs b/src/lib.rs index d735fe75..67f5e586 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,30 +15,29 @@ extern crate lazy_static; extern crate serde_json; pub mod class; -mod colors; mod decorators; mod diagnostics; mod display; pub mod r#enum; pub mod function; +pub mod html; pub mod interface; pub mod js_doc; pub mod node; mod params; mod parser; -mod ts_type; -mod ts_type_param; +pub mod ts_type; +pub mod ts_type_param; pub mod type_alias; mod util; pub mod variable; mod visibility; pub use node::DocNode; -pub use node::DocNodeKind; +pub use node::DocNodeDef; pub use node::Location; use node::ImportDef; -use node::ReexportKind; use params::ParamDef; cfg_if! { @@ -54,19 +53,13 @@ pub use parser::DocError; pub use parser::DocParser; pub use parser::DocParserOptions; -cfg_if! { - if #[cfg(feature = "html")] { - pub mod html; - } -} - #[cfg(test)] mod tests; #[cfg(feature = "rust")] pub fn find_nodes_by_name_recursively( doc_nodes: Vec, - name: String, + name: &str, ) -> Vec { let mut parts = name.splitn(2, '.'); let name = parts.next(); @@ -76,17 +69,14 @@ pub fn find_nodes_by_name_recursively( } let name = name.unwrap(); - let doc_nodes = find_nodes_by_name(doc_nodes, name.to_string()); + let doc_nodes = find_nodes_by_name(doc_nodes, name); let mut found: Vec = vec![]; match leftover { Some(leftover) => { for node in doc_nodes { let children = get_children_of_node(node); - found.extend(find_nodes_by_name_recursively( - children, - leftover.to_string(), - )); + found.extend(find_nodes_by_name_recursively(children, leftover)); } found } @@ -95,10 +85,10 @@ pub fn find_nodes_by_name_recursively( } #[cfg(feature = "rust")] -fn find_nodes_by_name(doc_nodes: Vec, name: String) -> Vec { +fn find_nodes_by_name(doc_nodes: Vec, name: &str) -> Vec { let mut found: Vec = vec![]; for node in doc_nodes { - if node.name == name { + if &*node.name == name { found.push(node); } } @@ -107,17 +97,15 @@ fn find_nodes_by_name(doc_nodes: Vec, name: String) -> Vec { #[cfg(feature = "rust")] fn get_children_of_node(node: DocNode) -> Vec { - match node.kind { - DocNodeKind::Namespace => { - let namespace_def = node.namespace_def.unwrap(); - namespace_def - .elements - .into_iter() - .map(std::sync::Arc::unwrap_or_clone) - .collect() - } - DocNodeKind::Interface => { - let interface_def = node.interface_def.unwrap(); + use node::DocNodeDef; + + match node.def { + DocNodeDef::Namespace { namespace_def } => namespace_def + .elements + .into_iter() + .map(std::sync::Arc::unwrap_or_clone) + .collect(), + DocNodeDef::Interface { interface_def } => { let mut doc_nodes: Vec = vec![]; for method in interface_def.methods { doc_nodes.push(method.into()); @@ -127,13 +115,12 @@ fn get_children_of_node(node: DocNode) -> Vec { } doc_nodes } - DocNodeKind::Class => { - let class_def = node.class_def.unwrap(); + DocNodeDef::Class { class_def } => { let mut doc_nodes: Vec = vec![]; - for method in class_def.methods { + for method in class_def.methods.into_vec().into_iter() { doc_nodes.push(method.into()); } - for property in class_def.properties { + for property in class_def.properties.into_vec().into_iter() { doc_nodes.push(property.into()); } doc_nodes diff --git a/src/node.rs b/src/node.rs index be44bb93..bbba2c61 100644 --- a/src/node.rs +++ b/src/node.rs @@ -1,11 +1,10 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +use crate::js_doc::JsDoc; use serde::Deserialize; use serde::Serialize; use std::sync::Arc; -use crate::js_doc::JsDoc; - #[derive(Debug, Serialize, Deserialize, Clone)] pub struct NamespaceDef { pub elements: Vec>, @@ -34,6 +33,7 @@ pub enum DocNodeKind { Interface, ModuleDoc, Namespace, + Reference, TypeAlias, Variable, } @@ -43,7 +43,7 @@ pub enum DocNodeKind { )] #[serde(rename_all = "camelCase")] pub struct Location { - pub filename: String, + pub filename: Box, /// The 1-indexed display line. /// todo(#150): why is one of these 0-indexed and the other 1-indexed? pub line: usize, @@ -74,36 +74,15 @@ impl PartialOrd for Location { #[derive(Debug, Serialize, Deserialize, Clone)] #[serde(rename_all = "camelCase")] -pub enum ReexportKind { - /// export * from "./path/to/module.js"; - All, - /// export * as someNamespace from "./path/to/module.js"; - Namespace(String), - /// (identifier, optional alias) - /// export { foo } from "./path/to/module.js"; - /// export { foo as bar } from "./path/to/module.js"; - Named(String, Option), -} - -#[derive(Debug, Serialize, Deserialize, Clone)] -#[serde(rename_all = "camelCase")] -pub struct Reexport { - pub kind: ReexportKind, +pub struct ImportDef { pub src: String, + pub imported: Option, } #[derive(Debug, Serialize, Deserialize, Clone)] #[serde(rename_all = "camelCase")] -pub struct ModuleDoc { - pub definitions: Vec, - pub reexports: Vec, -} - -#[derive(Debug, Serialize, Deserialize, Clone)] -#[serde(rename_all = "camelCase")] -pub struct ImportDef { - pub src: String, - pub imported: Option, +pub struct ReferenceDef { + pub target: Location, } #[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq)] @@ -117,57 +96,67 @@ pub enum DeclarationKind { #[derive(Debug, Serialize, Deserialize, Clone)] #[serde(rename_all = "camelCase")] pub struct DocNode { - pub kind: DocNodeKind, - pub name: String, + pub name: Box, #[serde(skip_serializing_if = "Option::is_none", default)] pub is_default: Option, pub location: Location, pub declaration_kind: DeclarationKind, #[serde(skip_serializing_if = "JsDoc::is_empty", default)] pub js_doc: JsDoc, + #[serde(flatten)] + pub def: DocNodeDef, +} - #[serde(skip_serializing_if = "Option::is_none", default)] - pub function_def: Option, - - #[serde(skip_serializing_if = "Option::is_none", default)] - pub variable_def: Option, - - #[serde(skip_serializing_if = "Option::is_none", default)] - pub enum_def: Option, - - #[serde(skip_serializing_if = "Option::is_none", default)] - pub class_def: Option, - - #[serde(skip_serializing_if = "Option::is_none", default)] - pub type_alias_def: Option, - - #[serde(skip_serializing_if = "Option::is_none", default)] - pub namespace_def: Option, - - #[serde(skip_serializing_if = "Option::is_none", default)] - pub interface_def: Option, - - #[serde(skip_serializing_if = "Option::is_none", default)] - pub import_def: Option, +#[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(tag = "kind", rename_all = "camelCase")] +pub enum DocNodeDef { + #[serde(rename_all = "camelCase")] + Function { + function_def: super::function::FunctionDef, + }, + #[serde(rename_all = "camelCase")] + Variable { + variable_def: super::variable::VariableDef, + }, + #[serde(rename_all = "camelCase")] + Enum { + enum_def: super::r#enum::EnumDef, + }, + #[serde(rename_all = "camelCase")] + Class { + class_def: super::class::ClassDef, + }, + #[serde(rename_all = "camelCase")] + TypeAlias { + type_alias_def: super::type_alias::TypeAliasDef, + }, + #[serde(rename_all = "camelCase")] + Namespace { + namespace_def: NamespaceDef, + }, + #[serde(rename_all = "camelCase")] + Interface { + interface_def: super::interface::InterfaceDef, + }, + #[serde(rename_all = "camelCase")] + Import { + import_def: ImportDef, + }, + ModuleDoc, + Reference { + reference_def: ReferenceDef, + }, } impl Default for DocNode { fn default() -> Self { Self { - kind: DocNodeKind::ModuleDoc, is_default: None, - name: "".to_string(), + name: "".into(), declaration_kind: DeclarationKind::Private, location: Location::default(), js_doc: JsDoc::default(), - function_def: None, - variable_def: None, - enum_def: None, - class_def: None, - type_alias_def: None, - namespace_def: None, - interface_def: None, - import_def: None, + def: DocNodeDef::ModuleDoc, } } } @@ -175,17 +164,17 @@ impl Default for DocNode { impl DocNode { pub fn module_doc(location: Location, js_doc: JsDoc) -> Self { Self { - kind: DocNodeKind::ModuleDoc, - name: "".to_string(), + name: "".into(), + is_default: None, location, declaration_kind: DeclarationKind::Export, js_doc, - ..Default::default() + def: DocNodeDef::ModuleDoc, } } pub fn function( - name: String, + name: Box, is_default: bool, location: Location, declaration_kind: DeclarationKind, @@ -193,19 +182,19 @@ impl DocNode { fn_def: super::function::FunctionDef, ) -> Self { Self { - kind: DocNodeKind::Function, name, is_default: Some(is_default), location, declaration_kind, js_doc, - function_def: Some(fn_def), - ..Default::default() + def: DocNodeDef::Function { + function_def: fn_def, + }, } } pub fn variable( - name: String, + name: Box, is_default: bool, location: Location, declaration_kind: DeclarationKind, @@ -213,19 +202,19 @@ impl DocNode { var_def: super::variable::VariableDef, ) -> Self { Self { - kind: DocNodeKind::Variable, name, is_default: Some(is_default), declaration_kind, location, js_doc, - variable_def: Some(var_def), - ..Default::default() + def: DocNodeDef::Variable { + variable_def: var_def, + }, } } pub fn r#enum( - name: String, + name: Box, is_default: bool, location: Location, declaration_kind: DeclarationKind, @@ -233,19 +222,17 @@ impl DocNode { enum_def: super::r#enum::EnumDef, ) -> Self { Self { - kind: DocNodeKind::Enum, name, is_default: Some(is_default), declaration_kind, location, js_doc, - enum_def: Some(enum_def), - ..Default::default() + def: DocNodeDef::Enum { enum_def }, } } pub fn class( - name: String, + name: Box, is_default: bool, location: Location, declaration_kind: DeclarationKind, @@ -253,19 +240,17 @@ impl DocNode { class_def: super::class::ClassDef, ) -> Self { Self { - kind: DocNodeKind::Class, name, is_default: Some(is_default), declaration_kind, location, js_doc, - class_def: Some(class_def), - ..Default::default() + def: DocNodeDef::Class { class_def }, } } pub fn type_alias( - name: String, + name: Box, is_default: bool, location: Location, declaration_kind: DeclarationKind, @@ -273,19 +258,17 @@ impl DocNode { type_alias_def: super::type_alias::TypeAliasDef, ) -> Self { Self { - kind: DocNodeKind::TypeAlias, name, is_default: Some(is_default), declaration_kind, location, js_doc, - type_alias_def: Some(type_alias_def), - ..Default::default() + def: DocNodeDef::TypeAlias { type_alias_def }, } } pub fn namespace( - name: String, + name: Box, is_default: bool, location: Location, declaration_kind: DeclarationKind, @@ -293,19 +276,17 @@ impl DocNode { namespace_def: NamespaceDef, ) -> Self { Self { - kind: DocNodeKind::Namespace, name, is_default: Some(is_default), declaration_kind, location, js_doc, - namespace_def: Some(namespace_def), - ..Default::default() + def: DocNodeDef::Namespace { namespace_def }, } } pub fn interface( - name: String, + name: Box, is_default: bool, location: Location, declaration_kind: DeclarationKind, @@ -313,51 +294,126 @@ impl DocNode { interface_def: super::interface::InterfaceDef, ) -> Self { Self { - kind: DocNodeKind::Interface, name, is_default: Some(is_default), declaration_kind, location, js_doc, - interface_def: Some(interface_def), - ..Default::default() + def: DocNodeDef::Interface { interface_def }, } } pub fn import( - name: String, + name: Box, location: Location, js_doc: JsDoc, import_def: ImportDef, ) -> Self { Self { - kind: DocNodeKind::Import, name, + is_default: None, declaration_kind: DeclarationKind::Private, location, js_doc, - import_def: Some(import_def), - ..Default::default() + def: DocNodeDef::Import { import_def }, + } + } + + pub fn reference( + name: Box, + location: Location, + js_doc: JsDoc, + reference_def: ReferenceDef, + ) -> Self { + Self { + name, + is_default: None, + declaration_kind: DeclarationKind::Private, + location, + js_doc, + def: DocNodeDef::Reference { reference_def }, } } pub fn get_name(&self) -> &str { - let default_name = match self.kind { - DocNodeKind::Class => self.class_def.as_ref().unwrap().def_name.as_ref(), - DocNodeKind::Function => { - self.function_def.as_ref().unwrap().def_name.as_ref() + let default_name = match &self.def { + DocNodeDef::Class { class_def } => class_def.def_name.as_deref(), + DocNodeDef::Function { function_def } => function_def.def_name.as_deref(), + DocNodeDef::Interface { interface_def } => { + interface_def.def_name.as_deref() } - DocNodeKind::Interface => { - self.interface_def.as_ref().unwrap().def_name.as_ref() - } - DocNodeKind::Enum - | DocNodeKind::Import - | DocNodeKind::ModuleDoc - | DocNodeKind::Namespace - | DocNodeKind::TypeAlias - | DocNodeKind::Variable => None, + DocNodeDef::Enum { .. } + | DocNodeDef::Import { .. } + | DocNodeDef::ModuleDoc { .. } + | DocNodeDef::Namespace { .. } + | DocNodeDef::TypeAlias { .. } + | DocNodeDef::Variable { .. } + | DocNodeDef::Reference { .. } => None, }; default_name.unwrap_or(&self.name) } + + pub fn class_def(&self) -> Option<&super::class::ClassDef> { + match &self.def { + DocNodeDef::Class { class_def } => Some(class_def), + _ => None, + } + } + + pub fn function_def(&self) -> Option<&super::function::FunctionDef> { + match &self.def { + DocNodeDef::Function { function_def } => Some(function_def), + _ => None, + } + } + + pub fn variable_def(&self) -> Option<&super::variable::VariableDef> { + match &self.def { + DocNodeDef::Variable { variable_def } => Some(variable_def), + _ => None, + } + } + + pub fn enum_def(&self) -> Option<&super::r#enum::EnumDef> { + match &self.def { + DocNodeDef::Enum { enum_def } => Some(enum_def), + _ => None, + } + } + + pub fn type_alias_def(&self) -> Option<&super::type_alias::TypeAliasDef> { + match &self.def { + DocNodeDef::TypeAlias { type_alias_def } => Some(type_alias_def), + _ => None, + } + } + + pub fn namespace_def(&self) -> Option<&NamespaceDef> { + match &self.def { + DocNodeDef::Namespace { namespace_def } => Some(namespace_def), + _ => None, + } + } + + pub fn interface_def(&self) -> Option<&super::interface::InterfaceDef> { + match &self.def { + DocNodeDef::Interface { interface_def } => Some(interface_def), + _ => None, + } + } + + pub fn import_def(&self) -> Option<&ImportDef> { + match &self.def { + DocNodeDef::Import { import_def } => Some(import_def), + _ => None, + } + } + + pub fn reference_def(&self) -> Option<&ReferenceDef> { + match &self.def { + DocNodeDef::Reference { reference_def } => Some(reference_def), + _ => None, + } + } } diff --git a/src/params.rs b/src/params.rs index 2e84889e..e59c38a3 100644 --- a/src/params.rs +++ b/src/params.rs @@ -9,8 +9,8 @@ use crate::ts_type::TsTypeDef; use deno_ast::swc::ast::ObjectPatProp; use deno_ast::swc::ast::Pat; use deno_ast::swc::ast::TsFnParam; -use deno_ast::ParsedSource; use deno_ast::SourceRangedForSpanned; +use deno_graph::symbols::EsModuleInfo; use serde::Deserialize; use serde::Serialize; use std::fmt::Display; @@ -47,14 +47,14 @@ pub enum ParamPatternDef { pub struct ParamDef { #[serde(flatten)] pub pattern: ParamPatternDef, - #[serde(skip_serializing_if = "Vec::is_empty", default)] - pub decorators: Vec, + #[serde(skip_serializing_if = "<[_]>::is_empty", default)] + pub decorators: Box<[DecoratorDef]>, pub ts_type: Option, } impl Display for ParamDef { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { - for decorator in &self.decorators { + for decorator in self.decorators.iter() { write!(f, "{} ", decorator)?; } match &self.pattern { @@ -143,44 +143,44 @@ impl Display for ObjectPatPropDef { } pub fn ident_to_param_def( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, ident: &deno_ast::swc::ast::BindingIdent, ) -> ParamDef { let ts_type = ident .type_ann .as_deref() - .map(|type_ann| TsTypeDef::new(parsed_source, &type_ann.type_ann)); + .map(|type_ann| TsTypeDef::new(module_info, &type_ann.type_ann)); ParamDef { pattern: ParamPatternDef::Identifier { name: ident.id.sym.to_string(), optional: ident.id.optional, }, - decorators: Vec::new(), + decorators: Box::new([]), ts_type, } } fn rest_pat_to_param_def( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, rest_pat: &deno_ast::swc::ast::RestPat, ) -> ParamDef { let ts_type = rest_pat .type_ann .as_deref() - .map(|type_ann| TsTypeDef::new(parsed_source, &type_ann.type_ann)); + .map(|type_ann| TsTypeDef::new(module_info, &type_ann.type_ann)); ParamDef { pattern: ParamPatternDef::Rest { - arg: Box::new(pat_to_param_def(parsed_source, &rest_pat.arg)), + arg: Box::new(pat_to_param_def(module_info, &rest_pat.arg)), }, - decorators: Vec::new(), + decorators: Box::new([]), ts_type, } } fn object_pat_prop_to_def( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, object_pat_prop: &ObjectPatProp, ) -> ObjectPatPropDef { match object_pat_prop { @@ -189,72 +189,72 @@ fn object_pat_prop_to_def( value: assign.value.as_ref().map(|_| "[UNSUPPORTED]".to_string()), }, ObjectPatProp::KeyValue(keyvalue) => ObjectPatPropDef::KeyValue { - key: prop_name_to_string(parsed_source, &keyvalue.key), - value: Box::new(pat_to_param_def(parsed_source, &keyvalue.value)), + key: prop_name_to_string(module_info, &keyvalue.key), + value: Box::new(pat_to_param_def(module_info, &keyvalue.value)), }, ObjectPatProp::Rest(rest) => ObjectPatPropDef::Rest { - arg: Box::new(pat_to_param_def(parsed_source, &rest.arg)), + arg: Box::new(pat_to_param_def(module_info, &rest.arg)), }, } } fn object_pat_to_param_def( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, object_pat: &deno_ast::swc::ast::ObjectPat, ) -> ParamDef { let props = object_pat .props .iter() - .map(|prop| object_pat_prop_to_def(parsed_source, prop)) + .map(|prop| object_pat_prop_to_def(module_info, prop)) .collect::>(); let ts_type = object_pat .type_ann .as_deref() - .map(|type_ann| TsTypeDef::new(parsed_source, &type_ann.type_ann)); + .map(|type_ann| TsTypeDef::new(module_info, &type_ann.type_ann)); ParamDef { pattern: ParamPatternDef::Object { props, optional: object_pat.optional, }, - decorators: Vec::new(), + decorators: Box::new([]), ts_type, } } fn array_pat_to_param_def( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, array_pat: &deno_ast::swc::ast::ArrayPat, ) -> ParamDef { let elements = array_pat .elems .iter() - .map(|elem| elem.as_ref().map(|e| pat_to_param_def(parsed_source, e))) + .map(|elem| elem.as_ref().map(|e| pat_to_param_def(module_info, e))) .collect::>>(); let ts_type = array_pat .type_ann .as_deref() - .map(|type_ann| TsTypeDef::new(parsed_source, &type_ann.type_ann)); + .map(|type_ann| TsTypeDef::new(module_info, &type_ann.type_ann)); ParamDef { pattern: ParamPatternDef::Array { elements, optional: array_pat.optional, }, - decorators: Vec::new(), + decorators: Box::new([]), ts_type, } } pub fn assign_pat_to_param_def( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, assign_pat: &deno_ast::swc::ast::AssignPat, ) -> ParamDef { - let mut left = pat_to_param_def(parsed_source, &assign_pat.left); + let mut left = pat_to_param_def(module_info, &assign_pat.left); if left.ts_type.is_none() { left.ts_type = crate::ts_type::infer_ts_type_from_expr( - parsed_source, + module_info, &assign_pat.right, false, ); @@ -265,56 +265,52 @@ pub fn assign_pat_to_param_def( left: Box::new(left), right: crate::interface::expr_to_name(&assign_pat.right), }, - decorators: Vec::new(), + decorators: Box::new([]), ts_type: None, } } pub fn param_to_param_def( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, param: &deno_ast::swc::ast::Param, ) -> ParamDef { - let mut def = pat_to_param_def(parsed_source, ¶m.pat); - def.decorators = decorators_to_defs(parsed_source, ¶m.decorators); + let mut def = pat_to_param_def(module_info, ¶m.pat); + def.decorators = decorators_to_defs(module_info, ¶m.decorators); def } pub fn pat_to_param_def( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, pat: &deno_ast::swc::ast::Pat, ) -> ParamDef { match pat { - Pat::Ident(ident) => ident_to_param_def(parsed_source, ident), - Pat::Array(array_pat) => array_pat_to_param_def(parsed_source, array_pat), - Pat::Rest(rest_pat) => rest_pat_to_param_def(parsed_source, rest_pat), - Pat::Object(object_pat) => { - object_pat_to_param_def(parsed_source, object_pat) - } - Pat::Assign(assign_pat) => { - assign_pat_to_param_def(parsed_source, assign_pat) - } + Pat::Ident(ident) => ident_to_param_def(module_info, ident), + Pat::Array(array_pat) => array_pat_to_param_def(module_info, array_pat), + Pat::Rest(rest_pat) => rest_pat_to_param_def(module_info, rest_pat), + Pat::Object(object_pat) => object_pat_to_param_def(module_info, object_pat), + Pat::Assign(assign_pat) => assign_pat_to_param_def(module_info, assign_pat), _ => unreachable!(), } } pub fn ts_fn_param_to_param_def( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, ts_fn_param: &deno_ast::swc::ast::TsFnParam, ) -> ParamDef { match ts_fn_param { - TsFnParam::Ident(ident) => ident_to_param_def(parsed_source, ident), + TsFnParam::Ident(ident) => ident_to_param_def(module_info, ident), TsFnParam::Array(array_pat) => { - array_pat_to_param_def(parsed_source, array_pat) + array_pat_to_param_def(module_info, array_pat) } - TsFnParam::Rest(rest_pat) => rest_pat_to_param_def(parsed_source, rest_pat), + TsFnParam::Rest(rest_pat) => rest_pat_to_param_def(module_info, rest_pat), TsFnParam::Object(object_pat) => { - object_pat_to_param_def(parsed_source, object_pat) + object_pat_to_param_def(module_info, object_pat) } } } pub fn prop_name_to_string( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, prop_name: &deno_ast::swc::ast::PropName, ) -> String { use deno_ast::swc::ast::PropName; @@ -324,7 +320,7 @@ pub fn prop_name_to_string( PropName::Num(num) => num.value.to_string(), PropName::BigInt(num) => num.value.to_string(), PropName::Computed(comp_prop_name) => comp_prop_name - .text_fast(parsed_source.text_info_lazy()) + .text_fast(module_info.source().text_info_lazy()) .to_string(), } } diff --git a/src/parser.rs b/src/parser.rs index d27485c7..63c5911e 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,44 +1,14 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -use crate::diagnostics::DiagnosticsCollector; -use crate::diagnostics::DocDiagnostic; -use crate::js_doc::JsDoc; -use crate::node; -use crate::node::DeclarationKind; -use crate::node::DocNode; -use crate::node::ModuleDoc; -use crate::node::NamespaceDef; -use crate::ts_type::infer_simple_ts_type_from_init; -use crate::ts_type::PropertyDef; -use crate::ts_type::TsTypeDef; -use crate::ts_type::TsTypeDefKind; -use crate::ts_type::TsTypeLiteralDef; -use crate::util::graph::resolve_deno_graph_module; -use crate::util::swc::get_location; -use crate::util::swc::get_text_info_location; -use crate::util::swc::js_doc_for_range; -use crate::util::swc::module_export_name_value; -use crate::util::swc::module_js_doc_for_source; -use crate::util::symbol::get_module_info; -use crate::variable::VariableDef; -use crate::visibility::SymbolVisibility; -use crate::DocNodeKind; -use crate::ImportDef; -use crate::Location; -use crate::ReexportKind; - use deno_ast::swc::ast::ClassDecl; use deno_ast::swc::ast::Decl; use deno_ast::swc::ast::DefaultDecl; use deno_ast::swc::ast::ExportDecl; use deno_ast::swc::ast::ExportDefaultDecl; use deno_ast::swc::ast::ExportDefaultExpr; -use deno_ast::swc::ast::ExportSpecifier; use deno_ast::swc::ast::FnDecl; use deno_ast::swc::ast::Ident; -use deno_ast::swc::ast::ImportSpecifier; use deno_ast::swc::ast::ModuleDecl; -use deno_ast::swc::ast::ModuleItem; use deno_ast::swc::ast::TsEnumDecl; use deno_ast::swc::ast::TsInterfaceDecl; use deno_ast::swc::ast::TsModuleDecl; @@ -47,7 +17,7 @@ use deno_ast::swc::ast::TsTypeAliasDecl; use deno_ast::swc::ast::VarDecl; use deno_ast::swc::ast::VarDeclKind; use deno_ast::swc::ast::VarDeclarator; -use deno_ast::ParsedSource; +use deno_ast::ModuleItemRef; use deno_ast::SourceRange; use deno_ast::SourceRanged; use deno_ast::SourceRangedForSpanned; @@ -56,22 +26,47 @@ use deno_graph::symbols::ExpandoPropertyRef; use deno_graph::symbols::ExportDeclRef; use deno_graph::symbols::ModuleInfoRef; use deno_graph::symbols::Symbol; +use deno_graph::symbols::SymbolDecl; use deno_graph::symbols::SymbolNodeRef; use deno_graph::symbols::UniqueSymbolId; +use deno_graph::EsParser; use deno_graph::Module; use deno_graph::ModuleGraph; -use deno_graph::ModuleParser; use deno_graph::ModuleSpecifier; - +use indexmap::IndexMap; use std::borrow::Cow; use std::cell::RefCell; -use std::collections::HashMap; use std::collections::HashSet; use std::error::Error; use std::fmt; use std::rc::Rc; use std::sync::Arc; +use crate::diagnostics::DiagnosticsCollector; +use crate::diagnostics::DocDiagnostic; +use crate::js_doc::JsDoc; +use crate::node::DeclarationKind; +use crate::node::DocNode; +use crate::node::DocNodeDef; +use crate::node::NamespaceDef; +use crate::node::ReferenceDef; +use crate::ts_type::infer_simple_ts_type_from_init; +use crate::ts_type::PropertyDef; +use crate::ts_type::TsTypeDef; +use crate::ts_type::TsTypeDefKind; +use crate::ts_type::TsTypeLiteralDef; +use crate::util::graph::resolve_deno_graph_module; +use crate::util::swc::get_location; +use crate::util::swc::get_text_info_location; +use crate::util::swc::js_doc_for_range; +use crate::util::swc::module_export_name_value; +use crate::util::swc::module_js_doc_for_source; +use crate::util::symbol::get_module_info; +use crate::variable::VariableDef; +use crate::visibility::SymbolVisibility; +use crate::ImportDef; +use crate::Location; + #[derive(Debug)] pub enum DocError { Resolve(String), @@ -99,18 +94,6 @@ impl From for DocError { } } -#[derive(Debug, Clone)] -enum ImportKind { - Namespace(String), - Named(String, Option), -} - -#[derive(Debug, Clone)] -struct Import { - src: String, - kind: ImportKind, -} - #[derive(Default, Clone)] pub struct DocParserOptions { /// Whether diagnostics should be collected. @@ -127,13 +110,15 @@ pub struct DocParser<'a> { private: bool, root_symbol: Rc>, visibility: SymbolVisibility, + specifiers: &'a [ModuleSpecifier], diagnostics: Option>>, } impl<'a> DocParser<'a> { pub fn new( graph: &'a ModuleGraph, - parser: &'a dyn ModuleParser, + parser: &'a dyn EsParser, + specifiers: &'a [ModuleSpecifier], options: DocParserOptions, ) -> Result { let root_symbol = @@ -150,6 +135,7 @@ impl<'a> DocParser<'a> { private: options.private, root_symbol, visibility, + specifiers, diagnostics, }) } @@ -167,23 +153,6 @@ impl<'a> DocParser<'a> { } } - /// Parses a module into a list of exported items, - /// as well as a list of reexported items which need to be fetched from other modules. - pub fn parse_module( - &self, - specifier: &ModuleSpecifier, - ) -> Result { - let module_info = self.get_module_info(specifier)?; - let definitions = self.get_doc_nodes_for_module_info(module_info)?; - self.collect_diagnostics_for_nodes(&definitions); - let reexports = self.get_reexports_for_module(module_info); - let module_doc = ModuleDoc { - definitions, - reexports, - }; - Ok(module_doc) - } - fn get_module_info( &self, specifier: &ModuleSpecifier, @@ -191,27 +160,246 @@ impl<'a> DocParser<'a> { get_module_info(&self.root_symbol, specifier) } - /// Fetches `file_name` and returns a list of exported items (no reexports). - #[cfg(feature = "rust")] pub fn parse( &self, + ) -> Result>, DocError> { + let mut doc_nodes_by_url = self + .specifiers + .iter() + .map(|specifier| { + Ok(( + specifier.clone(), + self.parse_with_reexports_inner(specifier, HashSet::new())?, + )) + }) + .collect::, DocError>>()?; + + let mut all_locations = doc_nodes_by_url + .values() + .flatten() + .flat_map(|node| { + fn walk_arc_nodes(nodes: &[Arc]) -> Vec { + nodes + .iter() + .flat_map(|node| { + if let Some(namespace) = node.namespace_def() { + walk_arc_nodes(&namespace.elements) + } else { + vec![node.location.clone()] + } + }) + .collect() + } + + if let Some(namespace) = node.namespace_def() { + walk_arc_nodes(&namespace.elements) + } else { + vec![node.location.clone()] + } + }) + .collect::>(); + + for (specifier, nodes) in doc_nodes_by_url.iter_mut() { + self.resolve_references_for_nodes( + specifier, + nodes, + &[], + &mut all_locations, + )?; + } + + for (_, doc_nodes) in &doc_nodes_by_url { + self.collect_diagnostics_for_nodes(doc_nodes); + } + + Ok(doc_nodes_by_url) + } + + fn resolve_references_for_nodes( + &self, specifier: &ModuleSpecifier, - ) -> Result, DocError> { - let module_info = self.get_module_info(specifier)?; - let doc_nodes = self.get_doc_nodes_for_module_info(module_info)?; - self.collect_diagnostics_for_nodes(&doc_nodes); - Ok(doc_nodes) + nodes: &mut Vec, + name_path: &[String], + all_locations: &mut HashSet, + ) -> Result<(), DocError> { + let mut i = 0; + while i < nodes.len() { + let name = nodes[i].name.to_string(); + + match &mut nodes[i].def { + DocNodeDef::Namespace { namespace_def } => { + let mut namespace_elements = namespace_def + .elements + .iter() + .map(|node| node.as_ref().clone()) + .collect::>(); + + let mut new_name_path = Vec::with_capacity(name_path.len() + 1); + new_name_path.extend_from_slice(name_path); + new_name_path.push(name); + + self.resolve_references_for_nodes( + specifier, + &mut namespace_elements, + &new_name_path, + all_locations, + )?; + + namespace_def.elements = + namespace_elements.into_iter().map(Arc::new).collect(); + } + DocNodeDef::Reference { reference_def } => { + let mut new_name_path = Vec::with_capacity(name_path.len() + 1); + new_name_path.extend_from_slice(name_path); + new_name_path.push(name); + + if !all_locations.contains(&reference_def.target) { + if let Some(new_nodes) = self.resolve_dangling_reference( + specifier, + reference_def, + new_name_path, + false, + )? { + nodes.splice(i..=i, new_nodes); + all_locations + .extend(nodes.iter().map(|node| node.location.clone())); + continue; + } + } + } + + _ => {} + } + + i += 1; + } + Ok(()) } - /// Fetches `file_name`, parses it, and resolves its reexports. - pub fn parse_with_reexports( + fn resolve_dangling_reference( &self, specifier: &ModuleSpecifier, - ) -> Result, DocError> { - let doc_nodes = - self.parse_with_reexports_inner(specifier, HashSet::new())?; - self.collect_diagnostics_for_nodes(&doc_nodes); - Ok(doc_nodes) + reference_def: &ReferenceDef, + mut name_path: Vec, + star: bool, + ) -> Result>, DocError> { + let module = resolve_deno_graph_module(self.graph, specifier)?; + + match module { + Module::Js(_) | Module::Json(_) | Module::Wasm(_) => { + let module_info = self.get_module_info(module.specifier())?; + let exports = module_info.exports(&self.root_symbol); + if name_path.is_empty() { + return Ok(Some(vec![])); + } + let root_name = name_path.remove(0); + let Some((mut export_name, export)) = exports + .resolved + .iter() + .find(|(name, _)| &&root_name == name) + else { + return Ok(Some(vec![])); + }; + + let export = export.as_resolved_export(); + let mut export_symbol = export.module.symbol(export.symbol_id).unwrap(); + + let mut definitions = self + .root_symbol + .go_to_definitions(export.module, export_symbol) + .collect::>(); + + if let Some(first_def) = definitions.first() { + use deno_graph::symbols::DefinitionKind; + match first_def.kind { + DefinitionKind::ExportStar(file_dep) => { + debug_assert_eq!(definitions.len(), 1); + let specifier = self.resolve_dependency( + &file_dep.specifier, + first_def.module.specifier(), + )?; + return self.resolve_dangling_reference( + specifier, + reference_def, + name_path, + true, + ); + } + DefinitionKind::Definition => { + for (i, name_path_item) in name_path.iter().enumerate() { + let Some((name, id)) = export_symbol + .exports() + .iter() + .find(|(name, _)| &name_path_item == name) + else { + let definitions = self + .root_symbol + .go_to_definitions(export.module, export_symbol) + .collect::>(); + + return self.resolve_dangling_reference( + definitions.first().unwrap().module.specifier(), + reference_def, + // -1 to include the root + name_path[i - 1..].to_vec(), + false, + ); + }; + + export_name = name; + export_symbol = export.module.symbol(*id).unwrap(); + } + + definitions = self + .root_symbol + .go_to_definitions(export.module, export_symbol) + .collect::>(); + } + } + } + + let original_range = &export_symbol.decls().first().unwrap().range; + + if let Some(first_def) = definitions.first() { + use deno_graph::symbols::DefinitionKind; + match first_def.kind { + DefinitionKind::ExportStar(_) => {} + DefinitionKind::Definition => { + if star || first_def.module.specifier() != module_info.specifier() + { + for definition in &definitions { + if definition_location(definition) == reference_def.target { + let decl = definition.symbol_decl; + let mut maybe_docs = self.docs_for_maybe_node( + definition.module, + definition.symbol, + decl.maybe_node(), + module_info.esm(), + first_def.module.specifier(), + Some(decl), + Some(original_range), + ); + if !maybe_docs.is_empty() { + for doc_node in &mut maybe_docs { + doc_node.name = export_name.as_str().into(); + doc_node.declaration_kind = DeclarationKind::Export; + } + + return Ok(Some(maybe_docs)); + } + } + } + } + } + } + } + + debug_assert!(false, "should not reach here"); + + Ok(Some(vec![])) + } + Module::Npm(_) | Module::Node(_) | Module::External(_) => Ok(None), + } } fn collect_diagnostics_for_nodes(&self, nodes: &[DocNode]) { @@ -232,7 +420,7 @@ impl<'a> DocParser<'a> { let module = resolve_deno_graph_module(self.graph, specifier)?; match module { - Module::Js(_) | Module::Json(_) => { + Module::Js(_) | Module::Json(_) | Module::Wasm(_) => { let module_info = self.get_module_info(module.specifier())?; let module_doc_nodes = self.get_doc_nodes_for_module_info(module_info)?; @@ -251,54 +439,47 @@ impl<'a> DocParser<'a> { match first_def.kind { DefinitionKind::ExportStar(file_dep) => { debug_assert_eq!(definitions.len(), 1); + let def_location = definition_location(first_def); let specifier = self.resolve_dependency( &file_dep.specifier, first_def.module.specifier(), )?; let doc_nodes = self - .parse_with_reexports_inner(&specifier, visited.clone())?; + .parse_with_reexports_inner(specifier, visited.clone())?; // hoist any module doc to be the exported namespaces module doc let mut js_doc = JsDoc::default(); for doc_node in &doc_nodes { - if matches!(doc_node.kind, DocNodeKind::ModuleDoc) { + if matches!(doc_node.def, DocNodeDef::ModuleDoc) { js_doc = doc_node.js_doc.clone(); } } let ns_def = NamespaceDef { elements: doc_nodes .into_iter() - .filter(|dn| !matches!(dn.kind, DocNodeKind::ModuleDoc)) - .map(Arc::new) + .filter(|dn| !matches!(dn.def, DocNodeDef::ModuleDoc)) + .map(|mut node| { + node.def = DocNodeDef::Reference { + reference_def: ReferenceDef { + target: node.location, + }, + }; + node.location = def_location.clone(); + + Arc::new(node) + }) .collect(), }; let ns_doc_node = DocNode::namespace( - export_name, + export_name.into_boxed_str(), false, - definition_location(first_def), + def_location, DeclarationKind::Export, js_doc, ns_def, ); flattened_docs.push(ns_doc_node); } - DefinitionKind::Definition => { - if first_def.module.specifier() != module_info.specifier() { - for definition in definitions { - let decl = definition.symbol_decl; - let maybe_docs = self.docs_for_maybe_node( - definition.module, - definition.symbol, - decl.maybe_node(), - ); - for mut doc_node in maybe_docs { - doc_node.name = export_name.clone(); - doc_node.declaration_kind = DeclarationKind::Export; - - flattened_docs.push(doc_node); - } - } - } - } + DefinitionKind::Definition => {} } } } @@ -318,15 +499,12 @@ impl<'a> DocParser<'a> { let referrer = module_info.specifier(); let mut imports = vec![]; - for node in &parsed_source.module().body { - if let deno_ast::swc::ast::ModuleItem::ModuleDecl(ModuleDecl::Import( - import_decl, - )) = node - { + for node in parsed_source.program_ref().body() { + if let ModuleItemRef::ModuleDecl(ModuleDecl::Import(import_decl)) = node { if let Some(js_doc) = - js_doc_for_range(parsed_source, &import_decl.range()) + js_doc_for_range(module_info, &import_decl.range()) { - let location = get_location(parsed_source, import_decl.start()); + let location = get_location(module_info, import_decl.start()); for specifier in &import_decl.specifiers { use deno_ast::swc::ast::ImportSpecifier::*; @@ -359,7 +537,7 @@ impl<'a> DocParser<'a> { }; let doc_node = DocNode::import( - name, + name.into_boxed_str(), location.clone(), js_doc.clone(), import_def, @@ -376,20 +554,21 @@ impl<'a> DocParser<'a> { fn get_doc_for_expando_property( &self, - source: &ParsedSource, + module_info: &EsModuleInfo, expando_property: ExpandoPropertyRef, ) -> Option { let location = - get_location(source, expando_property.prop_name_range().start()); + get_location(module_info, expando_property.prop_name_range().start()); let ts_type = infer_simple_ts_type_from_init( - source, + module_info, Some(expando_property.assignment()), /* is const */ true, ); - let js_doc = js_doc_for_range(source, &expando_property.inner().range())?; + let js_doc = + js_doc_for_range(module_info, &expando_property.inner().range())?; Some(DocNode::variable( - expando_property.prop_name().to_string(), + expando_property.prop_name().to_string().into_boxed_str(), false, location, DeclarationKind::Declare, @@ -414,7 +593,7 @@ impl<'a> DocParser<'a> { } else { Cow::Borrowed(full_range) }; - let js_doc = js_doc_for_range(module_info.source(), &full_range)?; + let js_doc = js_doc_for_range(module_info, &full_range)?; // todo(dsherret): it's not ideal to call this function over // and over for the same var declarator when there are a lot // of idents @@ -426,9 +605,9 @@ impl<'a> DocParser<'a> { .into_iter() .find(|(name, _)| name.as_str() == &*ident.sym) .map(|(name, var_def)| { - let location = get_location(module_info.source(), ident.start()); + let location = get_location(module_info, ident.start()); DocNode::variable( - name, + name.into_boxed_str(), false, location, DeclarationKind::Declare, @@ -440,7 +619,7 @@ impl<'a> DocParser<'a> { fn get_doc_for_class_decl( &self, - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, class_decl: &ClassDecl, full_range: &SourceRange, ) -> Option { @@ -450,13 +629,13 @@ impl<'a> DocParser<'a> { } _ => Cow::Borrowed(full_range), }; - let js_doc = js_doc_for_range(parsed_source, &jsdoc_range)?; + let js_doc = js_doc_for_range(module_info, &jsdoc_range)?; // declared classes cannot have decorators, so we ignore that return let (name, class_def, _) = - super::class::get_doc_for_class_decl(parsed_source, class_decl); - let location = get_location(parsed_source, full_range.start); + super::class::get_doc_for_class_decl(module_info, class_decl); + let location = get_location(module_info, full_range.start); Some(DocNode::class( - name, + name.into_boxed_str(), false, location, DeclarationKind::Declare, @@ -467,16 +646,16 @@ impl<'a> DocParser<'a> { fn get_doc_for_fn_decl( &self, - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, fn_decl: &FnDecl, full_range: &SourceRange, ) -> Option { - let js_doc = js_doc_for_range(parsed_source, full_range)?; + let js_doc = js_doc_for_range(module_info, full_range)?; let (name, function_def) = - super::function::get_doc_for_fn_decl(parsed_source, fn_decl); - let location = get_location(parsed_source, full_range.start); + super::function::get_doc_for_fn_decl(module_info, fn_decl); + let location = get_location(module_info, full_range.start); Some(DocNode::function( - name, + name.into_boxed_str(), false, location, DeclarationKind::Declare, @@ -487,19 +666,19 @@ impl<'a> DocParser<'a> { fn get_doc_for_interface_decl( &self, - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, ts_interface_decl: &TsInterfaceDecl, full_range: &SourceRange, ) -> Option { - let js_doc = js_doc_for_range(parsed_source, full_range)?; + let js_doc = js_doc_for_range(module_info, full_range)?; let (name, interface_def) = super::interface::get_doc_for_ts_interface_decl( - parsed_source, + module_info, ts_interface_decl, None, ); - let location = get_location(parsed_source, full_range.start); + let location = get_location(module_info, full_range.start); Some(DocNode::interface( - name, + name.into_boxed_str(), false, location, DeclarationKind::Declare, @@ -510,19 +689,19 @@ impl<'a> DocParser<'a> { fn get_docs_for_type_alias( &self, - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, ts_type_alias: &TsTypeAliasDecl, full_range: &SourceRange, ) -> Option { - let js_doc = js_doc_for_range(parsed_source, full_range)?; + let js_doc = js_doc_for_range(module_info, full_range)?; let (name, type_alias_def) = super::type_alias::get_doc_for_ts_type_alias_decl( - parsed_source, + module_info, ts_type_alias, ); - let location = get_location(parsed_source, full_range.start); + let location = get_location(module_info, full_range.start); Some(DocNode::type_alias( - name, + name.into_boxed_str(), false, location, DeclarationKind::Declare, @@ -533,16 +712,16 @@ impl<'a> DocParser<'a> { fn get_doc_for_enum( &self, - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, ts_enum: &TsEnumDecl, full_range: &SourceRange, ) -> Option { - let js_doc = js_doc_for_range(parsed_source, full_range)?; + let js_doc = js_doc_for_range(module_info, full_range)?; let (name, enum_def) = - super::r#enum::get_doc_for_ts_enum_decl(parsed_source, ts_enum); - let location = get_location(parsed_source, full_range.start); + super::r#enum::get_doc_for_ts_enum_decl(module_info, ts_enum); + let location = get_location(module_info, full_range.start); Some(DocNode::r#enum( - name, + name.into_boxed_str(), false, location, DeclarationKind::Declare, @@ -596,19 +775,22 @@ impl<'a> DocParser<'a> { let definitions = self .root_symbol .go_to_definitions(ModuleInfoRef::Esm(module_info), export_symbol); + let original_range = &export_symbol.decls().first().unwrap().range; + for definition in definitions { handled_symbols.insert(definition.symbol.unique_id()); - if definition.module.specifier() != module_info.specifier() { - continue; - } let maybe_docs = self.docs_for_maybe_node( definition.module, definition.symbol, definition.symbol_decl.maybe_node(), + Some(module_info), + module_info.specifier(), + Some(definition.symbol_decl), + Some(original_range), ); for mut doc_node in maybe_docs { - doc_node.name = export_name.to_string(); + doc_node.name = export_name.as_str().into(); doc_node.declaration_kind = DeclarationKind::Export; elements.push(Arc::new(doc_node)); @@ -639,11 +821,11 @@ impl<'a> DocParser<'a> { } } - let js_doc = js_doc_for_range(module_info.source(), full_range)?; - let location = get_location(module_info.source(), full_range.start); + let js_doc = js_doc_for_range(module_info, full_range)?; + let location = get_location(module_info, full_range.start); let is_default = namespace_name == "default"; Some(DocNode::namespace( - namespace_name, + namespace_name.into_boxed_str(), is_default, location, DeclarationKind::Declare, @@ -663,8 +845,15 @@ impl<'a> DocParser<'a> { .is_none()); let mut doc_nodes = Vec::with_capacity(child_symbol.decls().len()); for decl in child_symbol.decls() { - let maybe_docs = - self.docs_for_maybe_node(module_info, child_symbol, decl.maybe_node()); + let maybe_docs = self.docs_for_maybe_node( + module_info, + child_symbol, + decl.maybe_node(), + module_info.esm(), + module_info.specifier(), + None, + None, + ); for mut doc_node in maybe_docs { let is_declared = decl .maybe_node() @@ -683,19 +872,21 @@ impl<'a> DocParser<'a> { fn get_doc_for_export_default_decl( &self, - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, export_default_decl: &ExportDefaultDecl, ) -> Option { - let js_doc = js_doc_for_range(parsed_source, &export_default_decl.range())?; - let location = get_location(parsed_source, export_default_decl.start()); + let js_doc = js_doc_for_range(module_info, &export_default_decl.range())?; + let location = get_location(module_info, export_default_decl.start()); let name = "default".to_string(); let doc_node = match &export_default_decl.decl { DefaultDecl::Class(class_expr) => { - let default_name = - class_expr.ident.as_ref().map(|ident| ident.sym.to_string()); + let default_name = class_expr + .ident + .as_ref() + .map(|ident| ident.sym.to_string().into_boxed_str()); let (class_def, decorator_js_doc) = crate::class::class_to_class_def( - parsed_source, + module_info, &class_expr.class, default_name, ); @@ -705,7 +896,7 @@ impl<'a> DocParser<'a> { js_doc }; DocNode::class( - name, + name.into_boxed_str(), true, location, DeclarationKind::Export, @@ -717,12 +908,12 @@ impl<'a> DocParser<'a> { let default_name = fn_expr.ident.as_ref().map(|ident| ident.sym.to_string()); let function_def = crate::function::function_to_function_def( - parsed_source, + module_info, &fn_expr.function, default_name, ); DocNode::function( - name, + name.into_boxed_str(), true, location, DeclarationKind::Export, @@ -734,12 +925,12 @@ impl<'a> DocParser<'a> { let default_name = interface_decl.id.sym.to_string(); let (_, interface_def) = crate::interface::get_doc_for_ts_interface_decl( - parsed_source, + module_info, interface_decl, Some(default_name), ); DocNode::interface( - name, + name.into_boxed_str(), true, location, DeclarationKind::Export, @@ -754,14 +945,13 @@ impl<'a> DocParser<'a> { fn get_doc_for_export_default_expr( &self, - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, export_expr: &ExportDefaultExpr, ) -> Option { - if let Some(js_doc) = js_doc_for_range(parsed_source, &export_expr.range()) - { - let location = get_location(parsed_source, export_expr.start()); + if let Some(js_doc) = js_doc_for_range(module_info, &export_expr.range()) { + let location = get_location(module_info, export_expr.start()); Some(DocNode::variable( - String::from("default"), + "default".into(), true, location, DeclarationKind::Export, @@ -769,7 +959,7 @@ impl<'a> DocParser<'a> { VariableDef { kind: VarDeclKind::Var, ts_type: super::ts_type::infer_ts_type_from_expr( - parsed_source, + module_info, export_expr.expr.as_ref(), true, ), @@ -780,176 +970,28 @@ impl<'a> DocParser<'a> { } } - fn get_imports_for_module_body( - &self, - module_body: &[ModuleItem], - ) -> HashMap { - let mut imports = HashMap::new(); - - for node in module_body.iter() { - if let ModuleItem::ModuleDecl(ModuleDecl::Import(import_decl)) = node { - for specifier in &import_decl.specifiers { - let import = match specifier { - ImportSpecifier::Named(named_specifier) => Import { - kind: ImportKind::Named( - named_specifier.local.sym.to_string(), - named_specifier - .imported - .as_ref() - .map(module_export_name_value), - ), - src: import_decl.src.value.to_string(), - }, - ImportSpecifier::Default(default_specifier) => Import { - kind: ImportKind::Named( - default_specifier.local.sym.to_string(), - Some("default".to_string()), - ), - src: import_decl.src.value.to_string(), - }, - ImportSpecifier::Namespace(namespace_specifier) => Import { - kind: ImportKind::Namespace( - namespace_specifier.local.sym.to_string(), - ), - src: import_decl.src.value.to_string(), - }, - }; - - let name = match import.kind.clone() { - ImportKind::Named(name, _) | ImportKind::Namespace(name) => name, - }; - - imports.insert(name, import); - } - } - } - - imports - } - - pub fn get_reexports_for_module( + fn get_doc_for_reference( &self, - module_info: ModuleInfoRef, - ) -> Vec { - let Some(module_info) = module_info.esm() else { - return Vec::new(); - }; - let module_body = &module_info.source().module().body; - - let imports = self.get_imports_for_module_body(module_body); - - let mut reexports: Vec = vec![]; - - if self.private { - reexports.extend(imports.values().cloned().map(|import| node::Reexport { - src: import.src, - kind: match import.kind { - ImportKind::Named(orig, exported) => { - ReexportKind::Named(orig, exported) - } - ImportKind::Namespace(name) => ReexportKind::Namespace(name), - }, - })) - } - - for node in module_body.iter() { - if let deno_ast::swc::ast::ModuleItem::ModuleDecl(module_decl) = node { - let r = match module_decl { - ModuleDecl::ExportNamed(named_export) => { - if let Some(src) = &named_export.src { - let src_str = src.value.to_string(); - named_export - .specifiers - .iter() - .map(|export_specifier| match export_specifier { - ExportSpecifier::Namespace(ns_export) => node::Reexport { - kind: node::ReexportKind::Namespace( - module_export_name_value(&ns_export.name), - ), - src: src_str.to_string(), - }, - ExportSpecifier::Default(specifier) => node::Reexport { - kind: node::ReexportKind::Named( - "default".to_string(), - Some(specifier.exported.sym.to_string()), - ), - src: src_str.to_string(), - }, - ExportSpecifier::Named(named_export) => { - let export_name = - module_export_name_value(&named_export.orig); - let maybe_alias = named_export - .exported - .as_ref() - .map(module_export_name_value); - let kind = - node::ReexportKind::Named(export_name, maybe_alias); - node::Reexport { - kind, - src: src_str.to_string(), - } - } - }) - .collect::>() - } else { - named_export - .specifiers - .iter() - .filter_map(|specifier| { - if let ExportSpecifier::Named(specifier) = specifier { - if let Some(import) = - imports.get(&module_export_name_value(&specifier.orig)) - { - // If it has the same name as the original import and private values are exported, - // don't export this again and document the same value twice. - if self.private && specifier.exported.is_none() { - return None; - } - - let name = module_export_name_value( - specifier.exported.as_ref().unwrap_or(&specifier.orig), - ); - Some(node::Reexport { - src: import.src.clone(), - kind: match &import.kind { - ImportKind::Named(orig, maybe_export) => { - ReexportKind::Named( - maybe_export - .clone() - .unwrap_or_else(|| orig.clone()), - Some(name), - ) - } - ImportKind::Namespace(_) => { - ReexportKind::Namespace(name) - } - }, - }) - } else { - None - } - } else { - None - } - }) - .collect() - } - } - ModuleDecl::ExportAll(export_all) => { - let reexport = node::Reexport { - kind: node::ReexportKind::All, - src: export_all.src.value.to_string(), - }; - vec![reexport] - } - _ => vec![], - }; - - reexports.extend(r); - } + reference_module_info: &EsModuleInfo, + parsed_module_info: &EsModuleInfo, + reference_range: &SourceRange, + target_range: &SourceRange, + ) -> Option { + if let Some(js_doc) = + js_doc_for_range(reference_module_info, &reference_range.range()) + { + let location = + get_location(reference_module_info, reference_range.start()); + let target = get_location(parsed_module_info, target_range.start()); + Some(DocNode::reference( + "default".into(), + location, + js_doc, + ReferenceDef { target }, + )) + } else { + None } - - reexports } fn get_doc_nodes_for_module_info( @@ -980,12 +1022,12 @@ impl<'a> DocParser<'a> { module_info: &EsModuleInfo, ) -> Vec { let mut doc_nodes = Vec::new(); - let parsed_source = module_info.source(); // check to see if there is a module level JSDoc for the source file - if let Some(module_js_doc) = module_js_doc_for_source(parsed_source) { + if let Some(module_js_doc) = module_js_doc_for_source(module_info.source()) + { if let Some((js_doc, range)) = module_js_doc { let doc_node = - DocNode::module_doc(get_location(parsed_source, range.start), js_doc); + DocNode::module_doc(get_location(module_info, range.start), js_doc); doc_nodes.push(doc_node); } else { return vec![]; @@ -1004,18 +1046,20 @@ impl<'a> DocParser<'a> { let definitions = self .root_symbol .go_to_definitions(export.module, export_symbol); + let original_range = &export_symbol.decls().first().unwrap().range; for definition in definitions { - if definition.module.specifier() != module_info.specifier() { - continue; - } handled_symbols.insert(definition.symbol.unique_id()); let maybe_docs = self.docs_for_maybe_node( definition.module, definition.symbol, definition.symbol_decl.maybe_node(), + export.module.esm(), + export.module.specifier(), + Some(definition.symbol_decl), + Some(original_range), ); for mut doc_node in maybe_docs { - doc_node.name = export_name.clone(); + doc_node.name = export_name.as_str().into(); doc_node.is_default = Some(export_name == "default"); doc_node.declaration_kind = DeclarationKind::Export; @@ -1046,11 +1090,16 @@ impl<'a> DocParser<'a> { doc_nodes } + #[allow(clippy::too_many_arguments)] fn docs_for_maybe_node( &self, module_info: ModuleInfoRef, symbol: &Symbol, maybe_node: Option>, + original_module_source: Option<&EsModuleInfo>, + original_specifier: &ModuleSpecifier, + decl: Option<&SymbolDecl>, + original_range: Option<&SourceRange>, ) -> Vec { let mut docs = Vec::with_capacity(2); let maybe_doc = match module_info { @@ -1060,7 +1109,18 @@ impl<'a> DocParser<'a> { ), ModuleInfoRef::Esm(module_info) => { if let Some(node) = maybe_node { - self.get_doc_for_symbol_node_ref(module_info, symbol, node) + if module_info.specifier() == original_specifier { + self.get_doc_for_symbol_node_ref(module_info, symbol, node) + } else if let Some(decl) = decl { + self.get_doc_for_reference( + original_module_source.unwrap(), + module_info, + original_range.unwrap(), + &decl.range, + ) + } else { + None + } } else { None } @@ -1109,9 +1169,13 @@ impl<'a> DocParser<'a> { module_info, symbol, Some(SymbolNodeRef::ExpandoProperty(n)), + module_info.esm(), + module_info.specifier(), + None, + None, ); for doc in &mut docs { - doc.name = name.clone(); + doc.name = name.as_str().into(); doc.declaration_kind = DeclarationKind::Declare; } docs @@ -1128,11 +1192,11 @@ impl<'a> DocParser<'a> { DeclarationKind::Declare, // give this a JS doc to prevent a missing JS doc diagnostic JsDoc { - doc: Some(format!( - "Additional properties on the `{}` function.", - func_doc.name - )), - tags: vec![], + doc: Some( + format!("Additional properties on the `{}` function.", func_doc.name) + .into_boxed_str(), + ), + tags: Box::new([]), }, NamespaceDef { elements }, )) @@ -1196,34 +1260,33 @@ impl<'a> DocParser<'a> { symbol: &Symbol, node: SymbolNodeRef<'_>, ) -> Option { - let parsed_source = module_info.source(); match node { SymbolNodeRef::ClassDecl(n) => { - self.get_doc_for_class_decl(parsed_source, n, &n.class.range()) + self.get_doc_for_class_decl(module_info, n, &n.class.range()) } SymbolNodeRef::ExpandoProperty(n) => { - self.get_doc_for_expando_property(parsed_source, n) + self.get_doc_for_expando_property(module_info, n) } SymbolNodeRef::ExportDefaultDecl(n) => { - self.get_doc_for_export_default_decl(parsed_source, n) + self.get_doc_for_export_default_decl(module_info, n) } SymbolNodeRef::ExportDefaultExpr(n) => { - self.get_doc_for_export_default_expr(parsed_source, n) + self.get_doc_for_export_default_expr(module_info, n) } SymbolNodeRef::FnDecl(n) => { - self.get_doc_for_fn_decl(parsed_source, n, &n.function.range()) + self.get_doc_for_fn_decl(module_info, n, &n.function.range()) } SymbolNodeRef::TsEnum(n) => { - self.get_doc_for_enum(parsed_source, n, &n.range()) + self.get_doc_for_enum(module_info, n, &n.range()) } SymbolNodeRef::TsInterface(n) => { - self.get_doc_for_interface_decl(parsed_source, n, &n.range()) + self.get_doc_for_interface_decl(module_info, n, &n.range()) } SymbolNodeRef::TsNamespace(n) => { self.get_doc_for_ts_namespace(module_info, symbol, n, &n.range()) } SymbolNodeRef::TsTypeAlias(n) => { - self.get_docs_for_type_alias(parsed_source, n, &n.range()) + self.get_docs_for_type_alias(module_info, n, &n.range()) } SymbolNodeRef::Var(parent_decl, n, ident) => self .get_doc_for_var_declarator_ident( @@ -1239,13 +1302,13 @@ impl<'a> DocParser<'a> { } SymbolNodeRef::ExportDecl(export_decl, inner) => match inner { ExportDeclRef::Class(n) => { - self.get_doc_for_class_decl(parsed_source, n, &export_decl.range()) + self.get_doc_for_class_decl(module_info, n, &export_decl.range()) } ExportDeclRef::Fn(n) => { - self.get_doc_for_fn_decl(parsed_source, n, &export_decl.range()) + self.get_doc_for_fn_decl(module_info, n, &export_decl.range()) } ExportDeclRef::TsEnum(n) => { - self.get_doc_for_enum(parsed_source, n, &export_decl.range()) + self.get_doc_for_enum(module_info, n, &export_decl.range()) } ExportDeclRef::TsModule(n) => self.get_doc_for_ts_namespace( module_info, @@ -1253,13 +1316,11 @@ impl<'a> DocParser<'a> { n, &export_decl.range(), ), - ExportDeclRef::TsInterface(n) => self.get_doc_for_interface_decl( - parsed_source, - n, - &export_decl.range(), - ), + ExportDeclRef::TsInterface(n) => { + self.get_doc_for_interface_decl(module_info, n, &export_decl.range()) + } ExportDeclRef::TsTypeAlias(n) => { - self.get_docs_for_type_alias(parsed_source, n, &export_decl.range()) + self.get_docs_for_type_alias(module_info, n, &export_decl.range()) } ExportDeclRef::Var(var_decl, var_declarator, ident) => self .get_doc_for_var_declarator_ident( @@ -1339,7 +1400,7 @@ impl<'a> DocParser<'a> { &self, specifier: &str, referrer: &ModuleSpecifier, - ) -> Result { + ) -> Result<&ModuleSpecifier, DocError> { self .graph .resolve_dependency(specifier, referrer, /* prefer_types */ true) @@ -1358,21 +1419,22 @@ fn parse_json_module_doc_node( ) -> Option { if let Ok(value) = serde_json::from_str(source) { Some(DocNode { - kind: DocNodeKind::Variable, - name: "default".to_string(), + name: "default".into(), is_default: Some(true), location: Location { - filename: specifier.to_string(), + filename: specifier.to_string().into_boxed_str(), col: 0, line: 1, byte_index: 0, }, declaration_kind: DeclarationKind::Export, - variable_def: Some(VariableDef { - kind: VarDeclKind::Var, - ts_type: Some(parse_json_module_type(&value)), - }), - ..Default::default() + js_doc: JsDoc::default(), + def: DocNodeDef::Variable { + variable_def: VariableDef { + kind: VarDeclKind::Var, + ts_type: Some(parse_json_module_type(&value)), + }, + }, }) } else { // no doc nodes @@ -1411,7 +1473,7 @@ fn parse_json_module_type(value: &serde_json::Value) -> TsTypeDef { readonly: false, computed: false, optional: false, - type_params: Vec::new(), + type_params: Box::new([]), location: Default::default(), }) .collect(), @@ -1423,10 +1485,10 @@ fn parse_json_module_type(value: &serde_json::Value) -> TsTypeDef { } fn module_has_import(module_info: &EsModuleInfo) -> bool { - module_info.source().module().body.iter().any(|m| { + module_info.source().program_ref().body().any(|m| { matches!( m, - ModuleItem::ModuleDecl( + ModuleItemRef::ModuleDecl( ModuleDecl::Import(_) | ModuleDecl::TsImportEquals(_) ) ) diff --git a/src/printer.rs b/src/printer.rs index 697f5435..f75dc574 100644 --- a/src/printer.rs +++ b/src/printer.rs @@ -1,28 +1,34 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -use crate::colors; use crate::display::display_abstract; use crate::display::display_async; use crate::display::display_generator; -use crate::display::Indent; use crate::display::SliceDisplayer; use crate::js_doc::JsDoc; use crate::js_doc::JsDocTag; use crate::node::DeclarationKind; use crate::node::DocNode; -use crate::node::DocNodeKind; +use crate::node::DocNodeDef; +use crate::Location; + +use deno_terminal::colors; +use deno_terminal::colors::Style; use std::fmt::Display; use std::fmt::Formatter; use std::fmt::Result as FmtResult; +fn italic_cyan<'a, S: Display + 'a>(s: S) -> Style> { + colors::italic(colors::cyan(s)) +} + pub struct DocPrinter<'a> { doc_nodes: &'a [DocNode], use_color: bool, private: bool, } -impl<'a> DocPrinter<'a> { +impl DocPrinter<'_> { pub fn new( doc_nodes: &[DocNode], use_color: bool, @@ -45,13 +51,11 @@ impl<'a> DocPrinter<'a> { doc_nodes: &[DocNode], indent: i64, ) -> FmtResult { - if self.use_color { - colors::enable_color(); - } + colors::set_use_color(self.use_color); let mut sorted = Vec::from(doc_nodes); sorted.sort_unstable_by(|a, b| { - let kind_cmp = self.kind_order(&a.kind).cmp(&self.kind_order(&b.kind)); + let kind_cmp = self.kind_order(a).cmp(&self.kind_order(b)); if kind_cmp == core::cmp::Ordering::Equal { a.name.cmp(&b.name) } else { @@ -60,10 +64,12 @@ impl<'a> DocPrinter<'a> { }); for node in &sorted { - let has_overloads = if node.kind == DocNodeKind::Function { + let has_overloads = if matches!(node.def, DocNodeDef::Function { .. }) { sorted .iter() - .filter(|n| n.kind == DocNodeKind::Function && n.name == node.name) + .filter(|n| { + matches!(n.def, DocNodeDef::Function { .. }) && n.name == node.name + }) .count() > 1 } else { @@ -72,8 +78,7 @@ impl<'a> DocPrinter<'a> { if !has_overloads || node - .function_def - .as_ref() + .function_def() .map(|def| !def.has_body) .unwrap_or(false) { @@ -81,13 +86,8 @@ impl<'a> DocPrinter<'a> { w, "{}", colors::italic_gray(&format!( - "Defined in {}:{}:{}\n\n", - node.location.filename, - node.location.line, - // todo(#150): for some reason the column is 0-indexed and the line - // is 1-indexed. Display them both as 1-indexed so that vscode goes - // to the correct column when clicking this. - node.location.col + 1 + "Defined in {}\n\n", + get_location_string(&node.location), )) )?; } @@ -97,33 +97,34 @@ impl<'a> DocPrinter<'a> { self.format_jsdoc(w, &node.js_doc, indent + 1)?; writeln!(w)?; - match node.kind { - DocNodeKind::Class => self.format_class(w, node)?, - DocNodeKind::Enum => self.format_enum(w, node)?, - DocNodeKind::Interface => self.format_interface(w, node)?, - DocNodeKind::Namespace => self.format_namespace(w, node)?, + match node.def { + DocNodeDef::Class { .. } => self.format_class(w, node)?, + DocNodeDef::Enum { .. } => self.format_enum(w, node)?, + DocNodeDef::Interface { .. } => self.format_interface(w, node)?, + DocNodeDef::Namespace { .. } => self.format_namespace(w, node)?, _ => {} } } if self.use_color { - colors::disable_color(); + colors::set_use_color(false); } Ok(()) } - fn kind_order(&self, kind: &DocNodeKind) -> i64 { - match kind { - DocNodeKind::ModuleDoc => 0, - DocNodeKind::Function => 1, - DocNodeKind::Variable => 2, - DocNodeKind::Class => 3, - DocNodeKind::Enum => 4, - DocNodeKind::Interface => 5, - DocNodeKind::TypeAlias => 6, - DocNodeKind::Namespace => 7, - DocNodeKind::Import => 8, + fn kind_order(&self, node: &DocNode) -> i64 { + match node.def { + DocNodeDef::ModuleDoc { .. } => 0, + DocNodeDef::Function { .. } => 1, + DocNodeDef::Variable { .. } => 2, + DocNodeDef::Class { .. } => 3, + DocNodeDef::Enum { .. } => 4, + DocNodeDef::Interface { .. } => 5, + DocNodeDef::TypeAlias { .. } => 6, + DocNodeDef::Namespace { .. } => 7, + DocNodeDef::Import { .. } => 8, + DocNodeDef::Reference { .. } => 9, } } @@ -134,24 +135,29 @@ impl<'a> DocPrinter<'a> { indent: i64, has_overloads: bool, ) -> FmtResult { - match node.kind { - DocNodeKind::ModuleDoc => self.format_module_doc(w, node, indent), - DocNodeKind::Function => { + match node.def { + DocNodeDef::ModuleDoc { .. } => self.format_module_doc(w, node, indent), + DocNodeDef::Function { .. } => { self.format_function_signature(w, node, indent, has_overloads) } - DocNodeKind::Variable => self.format_variable_signature(w, node, indent), - DocNodeKind::Class => self.format_class_signature(w, node, indent), - DocNodeKind::Enum => self.format_enum_signature(w, node, indent), - DocNodeKind::Interface => { + DocNodeDef::Variable { .. } => { + self.format_variable_signature(w, node, indent) + } + DocNodeDef::Class { .. } => self.format_class_signature(w, node, indent), + DocNodeDef::Enum { .. } => self.format_enum_signature(w, node, indent), + DocNodeDef::Interface { .. } => { self.format_interface_signature(w, node, indent) } - DocNodeKind::TypeAlias => { + DocNodeDef::TypeAlias { .. } => { self.format_type_alias_signature(w, node, indent) } - DocNodeKind::Namespace => { + DocNodeDef::Namespace { .. } => { self.format_namespace_signature(w, node, indent) } - DocNodeKind::Import => Ok(()), + DocNodeDef::Import { .. } => Ok(()), + DocNodeDef::Reference { .. } => { + self.format_reference_signature(w, node, indent) + } } } @@ -169,7 +175,7 @@ impl<'a> DocPrinter<'a> { if !js_doc.tags.is_empty() { writeln!(w)?; } - for tag in &js_doc.tags { + for tag in js_doc.tags.iter() { self.format_jsdoc_tag(w, tag, indent)?; } Ok(()) @@ -178,7 +184,7 @@ impl<'a> DocPrinter<'a> { fn format_jsdoc_tag_maybe_doc( &self, w: &mut Formatter<'_>, - maybe_doc: &Option, + maybe_doc: &Option>, indent: i64, ) -> FmtResult { if let Some(doc) = maybe_doc { @@ -233,7 +239,7 @@ impl<'a> DocPrinter<'a> { "{}@{} {{{}}}", Indent(indent), colors::magenta("default"), - colors::italic_cyan(value) + italic_cyan(value), )?; self.format_jsdoc_tag_maybe_doc(w, doc, indent) } @@ -247,7 +253,7 @@ impl<'a> DocPrinter<'a> { "{}@{} {{{}}}", Indent(indent), colors::magenta("enum"), - colors::italic_cyan(type_ref) + italic_cyan(type_ref), )?; self.format_jsdoc_tag_maybe_doc(w, doc, indent) } @@ -264,7 +270,7 @@ impl<'a> DocPrinter<'a> { "{}@{} {{{}}}", Indent(indent), colors::magenta("extends"), - colors::italic_cyan(type_ref) + italic_cyan(type_ref) )?; self.format_jsdoc_tag_maybe_doc(w, doc, indent) } @@ -274,8 +280,9 @@ impl<'a> DocPrinter<'a> { JsDocTag::Internal => { writeln!(w, "{}@{}", Indent(indent), colors::magenta("internal")) } - JsDocTag::Module => { - writeln!(w, "{}@{}", Indent(indent), colors::magenta("module")) + JsDocTag::Module { name } => { + writeln!(w, "{}@{}", Indent(indent), colors::magenta("module"))?; + self.format_jsdoc_tag_maybe_doc(w, name, indent) } JsDocTag::Param { name, @@ -286,12 +293,12 @@ impl<'a> DocPrinter<'a> { } => { write!(w, "{}@{}", Indent(indent), colors::magenta("param"))?; if let Some(type_ref) = type_ref { - write!(w, " {{{}}}", colors::italic_cyan(type_ref))?; + write!(w, " {{{}}}", italic_cyan(type_ref))?; } if *optional { write!(w, " [?]")?; } else if let Some(default) = default { - write!(w, " [{}]", colors::italic_cyan(default))?; + write!(w, " [{}]", italic_cyan(default))?; } writeln!(w, " {}", colors::bold(name))?; self.format_jsdoc_tag_maybe_doc(w, doc, indent) @@ -312,7 +319,7 @@ impl<'a> DocPrinter<'a> { "{}@{} {{{}}} {}", Indent(indent), colors::magenta("property"), - colors::italic_cyan(type_ref), + italic_cyan(type_ref), colors::bold(name) )?; self.format_jsdoc_tag_maybe_doc(w, doc, indent) @@ -326,7 +333,7 @@ impl<'a> DocPrinter<'a> { JsDocTag::Return { type_ref, doc } => { write!(w, "{}@{}", Indent(indent), colors::magenta("return"))?; if let Some(type_ref) = type_ref { - writeln!(w, " {{{}}}", colors::italic_cyan(type_ref))?; + writeln!(w, " {{{}}}", italic_cyan(type_ref))?; } else { writeln!(w)?; } @@ -357,7 +364,7 @@ impl<'a> DocPrinter<'a> { "{}@{} {{{}}}", Indent(indent), colors::magenta("this"), - colors::italic_cyan(type_ref) + italic_cyan(type_ref) )?; self.format_jsdoc_tag_maybe_doc(w, doc, indent) } @@ -371,7 +378,7 @@ impl<'a> DocPrinter<'a> { "{}@{} {{{}}} {}", Indent(indent), colors::magenta("typedef"), - colors::italic_cyan(type_ref), + italic_cyan(type_ref), colors::bold(name) )?; self.format_jsdoc_tag_maybe_doc(w, doc, indent) @@ -382,7 +389,7 @@ impl<'a> DocPrinter<'a> { "{}@{} {{{}}}", Indent(indent), colors::magenta("typeref"), - colors::italic_cyan(type_ref) + italic_cyan(type_ref) )?; self.format_jsdoc_tag_maybe_doc(w, doc, indent) } @@ -408,7 +415,7 @@ impl<'a> DocPrinter<'a> { JsDocTag::Throws { type_ref, doc } => { write!(w, "{}@{}", Indent(indent), colors::magenta("return"))?; if let Some(type_ref) = type_ref { - writeln!(w, " {{{}}}", colors::italic_cyan(type_ref))?; + writeln!(w, " {{{}}}", italic_cyan(type_ref))?; } else { writeln!(w)?; } @@ -418,9 +425,9 @@ impl<'a> DocPrinter<'a> { } fn format_class(&self, w: &mut Formatter<'_>, node: &DocNode) -> FmtResult { - let class_def = node.class_def.as_ref().unwrap(); + let class_def = node.class_def().unwrap(); let has_overloads = class_def.constructors.len() > 1; - for node in &class_def.constructors { + for node in class_def.constructors.iter() { if !has_overloads || !node.has_body { writeln!(w, "{}{}", Indent(1), node,)?; self.format_jsdoc(w, &node.js_doc, 2)?; @@ -433,13 +440,13 @@ impl<'a> DocPrinter<'a> { .unwrap_or(deno_ast::swc::ast::Accessibility::Public) != deno_ast::swc::ast::Accessibility::Private }) { - for d in &node.decorators { + for d in node.decorators.iter() { writeln!(w, "{}{}", Indent(1), d)?; } writeln!(w, "{}{}", Indent(1), node,)?; self.format_jsdoc(w, &node.js_doc, 2)?; } - for index_sign_def in &class_def.index_signatures { + for index_sign_def in class_def.index_signatures.iter() { writeln!(w, "{}{}", Indent(1), index_sign_def)?; } for node in class_def.methods.iter().filter(|node| { @@ -456,7 +463,7 @@ impl<'a> DocPrinter<'a> { .count() > 1; if !has_overloads || !node.function_def.has_body { - for d in &node.function_def.decorators { + for d in node.function_def.decorators.iter() { writeln!(w, "{}{}", Indent(1), d)?; } writeln!(w, "{}{}", Indent(1), node,)?; @@ -467,7 +474,7 @@ impl<'a> DocPrinter<'a> { } fn format_enum(&self, w: &mut Formatter<'_>, node: &DocNode) -> FmtResult { - let enum_def = node.enum_def.as_ref().unwrap(); + let enum_def = node.enum_def().unwrap(); for member in &enum_def.members { writeln!(w, "{}{}", Indent(1), colors::bold(&member.name))?; self.format_jsdoc(w, &member.js_doc, 2)?; @@ -480,7 +487,7 @@ impl<'a> DocPrinter<'a> { w: &mut Formatter<'_>, node: &DocNode, ) -> FmtResult { - let interface_def = node.interface_def.as_ref().unwrap(); + let interface_def = node.interface_def().unwrap(); for constructor in &interface_def.constructors { writeln!(w, "{}{}", Indent(1), constructor)?; @@ -505,12 +512,14 @@ impl<'a> DocPrinter<'a> { w: &mut Formatter<'_>, node: &DocNode, ) -> FmtResult { - let elements = &node.namespace_def.as_ref().unwrap().elements; + let elements = &node.namespace_def().unwrap().elements; for node in elements { - let has_overloads = if node.kind == DocNodeKind::Function { + let has_overloads = if matches!(node.def, DocNodeDef::Function { .. }) { elements .iter() - .filter(|n| n.kind == DocNodeKind::Function && n.name == node.name) + .filter(|n| { + matches!(n.def, DocNodeDef::Function { .. }) && n.name == node.name + }) .count() > 1 } else { @@ -528,8 +537,8 @@ impl<'a> DocPrinter<'a> { node: &DocNode, indent: i64, ) -> FmtResult { - let class_def = node.class_def.as_ref().unwrap(); - for node in &class_def.decorators { + let class_def = node.class_def().unwrap(); + for node in class_def.decorators.iter() { writeln!(w, "{}{}", Indent(indent), node)?; } write!( @@ -595,7 +604,7 @@ impl<'a> DocPrinter<'a> { indent: i64, has_overloads: bool, ) -> FmtResult { - let function_def = node.function_def.as_ref().unwrap(); + let function_def = node.function_def().unwrap(); if !has_overloads || !function_def.has_body { write!( w, @@ -633,7 +642,7 @@ impl<'a> DocPrinter<'a> { node: &DocNode, indent: i64, ) -> FmtResult { - let interface_def = node.interface_def.as_ref().unwrap(); + let interface_def = node.interface_def().unwrap(); write!( w, "{}{}{} {}", @@ -680,7 +689,7 @@ impl<'a> DocPrinter<'a> { node: &DocNode, indent: i64, ) -> FmtResult { - let type_alias_def = node.type_alias_def.as_ref().unwrap(); + let type_alias_def = node.type_alias_def().unwrap(); write!( w, "{}{}{} {}", @@ -717,13 +726,32 @@ impl<'a> DocPrinter<'a> { ) } + fn format_reference_signature( + &self, + w: &mut Formatter<'_>, + node: &DocNode, + indent: i64, + ) -> FmtResult { + let reference_def = node.reference_def().unwrap(); + + writeln!( + w, + "{}{}{} {}: {}", + Indent(indent), + fmt_visibility(node.declaration_kind), + colors::magenta("reference"), + colors::bold(&node.name), + colors::italic_gray(get_location_string(&reference_def.target)), + ) + } + fn format_variable_signature( &self, w: &mut Formatter<'_>, node: &DocNode, indent: i64, ) -> FmtResult { - let variable_def = node.variable_def.as_ref().unwrap(); + let variable_def = node.variable_def().unwrap(); write!( w, "{}{}{} {}", @@ -743,7 +771,7 @@ impl<'a> DocPrinter<'a> { } } -impl<'a> Display for DocPrinter<'a> { +impl Display for DocPrinter<'_> { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { self.format(f) } @@ -756,3 +784,26 @@ fn fmt_visibility(decl_kind: DeclarationKind) -> impl std::fmt::Display { "" }) } + +fn get_location_string(location: &Location) -> String { + format!( + "{}:{}:{}", + location.filename, + location.line, + // todo(#150): for some reason the column is 0-indexed and the line + // is 1-indexed. Display them both as 1-indexed so that vscode goes + // to the correct column when clicking this. + location.col + 1 + ) +} + +struct Indent(pub i64); + +impl Display for Indent { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + for _ in 0..self.0 { + write!(f, " ")?; + } + Ok(()) + } +} diff --git a/src/tests.rs b/src/tests.rs index f77097ed..432aacfb 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1,5 +1,6 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +use crate::node::DocNodeDef; use crate::parser::DocParser; use crate::printer::DocPrinter; use crate::DocParserOptions; @@ -78,10 +79,14 @@ async fn content_type_handling() { }, ) .await; - let entries = DocParser::new(&graph, &analyzer, DocParserOptions::default()) - .unwrap() - .parse_with_reexports(&root) - .unwrap(); + let entries = + DocParser::new(&graph, &analyzer, &[root], DocParserOptions::default()) + .unwrap() + .parse() + .unwrap() + .into_values() + .next() + .unwrap(); assert_eq!(entries.len(), 1); } @@ -125,10 +130,14 @@ async fn types_header_handling() { }, ) .await; - let entries = DocParser::new(&graph, &analyzer, DocParserOptions::default()) - .unwrap() - .parse_with_reexports(&root) - .unwrap(); + let entries = + DocParser::new(&graph, &analyzer, &[root], DocParserOptions::default()) + .unwrap() + .parse() + .unwrap() + .into_values() + .next() + .unwrap(); assert_eq!( serde_json::to_value(&entries).unwrap(), json!([{ @@ -209,10 +218,18 @@ export function fooFn(a: number) { ], ) .await; - let entries = DocParser::new(&graph, &analyzer, DocParserOptions::default()) - .unwrap() - .parse_with_reexports(&specifier) - .unwrap(); + let entries = DocParser::new( + &graph, + &analyzer, + &[specifier], + DocParserOptions::default(), + ) + .unwrap() + .parse() + .unwrap() + .into_values() + .next() + .unwrap(); let expected_json = json!([ { @@ -344,10 +361,18 @@ export { Hello } from "./reexport.ts"; ], ) .await; - let entries = DocParser::new(&graph, &analyzer, DocParserOptions::default()) - .unwrap() - .parse_with_reexports(&specifier) - .unwrap(); + let entries = DocParser::new( + &graph, + &analyzer, + &[specifier], + DocParserOptions::default(), + ) + .unwrap() + .parse() + .unwrap() + .into_values() + .next() + .unwrap(); let expected_json = json!([ { @@ -418,10 +443,18 @@ async fn deep_reexports() { ], ) .await; - let entries = DocParser::new(&graph, &analyzer, DocParserOptions::default()) - .unwrap() - .parse_with_reexports(&specifier) - .unwrap(); + let entries = DocParser::new( + &graph, + &analyzer, + &[specifier], + DocParserOptions::default(), + ) + .unwrap() + .parse() + .unwrap() + .into_values() + .next() + .unwrap(); let expected_json = json!([ { @@ -450,7 +483,7 @@ async fn deep_reexports() { assert!(DocPrinter::new(&entries, false, false) .to_string() - .contains("const foo")) + .contains("const foo")); } #[tokio::test] @@ -476,10 +509,18 @@ export * as b from "./mod_doc.ts"; ], ) .await; - let entries = DocParser::new(&graph, &analyzer, DocParserOptions::default()) - .unwrap() - .parse_with_reexports(&specifier) - .unwrap(); + let entries = DocParser::new( + &graph, + &analyzer, + &[specifier], + DocParserOptions::default(), + ) + .unwrap() + .parse() + .unwrap() + .into_values() + .next() + .unwrap(); let actual = serde_json::to_value(&entries).unwrap(); let expected = json!([ @@ -540,7 +581,6 @@ export * as b from "./mod_doc.ts"; #[tokio::test] async fn filter_nodes_by_name() { use crate::find_nodes_by_name_recursively; - use crate::DocNodeKind; let source_code = r#" export namespace Deno { export class Buffer {} @@ -571,73 +611,68 @@ export namespace Deno { vec![("file:///test.ts", None, source_code)], ) .await; - let entries = DocParser::new(&graph, &analyzer, DocParserOptions::default()) - .unwrap() - .parse(&specifier) - .unwrap(); + let entries = DocParser::new( + &graph, + &analyzer, + &[specifier], + DocParserOptions::default(), + ) + .unwrap() + .parse() + .unwrap() + .into_values() + .next() + .unwrap(); // Namespace - let found = - find_nodes_by_name_recursively(entries.clone(), "Deno".to_string()); + let found = find_nodes_by_name_recursively(entries.clone(), "Deno"); assert_eq!(found.len(), 1); - assert_eq!(found[0].name, "Deno".to_string()); + assert_eq!(found[0].name.as_ref(), "Deno"); // Overloaded functions - let found = - find_nodes_by_name_recursively(entries.clone(), "Deno.test".to_string()); + let found = find_nodes_by_name_recursively(entries.clone(), "Deno.test"); assert_eq!(found.len(), 3); - assert_eq!(found[0].name, "test".to_string()); - assert_eq!(found[1].name, "test".to_string()); - assert_eq!(found[2].name, "test".to_string()); + assert_eq!(found[0].name.as_ref(), "test"); + assert_eq!(found[1].name.as_ref(), "test"); + assert_eq!(found[2].name.as_ref(), "test"); // Nested namespace - let found = - find_nodes_by_name_recursively(entries.clone(), "Deno.Inner.a".to_string()); + let found = find_nodes_by_name_recursively(entries.clone(), "Deno.Inner.a"); assert_eq!(found.len(), 1); - assert_eq!(found[0].name, "a".to_string()); + assert_eq!(found[0].name.as_ref(), "a"); // Interface property - let found = find_nodes_by_name_recursively( - entries.clone(), - "Deno.Conn.rid".to_string(), - ); + let found = find_nodes_by_name_recursively(entries.clone(), "Deno.Conn.rid"); assert_eq!(found.len(), 1); - assert_eq!(found[0].name, "rid".to_string()); - assert_eq!(found[0].kind, DocNodeKind::Variable); + assert_eq!(found[0].name.as_ref(), "rid"); + assert!(matches!(found[0].def, DocNodeDef::Variable { .. })); // Interface method - let found = find_nodes_by_name_recursively( - entries.clone(), - "Deno.Conn.closeWrite".to_string(), - ); + let found = + find_nodes_by_name_recursively(entries.clone(), "Deno.Conn.closeWrite"); assert_eq!(found.len(), 1); - assert_eq!(found[0].name, "closeWrite".to_string()); - assert_eq!(found[0].kind, DocNodeKind::Function); + assert_eq!(found[0].name.as_ref(), "closeWrite"); + assert!(matches!(found[0].def, DocNodeDef::Function { .. })); // Class property - let found = find_nodes_by_name_recursively( - entries.clone(), - "Deno.Process.pid".to_string(), - ); + let found = + find_nodes_by_name_recursively(entries.clone(), "Deno.Process.pid"); assert_eq!(found.len(), 1); - assert_eq!(found[0].name, "pid".to_string()); - assert_eq!(found[0].kind, DocNodeKind::Variable); + assert_eq!(found[0].name.as_ref(), "pid"); + assert!(matches!(found[0].def, DocNodeDef::Variable { .. })); // Class method - let found = find_nodes_by_name_recursively( - entries.clone(), - "Deno.Process.output".to_string(), - ); + let found = + find_nodes_by_name_recursively(entries.clone(), "Deno.Process.output"); assert_eq!(found.len(), 1); - assert_eq!(found[0].name, "output".to_string()); - assert_eq!(found[0].kind, DocNodeKind::Function); + assert_eq!(found[0].name.as_ref(), "output"); + assert!(matches!(found[0].def, DocNodeDef::Function { .. })); // No match - let found = - find_nodes_by_name_recursively(entries.clone(), "Deno.test.a".to_string()); + let found = find_nodes_by_name_recursively(entries.clone(), "Deno.test.a"); assert_eq!(found.len(), 0); - let found = find_nodes_by_name_recursively(entries, "a.b.c".to_string()); + let found = find_nodes_by_name_recursively(entries, "a.b.c"); assert_eq!(found.len(), 0); } @@ -658,10 +693,18 @@ async fn exports_imported_earlier() { ], ) .await; - let entries = DocParser::new(&graph, &analyzer, DocParserOptions::default()) - .unwrap() - .parse_with_reexports(&specifier) - .unwrap(); + let entries = DocParser::new( + &graph, + &analyzer, + &[specifier], + DocParserOptions::default(), + ) + .unwrap() + .parse() + .unwrap() + .into_values() + .next() + .unwrap(); let expected_json = json!([ { @@ -721,10 +764,18 @@ async fn exports_imported_earlier_renamed() { ], ) .await; - let entries = DocParser::new(&graph, &analyzer, DocParserOptions::default()) - .unwrap() - .parse_with_reexports(&specifier) - .unwrap(); + let entries = DocParser::new( + &graph, + &analyzer, + &[specifier], + DocParserOptions::default(), + ) + .unwrap() + .parse() + .unwrap() + .into_values() + .next() + .unwrap(); let expected_json = json!([ { @@ -785,10 +836,18 @@ async fn exports_imported_earlier_default() { ], ) .await; - let entries = DocParser::new(&graph, &analyzer, DocParserOptions::default()) - .unwrap() - .parse_with_reexports(&specifier) - .unwrap(); + let entries = DocParser::new( + &graph, + &analyzer, + &[specifier], + DocParserOptions::default(), + ) + .unwrap() + .parse() + .unwrap() + .into_values() + .next() + .unwrap(); let expected_json = json!([ { @@ -851,13 +910,17 @@ async fn exports_imported_earlier_private() { let entries = DocParser::new( &graph, &analyzer, + &[specifier], DocParserOptions { private: true, ..Default::default() }, ) .unwrap() - .parse_with_reexports(&specifier) + .parse() + .unwrap() + .into_values() + .next() .unwrap(); let expected_json = json!([ @@ -913,9 +976,9 @@ async fn variable_syntax() { .await; // This just needs to not throw a syntax error - DocParser::new(&graph, &analyzer, DocParserOptions::default()) + DocParser::new(&graph, &analyzer, &[specifier], DocParserOptions::default()) .unwrap() - .parse_with_reexports(&specifier) + .parse() .unwrap(); } @@ -930,16 +993,24 @@ async fn json_module() { ) .await; - let entries = DocParser::new(&graph, &analyzer, DocParserOptions::default()) - .unwrap() - .parse_with_reexports(&specifier) - .unwrap(); + let entries = DocParser::new( + &graph, + &analyzer, + &[specifier], + DocParserOptions::default(), + ) + .unwrap() + .parse() + .unwrap() + .into_values() + .next() + .unwrap(); let expected_json = json!([ { "kind": "variable", "name": "configFile", - "isDefault": true, + "isDefault": false, "location": { "filename": "file:///bar.json", "line": 1, diff --git a/src/ts_type.rs b/src/ts_type.rs index 3cd3f21f..eaeef51f 100644 --- a/src/ts_type.rs +++ b/src/ts_type.rs @@ -1,6 +1,5 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -use crate::colors; use crate::display::display_computed; use crate::display::display_optional; use crate::display::display_readonly; @@ -24,8 +23,9 @@ use crate::js_doc::JsDoc; use crate::node::DeclarationKind; use crate::variable::VariableDef; use deno_ast::swc::ast::*; -use deno_ast::ParsedSource; use deno_ast::SourceRangedForSpanned; +use deno_graph::symbols::EsModuleInfo; +use deno_terminal::colors; use serde::Deserialize; use serde::Serialize; use std::fmt::Display; @@ -33,16 +33,16 @@ use std::fmt::Formatter; use std::fmt::Result as FmtResult; impl TsTypeDef { - fn ts_lit_type(parsed_source: &ParsedSource, other: &TsLitType) -> Self { + fn ts_lit_type(module_info: &EsModuleInfo, other: &TsLitType) -> Self { match &other.lit { TsLit::Number(num) => TsTypeDef::number_literal(num), TsLit::Str(str_) => TsTypeDef::string_literal(str_), TsLit::Tpl(tpl) => TsTypeDef::tpl_literal( - parsed_source, + module_info, tpl .types .iter() - .map(|types| TsTypeDef::new(parsed_source, types)) + .map(|types| TsTypeDef::new(module_info, types)) .collect::>(), &tpl.quasis, ), @@ -51,8 +51,8 @@ impl TsTypeDef { } } - fn ts_array_type(parsed_source: &ParsedSource, other: &TsArrayType) -> Self { - let ts_type_def = TsTypeDef::new(parsed_source, &other.elem_type); + fn ts_array_type(module_info: &EsModuleInfo, other: &TsArrayType) -> Self { + let ts_type_def = TsTypeDef::new(module_info, &other.elem_type); TsTypeDef { array: Some(Box::new(ts_type_def)), @@ -61,11 +61,11 @@ impl TsTypeDef { } } - fn ts_tuple_type(parsed_source: &ParsedSource, other: &TsTupleType) -> Self { + fn ts_tuple_type(module_info: &EsModuleInfo, other: &TsTupleType) -> Self { let type_defs = other .elem_types .iter() - .map(|type_box| TsTypeDef::new(parsed_source, &type_box.ty)) + .map(|type_box| TsTypeDef::new(module_info, &type_box.ty)) .collect::>(); TsTypeDef { @@ -76,7 +76,7 @@ impl TsTypeDef { } fn ts_union_or_intersection_type( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, other: &TsUnionOrIntersectionType, ) -> Self { use deno_ast::swc::ast::TsUnionOrIntersectionType::*; @@ -86,7 +86,7 @@ impl TsTypeDef { let types_union = union_type .types .iter() - .map(|ts_type| TsTypeDef::new(parsed_source, ts_type)) + .map(|ts_type| TsTypeDef::new(module_info, ts_type)) .collect::>(); TsTypeDef { @@ -99,7 +99,7 @@ impl TsTypeDef { let types_intersection = intersection_type .types .iter() - .map(|ts_type| TsTypeDef::new(parsed_source, ts_type)) + .map(|ts_type| TsTypeDef::new(module_info, ts_type)) .collect::>(); TsTypeDef { @@ -112,7 +112,7 @@ impl TsTypeDef { } fn ts_keyword_type( - _parsed_source: &ParsedSource, + _module_info: &EsModuleInfo, other: &TsKeywordType, ) -> Self { use deno_ast::swc::ast::TsKeywordTypeKind::*; @@ -137,10 +137,10 @@ impl TsTypeDef { } fn ts_type_operator( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, other: &TsTypeOperator, ) -> Self { - let ts_type = TsTypeDef::new(parsed_source, &other.type_ann); + let ts_type = TsTypeDef::new(module_info, &other.type_ann); let type_operator_def = TsTypeOperatorDef { operator: other.op.as_str().to_string(), ts_type, @@ -154,10 +154,10 @@ impl TsTypeDef { } fn ts_parenthesized_type( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, other: &TsParenthesizedType, ) -> Self { - let ts_type = TsTypeDef::new(parsed_source, &other.type_ann); + let ts_type = TsTypeDef::new(module_info, &other.type_ann); TsTypeDef { parenthesized: Some(Box::new(ts_type)), @@ -166,8 +166,8 @@ impl TsTypeDef { } } - fn ts_rest_type(parsed_source: &ParsedSource, other: &TsRestType) -> Self { - let ts_type = TsTypeDef::new(parsed_source, &other.type_ann); + fn ts_rest_type(module_info: &EsModuleInfo, other: &TsRestType) -> Self { + let ts_type = TsTypeDef::new(module_info, &other.type_ann); TsTypeDef { rest: Some(Box::new(ts_type)), @@ -177,10 +177,10 @@ impl TsTypeDef { } fn ts_optional_type( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, other: &TsOptionalType, ) -> Self { - let ts_type = TsTypeDef::new(parsed_source, &other.type_ann); + let ts_type = TsTypeDef::new(module_info, &other.type_ann); TsTypeDef { optional: Some(Box::new(ts_type)), @@ -189,7 +189,7 @@ impl TsTypeDef { } } - fn ts_this_type(_parsed_source: &ParsedSource, _other: &TsThisType) -> Self { + fn ts_this_type(_module_info: &EsModuleInfo, _other: &TsThisType) -> Self { TsTypeDef { repr: "this".to_string(), this: Some(true), @@ -199,7 +199,7 @@ impl TsTypeDef { } fn ts_type_predicate( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, other: &TsTypePredicate, ) -> Self { let pred = TsTypePredicateDef { @@ -208,7 +208,7 @@ impl TsTypeDef { r#type: other .type_ann .as_ref() - .map(|t| Box::new(TsTypeDef::new(parsed_source, &t.type_ann))), + .map(|t| Box::new(TsTypeDef::new(module_info, &t.type_ann))), }; TsTypeDef { repr: pred.to_string(), @@ -218,7 +218,7 @@ impl TsTypeDef { } } - fn ts_type_query(_parsed_source: &ParsedSource, other: &TsTypeQuery) -> Self { + fn ts_type_query(_module_info: &EsModuleInfo, other: &TsTypeQuery) -> Self { use deno_ast::swc::ast::TsTypeQueryExpr::*; let type_name = match &other.expr_name { @@ -234,15 +234,15 @@ impl TsTypeDef { } } - fn ts_type_ref(parsed_source: &ParsedSource, other: &TsTypeRef) -> Self { + fn ts_type_ref(module_info: &EsModuleInfo, other: &TsTypeRef) -> Self { let type_name = ts_entity_name_to_name(&other.type_name); let type_params = if let Some(type_params_inst) = &other.type_params { let ts_type_defs = type_params_inst .params .iter() - .map(|ts_type| TsTypeDef::new(parsed_source, ts_type)) - .collect::>(); + .map(|ts_type| TsTypeDef::new(module_info, ts_type)) + .collect::>(); Some(ts_type_defs) } else { @@ -261,7 +261,7 @@ impl TsTypeDef { } pub fn ts_expr_with_type_args( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, other: &TsExprWithTypeArgs, ) -> Self { let type_name = expr_to_name(&other.expr); @@ -270,8 +270,8 @@ impl TsTypeDef { let ts_type_defs = type_params_inst .params .iter() - .map(|ts_type| TsTypeDef::new(parsed_source, ts_type)) - .collect::>(); + .map(|ts_type| TsTypeDef::new(module_info, ts_type)) + .collect::>(); Some(ts_type_defs) } else { @@ -290,14 +290,14 @@ impl TsTypeDef { } fn ts_indexed_access_type( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, other: &TsIndexedAccessType, ) -> Self { - TsTypeDef::new(parsed_source, &other.obj_type); + TsTypeDef::new(module_info, &other.obj_type); let indexed_access_def = TsIndexedAccessDef { readonly: other.readonly, - obj_type: Box::new(TsTypeDef::new(parsed_source, &other.obj_type)), - index_type: Box::new(TsTypeDef::new(parsed_source, &other.index_type)), + obj_type: Box::new(TsTypeDef::new(module_info, &other.obj_type)), + index_type: Box::new(TsTypeDef::new(module_info, &other.index_type)), }; TsTypeDef { @@ -307,25 +307,19 @@ impl TsTypeDef { } } - fn ts_mapped_type( - parsed_source: &ParsedSource, - other: &TsMappedType, - ) -> Self { + fn ts_mapped_type(module_info: &EsModuleInfo, other: &TsMappedType) -> Self { let mapped_type_def = TsMappedTypeDef { readonly: other.readonly, - type_param: Box::new(TsTypeParamDef::new( - parsed_source, - &other.type_param, - )), + type_param: Box::new(TsTypeParamDef::new(module_info, &other.type_param)), name_type: other .name_type .as_ref() - .map(|nt| Box::new(TsTypeDef::new(parsed_source, nt))), + .map(|nt| Box::new(TsTypeDef::new(module_info, nt))), optional: other.optional, ts_type: other .type_ann .as_ref() - .map(|a| Box::new(TsTypeDef::new(parsed_source, a))), + .map(|a| Box::new(TsTypeDef::new(module_info, a))), }; TsTypeDef { @@ -335,7 +329,7 @@ impl TsTypeDef { } } - fn ts_type_lit(parsed_source: &ParsedSource, other: &TsTypeLit) -> Self { + fn ts_type_lit(module_info: &EsModuleInfo, other: &TsTypeLit) -> Self { let mut constructors = vec![]; let mut methods = vec![]; let mut properties = vec![]; @@ -348,21 +342,21 @@ impl TsTypeDef { match &type_element { TsMethodSignature(ts_method_sig) => { if let Some(js_doc) = - js_doc_for_range(parsed_source, &ts_method_sig.range()) + js_doc_for_range(module_info, &ts_method_sig.range()) { let params = ts_method_sig .params .iter() - .map(|param| ts_fn_param_to_param_def(parsed_source, param)) + .map(|param| ts_fn_param_to_param_def(module_info, param)) .collect::>(); let maybe_return_type = ts_method_sig .type_ann .as_ref() - .map(|rt| TsTypeDef::new(parsed_source, &rt.type_ann)); + .map(|rt| TsTypeDef::new(module_info, &rt.type_ann)); let type_params = maybe_type_param_decl_to_type_param_defs( - parsed_source, + module_info, ts_method_sig.type_params.as_deref(), ); let name = expr_to_name(&ts_method_sig.key); @@ -370,7 +364,7 @@ impl TsTypeDef { name, js_doc, kind: MethodKind::Method, - location: get_location(parsed_source, ts_method_sig.start()), + location: get_location(module_info, ts_method_sig.start()), params, computed: ts_method_sig.computed, optional: ts_method_sig.optional, @@ -382,70 +376,68 @@ impl TsTypeDef { } TsGetterSignature(ts_getter_sig) => { if let Some(js_doc) = - js_doc_for_range(parsed_source, &ts_getter_sig.range()) + js_doc_for_range(module_info, &ts_getter_sig.range()) { let maybe_return_type = ts_getter_sig .type_ann .as_ref() - .map(|rt| TsTypeDef::new(parsed_source, &rt.type_ann)); + .map(|rt| TsTypeDef::new(module_info, &rt.type_ann)); let name = expr_to_name(&ts_getter_sig.key); let method_def = MethodDef { name, js_doc, kind: MethodKind::Getter, - location: get_location(parsed_source, ts_getter_sig.start()), + location: get_location(module_info, ts_getter_sig.start()), params: vec![], computed: ts_getter_sig.computed, optional: false, return_type: maybe_return_type, - type_params: vec![], + type_params: Box::new([]), }; methods.push(method_def); } } TsSetterSignature(ts_setter_sig) => { if let Some(js_doc) = - js_doc_for_range(parsed_source, &ts_setter_sig.range()) + js_doc_for_range(module_info, &ts_setter_sig.range()) { let name = expr_to_name(&ts_setter_sig.key); - let params = vec![ts_fn_param_to_param_def( - parsed_source, - &ts_setter_sig.param, - )]; + let params = + vec![ts_fn_param_to_param_def(module_info, &ts_setter_sig.param)]; let method_def = MethodDef { name, js_doc, kind: MethodKind::Setter, - location: get_location(parsed_source, ts_setter_sig.start()), + location: get_location(module_info, ts_setter_sig.start()), params, computed: ts_setter_sig.computed, optional: false, return_type: None, - type_params: vec![], + type_params: Box::new([]), }; methods.push(method_def); } } TsPropertySignature(ts_prop_sig) => { if let Some(js_doc) = - js_doc_for_range(parsed_source, &ts_prop_sig.range()) + js_doc_for_range(module_info, &ts_prop_sig.range()) { let name = expr_to_name(&ts_prop_sig.key); let ts_type = ts_prop_sig .type_ann .as_ref() - .map(|rt| TsTypeDef::new(parsed_source, &rt.type_ann)); + .map(|rt| TsTypeDef::new(module_info, &rt.type_ann)); let type_params = - maybe_type_param_decl_to_type_param_defs(parsed_source, None); + maybe_type_param_decl_to_type_param_defs(module_info, None); let prop_def = PropertyDef { name, js_doc, - location: get_location(parsed_source, ts_prop_sig.start()), + location: get_location(module_info, ts_prop_sig.start()), params: vec![], ts_type, readonly: ts_prop_sig.readonly, @@ -458,27 +450,27 @@ impl TsTypeDef { } TsCallSignatureDecl(ts_call_sig) => { if let Some(js_doc) = - js_doc_for_range(parsed_source, &ts_call_sig.range()) + js_doc_for_range(module_info, &ts_call_sig.range()) { let params = ts_call_sig .params .iter() - .map(|param| ts_fn_param_to_param_def(parsed_source, param)) + .map(|param| ts_fn_param_to_param_def(module_info, param)) .collect(); let ts_type = ts_call_sig .type_ann .as_ref() - .map(|rt| TsTypeDef::new(parsed_source, &rt.type_ann)); + .map(|rt| TsTypeDef::new(module_info, &rt.type_ann)); let type_params = maybe_type_param_decl_to_type_param_defs( - parsed_source, + module_info, ts_call_sig.type_params.as_deref(), ); let call_sig_def = CallSignatureDef { js_doc, - location: get_location(parsed_source, ts_call_sig.start()), + location: get_location(module_info, ts_call_sig.start()), params, ts_type, type_params, @@ -488,22 +480,22 @@ impl TsTypeDef { } TsIndexSignature(ts_index_sig) => { if let Some(js_doc) = - js_doc_for_range(parsed_source, &ts_index_sig.range()) + js_doc_for_range(module_info, &ts_index_sig.range()) { let params = ts_index_sig .params .iter() - .map(|param| ts_fn_param_to_param_def(parsed_source, param)) + .map(|param| ts_fn_param_to_param_def(module_info, param)) .collect(); let ts_type = ts_index_sig .type_ann .as_ref() - .map(|rt| TsTypeDef::new(parsed_source, &rt.type_ann)); + .map(|rt| TsTypeDef::new(module_info, &rt.type_ann)); let index_sig_def = IndexSignatureDef { js_doc, - location: get_location(parsed_source, ts_index_sig.start()), + location: get_location(module_info, ts_index_sig.start()), readonly: ts_index_sig.readonly, params, ts_type, @@ -513,27 +505,27 @@ impl TsTypeDef { } TsConstructSignatureDecl(ts_construct_sig) => { if let Some(prop_js_doc) = - js_doc_for_range(parsed_source, &ts_construct_sig.range()) + js_doc_for_range(module_info, &ts_construct_sig.range()) { let params = ts_construct_sig .params .iter() - .map(|param| ts_fn_param_to_param_def(parsed_source, param)) + .map(|param| ts_fn_param_to_param_def(module_info, param)) .collect(); let type_params = maybe_type_param_decl_to_type_param_defs( - parsed_source, + module_info, ts_construct_sig.type_params.as_deref(), ); let maybe_return_type = ts_construct_sig .type_ann .as_ref() - .map(|rt| TsTypeDef::new(parsed_source, &rt.type_ann)); + .map(|rt| TsTypeDef::new(module_info, &rt.type_ann)); let construct_sig_def = ConstructorDef { js_doc: prop_js_doc, - location: get_location(parsed_source, ts_construct_sig.start()), + location: get_location(module_info, ts_construct_sig.start()), params, return_type: maybe_return_type, type_params, @@ -561,17 +553,14 @@ impl TsTypeDef { } fn ts_conditional_type( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, other: &TsConditionalType, ) -> Self { let conditional_type_def = TsConditionalDef { - check_type: Box::new(TsTypeDef::new(parsed_source, &other.check_type)), - extends_type: Box::new(TsTypeDef::new( - parsed_source, - &other.extends_type, - )), - true_type: Box::new(TsTypeDef::new(parsed_source, &other.true_type)), - false_type: Box::new(TsTypeDef::new(parsed_source, &other.false_type)), + check_type: Box::new(TsTypeDef::new(module_info, &other.check_type)), + extends_type: Box::new(TsTypeDef::new(module_info, &other.extends_type)), + true_type: Box::new(TsTypeDef::new(module_info, &other.true_type)), + false_type: Box::new(TsTypeDef::new(module_info, &other.false_type)), }; TsTypeDef { @@ -581,12 +570,9 @@ impl TsTypeDef { } } - fn ts_infer_type(parsed_source: &ParsedSource, other: &TsInferType) -> Self { + fn ts_infer_type(module_info: &EsModuleInfo, other: &TsInferType) -> Self { let infer = TsInferDef { - type_param: Box::new(TsTypeParamDef::new( - parsed_source, - &other.type_param, - )), + type_param: Box::new(TsTypeParamDef::new(module_info, &other.type_param)), }; TsTypeDef { @@ -596,15 +582,12 @@ impl TsTypeDef { } } - fn ts_import_type( - parsed_source: &ParsedSource, - other: &TsImportType, - ) -> Self { + fn ts_import_type(module_info: &EsModuleInfo, other: &TsImportType) -> Self { let type_params = if let Some(type_params_inst) = &other.type_args { let ts_type_defs = type_params_inst .params .iter() - .map(|param| TsTypeDef::new(parsed_source, param)) + .map(|param| TsTypeDef::new(module_info, param)) .collect::>(); Some(ts_type_defs) @@ -626,7 +609,7 @@ impl TsTypeDef { } fn ts_fn_or_constructor_type( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, other: &TsFnOrConstructorType, ) -> Self { use deno_ast::swc::ast::TsFnOrConstructorType::*; @@ -636,17 +619,17 @@ impl TsTypeDef { let params = ts_fn_type .params .iter() - .map(|param| ts_fn_param_to_param_def(parsed_source, param)) + .map(|param| ts_fn_param_to_param_def(module_info, param)) .collect(); let type_params = maybe_type_param_decl_to_type_param_defs( - parsed_source, + module_info, ts_fn_type.type_params.as_deref(), ); TsFnOrConstructorDef { constructor: false, - ts_type: TsTypeDef::new(parsed_source, &ts_fn_type.type_ann.type_ann), + ts_type: TsTypeDef::new(module_info, &ts_fn_type.type_ann.type_ann), params, type_params, } @@ -655,16 +638,16 @@ impl TsTypeDef { let params = ctor_type .params .iter() - .map(|param| ts_fn_param_to_param_def(parsed_source, param)) + .map(|param| ts_fn_param_to_param_def(module_info, param)) .collect(); let type_params = maybe_type_param_decl_to_type_param_defs( - parsed_source, + module_info, ctor_type.type_params.as_deref(), ); TsFnOrConstructorDef { constructor: true, - ts_type: TsTypeDef::new(parsed_source, &ctor_type.type_ann.type_ann), + ts_type: TsTypeDef::new(module_info, &ctor_type.type_ann.type_ann), params, type_params, } @@ -678,65 +661,61 @@ impl TsTypeDef { } } - pub fn new(parsed_source: &ParsedSource, other: &TsType) -> Self { + pub fn new(module_info: &EsModuleInfo, other: &TsType) -> Self { use deno_ast::swc::ast::TsType::*; match other { TsKeywordType(keyword_type) => { - TsTypeDef::ts_keyword_type(parsed_source, keyword_type) - } - TsThisType(this_type) => { - TsTypeDef::ts_this_type(parsed_source, this_type) + TsTypeDef::ts_keyword_type(module_info, keyword_type) } + TsThisType(this_type) => TsTypeDef::ts_this_type(module_info, this_type), TsFnOrConstructorType(fn_or_con_type) => { - TsTypeDef::ts_fn_or_constructor_type(parsed_source, fn_or_con_type) + TsTypeDef::ts_fn_or_constructor_type(module_info, fn_or_con_type) } - TsTypeRef(type_ref) => TsTypeDef::ts_type_ref(parsed_source, type_ref), + TsTypeRef(type_ref) => TsTypeDef::ts_type_ref(module_info, type_ref), TsTypeQuery(type_query) => { - TsTypeDef::ts_type_query(parsed_source, type_query) + TsTypeDef::ts_type_query(module_info, type_query) } TsTypeLit(type_literal) => { - TsTypeDef::ts_type_lit(parsed_source, type_literal) + TsTypeDef::ts_type_lit(module_info, type_literal) } TsArrayType(array_type) => { - TsTypeDef::ts_array_type(parsed_source, array_type) + TsTypeDef::ts_array_type(module_info, array_type) } TsTupleType(tuple_type) => { - TsTypeDef::ts_tuple_type(parsed_source, tuple_type) + TsTypeDef::ts_tuple_type(module_info, tuple_type) } TsOptionalType(optional_type) => { - TsTypeDef::ts_optional_type(parsed_source, optional_type) - } - TsRestType(rest_type) => { - TsTypeDef::ts_rest_type(parsed_source, rest_type) + TsTypeDef::ts_optional_type(module_info, optional_type) } + TsRestType(rest_type) => TsTypeDef::ts_rest_type(module_info, rest_type), TsUnionOrIntersectionType(union_or_inter) => { - TsTypeDef::ts_union_or_intersection_type(parsed_source, union_or_inter) + TsTypeDef::ts_union_or_intersection_type(module_info, union_or_inter) } TsConditionalType(conditional_type) => { - TsTypeDef::ts_conditional_type(parsed_source, conditional_type) + TsTypeDef::ts_conditional_type(module_info, conditional_type) } TsInferType(infer_type) => { - TsTypeDef::ts_infer_type(parsed_source, infer_type) + TsTypeDef::ts_infer_type(module_info, infer_type) } TsParenthesizedType(paren_type) => { - TsTypeDef::ts_parenthesized_type(parsed_source, paren_type) + TsTypeDef::ts_parenthesized_type(module_info, paren_type) } TsTypeOperator(type_op_type) => { - TsTypeDef::ts_type_operator(parsed_source, type_op_type) + TsTypeDef::ts_type_operator(module_info, type_op_type) } TsIndexedAccessType(indexed_access_type) => { - TsTypeDef::ts_indexed_access_type(parsed_source, indexed_access_type) + TsTypeDef::ts_indexed_access_type(module_info, indexed_access_type) } TsMappedType(mapped_type) => { - TsTypeDef::ts_mapped_type(parsed_source, mapped_type) + TsTypeDef::ts_mapped_type(module_info, mapped_type) } - TsLitType(lit_type) => TsTypeDef::ts_lit_type(parsed_source, lit_type), + TsLitType(lit_type) => TsTypeDef::ts_lit_type(module_info, lit_type), TsTypePredicate(type_predicate_type) => { - TsTypeDef::ts_type_predicate(parsed_source, type_predicate_type) + TsTypeDef::ts_type_predicate(module_info, type_predicate_type) } TsImportType(import_type) => { - TsTypeDef::ts_import_type(parsed_source, import_type) + TsTypeDef::ts_import_type(module_info, import_type) } } } @@ -758,7 +737,7 @@ fn ts_entity_name_to_name(entity_name: &TsEntityName) -> String { #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] #[serde(rename_all = "camelCase")] pub struct TsTypeRefDef { - pub type_params: Option>, + pub type_params: Option>, pub type_name: String, } @@ -803,23 +782,23 @@ pub struct TsFnOrConstructorDef { pub constructor: bool, pub ts_type: TsTypeDef, pub params: Vec, - pub type_params: Vec, + pub type_params: Box<[TsTypeParamDef]>, } impl TsFnOrConstructorDef { - fn arrow_expr(parsed_source: &ParsedSource, expr: &ArrowExpr) -> Self { + fn arrow_expr(module_info: &EsModuleInfo, expr: &ArrowExpr) -> Self { let params = expr .params .iter() - .map(|pat| pat_to_param_def(parsed_source, pat)) + .map(|pat| pat_to_param_def(module_info, pat)) .collect(); let ts_type = expr .return_type .as_deref() - .map(|return_type| TsTypeDef::new(parsed_source, &return_type.type_ann)) + .map(|return_type| TsTypeDef::new(module_info, &return_type.type_ann)) .unwrap_or_else(|| TsTypeDef::keyword("unknown")); let type_params = maybe_type_param_decl_to_type_param_defs( - parsed_source, + module_info, expr.type_params.as_deref(), ); @@ -831,21 +810,21 @@ impl TsFnOrConstructorDef { } } - fn fn_expr(parsed_source: &ParsedSource, expr: &FnExpr) -> Self { + fn fn_expr(module_info: &EsModuleInfo, expr: &FnExpr) -> Self { let params = expr .function .params .iter() - .map(|param| pat_to_param_def(parsed_source, ¶m.pat)) + .map(|param| pat_to_param_def(module_info, ¶m.pat)) .collect(); let ts_type = expr .function .return_type .as_deref() - .map(|return_type| TsTypeDef::new(parsed_source, &return_type.type_ann)) + .map(|return_type| TsTypeDef::new(module_info, &return_type.type_ann)) .unwrap_or_else(|| TsTypeDef::keyword("unknown")); let type_params = maybe_type_param_decl_to_type_param_defs( - parsed_source, + module_info, expr.function.type_params.as_deref(), ); @@ -924,7 +903,7 @@ pub struct ConstructorDef { pub js_doc: JsDoc, pub params: Vec, pub return_type: Option, - pub type_params: Vec, + pub type_params: Box<[TsTypeParamDef]>, pub location: Location, } @@ -953,13 +932,13 @@ pub struct MethodDef { pub computed: bool, pub optional: bool, pub return_type: Option, - pub type_params: Vec, + pub type_params: Box<[TsTypeParamDef]>, } impl From for DocNode { fn from(def: MethodDef) -> DocNode { DocNode::function( - def.name, + def.name.into_boxed_str(), false, def.location, DeclarationKind::Private, @@ -972,7 +951,7 @@ impl From for DocNode { is_async: false, is_generator: false, type_params: def.type_params, - decorators: vec![], + decorators: Box::new([]), }, ) } @@ -1008,13 +987,13 @@ pub struct PropertyDef { pub computed: bool, pub optional: bool, pub ts_type: Option, - pub type_params: Vec, + pub type_params: Box<[TsTypeParamDef]>, } impl From for DocNode { fn from(def: PropertyDef) -> DocNode { DocNode::variable( - def.name, + def.name.into_boxed_str(), false, def.location, DeclarationKind::Private, @@ -1052,7 +1031,7 @@ pub struct CallSignatureDef { pub location: Location, pub params: Vec, pub ts_type: Option, - pub type_params: Vec, + pub type_params: Box<[TsTypeParamDef]>, } impl Display for CallSignatureDef { @@ -1289,7 +1268,7 @@ impl TsTypeDef { } pub fn tpl_literal( - _parsed_source: &ParsedSource, + _module_info: &EsModuleInfo, types: Vec, quasis: &[TplElement], ) -> Self { @@ -1426,23 +1405,23 @@ impl TsTypeDef { } } -pub fn infer_ts_type_from_expr( - parsed_source: &ParsedSource, +pub(crate) fn infer_ts_type_from_expr( + module_info: &EsModuleInfo, expr: &Expr, is_const: bool, ) -> Option { match expr { Expr::Array(arr_lit) => { // e.g.) const n = ["a", 1]; - infer_ts_type_from_arr_lit(parsed_source, arr_lit, false) + infer_ts_type_from_arr_lit(module_info, arr_lit, false) } Expr::Arrow(expr) => { // e.g.) const f = (a: string): void => {}; - infer_ts_type_from_arrow_expr(parsed_source, expr) + infer_ts_type_from_arrow_expr(module_info, expr) } Expr::Fn(expr) => { // e.g.) const f = function a(a:string): void {}; - infer_ts_type_from_fn_expr(parsed_source, expr) + infer_ts_type_from_fn_expr(module_info, expr) } Expr::Lit(lit) => { // e.g.) const n = 100; @@ -1450,15 +1429,15 @@ pub fn infer_ts_type_from_expr( } Expr::New(expr) => { // e.g.) const d = new Date() - infer_ts_type_from_new_expr(parsed_source, expr) + infer_ts_type_from_new_expr(module_info, expr) } Expr::Tpl(tpl) => { // e.g.) const s = `hello`; - Some(infer_ts_type_from_tpl(parsed_source, tpl, is_const)) + Some(infer_ts_type_from_tpl(module_info, tpl, is_const)) } Expr::TsConstAssertion(assertion) => { // e.g.) const s = [] as const; - infer_ts_type_from_const_assertion(parsed_source, assertion) + infer_ts_type_from_const_assertion(module_info, assertion) } Expr::Call(expr) => { // e.g.) const value = Number(123); @@ -1466,11 +1445,11 @@ pub fn infer_ts_type_from_expr( } Expr::Object(obj) => { // e.g.) const value = {foo: "bar"}; - infer_ts_type_from_obj(parsed_source, obj) + infer_ts_type_from_obj(module_info, obj) } Expr::TsSatisfies(satisfies) => { // e.g.) const value = {foo: "bar"} satifies Record; - infer_ts_type_from_expr(parsed_source, &satisfies.expr, is_const) + infer_ts_type_from_expr(module_info, &satisfies.expr, is_const) } Expr::Update(_) => { // e.g.) let foo = 0; @@ -1479,24 +1458,24 @@ pub fn infer_ts_type_from_expr( } Expr::TsTypeAssertion(assertion) => { // e.g.) export const foo = 1; - Some(TsTypeDef::new(parsed_source, &assertion.type_ann)) + Some(TsTypeDef::new(module_info, &assertion.type_ann)) } Expr::TsAs(as_expr) => { // e.g.) export const foo = 1 as string; - Some(TsTypeDef::new(parsed_source, &as_expr.type_ann)) + Some(TsTypeDef::new(module_info, &as_expr.type_ann)) } Expr::Paren(paren) => { // e.g.) export const foo = (1); - infer_ts_type_from_expr(parsed_source, &paren.expr, is_const) + infer_ts_type_from_expr(module_info, &paren.expr, is_const) } Expr::Await(await_expr) => { // e.g.) export const foo = await 1; - infer_ts_type_from_expr(parsed_source, &await_expr.arg, is_const) + infer_ts_type_from_expr(module_info, &await_expr.arg, is_const) } Expr::Cond(cond) => { // e.g.) export const foo = true ? "a" : 1; - let left = infer_ts_type_from_expr(parsed_source, &cond.cons, is_const)?; - let right = infer_ts_type_from_expr(parsed_source, &cond.alt, is_const)?; + let left = infer_ts_type_from_expr(module_info, &cond.cons, is_const)?; + let right = infer_ts_type_from_expr(module_info, &cond.alt, is_const)?; Some(TsTypeDef { union: Some(vec![left, right]), @@ -1508,7 +1487,7 @@ pub fn infer_ts_type_from_expr( // e.g.) export const foo = (true ? "a" : null)!; // e.g.) export const foo = null!; let with_null = - infer_ts_type_from_expr(parsed_source, &non_null.expr, is_const)?; + infer_ts_type_from_expr(module_info, &non_null.expr, is_const)?; if let Some(union) = with_null.union { let mut non_null_union = union @@ -1591,20 +1570,20 @@ pub fn infer_ts_type_from_expr( } } -pub fn infer_simple_ts_type_from_init( - parsed_source: &ParsedSource, +pub(crate) fn infer_simple_ts_type_from_init( + module_info: &EsModuleInfo, init: Option<&Expr>, is_const: bool, ) -> Option { if let Some(init_expr) = init { - infer_ts_type_from_expr(parsed_source, init_expr, is_const) + infer_ts_type_from_expr(module_info, init_expr, is_const) } else { None } } fn infer_ts_type_from_arr_lit( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, arr_lit: &ArrayLit, is_const: bool, ) -> Option { @@ -1612,7 +1591,7 @@ fn infer_ts_type_from_arr_lit( for expr in arr_lit.elems.iter().flatten() { if expr.spread.is_none() { if let Some(ts_type) = - infer_ts_type_from_expr(parsed_source, &expr.expr, is_const) + infer_ts_type_from_expr(module_info, &expr.expr, is_const) { if !defs.contains(&ts_type) { defs.push(ts_type); @@ -1660,13 +1639,13 @@ fn infer_ts_type_from_arr_lit( } fn infer_ts_type_from_arrow_expr( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, expr: &ArrowExpr, ) -> Option { Some(TsTypeDef { kind: Some(TsTypeDefKind::FnOrConstructor), fn_or_constructor: Some(Box::new(TsFnOrConstructorDef::arrow_expr( - parsed_source, + module_info, expr, ))), ..Default::default() @@ -1674,13 +1653,13 @@ fn infer_ts_type_from_arrow_expr( } fn infer_ts_type_from_fn_expr( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, expr: &FnExpr, ) -> Option { Some(TsTypeDef { kind: Some(TsTypeDefKind::FnOrConstructor), fn_or_constructor: Some(Box::new(TsFnOrConstructorDef::fn_expr( - parsed_source, + module_info, expr, ))), ..Default::default() @@ -1688,15 +1667,15 @@ fn infer_ts_type_from_fn_expr( } fn infer_ts_type_from_const_assertion( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, assertion: &TsConstAssertion, ) -> Option { match &*assertion.expr { Expr::Array(arr_lit) => { // e.g.) const n = ["a", 1] as const; - infer_ts_type_from_arr_lit(parsed_source, arr_lit, true) + infer_ts_type_from_arr_lit(module_info, arr_lit, true) } - _ => infer_ts_type_from_expr(parsed_source, &assertion.expr, true), + _ => infer_ts_type_from_expr(module_info, &assertion.expr, true), } } @@ -1737,7 +1716,7 @@ fn infer_ts_type_from_lit(lit: &Lit, is_const: bool) -> Option { } fn infer_ts_type_from_new_expr( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, new_expr: &NewExpr, ) -> Option { match new_expr.callee.as_ref() { @@ -1746,7 +1725,7 @@ fn infer_ts_type_from_new_expr( kind: Some(TsTypeDefKind::TypeRef), type_ref: Some(TsTypeRefDef { type_params: new_expr.type_args.as_ref().map(|init| { - maybe_type_param_instantiation_to_type_defs(parsed_source, Some(init)) + maybe_type_param_instantiation_to_type_defs(module_info, Some(init)) }), type_name: ident.sym.to_string(), }), @@ -1781,10 +1760,10 @@ fn infer_ts_type_from_call_expr(call_expr: &CallExpr) -> Option { } fn infer_ts_type_from_obj( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, obj: &ObjectLit, ) -> Option { - let (methods, properties) = infer_ts_type_from_obj_inner(parsed_source, obj); + let (methods, properties) = infer_ts_type_from_obj_inner(module_info, obj); if methods.is_empty() && properties.is_empty() { None } else { @@ -1793,7 +1772,7 @@ fn infer_ts_type_from_obj( } fn infer_ts_type_from_obj_inner( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, obj: &ObjectLit, ) -> (Vec, Vec) { let mut methods = Vec::::new(); @@ -1807,86 +1786,87 @@ fn infer_ts_type_from_obj_inner( properties.push(PropertyDef { name: shorthand.sym.to_string(), js_doc: Default::default(), - location: get_location(parsed_source, shorthand.start()), + location: get_location(module_info, shorthand.start()), params: vec![], readonly: false, computed: false, optional: false, ts_type: None, - type_params: vec![], + type_params: Box::new([]), }); } Prop::KeyValue(kv) => { properties.push(PropertyDef { - name: prop_name_to_string(parsed_source, &kv.key), + name: prop_name_to_string(module_info, &kv.key), js_doc: Default::default(), - location: get_location(parsed_source, kv.start()), + location: get_location(module_info, kv.start()), params: vec![], readonly: false, computed: kv.key.is_computed(), optional: false, - ts_type: infer_ts_type_from_expr(parsed_source, &kv.value, false), - type_params: vec![], + ts_type: infer_ts_type_from_expr(module_info, &kv.value, false), + type_params: Box::new([]), }); } Prop::Assign(_) => unreachable!("This is invalid for object literal!"), Prop::Getter(getter) => { - let name = prop_name_to_string(parsed_source, &getter.key); + let name = prop_name_to_string(module_info, &getter.key); let computed = getter.key.is_computed(); let return_type = getter .type_ann .as_ref() - .map(|type_ann| TsTypeDef::new(parsed_source, &type_ann.type_ann)); + .map(|type_ann| TsTypeDef::new(module_info, &type_ann.type_ann)); methods.push(MethodDef { name, js_doc: Default::default(), kind: MethodKind::Getter, - location: get_location(parsed_source, getter.start()), + location: get_location(module_info, getter.start()), params: vec![], computed, optional: false, return_type, - type_params: vec![], + type_params: Box::new([]), }); } Prop::Setter(setter) => { - let name = prop_name_to_string(parsed_source, &setter.key); + let name = prop_name_to_string(module_info, &setter.key); let computed = setter.key.is_computed(); - let param = pat_to_param_def(parsed_source, setter.param.as_ref()); + let param = pat_to_param_def(module_info, setter.param.as_ref()); methods.push(MethodDef { name, js_doc: Default::default(), kind: MethodKind::Setter, - location: get_location(parsed_source, setter.start()), + location: get_location(module_info, setter.start()), params: vec![param], computed, optional: false, return_type: None, - type_params: vec![], + type_params: Box::new([]), }); } Prop::Method(method) => { - let name = prop_name_to_string(parsed_source, &method.key); + let name = prop_name_to_string(module_info, &method.key); let computed = method.key.is_computed(); let params = method .function .params .iter() - .map(|param| param_to_param_def(parsed_source, param)) + .map(|param| param_to_param_def(module_info, param)) .collect(); - let return_type = - method.function.return_type.as_ref().map(|type_ann| { - TsTypeDef::new(parsed_source, &type_ann.type_ann) - }); + let return_type = method + .function + .return_type + .as_ref() + .map(|type_ann| TsTypeDef::new(module_info, &type_ann.type_ann)); let type_params = maybe_type_param_decl_to_type_param_defs( - parsed_source, + module_info, method.function.type_params.as_deref(), ); methods.push(MethodDef { name, js_doc: Default::default(), kind: MethodKind::Method, - location: get_location(parsed_source, method.start()), + location: get_location(module_info, method.start()), params, computed, optional: false, @@ -1898,7 +1878,7 @@ fn infer_ts_type_from_obj_inner( PropOrSpread::Spread(spread) => { if let Expr::Object(obj) = &*spread.expr { let (spread_methods, spread_properties) = - infer_ts_type_from_obj_inner(parsed_source, obj); + infer_ts_type_from_obj_inner(module_info, obj); methods.extend(spread_methods); properties.extend(spread_properties); } @@ -1909,18 +1889,18 @@ fn infer_ts_type_from_obj_inner( } fn infer_ts_type_from_tpl( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, tpl: &Tpl, is_const: bool, ) -> TsTypeDef { let exprs = tpl .exprs .iter() - .map(|expr| infer_ts_type_from_expr(parsed_source, expr, is_const)) + .map(|expr| infer_ts_type_from_expr(module_info, expr, is_const)) .collect::>>(); if let Some(exprs) = exprs { - TsTypeDef::tpl_literal(parsed_source, exprs, &tpl.quasis) + TsTypeDef::tpl_literal(module_info, exprs, &tpl.quasis) } else { TsTypeDef::string_with_repr("string") } @@ -2141,17 +2121,17 @@ impl Display for TsTypeDef { } } -pub fn maybe_type_param_instantiation_to_type_defs( - parsed_source: &ParsedSource, +pub(crate) fn maybe_type_param_instantiation_to_type_defs( + module_info: &EsModuleInfo, maybe_type_param_instantiation: Option<&TsTypeParamInstantiation>, -) -> Vec { +) -> Box<[TsTypeDef]> { if let Some(type_param_instantiation) = maybe_type_param_instantiation { type_param_instantiation .params .iter() - .map(|type_param| TsTypeDef::new(parsed_source, type_param)) - .collect::>() + .map(|type_param| TsTypeDef::new(module_info, type_param)) + .collect::>() } else { - vec![] + Box::new([]) } } diff --git a/src/ts_type_param.rs b/src/ts_type_param.rs index 576a471d..bd5a87b1 100644 --- a/src/ts_type_param.rs +++ b/src/ts_type_param.rs @@ -3,7 +3,7 @@ use crate::ts_type::TsTypeDef; use deno_ast::swc::ast::TsTypeParam; use deno_ast::swc::ast::TsTypeParamDecl; -use deno_ast::ParsedSource; +use deno_graph::symbols::EsModuleInfo; use serde::Deserialize; use serde::Serialize; use std::fmt::Display; @@ -36,16 +36,16 @@ impl Display for TsTypeParamDef { } impl TsTypeParamDef { - pub fn new(parsed_source: &ParsedSource, param: &TsTypeParam) -> Self { + pub fn new(module_info: &EsModuleInfo, param: &TsTypeParam) -> Self { let name = param.name.sym.to_string(); let constraint = param .constraint .as_ref() - .map(|constraint| TsTypeDef::new(parsed_source, constraint)); + .map(|constraint| TsTypeDef::new(module_info, constraint)); let default = param .default .as_ref() - .map(|default| TsTypeDef::new(parsed_source, default)); + .map(|default| TsTypeDef::new(module_info, default)); TsTypeParamDef { name, @@ -55,17 +55,17 @@ impl TsTypeParamDef { } } -pub fn maybe_type_param_decl_to_type_param_defs( - parsed_source: &ParsedSource, +pub(crate) fn maybe_type_param_decl_to_type_param_defs( + module_info: &EsModuleInfo, maybe_type_param_decl: Option<&TsTypeParamDecl>, -) -> Vec { +) -> Box<[TsTypeParamDef]> { if let Some(type_params_decl) = maybe_type_param_decl { type_params_decl .params .iter() - .map(|type_param| TsTypeParamDef::new(parsed_source, type_param)) - .collect::>() + .map(|type_param| TsTypeParamDef::new(module_info, type_param)) + .collect::>() } else { - vec![] + Box::new([]) } } diff --git a/src/type_alias.rs b/src/type_alias.rs index bdaf0fb0..14ebadd5 100644 --- a/src/type_alias.rs +++ b/src/type_alias.rs @@ -2,7 +2,7 @@ use crate::ts_type::TsTypeDef; use crate::ts_type_param::maybe_type_param_decl_to_type_param_defs; use crate::ts_type_param::TsTypeParamDef; -use deno_ast::ParsedSource; +use deno_graph::symbols::EsModuleInfo; use serde::Deserialize; use serde::Serialize; @@ -10,17 +10,17 @@ use serde::Serialize; #[serde(rename_all = "camelCase")] pub struct TypeAliasDef { pub ts_type: TsTypeDef, - pub type_params: Vec, + pub type_params: Box<[TsTypeParamDef]>, } pub fn get_doc_for_ts_type_alias_decl( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, type_alias_decl: &deno_ast::swc::ast::TsTypeAliasDecl, ) -> (String, TypeAliasDef) { let alias_name = type_alias_decl.id.sym.to_string(); - let ts_type = TsTypeDef::new(parsed_source, &type_alias_decl.type_ann); + let ts_type = TsTypeDef::new(module_info, &type_alias_decl.type_ann); let type_params = maybe_type_param_decl_to_type_param_defs( - parsed_source, + module_info, type_alias_decl.type_params.as_deref(), ); let type_alias_def = TypeAliasDef { diff --git a/src/util/swc.rs b/src/util/swc.rs index f1d807b0..e1067da1 100644 --- a/src/util/swc.rs +++ b/src/util/swc.rs @@ -8,6 +8,7 @@ use deno_ast::SourcePos; use deno_ast::SourceRange; use deno_ast::SourceRangedForSpanned; use deno_ast::SourceTextInfo; +use deno_graph::symbols::EsModuleInfo; use regex::Regex; use crate::js_doc::JsDoc; @@ -53,10 +54,10 @@ pub(crate) fn js_doc_for_range_include_ignore( } pub(crate) fn js_doc_for_range( - parsed_source: &ParsedSource, + module_info: &EsModuleInfo, range: &SourceRange, ) -> Option { - let js_doc = js_doc_for_range_include_ignore(parsed_source, range); + let js_doc = js_doc_for_range_include_ignore(module_info.source(), range); if js_doc.tags.contains(&JsDocTag::Ignore) { None } else { @@ -71,9 +72,8 @@ pub(crate) fn module_js_doc_for_source( parsed_source: &ParsedSource, ) -> Option> { let shebang_length = parsed_source - .module() - .shebang - .as_ref() + .program_ref() + .shebang() .map_or(0, |shebang| shebang.len()); let pos_leading_comment = parsed_source.comments().leading_map().keys().min()?; @@ -91,7 +91,11 @@ pub(crate) fn module_js_doc_for_source( }) }) { let js_doc = parse_js_doc(js_doc_comment); - if js_doc.tags.contains(&JsDocTag::Module) { + if js_doc + .tags + .iter() + .any(|tag| matches!(tag, JsDocTag::Module { .. })) + { if js_doc.tags.contains(&JsDocTag::Ignore) { return Some(None); } @@ -101,10 +105,10 @@ pub(crate) fn module_js_doc_for_source( None } -pub fn get_location(parsed_source: &ParsedSource, pos: SourcePos) -> Location { +pub fn get_location(module_info: &EsModuleInfo, pos: SourcePos) -> Location { get_text_info_location( - parsed_source.specifier().as_str(), - parsed_source.text_info_lazy(), + module_info.specifier().as_str(), + module_info.source().text_info_lazy(), pos, ) } @@ -119,7 +123,7 @@ pub fn get_text_info_location( text_info.line_and_column_display_with_indent_width(pos, 4); let byte_index = pos.as_byte_index(text_info.range().start); Location { - filename: specifier.to_string(), + filename: specifier.into(), // todo(#150): make 0-indexed line: line_and_column_index.line_number, col: line_and_column_index.column_number - 1, diff --git a/src/variable.rs b/src/variable.rs index fa25f482..fcf9dca7 100644 --- a/src/variable.rs +++ b/src/variable.rs @@ -2,7 +2,6 @@ use deno_ast::swc::ast::Pat; use deno_ast::swc::ast::VarDeclKind; -use deno_ast::ParsedSource; use deno_graph::symbols::EsModuleInfo; use deno_graph::symbols::SymbolNodeRef; use serde::Deserialize; @@ -41,7 +40,7 @@ pub fn get_docs_for_var_declarator( Pat::Invalid(_) | Pat::Expr(_) | Pat::Rest(_) | Pat::Assign(_) => None, }; let maybe_ts_type = maybe_ts_type_ann - .map(|def| TsTypeDef::new(module_info.source(), &def.type_ann)) + .map(|def| TsTypeDef::new(module_info, &def.type_ann)) .or_else(|| { if let Some(ref_name) = ref_name { module_info.symbol_from_swc(&ref_name).and_then(|symbol| { @@ -53,15 +52,12 @@ pub fn get_docs_for_var_declarator( { if let Pat::Ident(ident) = &var_declarator.name { if let Some(type_ann) = &ident.type_ann { - return Some(TsTypeDef::new( - module_info.source(), - &type_ann.type_ann, - )); + return Some(TsTypeDef::new(module_info, &type_ann.type_ann)); } } } let maybe_type_ann = infer_simple_ts_type_from_init( - module_info.source(), + module_info, var_declarator.init.as_deref(), var_decl.kind == VarDeclKind::Const, ); @@ -77,7 +73,7 @@ pub fn get_docs_for_var_declarator( }) .or_else(|| { infer_simple_ts_type_from_init( - module_info.source(), + module_info, var_declarator.init.as_deref(), var_decl.kind == VarDeclKind::Const, ) @@ -97,14 +93,14 @@ pub fn get_docs_for_var_declarator( var_decl.kind, maybe_ts_type.as_ref(), &mut items, - module_info.source(), + module_info, ), Pat::Array(arr) => get_vars_from_array_destructuring( arr, var_decl.kind, maybe_ts_type.as_ref(), &mut items, - module_info.source(), + module_info, ), Pat::Expr(_) | Pat::Invalid(_) | Pat::Assign(_) | Pat::Rest(_) => {} } @@ -116,14 +112,14 @@ fn get_vars_from_obj_destructuring( kind: VarDeclKind, maybe_ts_type: Option<&TsTypeDef>, items: &mut Vec<(String, VariableDef)>, - source: &ParsedSource, + module_info: &EsModuleInfo, ) { let mut reached_rest = false; for prop in &obj.props { assert!(!reached_rest, "object rest is always last"); let (name, reassign_name, rest_type_ann) = match prop { deno_ast::swc::ast::ObjectPatProp::KeyValue(kv) => ( - crate::params::prop_name_to_string(source, &kv.key), + crate::params::prop_name_to_string(module_info, &kv.key), match &*kv.value { Pat::Ident(ident) => Some(ident.sym.to_string()), Pat::Assign(assign) => { @@ -183,7 +179,8 @@ fn get_vars_from_obj_destructuring( }) }) } else { - rest_type_ann.map(|type_ann| TsTypeDef::new(source, &type_ann.type_ann)) + rest_type_ann + .map(|type_ann| TsTypeDef::new(module_info, &type_ann.type_ann)) }; let variable_def = VariableDef { ts_type, kind }; @@ -196,7 +193,7 @@ fn get_vars_from_array_destructuring( kind: VarDeclKind, maybe_ts_type: Option<&TsTypeDef>, items: &mut Vec<(String, VariableDef)>, - source: &ParsedSource, + module_info: &EsModuleInfo, ) { let mut reached_rest = false; for (i, elem) in arr.elems.iter().enumerate() { @@ -249,7 +246,7 @@ fn get_vars_from_array_destructuring( }) } else { rest_type_ann - .map(|type_ann| TsTypeDef::new(source, &type_ann.type_ann)) + .map(|type_ann| TsTypeDef::new(module_info, &type_ann.type_ann)) .or_else(|| { maybe_ts_type.and_then(|ts_type| { if ts_type.kind == Some(TsTypeDefKind::Array) { diff --git a/tailwind.config.ts b/tailwind.config.ts index e2795aca..02a5ba78 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -1,4 +1,4 @@ -import { type Config } from "npm:tailwindcss@3.4.3"; +import { type Config } from "tailwindcss"; const TAG_PURPLE = "#7B61FF"; const TAG_CYAN = "#0CAFC6"; @@ -63,6 +63,9 @@ export default { margin: { "indent": "2ch", }, + maxWidth: { + "prose": "75ch", + }, }, }, darkMode: "class", diff --git a/tests/helpers/mod.rs b/tests/helpers/mod.rs index 5d9db62f..a2f3030b 100644 --- a/tests/helpers/mod.rs +++ b/tests/helpers/mod.rs @@ -60,16 +60,19 @@ impl TestBuilder { ) .await; graph.valid().unwrap(); + let entrypoints = &[entry_point_url]; let parser = DocParser::new( &graph, &analyzer, + entrypoints, DocParserOptions { private: self.private, diagnostics: true, }, ) .unwrap(); - let entries = parser.parse_with_reexports(&entry_point_url).unwrap(); + + let entries = parser.parse().unwrap().into_values().next().unwrap(); let doc = DocPrinter::new(&entries, false, self.private).to_string(); let diagnostics = parser.take_diagnostics(); diff --git a/tests/html_test.rs b/tests/html_test.rs index b585cf3d..1e262f43 100644 --- a/tests/html_test.rs +++ b/tests/html_test.rs @@ -6,6 +6,7 @@ use deno_doc::html::*; use deno_doc::DocNode; use deno_doc::DocParser; use deno_doc::DocParserOptions; +use deno_graph::source::LoadError; use deno_graph::source::LoadFuture; use deno_graph::source::LoadOptions; use deno_graph::source::LoadResponse; @@ -18,6 +19,7 @@ use futures::future; use indexmap::IndexMap; use std::fs; use std::rc::Rc; +use std::sync::Arc; struct SourceFileLoader {} @@ -37,7 +39,7 @@ impl Loader for SourceFileLoader { content: content.into(), }) }) - .map_err(|err| err.into()) + .map_err(|err| LoadError::Other(Arc::new(err))) } else { Ok(None) }; @@ -45,7 +47,7 @@ impl Loader for SourceFileLoader { } } -struct EmptyResolver {} +struct EmptyResolver; impl HrefResolver for EmptyResolver { fn resolve_path( @@ -68,17 +70,44 @@ impl HrefResolver for EmptyResolver { None } - fn resolve_usage(&self, current_resolve: UrlResolveKind) -> Option { - current_resolve - .get_file() - .map(|current_file| current_file.path.to_string()) + fn resolve_source(&self, _location: &deno_doc::Location) -> Option { + None } - fn resolve_source(&self, _location: &deno_doc::Location) -> Option { + fn resolve_external_jsdoc_module( + &self, + _module: &str, + _symbol: Option<&str>, + ) -> Option<(String, String)> { None } } +impl UsageComposer for EmptyResolver { + fn is_single_mode(&self) -> bool { + true + } + + fn compose( + &self, + current_resolve: UrlResolveKind, + usage_to_md: UsageToMd, + ) -> IndexMap { + current_resolve + .get_file() + .map(|current_file| { + IndexMap::from([( + UsageComposerEntry { + name: "".to_string(), + icon: None, + }, + usage_to_md(current_file.path.as_str(), None), + )]) + }) + .unwrap_or_default() + } +} + async fn get_files(subpath: &str) -> IndexMap> { let files = fs::read_dir( std::env::current_dir() @@ -89,13 +118,14 @@ async fn get_files(subpath: &str) -> IndexMap> { ) .unwrap(); - let source_files: Vec = files + let mut source_files: Vec = files .into_iter() .map(|entry| { let entry = entry.unwrap(); ModuleSpecifier::from_file_path(entry.path()).unwrap() }) .collect(); + source_files.sort(); let loader = SourceFileLoader {}; let analyzer = CapturingModuleAnalyzer::default(); @@ -111,45 +141,96 @@ async fn get_files(subpath: &str) -> IndexMap> { ) .await; - let parser = DocParser::new( + DocParser::new( &graph, &analyzer, + &source_files, DocParserOptions { diagnostics: false, private: false, }, ) + .unwrap() + .parse() + .unwrap() +} + +#[tokio::test] +async fn html_doc_dts() { + let ctx = GenerateCtx::create_basic( + GenerateOptions { + package_name: None, + main_entrypoint: None, + href_resolver: Rc::new(EmptyResolver), + usage_composer: Rc::new(EmptyResolver), + rewrite_map: None, + category_docs: None, + disable_search: false, + symbol_redirect_map: None, + default_symbol_map: None, + markdown_renderer: comrak::create_renderer(None, None, None), + markdown_stripper: Rc::new(comrak::strip), + head_inject: None, + }, + get_files("dts").await, + ) .unwrap(); + let files = generate(ctx).unwrap(); - let mut source_files = source_files.clone(); - source_files.sort(); - let mut doc_nodes_by_url = IndexMap::with_capacity(source_files.len()); - for source_file in source_files { - let nodes = parser.parse_with_reexports(&source_file).unwrap(); - doc_nodes_by_url.insert(source_file, nodes); - } + let mut file_names = files.keys().collect::>(); + file_names.sort(); + + assert_eq!( + file_names, + [ + "./all_symbols.html", + "./index.html", + "./~/ResponseInit.html", + "./~/ResponseInit.status.html", + "./~/ResponseInit.statusText.html", + "./~/WebSocket.OPEN.html", + "./~/WebSocket.bufferedAmount.html", + "./~/WebSocket.html", + "./~/WebSocket.prototype.html", + "comrak.css", + "fuse.js", + "page.css", + "reset.css", + "script.js", + "search.js", + "search_index.js", + "styles.css" + ] + ); - doc_nodes_by_url + for file_name in file_names { + if !file_name.ends_with(".css") { + insta::assert_snapshot!(files.get(file_name).unwrap()); + } + } } #[tokio::test] -async fn html_doc_files() { - let files = generate( +async fn html_doc_files_single() { + let ctx = GenerateCtx::create_basic( GenerateOptions { package_name: None, main_entrypoint: None, - href_resolver: Rc::new(EmptyResolver {}), - usage_composer: None, + href_resolver: Rc::new(EmptyResolver), + usage_composer: Rc::new(EmptyResolver), rewrite_map: None, - composable_output: false, category_docs: None, disable_search: false, symbol_redirect_map: None, default_symbol_map: None, + markdown_renderer: comrak::create_renderer(None, None, None), + markdown_stripper: Rc::new(comrak::strip), + head_inject: None, }, get_files("single").await, ) .unwrap(); + let files = generate(ctx).unwrap(); let mut file_names = files.keys().collect::>(); file_names.sort(); @@ -165,6 +246,7 @@ async fn html_doc_files() { "./~/Foo.prototype.html", "./~/Foobar.html", "./~/Foobar.prototype.html", + "comrak.css", "fuse.js", "page.css", "reset.css", @@ -175,56 +257,56 @@ async fn html_doc_files() { ] ); - #[cfg(all(not(feature = "syntect"), not(feature = "tree-sitter")))] - { - insta::assert_snapshot!(files.get("./all_symbols.html").unwrap()); - insta::assert_snapshot!(files.get("./index.html").unwrap()); - insta::assert_snapshot!(files.get("./~/Bar.html").unwrap()); - insta::assert_snapshot!(files.get("./~/Bar.prototype.html").unwrap()); - insta::assert_snapshot!(files.get("./~/Foo.html").unwrap()); - insta::assert_snapshot!(files.get("./~/Foo.prototype.html").unwrap()); - insta::assert_snapshot!(files.get("./~/Foobar.html").unwrap()); - insta::assert_snapshot!(files.get("./~/Foobar.prototype.html").unwrap()); - insta::assert_snapshot!(files.get("fuse.js").unwrap()); - insta::assert_snapshot!(files.get("script.js").unwrap()); - insta::assert_snapshot!(files.get("search.js").unwrap()); - insta::assert_snapshot!(files.get("search_index.js").unwrap()); + for file_name in file_names { + if !file_name.ends_with(".css") { + insta::assert_snapshot!(files.get(file_name).unwrap()); + } } } #[tokio::test] -async fn html_doc_files_rewrite() { +async fn html_doc_files_multiple() { let multiple_dir = std::env::current_dir() .unwrap() .join("tests") .join("testdata") .join("multiple"); let mut rewrite_map = IndexMap::new(); - rewrite_map.insert( - ModuleSpecifier::from_file_path(multiple_dir.join("a.ts")).unwrap(), - ".".to_string(), - ); + let main_specifier = + ModuleSpecifier::from_file_path(multiple_dir.join("a.ts")).unwrap(); + rewrite_map.insert(main_specifier.clone(), ".".to_string()); rewrite_map.insert( ModuleSpecifier::from_file_path(multiple_dir.join("b.ts")).unwrap(), "foo".to_string(), ); + rewrite_map.insert( + ModuleSpecifier::from_file_path(multiple_dir.join("c.ts")).unwrap(), + "c".to_string(), + ); + rewrite_map.insert( + ModuleSpecifier::from_file_path(multiple_dir.join("_d.ts")).unwrap(), + "d".to_string(), + ); - let files = generate( + let ctx = GenerateCtx::create_basic( GenerateOptions { package_name: None, - main_entrypoint: None, - href_resolver: Rc::new(EmptyResolver {}), - usage_composer: None, + main_entrypoint: Some(main_specifier), + href_resolver: Rc::new(EmptyResolver), + usage_composer: Rc::new(EmptyResolver), rewrite_map: Some(rewrite_map), - composable_output: false, category_docs: None, disable_search: false, symbol_redirect_map: None, default_symbol_map: None, + markdown_renderer: comrak::create_renderer(None, None, None), + markdown_stripper: Rc::new(comrak::strip), + head_inject: None, }, get_files("multiple").await, ) .unwrap(); + let files = generate(ctx).unwrap(); let mut file_names = files.keys().collect::>(); file_names.sort(); @@ -236,24 +318,68 @@ async fn html_doc_files_rewrite() { "./index.html", "./~/A.html", "./~/A.prototype.html", + "./~/AbstractClass.html", + "./~/AbstractClass.prototype.foo.html", + "./~/AbstractClass.prototype.getter.html", + "./~/AbstractClass.prototype.html", + "./~/AbstractClass.prototype.method.html", "./~/B.html", "./~/B.prototype.html", "./~/Bar.html", "./~/Bar.prototype.html", + "./~/Baz.bar.html", "./~/Baz.foo.html", "./~/Baz.html", + "./~/CompoundType.bufferedAmount.html", + "./~/CompoundType.html", + "./~/EmptyInterface.html", + "./~/Enum.html", + "./~/Enum2.html", "./~/Foo.bar.html", "./~/Foo.html", "./~/Foo.prototype.\">.html", + "./~/Foo.prototype.[Symbol.iterator].html", "./~/Foo.prototype.foo.html", + "./~/Foo.prototype.getter.html", + "./~/Foo.prototype.getterAndSetter.html", "./~/Foo.prototype.html", + "./~/Foo.prototype.methodWithOverloads.html", + "./~/Foo.prototype.protectedProperty.html", + "./~/Foo.prototype.readonlyProperty.html", + "./~/Foo.prototype.setter.html", + "./~/Foo.prototype.test.html", + "./~/Foo.staticMethod.html", + "./~/Foo.staticSetter.html", "./~/Foobar.html", "./~/Foobar.prototype.html", + "./~/Hello.ab.html", + "./~/Hello.computedMethod.html", "./~/Hello.html", + "./~/Hello.optionalMethod.html", + "./~/Hello.test.html", "./~/Hello.world.html", + "./~/Hello.x.html", + "./~/InterfaceWithIndexSignature.html", + "./~/Testing.externalFunction.html", + "./~/Testing.html", + "./~/Testing.prototype.html", + "./~/Testing.t.html", + "./~/Testing.x.html", + "./~/TypeAlias.html", + "./~/anotherVariable.bar.html", + "./~/anotherVariable.foo.html", + "./~/anotherVariable.html", "./~/c.html", "./~/d.html", + "./~/functionWithOptionalParameters.html", "./~/qaz.html", + "./~/someVariable.html", + "./~/x.html", + "c/index.html", + "c/~/x.html", + "comrak.css", + "d/index.html", + "d/~/externalFunction.html", "foo/index.html", "foo/~/default.html", "foo/~/x.html", @@ -267,31 +393,10 @@ async fn html_doc_files_rewrite() { ] ); - #[cfg(all(not(feature = "syntect"), not(feature = "tree-sitter")))] - { - insta::assert_snapshot!(files.get("./all_symbols.html").unwrap()); - insta::assert_snapshot!(files.get("./index.html").unwrap()); - insta::assert_snapshot!(files.get("./~/Bar.html").unwrap()); - insta::assert_snapshot!(files.get("./~/Bar.prototype.html").unwrap()); - insta::assert_snapshot!(files.get("./~/Baz.html").unwrap()); - insta::assert_snapshot!(files.get("./~/Baz.foo.html").unwrap()); - insta::assert_snapshot!(files.get("./~/Foo.html").unwrap()); - insta::assert_snapshot!(files.get("./~/Foo.bar.html").unwrap()); - insta::assert_snapshot!(files - .get("./~/Foo.prototype.\">.html") - .unwrap()); - insta::assert_snapshot!(files.get("./~/Foo.prototype.foo.html").unwrap()); - insta::assert_snapshot!(files.get("./~/Foo.prototype.html").unwrap()); - insta::assert_snapshot!(files.get("./~/Foobar.html").unwrap()); - insta::assert_snapshot!(files.get("./~/Foobar.prototype.html").unwrap()); - insta::assert_snapshot!(files.get("./~/Hello.html").unwrap()); - insta::assert_snapshot!(files.get("./~/Hello.world.html").unwrap()); - insta::assert_snapshot!(files.get("foo/index.html").unwrap()); - insta::assert_snapshot!(files.get("foo/~/x.html").unwrap()); - insta::assert_snapshot!(files.get("fuse.js").unwrap()); - insta::assert_snapshot!(files.get("script.js").unwrap()); - insta::assert_snapshot!(files.get("search.js").unwrap()); - insta::assert_snapshot!(files.get("search_index.js").unwrap()); + for file_name in file_names { + if !file_name.ends_with(".css") { + insta::assert_snapshot!(files.get(file_name).unwrap()); + } } } @@ -314,6 +419,14 @@ async fn symbol_group() { ModuleSpecifier::from_file_path(multiple_dir.join("b.ts")).unwrap(), "foo".to_string(), ); + rewrite_map.insert( + ModuleSpecifier::from_file_path(multiple_dir.join("c.ts")).unwrap(), + "c".to_string(), + ); + rewrite_map.insert( + ModuleSpecifier::from_file_path(multiple_dir.join("_d.ts")).unwrap(), + "d".to_string(), + ); let ctx = GenerateCtx::new( GenerateOptions { @@ -321,14 +434,16 @@ async fn symbol_group() { main_entrypoint: Some( ModuleSpecifier::from_file_path(multiple_dir.join("a.ts")).unwrap(), ), - href_resolver: Rc::new(EmptyResolver {}), - usage_composer: None, + href_resolver: Rc::new(EmptyResolver), + usage_composer: Rc::new(EmptyResolver), rewrite_map: Some(rewrite_map), - composable_output: false, category_docs: None, disable_search: false, symbol_redirect_map: None, default_symbol_map: None, + markdown_renderer: comrak::create_renderer(None, None, None), + markdown_stripper: Rc::new(comrak::strip), + head_inject: None, }, None, Default::default(), @@ -360,11 +475,10 @@ async fn symbol_group() { ); let html_head_ctx = pages::HtmlHeadCtx::new( + &ctx, &root, - &symbol_group_ctx.name, - ctx.package_name.as_ref(), + Some(&symbol_group_ctx.name), Some(short_path), - false, ); Some(pages::SymbolPageCtx { @@ -382,7 +496,6 @@ async fn symbol_group() { } } - #[cfg(all(not(feature = "syntect"), not(feature = "tree-sitter")))] insta::assert_json_snapshot!(files); } @@ -405,6 +518,14 @@ async fn symbol_search() { ModuleSpecifier::from_file_path(multiple_dir.join("b.ts")).unwrap(), "foo".to_string(), ); + rewrite_map.insert( + ModuleSpecifier::from_file_path(multiple_dir.join("c.ts")).unwrap(), + "c".to_string(), + ); + rewrite_map.insert( + ModuleSpecifier::from_file_path(multiple_dir.join("_d.ts")).unwrap(), + "_d".to_string(), + ); let ctx = GenerateCtx::new( GenerateOptions { @@ -412,14 +533,16 @@ async fn symbol_search() { main_entrypoint: Some( ModuleSpecifier::from_file_path(multiple_dir.join("a.ts")).unwrap(), ), - href_resolver: Rc::new(EmptyResolver {}), - usage_composer: None, + href_resolver: Rc::new(EmptyResolver), + usage_composer: Rc::new(EmptyResolver), rewrite_map: Some(rewrite_map), - composable_output: false, category_docs: None, disable_search: false, symbol_redirect_map: None, default_symbol_map: None, + markdown_renderer: comrak::create_renderer(None, None, None), + markdown_stripper: Rc::new(comrak::strip), + head_inject: None, }, None, Default::default(), @@ -451,6 +574,14 @@ async fn module_doc() { ModuleSpecifier::from_file_path(multiple_dir.join("b.ts")).unwrap(), "foo".to_string(), ); + rewrite_map.insert( + ModuleSpecifier::from_file_path(multiple_dir.join("c.ts")).unwrap(), + "c".to_string(), + ); + rewrite_map.insert( + ModuleSpecifier::from_file_path(multiple_dir.join("_d.ts")).unwrap(), + "d".to_string(), + ); let ctx = GenerateCtx::new( GenerateOptions { @@ -458,14 +589,16 @@ async fn module_doc() { main_entrypoint: Some( ModuleSpecifier::from_file_path(multiple_dir.join("a.ts")).unwrap(), ), - href_resolver: Rc::new(EmptyResolver {}), - usage_composer: None, + href_resolver: Rc::new(EmptyResolver), + usage_composer: Rc::new(EmptyResolver), rewrite_map: Some(rewrite_map), - composable_output: false, category_docs: None, disable_search: false, symbol_redirect_map: None, default_symbol_map: None, + markdown_renderer: comrak::create_renderer(None, None, None), + markdown_stripper: Rc::new(comrak::strip), + head_inject: None, }, None, FileMode::Single, @@ -476,13 +609,15 @@ async fn module_doc() { let mut module_docs = vec![]; for (short_path, doc_nodes) in &ctx.doc_nodes { - let render_ctx = - RenderContext::new(&ctx, doc_nodes, UrlResolveKind::File(short_path)); + let render_ctx = RenderContext::new( + &ctx, + doc_nodes, + UrlResolveKind::File { file: short_path }, + ); let module_doc = jsdoc::ModuleDocCtx::new(&render_ctx, short_path); module_docs.push(module_doc); } - #[cfg(all(not(feature = "syntect"), not(feature = "tree-sitter")))] - insta::assert_json_snapshot!(module_docs); // no syntax + insta::assert_json_snapshot!(module_docs); } diff --git a/tests/snapshots/html_test__html_doc_dts-10.snap b/tests/snapshots/html_test__html_doc_dts-10.snap new file mode 100644 index 00000000..4778501f --- /dev/null +++ b/tests/snapshots/html_test__html_doc_dts-10.snap @@ -0,0 +1,15 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- +// deno-fmt-ignore-file +// deno-lint-ignore-file +/** + * Fuse.js v7.0.0 - Lightweight fuzzy-search (http://fusejs.io) + * + * Copyright (c) 2023 Kiro Risk (http://kiro.me) + * All Rights Reserved. Apache Software License 2.0 + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ +var e,t;e=this,t=function(){"use strict";function e(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function t(t){for(var n=1;ne.length)&&(t=e.length);for(var n=0,r=new Array(t);n0&&void 0!==arguments[0]?arguments[0]:{},n=t.getFn,i=void 0===n?$.getFn:n,o=t.fieldNormWeight,c=void 0===o?$.fieldNormWeight:o;r(this,e),this.norm=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:3,n=new Map,r=Math.pow(10,t);return{get:function(t){var i=t.match(F).length;if(n.has(i))return n.get(i);var o=1/Math.pow(i,.5*e),c=parseFloat(Math.round(o*r)/r);return n.set(i,c),c},clear:function(){n.clear()}}}(c,3),this.getFn=i,this.isCreated=!1,this.setIndexRecords()}return o(e,[{key:"setSources",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.docs=e}},{key:"setIndexRecords",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.records=e}},{key:"setKeys",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.keys=t,this._keysMap={},t.forEach((function(t,n){e._keysMap[t.id]=n}))}},{key:"create",value:function(){var e=this;!this.isCreated&&this.docs.length&&(this.isCreated=!0,m(this.docs[0])?this.docs.forEach((function(t,n){e._addString(t,n)})):this.docs.forEach((function(t,n){e._addObject(t,n)})),this.norm.clear())}},{key:"add",value:function(e){var t=this.size();m(e)?this._addString(e,t):this._addObject(e,t)}},{key:"removeAt",value:function(e){this.records.splice(e,1);for(var t=e,n=this.size();t2&&void 0!==arguments[2]?arguments[2]:{},r=n.getFn,i=void 0===r?$.getFn:r,o=n.fieldNormWeight,c=void 0===o?$.fieldNormWeight:o,a=new R({getFn:i,fieldNormWeight:c});return a.setKeys(e.map(A)),a.setSources(t),a.create(),a}function N(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t.errors,r=void 0===n?0:n,i=t.currentLocation,o=void 0===i?0:i,c=t.expectedLocation,a=void 0===c?0:c,s=t.distance,u=void 0===s?$.distance:s,h=t.ignoreLocation,l=void 0===h?$.ignoreLocation:h,f=r/e.length;if(l)return f;var d=Math.abs(a-o);return u?f+d/u:d?1:f}var W=32;function T(e,t,n){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},i=r.location,o=void 0===i?$.location:i,c=r.distance,a=void 0===c?$.distance:c,s=r.threshold,u=void 0===s?$.threshold:s,h=r.findAllMatches,l=void 0===h?$.findAllMatches:h,f=r.minMatchCharLength,d=void 0===f?$.minMatchCharLength:f,v=r.includeMatches,g=void 0===v?$.includeMatches:v,y=r.ignoreLocation,p=void 0===y?$.ignoreLocation:y;if(t.length>W)throw new Error("Pattern length exceeds max of ".concat(W,"."));for(var m,k=t.length,M=e.length,b=Math.max(0,Math.min(o,M)),x=u,w=b,S=d>1||g,L=S?Array(M):[];(m=e.indexOf(t,w))>-1;){var _=N(t,{currentLocation:m,expectedLocation:b,distance:a,ignoreLocation:p});if(x=Math.min(_,x),w=m+k,S)for(var O=0;O=P;D-=1){var K=D-1,q=n[e.charAt(K)];if(S&&(L[K]=+!!q),z[D]=(z[D+1]<<1|1)&q,E&&(z[D]|=(j[D+1]|j[D])<<1|1|j[D+1]),z[D]&C&&(A=N(t,{errors:E,currentLocation:K,expectedLocation:b,distance:a,ignoreLocation:p}))<=x){if(x=A,(w=K)<=b)break;P=Math.max(1,2*b-w)}}if(N(t,{errors:E+1,currentLocation:b,expectedLocation:b,distance:a,ignoreLocation:p})>x)break;j=z}var B={isMatch:w>=0,score:Math.max(.001,A)};if(S){var J=function(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:$.minMatchCharLength,n=[],r=-1,i=-1,o=0,c=e.length;o=t&&n.push([r,i]),r=-1)}return e[o-1]&&o-r>=t&&n.push([r,o-1]),n}(L,d);J.length?g&&(B.indices=J):B.isMatch=!1}return B}function z(e){for(var t={},n=0,r=e.length;n1&&void 0!==arguments[1]?arguments[1]:{},o=i.location,c=void 0===o?$.location:o,a=i.threshold,s=void 0===a?$.threshold:a,u=i.distance,h=void 0===u?$.distance:u,l=i.includeMatches,f=void 0===l?$.includeMatches:l,d=i.findAllMatches,v=void 0===d?$.findAllMatches:d,g=i.minMatchCharLength,y=void 0===g?$.minMatchCharLength:g,p=i.isCaseSensitive,m=void 0===p?$.isCaseSensitive:p,k=i.ignoreLocation,M=void 0===k?$.ignoreLocation:k;if(r(this,e),this.options={location:c,threshold:s,distance:h,includeMatches:f,findAllMatches:v,minMatchCharLength:y,isCaseSensitive:m,ignoreLocation:M},this.pattern=m?t:t.toLowerCase(),this.chunks=[],this.pattern.length){var b=function(e,t){n.chunks.push({pattern:e,alphabet:z(e),startIndex:t})},x=this.pattern.length;if(x>W){for(var w=0,S=x%W,L=x-S;w1&&void 0!==arguments[1]?arguments[1]:{},c=o.location,a=void 0===c?$.location:c,s=o.threshold,u=void 0===s?$.threshold:s,h=o.distance,l=void 0===h?$.distance:h,f=o.includeMatches,d=void 0===f?$.includeMatches:f,v=o.findAllMatches,g=void 0===v?$.findAllMatches:v,y=o.minMatchCharLength,p=void 0===y?$.minMatchCharLength:y,m=o.isCaseSensitive,k=void 0===m?$.isCaseSensitive:m,M=o.ignoreLocation,b=void 0===M?$.ignoreLocation:M;return r(this,n),(i=t.call(this,e))._bitapSearch=new D(e,{location:a,threshold:u,distance:l,includeMatches:d,findAllMatches:g,minMatchCharLength:p,isCaseSensitive:k,ignoreLocation:b}),i}return o(n,[{key:"search",value:function(e){return this._bitapSearch.searchIn(e)}}],[{key:"type",get:function(){return"fuzzy"}},{key:"multiRegex",get:function(){return/^"(.*)"$/}},{key:"singleRegex",get:function(){return/^(.*)$/}}]),n}(K),X=function(e){a(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return o(n,[{key:"search",value:function(e){for(var t,n=0,r=[],i=this.pattern.length;(t=e.indexOf(this.pattern,n))>-1;)n=t+i,r.push([t,n-1]);var o=!!r.length;return{isMatch:o,score:o?0:1,indices:r}}}],[{key:"type",get:function(){return"include"}},{key:"multiRegex",get:function(){return/^'"(.*)"$/}},{key:"singleRegex",get:function(){return/^'(.*)$/}}]),n}(K),Y=[B,X,U,V,H,G,J,Q],Z=Y.length,ee=/ +(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/,te=new Set([Q.type,X.type]),ne=function(){function e(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=n.isCaseSensitive,o=void 0===i?$.isCaseSensitive:i,c=n.includeMatches,a=void 0===c?$.includeMatches:c,s=n.minMatchCharLength,u=void 0===s?$.minMatchCharLength:s,h=n.ignoreLocation,l=void 0===h?$.ignoreLocation:h,f=n.findAllMatches,d=void 0===f?$.findAllMatches:f,v=n.location,g=void 0===v?$.location:v,y=n.threshold,p=void 0===y?$.threshold:y,m=n.distance,k=void 0===m?$.distance:m;r(this,e),this.query=null,this.options={isCaseSensitive:o,includeMatches:a,minMatchCharLength:u,findAllMatches:d,ignoreLocation:l,location:g,threshold:p,distance:k},this.pattern=o?t:t.toLowerCase(),this.query=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return e.split("|").map((function(e){for(var n=e.trim().split(ee).filter((function(e){return e&&!!e.trim()})),r=[],i=0,o=n.length;i2&&void 0!==arguments[2]?arguments[2]:{}).auto,r=void 0===n||n;return ue(e)||(e=he(e)),function e(n){var i=Object.keys(n),o=function(e){return!!e[ae]}(n);if(!o&&i.length>1&&!ue(n))return e(he(n));if(function(e){return!g(e)&&b(e)&&!ue(e)}(n)){var c=o?n[ae]:i[0],a=o?n[se]:n[c];if(!m(a))throw new Error(function(e){return"Invalid value for key ".concat(e)}(c));var s={keyId:C(c),pattern:a};return r&&(s.searcher=ie(a,t)),s}var u={children:[],operator:i[0]};return i.forEach((function(t){var r=n[t];g(r)&&r.forEach((function(t){u.children.push(e(t))}))})),u}(e)}function fe(e,t){var n=e.matches;t.matches=[],x(n)&&n.forEach((function(e){if(x(e.indices)&&e.indices.length){var n={indices:e.indices,value:e.value};e.key&&(n.key=e.key.src),e.idx>-1&&(n.refIndex=e.idx),t.matches.push(n)}}))}function de(e,t){t.score=e.score}var ve=function(){function e(n){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},o=arguments.length>2?arguments[2]:void 0;r(this,e),this.options=t(t({},$),i),this.options.useExtendedSearch,this._keyStore=new j(this.options.keys),this.setCollection(n,o)}return o(e,[{key:"setCollection",value:function(e,t){if(this._docs=e,t&&!(t instanceof R))throw new Error("Incorrect 'index' type");this._myIndex=t||P(this.options.keys,this._docs,{getFn:this.options.getFn,fieldNormWeight:this.options.fieldNormWeight})}},{key:"add",value:function(e){x(e)&&(this._docs.push(e),this._myIndex.add(e))}},{key:"remove",value:function(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:function(){return!1},t=[],n=0,r=this._docs.length;n1&&void 0!==arguments[1]?arguments[1]:{}).limit,n=void 0===t?-1:t,r=this.options,i=r.includeMatches,o=r.includeScore,c=r.shouldSort,a=r.sortFn,s=r.ignoreFieldNorm,u=m(e)?m(this._docs[0])?this._searchStringList(e):this._searchObjectList(e):this._searchLogical(e);return function(e,t){var n=t.ignoreFieldNorm,r=void 0===n?$.ignoreFieldNorm:n;e.forEach((function(e){var t=1;e.matches.forEach((function(e){var n=e.key,i=e.norm,o=e.score,c=n?n.weight:null;t*=Math.pow(0===o&&c?Number.EPSILON:o,(c||1)*(r?1:i))})),e.score=t}))}(u,{ignoreFieldNorm:s}),c&&u.sort(a),k(n)&&n>-1&&(u=u.slice(0,n)),function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=n.includeMatches,i=void 0===r?$.includeMatches:r,o=n.includeScore,c=void 0===o?$.includeScore:o,a=[];return i&&a.push(fe),c&&a.push(de),e.map((function(e){var n=e.idx,r={item:t[n],refIndex:n};return a.length&&a.forEach((function(t){t(e,r)})),r}))}(u,this._docs,{includeMatches:i,includeScore:o})}},{key:"_searchStringList",value:function(e){var t=ie(e,this.options),n=this._myIndex.records,r=[];return n.forEach((function(e){var n=e.v,i=e.i,o=e.n;if(x(n)){var c=t.searchIn(n),a=c.isMatch,s=c.score,u=c.indices;a&&r.push({item:n,idx:i,matches:[{score:s,value:n,norm:o,indices:u}]})}})),r}},{key:"_searchLogical",value:function(e){var t=this,n=le(e,this.options),r=function e(n,r,i){if(!n.children){var o=n.keyId,c=n.searcher,a=t._findMatches({key:t._keyStore.get(o),value:t._myIndex.getValueForItemAtKeyId(r,o),searcher:c});return a&&a.length?[{idx:i,item:r,matches:a}]:[]}for(var s=[],u=0,h=n.children.length;u1&&void 0!==arguments[1]?arguments[1]:{},n=t.getFn,r=void 0===n?$.getFn:n,i=t.fieldNormWeight,o=void 0===i?$.fieldNormWeight:i,c=e.keys,a=e.records,s=new R({getFn:r,fieldNormWeight:o});return s.setKeys(c),s.setIndexRecords(a),s},ve.config=$,function(){re.push.apply(re,arguments)}(ne),ve},"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Fuse=t(); diff --git a/tests/snapshots/html_test__html_doc_dts-11.snap b/tests/snapshots/html_test__html_doc_dts-11.snap new file mode 100644 index 00000000..e67d0c9c --- /dev/null +++ b/tests/snapshots/html_test__html_doc_dts-11.snap @@ -0,0 +1,39 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- +function findParent(el, find) { + do { + if (find(el)) { + return el; + } + } while (el = el.parentElement); +} + +document.addEventListener("click", (e) => { + const target = findParent( + e.target, + (el) => el instanceof HTMLButtonElement && el.dataset["copy"], + ); + if (target) { + navigator?.clipboard?.writeText(target.dataset["copy"]); + target.classList.add("copied"); + setTimeout(() => target.classList.remove("copied"), 1000); + } +}); + +window.addEventListener("load", () => { + const usageSelector = document.getElementById("usageSelector"); + + document.addEventListener("mouseup", (e) => { + if ( + findParent( + e.target, + (el) => + el.parentElement === usageSelector && el instanceof HTMLDivElement, + ) + ) { + usageSelector.open = false; + } + }); +}); diff --git a/tests/snapshots/html_test__html_doc_dts-12.snap b/tests/snapshots/html_test__html_doc_dts-12.snap new file mode 100644 index 00000000..33d6c4a7 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_dts-12.snap @@ -0,0 +1,145 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- +const Fuse = window.Fuse; + +const searchInput = document.querySelector("#searchbar"); +const contentDiv = document.querySelector("#content"); +const searchResultsDiv = document.querySelector("#searchResults"); +const currentFile = + document.querySelector("meta[name='doc-current-file']").attributes + .getNamedItem("content").value; +const pathToRoot = "../".repeat( + currentFile ? (currentFile.split("/").length + 1) : 0, +); +searchInput.removeAttribute("style"); + +const SEARCH_INDEX = window.DENO_DOC_SEARCH_INDEX; + +const fuse = new Fuse(SEARCH_INDEX.nodes, { + keys: [{ + name: "name", + weight: 2, + }], + isCaseSensitive: false, + minMatchCharLength: 2, + threshold: 0.4, +}); + +const loadedUrl = new URL(window.location.href); +const val = loadedUrl.searchParams.get("q"); +if (val) { + searchInput.value = val; + doSearch(val); +} + +window.addEventListener("load", function () { + document.addEventListener("keydown", function (event) { + if (event.key.toLowerCase() === "s") { + if (event.target !== searchInput) { + searchInput.focus(); + event.preventDefault(); + } + } + }); + + const emptyPlaceholder = "Click or press 'S' to search..."; + searchInput.placeholder = emptyPlaceholder; + + searchInput.addEventListener("focus", function () { + searchInput.placeholder = "Type your query here..."; + }); + + searchInput.addEventListener("blur", function () { + searchInput.placeholder = emptyPlaceholder; + }); +}); + +function debounce(func, delay) { + let timerId; + + return function () { + const context = this; + const args = arguments; + + clearTimeout(timerId); + + timerId = setTimeout(function () { + func.apply(context, args); + }, delay); + }; +} + +const debouncedSearch = debounce(doSearch, 250); + +searchInput.addEventListener("input", (e) => { + const val = e.target.value; + debouncedSearch(val); +}); + +function doSearch(val) { + if (!val) { + updateCurrentLocation(val); + showPage(); + } else { + const results = searchInIndex(val); + // console.log("results", results); + updateCurrentLocation(val); + renderResults(results); + showSearchResults(); + } +} + +function updateCurrentLocation(val) { + const url = new URL(window.location.href); + if (val) { + url.searchParams.set("q", val); + } else { + url.searchParams.delete("q"); + } + window.history.replaceState({}, "", url.href); +} + +function showPage() { + contentDiv.style.display = "flex"; + searchResultsDiv.style.display = "none"; +} + +function showSearchResults() { + contentDiv.style.display = "none"; + searchResultsDiv.style.display = "block"; +} + +function renderResults(results) { + if (results.length === 0) { + searchResultsDiv.innerHTML = `No result`; + return; + } + + let html = `
      `; + + for (const result of results) { + const kind = result.kind.map((kind) => { + return `
      ${kind.char}
      `; + }).join(""); + + html += `
    • + +
      +
      + ${kind} +
      + ${result.name} +
      +
      +
    • `; + } + + html += `
    `; + searchResultsDiv.innerHTML = html; +} + +function searchInIndex(val) { + return fuse.search(val).map((result) => result.item); +} diff --git a/tests/snapshots/html_test__html_doc_dts-13.snap b/tests/snapshots/html_test__html_doc_dts-13.snap new file mode 100644 index 00000000..e22f4aa6 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_dts-13.snap @@ -0,0 +1,7 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- +(function () { + window.DENO_DOC_SEARCH_INDEX = {"kind":"search","nodes":[{"kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"ResponseInit","file":".","doc":"","url":"././~/ResponseInit.html","deprecated":false},{"kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ResponseInit.status","file":".","doc":"","url":"././~/ResponseInit.status.html","deprecated":false},{"kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"ResponseInit.statusText","file":".","doc":"","url":"././~/ResponseInit.statusText.html","deprecated":false},{"kind":[{"char":"I","kind":"Interface","title":"Interface"},{"char":"v","kind":"Variable","title":"Variable"}],"name":"WebSocket","file":".","doc":"","url":"././~/WebSocket.html","deprecated":false},{"kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"WebSocket.bufferedAmount","file":".","doc":"","url":"././~/WebSocket.bufferedAmount.html","deprecated":false},{"kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"WebSocket.prototype","file":".","doc":"","url":"././~/WebSocket.prototype.html","deprecated":false},{"kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"WebSocket.OPEN","file":".","doc":"","url":"././~/WebSocket.OPEN.html","deprecated":false}]}; +})() diff --git a/tests/snapshots/html_test__html_doc_dts-2.snap b/tests/snapshots/html_test__html_doc_dts-2.snap new file mode 100644 index 00000000..f16431b3 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_dts-2.snap @@ -0,0 +1,56 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + documentation + + + + + + + + + + +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_dts-3.snap b/tests/snapshots/html_test__html_doc_dts-3.snap new file mode 100644 index 00000000..1db1de3c --- /dev/null +++ b/tests/snapshots/html_test__html_doc_dts-3.snap @@ -0,0 +1,152 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + ResponseInit - documentation + + + + + + + + + + +
    + +
    +
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_dts-4.snap b/tests/snapshots/html_test__html_doc_dts-4.snap new file mode 100644 index 00000000..329c4fac --- /dev/null +++ b/tests/snapshots/html_test__html_doc_dts-4.snap @@ -0,0 +1,100 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + ResponseInit.status - documentation + + + + + + + + + + +
    + +
    +
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_dts-5.snap b/tests/snapshots/html_test__html_doc_dts-5.snap new file mode 100644 index 00000000..bf4ad204 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_dts-5.snap @@ -0,0 +1,100 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + ResponseInit.statusText - documentation + + + + + + + + + + +
    + +
    +
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_dts-6.snap b/tests/snapshots/html_test__html_doc_dts-6.snap new file mode 100644 index 00000000..78ba07b0 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_dts-6.snap @@ -0,0 +1,100 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + WebSocket.OPEN - documentation + + + + + + + + + + +
    + +
    +
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_dts-7.snap b/tests/snapshots/html_test__html_doc_dts-7.snap new file mode 100644 index 00000000..d4f94b67 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_dts-7.snap @@ -0,0 +1,100 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + WebSocket.bufferedAmount - documentation + + + + + + + + + + +
    + +
    +
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_dts-8.snap b/tests/snapshots/html_test__html_doc_dts-8.snap new file mode 100644 index 00000000..c3c3550b --- /dev/null +++ b/tests/snapshots/html_test__html_doc_dts-8.snap @@ -0,0 +1,212 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + WebSocket - documentation + + + + + + + + + + +
    + +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_dts-9.snap b/tests/snapshots/html_test__html_doc_dts-9.snap new file mode 100644 index 00000000..ab398167 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_dts-9.snap @@ -0,0 +1,100 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + WebSocket.prototype - documentation + + + + + + + + + + +
    + +
    +
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_dts.snap b/tests/snapshots/html_test__html_doc_dts.snap new file mode 100644 index 00000000..9a39d818 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_dts.snap @@ -0,0 +1,74 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + All Symbols - documentation + + + + + + + + + + +
    + +
    +
    +
    I
    +
    + ResponseInit + +
    No documentation available
    +
    I
    v
    +
    + WebSocket + +
    No documentation available
    +
    +
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files-10.snap b/tests/snapshots/html_test__html_doc_files-10.snap index 89b94021..e67d0c9c 100644 --- a/tests/snapshots/html_test__html_doc_files-10.snap +++ b/tests/snapshots/html_test__html_doc_files-10.snap @@ -1,6 +1,6 @@ --- source: tests/html_test.rs -expression: "files.get(\"script.js\").unwrap()" +expression: files.get(file_name).unwrap() --- function findParent(el, find) { do { @@ -17,6 +17,8 @@ document.addEventListener("click", (e) => { ); if (target) { navigator?.clipboard?.writeText(target.dataset["copy"]); + target.classList.add("copied"); + setTimeout(() => target.classList.remove("copied"), 1000); } }); diff --git a/tests/snapshots/html_test__html_doc_files-11.snap b/tests/snapshots/html_test__html_doc_files-11.snap index 3c39d30f..33d6c4a7 100644 --- a/tests/snapshots/html_test__html_doc_files-11.snap +++ b/tests/snapshots/html_test__html_doc_files-11.snap @@ -1,11 +1,11 @@ --- source: tests/html_test.rs -expression: "files.get(\"search.js\").unwrap()" +expression: files.get(file_name).unwrap() --- const Fuse = window.Fuse; const searchInput = document.querySelector("#searchbar"); -const mainContentTags = document.getElementsByTagName("main"); +const contentDiv = document.querySelector("#content"); const searchResultsDiv = document.querySelector("#searchResults"); const currentFile = document.querySelector("meta[name='doc-current-file']").attributes @@ -102,16 +102,12 @@ function updateCurrentLocation(val) { } function showPage() { - for (const mainTag of mainContentTags) { - mainTag.style.display = "block"; - } + contentDiv.style.display = "flex"; searchResultsDiv.style.display = "none"; } function showSearchResults() { - for (const mainTag of mainContentTags) { - mainTag.style.display = "none"; - } + contentDiv.style.display = "none"; searchResultsDiv.style.display = "block"; } @@ -125,8 +121,7 @@ function renderResults(results) { for (const result of results) { const kind = result.kind.map((kind) => { - const [rustKind, title, symbol] = docNodeKindToStringVariants(kind); - return `
    ${symbol}
    `; + return `
    ${kind.char}
    `; }).join(""); html += `
  • @@ -137,7 +132,6 @@ function renderResults(results) {
  • ${result.name} -
    ${result.location.filename}:${result.location.line}
    `; } @@ -149,24 +143,3 @@ function renderResults(results) { function searchInIndex(val) { return fuse.search(val).map((result) => result.item); } - -function docNodeKindToStringVariants(kind) { - switch (kind) { - case "function": - return ["Function", "Function", "f"]; - case "variable": - return ["Variable", "Variable", "v"]; - case "class": - return ["Class", "Class", "c"]; - case "enum": - return ["Enum", "Enum", "E"]; - case "interface": - return ["Interface", "Interface", "I"]; - case "typeAlias": - return ["TypeAlias", "Type Alias", "T"]; - case "namespace": - return ["Namespace", "Namespace", "N"]; - default: - return []; - } -} diff --git a/tests/snapshots/html_test__html_doc_files-12.snap b/tests/snapshots/html_test__html_doc_files-12.snap index 6f2145ca..e465acb3 100644 --- a/tests/snapshots/html_test__html_doc_files-12.snap +++ b/tests/snapshots/html_test__html_doc_files-12.snap @@ -1,7 +1,7 @@ --- source: tests/html_test.rs -expression: "files.get(\"search_index.js\").unwrap()" +expression: files.get(file_name).unwrap() --- (function () { - window.DENO_DOC_SEARCH_INDEX = {"nodes":[{"kind":["class"],"name":"Bar","file":".","doc":"","location":{"filename":"default","line":8,"col":0,"byteIndex":77},"url":"././~/Bar.html","category":"","declarationKind":"export","deprecated":false},{"kind":["class"],"name":"Foo","file":".","doc":"```ts\nusing time = new FakeTime();\n```","location":{"filename":"default","line":6,"col":0,"byteIndex":56},"url":"././~/Foo.html","category":"","declarationKind":"export","deprecated":false},{"kind":["class"],"name":"Foobar","file":".","doc":"","location":{"filename":"default","line":13,"col":0,"byteIndex":175},"url":"././~/Foobar.html","category":"","declarationKind":"export","deprecated":false}]}; + window.DENO_DOC_SEARCH_INDEX = {"kind":"search","nodes":[{"kind":[{"char":"c","kind":"Class","title":"Class"}],"name":"Bar","file":".","doc":"","url":"././~/Bar.html","deprecated":false},{"kind":[{"char":"c","kind":"Class","title":"Class"}],"name":"Foo","file":".","doc":"```ts\nusing time = new FakeTime();\n```","url":"././~/Foo.html","deprecated":false},{"kind":[{"char":"c","kind":"Class","title":"Class"}],"name":"Foobar","file":".","doc":"","url":"././~/Foobar.html","deprecated":false}]}; })() diff --git a/tests/snapshots/html_test__html_doc_files-13.snap b/tests/snapshots/html_test__html_doc_files-13.snap deleted file mode 100644 index 6f2145ca..00000000 --- a/tests/snapshots/html_test__html_doc_files-13.snap +++ /dev/null @@ -1,7 +0,0 @@ ---- -source: tests/html_test.rs -expression: "files.get(\"search_index.js\").unwrap()" ---- -(function () { - window.DENO_DOC_SEARCH_INDEX = {"nodes":[{"kind":["class"],"name":"Bar","file":".","doc":"","location":{"filename":"default","line":8,"col":0,"byteIndex":77},"url":"././~/Bar.html","category":"","declarationKind":"export","deprecated":false},{"kind":["class"],"name":"Foo","file":".","doc":"```ts\nusing time = new FakeTime();\n```","location":{"filename":"default","line":6,"col":0,"byteIndex":56},"url":"././~/Foo.html","category":"","declarationKind":"export","deprecated":false},{"kind":["class"],"name":"Foobar","file":".","doc":"","location":{"filename":"default","line":13,"col":0,"byteIndex":175},"url":"././~/Foobar.html","category":"","declarationKind":"export","deprecated":false}]}; -})() diff --git a/tests/snapshots/html_test__html_doc_files-2.snap b/tests/snapshots/html_test__html_doc_files-2.snap index 48a6dd88..bb76e0ff 100644 --- a/tests/snapshots/html_test__html_doc_files-2.snap +++ b/tests/snapshots/html_test__html_doc_files-2.snap @@ -1,23 +1,20 @@ --- source: tests/html_test.rs -expression: "files.get(\"./index.html\").unwrap()" +expression: files.get(file_name).unwrap() --- - Index - documentation + documentation - - - + - - +
    -
    -
    -
    +
    +
    +
    @@ -53,7 +50,7 @@ expression: "files.get(\"./index.html\").unwrap()" Foobar
    -
    +
    diff --git a/tests/snapshots/html_test__html_doc_files-3.snap b/tests/snapshots/html_test__html_doc_files-3.snap index 0ceb343c..de5a369b 100644 --- a/tests/snapshots/html_test__html_doc_files-3.snap +++ b/tests/snapshots/html_test__html_doc_files-3.snap @@ -1,6 +1,6 @@ --- source: tests/html_test.rs -expression: "files.get(\"./~/Bar.html\").unwrap()" +expression: files.get(file_name).unwrap() --- @@ -11,13 +11,10 @@ expression: "files.get(\"./~/Bar.html\").unwrap()" - - - + - - +
    -
    +
    @@ -52,16 +49,20 @@ expression: "files.get(\"./~/Bar.html\").unwrap()"
    -

    Usage

    import { Bar } from ".";
    +    

    Usage

    import { Bar } from ".";
     
    -
    +
    diff --git a/tests/snapshots/html_test__html_doc_files-4.snap b/tests/snapshots/html_test__html_doc_files-4.snap index 44deac7d..2c441d4e 100644 --- a/tests/snapshots/html_test__html_doc_files-4.snap +++ b/tests/snapshots/html_test__html_doc_files-4.snap @@ -1,5 +1,5 @@ --- source: tests/html_test.rs -expression: "files.get(\"./~/Bar.prototype.html\").unwrap()" +expression: files.get(file_name).unwrap() --- diff --git a/tests/snapshots/html_test__html_doc_files-5.snap b/tests/snapshots/html_test__html_doc_files-5.snap index 17b17322..d31210dd 100644 --- a/tests/snapshots/html_test__html_doc_files-5.snap +++ b/tests/snapshots/html_test__html_doc_files-5.snap @@ -1,6 +1,6 @@ --- source: tests/html_test.rs -expression: "files.get(\"./~/Foo.html\").unwrap()" +expression: files.get(file_name).unwrap() --- @@ -11,13 +11,10 @@ expression: "files.get(\"./~/Foo.html\").unwrap()" - - - + - - +
    -
    +
    class Foo -
    using time = new FakeTime();
    +          
    using time = new FakeTime();
     
    @@ -58,16 +59,20 @@ expression: "files.get(\"./~/Foo.html\").unwrap()"
    -

    Usage

    import { Foo } from ".";
    +    

    Usage

    import { Foo } from ".";
     
    -
    +
    diff --git a/tests/snapshots/html_test__html_doc_files-6.snap b/tests/snapshots/html_test__html_doc_files-6.snap index b9b3a768..50404116 100644 --- a/tests/snapshots/html_test__html_doc_files-6.snap +++ b/tests/snapshots/html_test__html_doc_files-6.snap @@ -1,5 +1,5 @@ --- source: tests/html_test.rs -expression: "files.get(\"./~/Foo.prototype.html\").unwrap()" +expression: files.get(file_name).unwrap() --- diff --git a/tests/snapshots/html_test__html_doc_files-7.snap b/tests/snapshots/html_test__html_doc_files-7.snap index 9dac7db6..653ac3f3 100644 --- a/tests/snapshots/html_test__html_doc_files-7.snap +++ b/tests/snapshots/html_test__html_doc_files-7.snap @@ -1,6 +1,6 @@ --- source: tests/html_test.rs -expression: "files.get(\"./~/Foobar.html\").unwrap()" +expression: files.get(file_name).unwrap() --- @@ -11,13 +11,10 @@ expression: "files.get(\"./~/Foobar.html\").unwrap()" - - - + - - +
    -
    +
    @@ -50,16 +47,20 @@ expression: "files.get(\"./~/Foobar.html\").unwrap()"
    -

    Usage

    import default from ".";
    -
    -
    +
    diff --git a/tests/snapshots/html_test__html_doc_files-8.snap b/tests/snapshots/html_test__html_doc_files-8.snap index e35237a6..98d0f995 100644 --- a/tests/snapshots/html_test__html_doc_files-8.snap +++ b/tests/snapshots/html_test__html_doc_files-8.snap @@ -1,5 +1,5 @@ --- source: tests/html_test.rs -expression: "files.get(\"./~/Foobar.prototype.html\").unwrap()" +expression: files.get(file_name).unwrap() --- diff --git a/tests/snapshots/html_test__html_doc_files-9.snap b/tests/snapshots/html_test__html_doc_files-9.snap index cf016dae..4778501f 100644 --- a/tests/snapshots/html_test__html_doc_files-9.snap +++ b/tests/snapshots/html_test__html_doc_files-9.snap @@ -1,6 +1,6 @@ --- source: tests/html_test.rs -expression: "files.get(\"fuse.js\").unwrap()" +expression: files.get(file_name).unwrap() --- // deno-fmt-ignore-file // deno-lint-ignore-file diff --git a/tests/snapshots/html_test__html_doc_files.snap b/tests/snapshots/html_test__html_doc_files.snap index dd3b0906..686a23ff 100644 --- a/tests/snapshots/html_test__html_doc_files.snap +++ b/tests/snapshots/html_test__html_doc_files.snap @@ -1,6 +1,6 @@ --- source: tests/html_test.rs -expression: "files.get(\"./all_symbols.html\").unwrap()" +expression: files.get(file_name).unwrap() --- @@ -11,13 +11,10 @@ expression: "files.get(\"./all_symbols.html\").unwrap()" - - - + - - +
    -
    +
    Foo -
    No documentation available
    -
    +
    No documentation available
    c
    Foobar -
    No documentation available
    -
    +
    No documentation available
    -
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-10.snap b/tests/snapshots/html_test__html_doc_files_multiple-10.snap new file mode 100644 index 00000000..33117ae4 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-10.snap @@ -0,0 +1,68 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + B - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    + class B +
    Private
    +
    +
    +
    +
    +
    +

    Usage

    import { B } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-11.snap b/tests/snapshots/html_test__html_doc_files_multiple-11.snap new file mode 100644 index 00000000..797228af --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-11.snap @@ -0,0 +1,5 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-12.snap b/tests/snapshots/html_test__html_doc_files_multiple-12.snap new file mode 100644 index 00000000..84c7d54e --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-12.snap @@ -0,0 +1,75 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Bar - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    + class Bar +
    + extends Foo<string> +
    +

    Some quote in bar docs +This quote part is ignored +when getting the title of this doc

    +
    +

    Bar docs

    +
    +
    +
    +
    +
    +

    Usage

    import { Bar } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-13.snap b/tests/snapshots/html_test__html_doc_files_multiple-13.snap new file mode 100644 index 00000000..2c441d4e --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-13.snap @@ -0,0 +1,5 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-14.snap b/tests/snapshots/html_test__html_doc_files_multiple-14.snap new file mode 100644 index 00000000..41037ed1 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-14.snap @@ -0,0 +1,123 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Baz.bar - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { type Baz } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-15.snap b/tests/snapshots/html_test__html_doc_files_multiple-15.snap new file mode 100644 index 00000000..ff9a0caa --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-15.snap @@ -0,0 +1,98 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Baz.foo - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    + property Baz.foo +
    + +
    +
    Record<string, T extends string ? 0 : 1> + +
    +
    +
    +
    +
    +
    +
    +

    Usage

    import { type Baz } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-16.snap b/tests/snapshots/html_test__html_doc_files_multiple-16.snap new file mode 100644 index 00000000..75c40f48 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-16.snap @@ -0,0 +1,224 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Baz - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { type Baz } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-17.snap b/tests/snapshots/html_test__html_doc_files_multiple-17.snap new file mode 100644 index 00000000..520c212b --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-17.snap @@ -0,0 +1,98 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + CompoundType.bufferedAmount - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    + property CompoundType.bufferedAmount +
    + +
    +
    number + +
    +
    +
    +
    +
    +
    +
    +

    Usage

    import { type CompoundType } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-18.snap b/tests/snapshots/html_test__html_doc_files_multiple-18.snap new file mode 100644 index 00000000..2d045506 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-18.snap @@ -0,0 +1,128 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + CompoundType - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    + variable CompoundType +
    +
    +
    +
    +
    +

    Usage

    import { CompoundType } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-19.snap b/tests/snapshots/html_test__html_doc_files_multiple-19.snap new file mode 100644 index 00000000..65b73b3a --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-19.snap @@ -0,0 +1,67 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + EmptyInterface - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    + interface EmptyInterface +
    +
    +
    +
    +
    +

    Usage

    import { type EmptyInterface } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-2.snap b/tests/snapshots/html_test__html_doc_files_multiple-2.snap new file mode 100644 index 00000000..34b065fb --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-2.snap @@ -0,0 +1,74 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + documentation + + + + + + + + + + +
    + +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-20.snap b/tests/snapshots/html_test__html_doc_files_multiple-20.snap new file mode 100644 index 00000000..e9708447 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-20.snap @@ -0,0 +1,148 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Enum - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { Enum } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-21.snap b/tests/snapshots/html_test__html_doc_files_multiple-21.snap new file mode 100644 index 00000000..5723cb3e --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-21.snap @@ -0,0 +1,148 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Enum2 - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { Enum2 } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-22.snap b/tests/snapshots/html_test__html_doc_files_multiple-22.snap new file mode 100644 index 00000000..b0211beb --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-22.snap @@ -0,0 +1,98 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Foo.bar - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { Foo } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-23.snap b/tests/snapshots/html_test__html_doc_files_multiple-23.snap new file mode 100644 index 00000000..413a65f4 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-23.snap @@ -0,0 +1,807 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Foo - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    + class Foo +

    some Foo docs Bar

    +
    + + + + + + + + + + +

    test

    +

    +

    hello

    +

    bar

    +
    foo
    +
    +

    baz

    +
    +
    +
    + + + + + + + + + + +

    test 2

    +

    +

    hello

    +

    bar

    +
    foo
    +
    +

    baz

    +
    +
    +
    +
    +

    + + + + + + + + + + +Constructors

    + +
    +
    new
    +
    + + + + + + + + + + +Foo(value: T) + +
    +
    +
    +

    + + + + + + + + + + +Type Parameters

    + +
    +
    +
    +

    + + + + + + + + + + +Properties

    +
    + +
    +
    abstract
    +
    + + + + + + + + + + +foo: A + +
    +
    + +
    +
    + +
    +
    protected
    +
    readonly
    +
    + + + + + + + + + + +getter + +
    +
    + +
    +
    protected
    +
    + + + + + + + + + + +protectedProperty: boolean + +
    +
    + +
    +
    readonly
    +
    + + + + + + + + + + +readonlyProperty: boolean + +
    +
    + +
    +
    writeonly
    +
    + + + + + + + + + + +setter: string + +
    +
    + +
    +
    +
    +
    + +
    +
    private
    +
    + + + + + + + + + + +methodWithOverloads(s: number): void + +
    +
    + +
    +
    private
    +
    + + + + + + + + + + +methodWithOverloads(s: string): void + +
    +
    + +
    +
    +
    +
    +

    + + + + + + + + + + +Static Properties

    + +
    +
    + + + + + + + + + + +bar: "string" + +
    +
    + +
    +
    writeonly
    +
    + + + + + + + + + + +staticSetter: number + +
    +
    +
    +

    + + + + + + + + + + +Static Methods

    +
    +
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-24.snap b/tests/snapshots/html_test__html_doc_files_multiple-24.snap new file mode 100644 index 00000000..fab8ce2a --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-24.snap @@ -0,0 +1,98 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Foo.prototype."><img src=x onerror=alert(1)> - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    + property Foo.prototype."><img src=x onerror=alert(1)> +
    + +
    +
    number + +
    +
    +
    +
    +
    +
    +
    +

    Usage

    import { Foo } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-25.snap b/tests/snapshots/html_test__html_doc_files_multiple-25.snap new file mode 100644 index 00000000..13a6ec9e --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-25.snap @@ -0,0 +1,123 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Foo.prototype.[Symbol.iterator] - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { Foo } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-26.snap b/tests/snapshots/html_test__html_doc_files_multiple-26.snap new file mode 100644 index 00000000..fa0b959b --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-26.snap @@ -0,0 +1,98 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Foo.prototype.foo - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { Foo } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-27.snap b/tests/snapshots/html_test__html_doc_files_multiple-27.snap new file mode 100644 index 00000000..00a5367a --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-27.snap @@ -0,0 +1,117 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Foo.prototype.getter - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { Foo } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-28.snap b/tests/snapshots/html_test__html_doc_files_multiple-28.snap new file mode 100644 index 00000000..fcd292e5 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-28.snap @@ -0,0 +1,231 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Foo.prototype.getterAndSetter - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { Foo } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-29.snap b/tests/snapshots/html_test__html_doc_files_multiple-29.snap new file mode 100644 index 00000000..50404116 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-29.snap @@ -0,0 +1,5 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-3.snap b/tests/snapshots/html_test__html_doc_files_multiple-3.snap new file mode 100644 index 00000000..62dcf5d5 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-3.snap @@ -0,0 +1,68 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + A - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    + class A +
    Private
    +
    +
    +
    +
    +
    +

    Usage

    import { A } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-30.snap b/tests/snapshots/html_test__html_doc_files_multiple-30.snap new file mode 100644 index 00000000..e649a86c --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-30.snap @@ -0,0 +1,282 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Foo.prototype.methodWithOverloads - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { Foo } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-31.snap b/tests/snapshots/html_test__html_doc_files_multiple-31.snap new file mode 100644 index 00000000..8cd449e3 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-31.snap @@ -0,0 +1,98 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Foo.prototype.protectedProperty - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    + property Foo.prototype.protectedProperty +
    + +
    +
    boolean + +
    +
    +
    +
    +
    +
    +
    +

    Usage

    import { Foo } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-32.snap b/tests/snapshots/html_test__html_doc_files_multiple-32.snap new file mode 100644 index 00000000..359ba68d --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-32.snap @@ -0,0 +1,98 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Foo.prototype.readonlyProperty - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    + property Foo.prototype.readonlyProperty +
    + +
    +
    boolean + +
    +
    +
    +
    +
    +
    +
    +

    Usage

    import { Foo } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-33.snap b/tests/snapshots/html_test__html_doc_files_multiple-33.snap new file mode 100644 index 00000000..394259ca --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-33.snap @@ -0,0 +1,175 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Foo.prototype.setter - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { Foo } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-34.snap b/tests/snapshots/html_test__html_doc_files_multiple-34.snap new file mode 100644 index 00000000..a810ebc2 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-34.snap @@ -0,0 +1,123 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Foo.prototype.test - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { Foo } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-35.snap b/tests/snapshots/html_test__html_doc_files_multiple-35.snap new file mode 100644 index 00000000..2f0580bc --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-35.snap @@ -0,0 +1,123 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Foo.staticMethod - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { Foo } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-36.snap b/tests/snapshots/html_test__html_doc_files_multiple-36.snap new file mode 100644 index 00000000..0c1dbe9e --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-36.snap @@ -0,0 +1,175 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Foo.staticSetter - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { Foo } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-37.snap b/tests/snapshots/html_test__html_doc_files_multiple-37.snap new file mode 100644 index 00000000..bb0f12e4 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-37.snap @@ -0,0 +1,114 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Foobar - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    + class Foobar +
    // This code block is ignored when getting the title of this doc
    +const foobar = new Foobar();
    +
    +

    Foobar docs

    +

    +heading

    +

    content

    +

    +sub heading

    +
    +
    +
    +
    +
    +
    +
    +

    Usage

    import Foobar from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-38.snap b/tests/snapshots/html_test__html_doc_files_multiple-38.snap new file mode 100644 index 00000000..98d0f995 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-38.snap @@ -0,0 +1,5 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-39.snap b/tests/snapshots/html_test__html_doc_files_multiple-39.snap new file mode 100644 index 00000000..69febab7 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-39.snap @@ -0,0 +1,98 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Hello.ab - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { type Hello } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-4.snap b/tests/snapshots/html_test__html_doc_files_multiple-4.snap new file mode 100644 index 00000000..071e34c0 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-4.snap @@ -0,0 +1,5 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-40.snap b/tests/snapshots/html_test__html_doc_files_multiple-40.snap new file mode 100644 index 00000000..4597e25c --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-40.snap @@ -0,0 +1,175 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Hello.computedMethod - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { type Hello } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-41.snap b/tests/snapshots/html_test__html_doc_files_multiple-41.snap new file mode 100644 index 00000000..65d450fa --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-41.snap @@ -0,0 +1,427 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Hello - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    + interface Hello +
    +

    + + + + + + + + + + +Type Parameters

    + +
    +
    + + + + + + + + + + +T extends string + +
    +
    + +
    +
    + + + + + + + + + + +E extends T + +
    +
    + +
    +
    + + + + + + + + + + +R = number + +
    +
    +
    +

    + + + + + + + + + + +Call Signatures

    + +
    +
    (a: string): string + +
    +
    +
    +

    + + + + + + + + + + +Properties

    + +
    +
    + + + + + + + + + + +world: string = "foo" + +
    +
    + +
    +
    readonly
    +
    optional
    +
    + + + + + + + + + + +test: "test" + +

    Some docs

    +
    +
    + +
    +
    +
    + +
    +
    + + + + + + + + + + +x: { [foo: string]: number; } + +
    +
    +
    + +
    +
    optional
    +
    + + + + + + + + + + +optionalMethod(): [string] + +
    +
    + +
    +
    optional
    +
    + + + + + + + + + + +[computedMethod](a: T extends () => infer R ? R : any): void + +
    +
    +
    +
    +
    +
    +
    +

    Usage

    import { type Hello } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-42.snap b/tests/snapshots/html_test__html_doc_files_multiple-42.snap new file mode 100644 index 00000000..0c9b0194 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-42.snap @@ -0,0 +1,123 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Hello.optionalMethod - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { type Hello } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-43.snap b/tests/snapshots/html_test__html_doc_files_multiple-43.snap new file mode 100644 index 00000000..e12b595c --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-43.snap @@ -0,0 +1,99 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Hello.test - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { type Hello } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-44.snap b/tests/snapshots/html_test__html_doc_files_multiple-44.snap new file mode 100644 index 00000000..c24fc64b --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-44.snap @@ -0,0 +1,98 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Hello.world - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { type Hello } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-45.snap b/tests/snapshots/html_test__html_doc_files_multiple-45.snap new file mode 100644 index 00000000..39005def --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-45.snap @@ -0,0 +1,115 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Hello.x - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { type Hello } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-46.snap b/tests/snapshots/html_test__html_doc_files_multiple-46.snap new file mode 100644 index 00000000..df545673 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-46.snap @@ -0,0 +1,115 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + InterfaceWithIndexSignature - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { type InterfaceWithIndexSignature } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-47.snap b/tests/snapshots/html_test__html_doc_files_multiple-47.snap new file mode 100644 index 00000000..5bdb0d2c --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-47.snap @@ -0,0 +1,178 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Testing.externalFunction - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { Testing } from ".";
    +const { externalFunction } = Testing;
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-48.snap b/tests/snapshots/html_test__html_doc_files_multiple-48.snap new file mode 100644 index 00000000..e38999f5 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-48.snap @@ -0,0 +1,115 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Testing - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    + class Testing +
    +
    +
    +
    +
    +

    Usage

    import { Testing } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-49.snap b/tests/snapshots/html_test__html_doc_files_multiple-49.snap new file mode 100644 index 00000000..1f543d84 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-49.snap @@ -0,0 +1,5 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-5.snap b/tests/snapshots/html_test__html_doc_files_multiple-5.snap new file mode 100644 index 00000000..8502682e --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-5.snap @@ -0,0 +1,205 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + AbstractClass - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { AbstractClass } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-50.snap b/tests/snapshots/html_test__html_doc_files_multiple-50.snap new file mode 100644 index 00000000..7fda4635 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-50.snap @@ -0,0 +1,123 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Testing.t - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { Testing } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-51.snap b/tests/snapshots/html_test__html_doc_files_multiple-51.snap new file mode 100644 index 00000000..518a3c89 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-51.snap @@ -0,0 +1,178 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Testing.x - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { Testing } from ".";
    +const { x } = Testing;
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-52.snap b/tests/snapshots/html_test__html_doc_files_multiple-52.snap new file mode 100644 index 00000000..0c355fa8 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-52.snap @@ -0,0 +1,98 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + TypeAlias - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { type TypeAlias } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-53.snap b/tests/snapshots/html_test__html_doc_files_multiple-53.snap new file mode 100644 index 00000000..27d2ef14 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-53.snap @@ -0,0 +1,123 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + anotherVariable.bar - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { anotherVariable } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-54.snap b/tests/snapshots/html_test__html_doc_files_multiple-54.snap new file mode 100644 index 00000000..04a6b462 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-54.snap @@ -0,0 +1,98 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + anotherVariable.foo - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { anotherVariable } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-55.snap b/tests/snapshots/html_test__html_doc_files_multiple-55.snap new file mode 100644 index 00000000..f9c45084 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-55.snap @@ -0,0 +1,172 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + anotherVariable - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { anotherVariable } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-56.snap b/tests/snapshots/html_test__html_doc_files_multiple-56.snap new file mode 100644 index 00000000..98f2f0c4 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-56.snap @@ -0,0 +1,123 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + c - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { c } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-57.snap b/tests/snapshots/html_test__html_doc_files_multiple-57.snap new file mode 100644 index 00000000..e311c0f4 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-57.snap @@ -0,0 +1,475 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + d - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    + function d +
    + + + + + + + + + + + +d<T = string>(
    foo?: number,
    bar?: string,
    baz?: { hello?: string; },
    qaz: T,
    ...strings: string[],
    ): string
    +
    + + + + + + + + + + +

    test

    +

    +
    d();
    +
    +
    +
    +
    + + + + + + + + + + +

    Example 2

    +

    +
    d();
    +
    +
    +
    +
    +
    +

    + + + + + + + + + + +Type Parameters

    + +
    +
    + + + + + + + + + + +T = string + +
    +
    +
    +

    + + + + + + + + + + +Parameters

    + +
    +
    optional
    +
    + + + + + + + + + + +foo: number = 1 + +

    {number} some parameter

    +
    +
    + +
    +
    optional
    +
    + + + + + + + + + + +bar: string = bar + +
    +
    + +
    +
    optional
    +
    + + + + + + + + + + +baz: { hello?: string; } + +
    +
    + +
    +
    +
    + +
    +
    + + + + + + + + + + +...strings: string[] + +
    +
    +
    +

    + + + + + + + + + + +Return Type

    + +
    +
    string + +

    a new string

    +
    +
    +
    + +
    +
    Foo + +

    bar

    +
    +
    +
    +
    +
    +
    +
    +
    +

    Usage

    import { d } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-58.snap b/tests/snapshots/html_test__html_doc_files_multiple-58.snap new file mode 100644 index 00000000..1b8b885c --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-58.snap @@ -0,0 +1,349 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + functionWithOptionalParameters - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    + function functionWithOptionalParameters +
    + + + + + + + + + + + +functionWithOptionalParameters(
    foo?: number,
    bar?: number,
    baz?: [number],
    unnamed 3?: string[],
    unnamed 4?: { qux: number; },
    ): void
    +
    +

    + + + + + + + + + + +Parameters

    + +
    +
    optional
    +
    + + + + + + + + + + +foo: number = 1 + +
    +
    + +
    +
    optional
    +
    + + + + + + + + + + +bar: number + +
    +
    + +
    +
    optional
    +
    + + + + + + + + + + +baz: [number] + +
    +
    + +
    +
    optional
    +
    + + + + + + + + + + +unnamed 3: string[] + +
    +
    + +
    +
    optional
    +
    + + + + + + + + + + +unnamed 4: { qux: number; } + +
    +
    +
    +

    + + + + + + + + + + +Return Type

    + +
    +
    void + +
    +
    +
    + +
    +
    + +

    bar

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Usage

    import { functionWithOptionalParameters } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-59.snap b/tests/snapshots/html_test__html_doc_files_multiple-59.snap new file mode 100644 index 00000000..929b3a87 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-59.snap @@ -0,0 +1,273 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + qaz - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { qaz } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-6.snap b/tests/snapshots/html_test__html_doc_files_multiple-6.snap new file mode 100644 index 00000000..a284d068 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-6.snap @@ -0,0 +1,98 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + AbstractClass.prototype.foo - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    + property AbstractClass.prototype.foo +
    + +
    +
    string + +
    +
    +
    +
    +
    +
    +
    +

    Usage

    import { AbstractClass } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-60.snap b/tests/snapshots/html_test__html_doc_files_multiple-60.snap new file mode 100644 index 00000000..78f462d8 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-60.snap @@ -0,0 +1,67 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + someVariable - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    + variable someVariable +
    +
    +
    +
    +
    +

    Usage

    import { someVariable } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-61.snap b/tests/snapshots/html_test__html_doc_files_multiple-61.snap new file mode 100644 index 00000000..ec61854b --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-61.snap @@ -0,0 +1,176 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + x - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { x } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-62.snap b/tests/snapshots/html_test__html_doc_files_multiple-62.snap new file mode 100644 index 00000000..fabd521e --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-62.snap @@ -0,0 +1,126 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + c - documentation + + + + + + + + + + +
    +
    +
    +
    +
    f
    +
    + x + +
    No documentation available
    +
    +
    +
    +
    +
    +
    +
    +

    Usage

    import * as c from "c";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-63.snap b/tests/snapshots/html_test__html_doc_files_multiple-63.snap new file mode 100644 index 00000000..5163716f --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-63.snap @@ -0,0 +1,184 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + x - c - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { x } from "c";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-64.snap b/tests/snapshots/html_test__html_doc_files_multiple-64.snap new file mode 100644 index 00000000..2b0f7db3 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-64.snap @@ -0,0 +1,126 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + d - documentation + + + + + + + + + + +
    +
    +
    +
    +
    f
    +
    + externalFunction + +
    No documentation available
    +
    +
    +
    +
    +
    +
    +
    +

    Usage

    import * as mod from "d";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-65.snap b/tests/snapshots/html_test__html_doc_files_multiple-65.snap new file mode 100644 index 00000000..f889f9f3 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-65.snap @@ -0,0 +1,184 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + externalFunction - d - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { externalFunction } from "d";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-66.snap b/tests/snapshots/html_test__html_doc_files_multiple-66.snap new file mode 100644 index 00000000..0f556760 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-66.snap @@ -0,0 +1,157 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + foo - documentation + + + + + + + + + + +
    +
    +
    +
    +
    f
    +
    + x + +
    No documentation available
    +
    +
    +
    v
    +
    + default + +

    The default export item.

    +
    +
    +
    +
    +
    +
    +
    +
    +

    Usage

    import * as bar from "foo";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-67.snap b/tests/snapshots/html_test__html_doc_files_multiple-67.snap new file mode 100644 index 00000000..06a96583 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-67.snap @@ -0,0 +1,108 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + default - foo - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import bar from "foo";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-68.snap b/tests/snapshots/html_test__html_doc_files_multiple-68.snap new file mode 100644 index 00000000..f4f6af3f --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-68.snap @@ -0,0 +1,184 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + x - foo - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { x } from "foo";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-69.snap b/tests/snapshots/html_test__html_doc_files_multiple-69.snap new file mode 100644 index 00000000..4778501f --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-69.snap @@ -0,0 +1,15 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- +// deno-fmt-ignore-file +// deno-lint-ignore-file +/** + * Fuse.js v7.0.0 - Lightweight fuzzy-search (http://fusejs.io) + * + * Copyright (c) 2023 Kiro Risk (http://kiro.me) + * All Rights Reserved. Apache Software License 2.0 + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ +var e,t;e=this,t=function(){"use strict";function e(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function t(t){for(var n=1;ne.length)&&(t=e.length);for(var n=0,r=new Array(t);n0&&void 0!==arguments[0]?arguments[0]:{},n=t.getFn,i=void 0===n?$.getFn:n,o=t.fieldNormWeight,c=void 0===o?$.fieldNormWeight:o;r(this,e),this.norm=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:3,n=new Map,r=Math.pow(10,t);return{get:function(t){var i=t.match(F).length;if(n.has(i))return n.get(i);var o=1/Math.pow(i,.5*e),c=parseFloat(Math.round(o*r)/r);return n.set(i,c),c},clear:function(){n.clear()}}}(c,3),this.getFn=i,this.isCreated=!1,this.setIndexRecords()}return o(e,[{key:"setSources",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.docs=e}},{key:"setIndexRecords",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.records=e}},{key:"setKeys",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.keys=t,this._keysMap={},t.forEach((function(t,n){e._keysMap[t.id]=n}))}},{key:"create",value:function(){var e=this;!this.isCreated&&this.docs.length&&(this.isCreated=!0,m(this.docs[0])?this.docs.forEach((function(t,n){e._addString(t,n)})):this.docs.forEach((function(t,n){e._addObject(t,n)})),this.norm.clear())}},{key:"add",value:function(e){var t=this.size();m(e)?this._addString(e,t):this._addObject(e,t)}},{key:"removeAt",value:function(e){this.records.splice(e,1);for(var t=e,n=this.size();t2&&void 0!==arguments[2]?arguments[2]:{},r=n.getFn,i=void 0===r?$.getFn:r,o=n.fieldNormWeight,c=void 0===o?$.fieldNormWeight:o,a=new R({getFn:i,fieldNormWeight:c});return a.setKeys(e.map(A)),a.setSources(t),a.create(),a}function N(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t.errors,r=void 0===n?0:n,i=t.currentLocation,o=void 0===i?0:i,c=t.expectedLocation,a=void 0===c?0:c,s=t.distance,u=void 0===s?$.distance:s,h=t.ignoreLocation,l=void 0===h?$.ignoreLocation:h,f=r/e.length;if(l)return f;var d=Math.abs(a-o);return u?f+d/u:d?1:f}var W=32;function T(e,t,n){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},i=r.location,o=void 0===i?$.location:i,c=r.distance,a=void 0===c?$.distance:c,s=r.threshold,u=void 0===s?$.threshold:s,h=r.findAllMatches,l=void 0===h?$.findAllMatches:h,f=r.minMatchCharLength,d=void 0===f?$.minMatchCharLength:f,v=r.includeMatches,g=void 0===v?$.includeMatches:v,y=r.ignoreLocation,p=void 0===y?$.ignoreLocation:y;if(t.length>W)throw new Error("Pattern length exceeds max of ".concat(W,"."));for(var m,k=t.length,M=e.length,b=Math.max(0,Math.min(o,M)),x=u,w=b,S=d>1||g,L=S?Array(M):[];(m=e.indexOf(t,w))>-1;){var _=N(t,{currentLocation:m,expectedLocation:b,distance:a,ignoreLocation:p});if(x=Math.min(_,x),w=m+k,S)for(var O=0;O=P;D-=1){var K=D-1,q=n[e.charAt(K)];if(S&&(L[K]=+!!q),z[D]=(z[D+1]<<1|1)&q,E&&(z[D]|=(j[D+1]|j[D])<<1|1|j[D+1]),z[D]&C&&(A=N(t,{errors:E,currentLocation:K,expectedLocation:b,distance:a,ignoreLocation:p}))<=x){if(x=A,(w=K)<=b)break;P=Math.max(1,2*b-w)}}if(N(t,{errors:E+1,currentLocation:b,expectedLocation:b,distance:a,ignoreLocation:p})>x)break;j=z}var B={isMatch:w>=0,score:Math.max(.001,A)};if(S){var J=function(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:$.minMatchCharLength,n=[],r=-1,i=-1,o=0,c=e.length;o=t&&n.push([r,i]),r=-1)}return e[o-1]&&o-r>=t&&n.push([r,o-1]),n}(L,d);J.length?g&&(B.indices=J):B.isMatch=!1}return B}function z(e){for(var t={},n=0,r=e.length;n1&&void 0!==arguments[1]?arguments[1]:{},o=i.location,c=void 0===o?$.location:o,a=i.threshold,s=void 0===a?$.threshold:a,u=i.distance,h=void 0===u?$.distance:u,l=i.includeMatches,f=void 0===l?$.includeMatches:l,d=i.findAllMatches,v=void 0===d?$.findAllMatches:d,g=i.minMatchCharLength,y=void 0===g?$.minMatchCharLength:g,p=i.isCaseSensitive,m=void 0===p?$.isCaseSensitive:p,k=i.ignoreLocation,M=void 0===k?$.ignoreLocation:k;if(r(this,e),this.options={location:c,threshold:s,distance:h,includeMatches:f,findAllMatches:v,minMatchCharLength:y,isCaseSensitive:m,ignoreLocation:M},this.pattern=m?t:t.toLowerCase(),this.chunks=[],this.pattern.length){var b=function(e,t){n.chunks.push({pattern:e,alphabet:z(e),startIndex:t})},x=this.pattern.length;if(x>W){for(var w=0,S=x%W,L=x-S;w1&&void 0!==arguments[1]?arguments[1]:{},c=o.location,a=void 0===c?$.location:c,s=o.threshold,u=void 0===s?$.threshold:s,h=o.distance,l=void 0===h?$.distance:h,f=o.includeMatches,d=void 0===f?$.includeMatches:f,v=o.findAllMatches,g=void 0===v?$.findAllMatches:v,y=o.minMatchCharLength,p=void 0===y?$.minMatchCharLength:y,m=o.isCaseSensitive,k=void 0===m?$.isCaseSensitive:m,M=o.ignoreLocation,b=void 0===M?$.ignoreLocation:M;return r(this,n),(i=t.call(this,e))._bitapSearch=new D(e,{location:a,threshold:u,distance:l,includeMatches:d,findAllMatches:g,minMatchCharLength:p,isCaseSensitive:k,ignoreLocation:b}),i}return o(n,[{key:"search",value:function(e){return this._bitapSearch.searchIn(e)}}],[{key:"type",get:function(){return"fuzzy"}},{key:"multiRegex",get:function(){return/^"(.*)"$/}},{key:"singleRegex",get:function(){return/^(.*)$/}}]),n}(K),X=function(e){a(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return o(n,[{key:"search",value:function(e){for(var t,n=0,r=[],i=this.pattern.length;(t=e.indexOf(this.pattern,n))>-1;)n=t+i,r.push([t,n-1]);var o=!!r.length;return{isMatch:o,score:o?0:1,indices:r}}}],[{key:"type",get:function(){return"include"}},{key:"multiRegex",get:function(){return/^'"(.*)"$/}},{key:"singleRegex",get:function(){return/^'(.*)$/}}]),n}(K),Y=[B,X,U,V,H,G,J,Q],Z=Y.length,ee=/ +(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/,te=new Set([Q.type,X.type]),ne=function(){function e(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=n.isCaseSensitive,o=void 0===i?$.isCaseSensitive:i,c=n.includeMatches,a=void 0===c?$.includeMatches:c,s=n.minMatchCharLength,u=void 0===s?$.minMatchCharLength:s,h=n.ignoreLocation,l=void 0===h?$.ignoreLocation:h,f=n.findAllMatches,d=void 0===f?$.findAllMatches:f,v=n.location,g=void 0===v?$.location:v,y=n.threshold,p=void 0===y?$.threshold:y,m=n.distance,k=void 0===m?$.distance:m;r(this,e),this.query=null,this.options={isCaseSensitive:o,includeMatches:a,minMatchCharLength:u,findAllMatches:d,ignoreLocation:l,location:g,threshold:p,distance:k},this.pattern=o?t:t.toLowerCase(),this.query=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return e.split("|").map((function(e){for(var n=e.trim().split(ee).filter((function(e){return e&&!!e.trim()})),r=[],i=0,o=n.length;i2&&void 0!==arguments[2]?arguments[2]:{}).auto,r=void 0===n||n;return ue(e)||(e=he(e)),function e(n){var i=Object.keys(n),o=function(e){return!!e[ae]}(n);if(!o&&i.length>1&&!ue(n))return e(he(n));if(function(e){return!g(e)&&b(e)&&!ue(e)}(n)){var c=o?n[ae]:i[0],a=o?n[se]:n[c];if(!m(a))throw new Error(function(e){return"Invalid value for key ".concat(e)}(c));var s={keyId:C(c),pattern:a};return r&&(s.searcher=ie(a,t)),s}var u={children:[],operator:i[0]};return i.forEach((function(t){var r=n[t];g(r)&&r.forEach((function(t){u.children.push(e(t))}))})),u}(e)}function fe(e,t){var n=e.matches;t.matches=[],x(n)&&n.forEach((function(e){if(x(e.indices)&&e.indices.length){var n={indices:e.indices,value:e.value};e.key&&(n.key=e.key.src),e.idx>-1&&(n.refIndex=e.idx),t.matches.push(n)}}))}function de(e,t){t.score=e.score}var ve=function(){function e(n){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},o=arguments.length>2?arguments[2]:void 0;r(this,e),this.options=t(t({},$),i),this.options.useExtendedSearch,this._keyStore=new j(this.options.keys),this.setCollection(n,o)}return o(e,[{key:"setCollection",value:function(e,t){if(this._docs=e,t&&!(t instanceof R))throw new Error("Incorrect 'index' type");this._myIndex=t||P(this.options.keys,this._docs,{getFn:this.options.getFn,fieldNormWeight:this.options.fieldNormWeight})}},{key:"add",value:function(e){x(e)&&(this._docs.push(e),this._myIndex.add(e))}},{key:"remove",value:function(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:function(){return!1},t=[],n=0,r=this._docs.length;n1&&void 0!==arguments[1]?arguments[1]:{}).limit,n=void 0===t?-1:t,r=this.options,i=r.includeMatches,o=r.includeScore,c=r.shouldSort,a=r.sortFn,s=r.ignoreFieldNorm,u=m(e)?m(this._docs[0])?this._searchStringList(e):this._searchObjectList(e):this._searchLogical(e);return function(e,t){var n=t.ignoreFieldNorm,r=void 0===n?$.ignoreFieldNorm:n;e.forEach((function(e){var t=1;e.matches.forEach((function(e){var n=e.key,i=e.norm,o=e.score,c=n?n.weight:null;t*=Math.pow(0===o&&c?Number.EPSILON:o,(c||1)*(r?1:i))})),e.score=t}))}(u,{ignoreFieldNorm:s}),c&&u.sort(a),k(n)&&n>-1&&(u=u.slice(0,n)),function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=n.includeMatches,i=void 0===r?$.includeMatches:r,o=n.includeScore,c=void 0===o?$.includeScore:o,a=[];return i&&a.push(fe),c&&a.push(de),e.map((function(e){var n=e.idx,r={item:t[n],refIndex:n};return a.length&&a.forEach((function(t){t(e,r)})),r}))}(u,this._docs,{includeMatches:i,includeScore:o})}},{key:"_searchStringList",value:function(e){var t=ie(e,this.options),n=this._myIndex.records,r=[];return n.forEach((function(e){var n=e.v,i=e.i,o=e.n;if(x(n)){var c=t.searchIn(n),a=c.isMatch,s=c.score,u=c.indices;a&&r.push({item:n,idx:i,matches:[{score:s,value:n,norm:o,indices:u}]})}})),r}},{key:"_searchLogical",value:function(e){var t=this,n=le(e,this.options),r=function e(n,r,i){if(!n.children){var o=n.keyId,c=n.searcher,a=t._findMatches({key:t._keyStore.get(o),value:t._myIndex.getValueForItemAtKeyId(r,o),searcher:c});return a&&a.length?[{idx:i,item:r,matches:a}]:[]}for(var s=[],u=0,h=n.children.length;u1&&void 0!==arguments[1]?arguments[1]:{},n=t.getFn,r=void 0===n?$.getFn:n,i=t.fieldNormWeight,o=void 0===i?$.fieldNormWeight:i,c=e.keys,a=e.records,s=new R({getFn:r,fieldNormWeight:o});return s.setKeys(c),s.setIndexRecords(a),s},ve.config=$,function(){re.push.apply(re,arguments)}(ne),ve},"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Fuse=t(); diff --git a/tests/snapshots/html_test__html_doc_files_multiple-7.snap b/tests/snapshots/html_test__html_doc_files_multiple-7.snap new file mode 100644 index 00000000..57305a42 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-7.snap @@ -0,0 +1,123 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + AbstractClass.prototype.getter - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { AbstractClass } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-70.snap b/tests/snapshots/html_test__html_doc_files_multiple-70.snap new file mode 100644 index 00000000..e67d0c9c --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-70.snap @@ -0,0 +1,39 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- +function findParent(el, find) { + do { + if (find(el)) { + return el; + } + } while (el = el.parentElement); +} + +document.addEventListener("click", (e) => { + const target = findParent( + e.target, + (el) => el instanceof HTMLButtonElement && el.dataset["copy"], + ); + if (target) { + navigator?.clipboard?.writeText(target.dataset["copy"]); + target.classList.add("copied"); + setTimeout(() => target.classList.remove("copied"), 1000); + } +}); + +window.addEventListener("load", () => { + const usageSelector = document.getElementById("usageSelector"); + + document.addEventListener("mouseup", (e) => { + if ( + findParent( + e.target, + (el) => + el.parentElement === usageSelector && el instanceof HTMLDivElement, + ) + ) { + usageSelector.open = false; + } + }); +}); diff --git a/tests/snapshots/html_test__html_doc_files_multiple-71.snap b/tests/snapshots/html_test__html_doc_files_multiple-71.snap new file mode 100644 index 00000000..33d6c4a7 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-71.snap @@ -0,0 +1,145 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- +const Fuse = window.Fuse; + +const searchInput = document.querySelector("#searchbar"); +const contentDiv = document.querySelector("#content"); +const searchResultsDiv = document.querySelector("#searchResults"); +const currentFile = + document.querySelector("meta[name='doc-current-file']").attributes + .getNamedItem("content").value; +const pathToRoot = "../".repeat( + currentFile ? (currentFile.split("/").length + 1) : 0, +); +searchInput.removeAttribute("style"); + +const SEARCH_INDEX = window.DENO_DOC_SEARCH_INDEX; + +const fuse = new Fuse(SEARCH_INDEX.nodes, { + keys: [{ + name: "name", + weight: 2, + }], + isCaseSensitive: false, + minMatchCharLength: 2, + threshold: 0.4, +}); + +const loadedUrl = new URL(window.location.href); +const val = loadedUrl.searchParams.get("q"); +if (val) { + searchInput.value = val; + doSearch(val); +} + +window.addEventListener("load", function () { + document.addEventListener("keydown", function (event) { + if (event.key.toLowerCase() === "s") { + if (event.target !== searchInput) { + searchInput.focus(); + event.preventDefault(); + } + } + }); + + const emptyPlaceholder = "Click or press 'S' to search..."; + searchInput.placeholder = emptyPlaceholder; + + searchInput.addEventListener("focus", function () { + searchInput.placeholder = "Type your query here..."; + }); + + searchInput.addEventListener("blur", function () { + searchInput.placeholder = emptyPlaceholder; + }); +}); + +function debounce(func, delay) { + let timerId; + + return function () { + const context = this; + const args = arguments; + + clearTimeout(timerId); + + timerId = setTimeout(function () { + func.apply(context, args); + }, delay); + }; +} + +const debouncedSearch = debounce(doSearch, 250); + +searchInput.addEventListener("input", (e) => { + const val = e.target.value; + debouncedSearch(val); +}); + +function doSearch(val) { + if (!val) { + updateCurrentLocation(val); + showPage(); + } else { + const results = searchInIndex(val); + // console.log("results", results); + updateCurrentLocation(val); + renderResults(results); + showSearchResults(); + } +} + +function updateCurrentLocation(val) { + const url = new URL(window.location.href); + if (val) { + url.searchParams.set("q", val); + } else { + url.searchParams.delete("q"); + } + window.history.replaceState({}, "", url.href); +} + +function showPage() { + contentDiv.style.display = "flex"; + searchResultsDiv.style.display = "none"; +} + +function showSearchResults() { + contentDiv.style.display = "none"; + searchResultsDiv.style.display = "block"; +} + +function renderResults(results) { + if (results.length === 0) { + searchResultsDiv.innerHTML = `No result`; + return; + } + + let html = `
      `; + + for (const result of results) { + const kind = result.kind.map((kind) => { + return `
      ${kind.char}
      `; + }).join(""); + + html += `
    • + +
      +
      + ${kind} +
      + ${result.name} +
      +
      +
    • `; + } + + html += `
    `; + searchResultsDiv.innerHTML = html; +} + +function searchInIndex(val) { + return fuse.search(val).map((result) => result.item); +} diff --git a/tests/snapshots/html_test__html_doc_files_multiple-72.snap b/tests/snapshots/html_test__html_doc_files_multiple-72.snap new file mode 100644 index 00000000..ed67e780 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-72.snap @@ -0,0 +1,7 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- +(function () { + window.DENO_DOC_SEARCH_INDEX = {"kind":"search","nodes":[{"kind":[{"char":"c","kind":"Class","title":"Class"}],"name":"A","file":".","doc":"","url":"././~/A.html","deprecated":false},{"kind":[{"char":"c","kind":"Class","title":"Class"}],"name":"AbstractClass","file":".","doc":"","url":"././~/AbstractClass.html","deprecated":false},{"kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"AbstractClass.prototype.method","file":".","doc":"","url":"././~/AbstractClass.prototype.method.html","deprecated":false},{"kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"AbstractClass.prototype.getter","file":".","doc":"","url":"././~/AbstractClass.prototype.getter.html","deprecated":false},{"kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"AbstractClass.prototype.foo","file":".","doc":"","url":"././~/AbstractClass.prototype.foo.html","deprecated":false},{"kind":[{"char":"c","kind":"Class","title":"Class"}],"name":"B","file":".","doc":"","url":"././~/B.html","deprecated":false},{"kind":[{"char":"c","kind":"Class","title":"Class"}],"name":"Bar","file":".","doc":"> Some quote in bar docs\n> This quote part is ignored\n> when getting the title of this doc\n\nBar docs","url":"././~/Bar.html","deprecated":false},{"kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"Baz","file":".","doc":"","url":"././~/Baz.html","deprecated":false},{"kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"Baz.bar","file":".","doc":"","url":"././~/Baz.bar.html","deprecated":false},{"kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Baz.foo","file":".","doc":"","url":"././~/Baz.foo.html","deprecated":false},{"kind":[{"char":"I","kind":"Interface","title":"Interface"},{"char":"v","kind":"Variable","title":"Variable"}],"name":"CompoundType","file":".","doc":"","url":"././~/CompoundType.html","deprecated":false},{"kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"CompoundType.bufferedAmount","file":".","doc":"","url":"././~/CompoundType.bufferedAmount.html","deprecated":false},{"kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"EmptyInterface","file":".","doc":"","url":"././~/EmptyInterface.html","deprecated":false},{"kind":[{"char":"E","kind":"Enum","title":"Enum"}],"name":"Enum","file":".","doc":"","url":"././~/Enum.html","deprecated":false},{"kind":[{"char":"E","kind":"Enum","title":"Enum"}],"name":"Enum2","file":".","doc":"","url":"././~/Enum2.html","deprecated":false},{"kind":[{"char":"c","kind":"Class","title":"Class"}],"name":"Foo","file":".","doc":"some Foo docs {@linkcode Bar}\n","url":"././~/Foo.html","deprecated":false},{"kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"Foo.prototype.[Symbol.iterator]","file":".","doc":"","url":"././~/Foo.prototype.[Symbol.iterator].html","deprecated":false},{"kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"Foo.prototype.getter","file":".","doc":"","url":"././~/Foo.prototype.getter.html","deprecated":false},{"kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"Foo.prototype.setter","file":".","doc":"","url":"././~/Foo.prototype.setter.html","deprecated":false},{"kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"Foo.prototype.getterAndSetter","file":".","doc":"","url":"././~/Foo.prototype.getterAndSetter.html","deprecated":false},{"kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"Foo.prototype.getterAndSetter","file":".","doc":"","url":"././~/Foo.prototype.getterAndSetter.html","deprecated":false},{"kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"Foo.staticSetter","file":".","doc":"","url":"././~/Foo.staticSetter.html","deprecated":false},{"kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"Foo.prototype.test","file":".","doc":"","url":"././~/Foo.prototype.test.html","deprecated":false},{"kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"Foo.staticMethod","file":".","doc":"","url":"././~/Foo.staticMethod.html","deprecated":false},{"kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"Foo.prototype.methodWithOverloads","file":".","doc":"","url":"././~/Foo.prototype.methodWithOverloads.html","deprecated":false},{"kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"Foo.prototype.methodWithOverloads","file":".","doc":"","url":"././~/Foo.prototype.methodWithOverloads.html","deprecated":false},{"kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"Foo.prototype.methodWithOverloads","file":".","doc":"","url":"././~/Foo.prototype.methodWithOverloads.html","deprecated":false},{"kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Foo.bar","file":".","doc":"","url":"././~/Foo.bar.html","deprecated":false},{"kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Foo.prototype.protectedProperty","file":".","doc":"","url":"././~/Foo.prototype.protectedProperty.html","deprecated":false},{"kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Foo.prototype.readonlyProperty","file":".","doc":"","url":"././~/Foo.prototype.readonlyProperty.html","deprecated":false},{"kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Foo.prototype.foo","file":".","doc":"","url":"././~/Foo.prototype.foo.html","deprecated":false},{"kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Foo.prototype.\"><img src=x onerror=alert(1)>","file":".","doc":"","url":"././~/Foo.prototype.\">.html","deprecated":false},{"kind":[{"char":"c","kind":"Class","title":"Class"}],"name":"Foobar","file":".","doc":"```ts\n// This code block is ignored when getting the title of this doc\nconst foobar = new Foobar();\n```\n\nFoobar docs\n\n# heading\n\ncontent\n\n## sub heading\n","url":"././~/Foobar.html","deprecated":false},{"kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"Hello","file":".","doc":"","url":"././~/Hello.html","deprecated":false},{"kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"Hello.optionalMethod","file":".","doc":"","url":"././~/Hello.optionalMethod.html","deprecated":false},{"kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"Hello.computedMethod","file":".","doc":"","url":"././~/Hello.computedMethod.html","deprecated":false},{"kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Hello.world","file":".","doc":"","url":"././~/Hello.world.html","deprecated":false},{"kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Hello.test","file":".","doc":"Some docs","url":"././~/Hello.test.html","deprecated":false},{"kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Hello.ab","file":".","doc":"","url":"././~/Hello.ab.html","deprecated":false},{"kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Hello.x","file":".","doc":"","url":"././~/Hello.x.html","deprecated":false},{"kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"InterfaceWithIndexSignature","file":".","doc":"","url":"././~/InterfaceWithIndexSignature.html","deprecated":false},{"kind":[{"char":"c","kind":"Class","title":"Class"},{"char":"N","kind":"Namespace","title":"Namespace"}],"name":"Testing","file":".","doc":"","url":"././~/Testing.html","deprecated":false},{"kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"Testing.t","file":".","doc":"","url":"././~/Testing.t.html","deprecated":false},{"kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"TypeAlias","file":".","doc":"","url":"././~/TypeAlias.html","deprecated":false},{"kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"anotherVariable","file":".","doc":"","url":"././~/anotherVariable.html","deprecated":false},{"kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"anotherVariable.bar","file":".","doc":"","url":"././~/anotherVariable.bar.html","deprecated":false},{"kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"anotherVariable.foo","file":".","doc":"","url":"././~/anotherVariable.foo.html","deprecated":false},{"kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"c","file":".","doc":"","url":"././~/c.html","deprecated":false},{"kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"d","file":".","doc":"","url":"././~/d.html","deprecated":false},{"kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"functionWithOptionalParameters","file":".","doc":"","url":"././~/functionWithOptionalParameters.html","deprecated":false},{"kind":[{"char":"f","kind":"Function","title":"Function"},{"char":"f","kind":"Function","title":"Function"},{"char":"f","kind":"Function","title":"Function"}],"name":"qaz","file":".","doc":"content\n","url":"././~/qaz.html","deprecated":false},{"kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"someVariable","file":".","doc":"","url":"././~/someVariable.html","deprecated":false},{"kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"Testing.x","file":"c","doc":"","url":"./c/~/Testing.x.html","deprecated":false},{"kind":[{"char":"f","kind":"Function","title":"Function"},{"char":"f","kind":"Function","title":"Function"},{"char":"f","kind":"Function","title":"Function"}],"name":"x","file":"c","doc":"","url":"./c/~/x.html","deprecated":false},{"kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"Testing.externalFunction","file":"d","doc":"","url":"./d/~/Testing.externalFunction.html","deprecated":false},{"kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"externalFunction","file":"d","doc":"","url":"./d/~/externalFunction.html","deprecated":false},{"kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"default","file":"foo","doc":"The default export item.\n\nThis item reproduces the issue reported in {@link https://github.com/jsr-io/jsr/issues/459}","url":"./foo/~/default.html","deprecated":false}]}; +})() diff --git a/tests/snapshots/html_test__html_doc_files_multiple-8.snap b/tests/snapshots/html_test__html_doc_files_multiple-8.snap new file mode 100644 index 00000000..90d0be17 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-8.snap @@ -0,0 +1,5 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + diff --git a/tests/snapshots/html_test__html_doc_files_multiple-9.snap b/tests/snapshots/html_test__html_doc_files_multiple-9.snap new file mode 100644 index 00000000..82c65392 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple-9.snap @@ -0,0 +1,175 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + AbstractClass.prototype.method - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { AbstractClass } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_multiple.snap b/tests/snapshots/html_test__html_doc_files_multiple.snap new file mode 100644 index 00000000..945a7e12 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_multiple.snap @@ -0,0 +1,281 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + All Symbols - documentation + + + + + + + + + + +
    +
    +
    +
    c
    +
    + AbstractClass + +
    No documentation available
    +
    v
    +
    + anotherVariable + +
    No documentation available
    +
    c
    +
    + Bar + +

    Bar docs

    +
    +
    T
    +
    + Baz + +
    No documentation available
    +
    f
    +
    + c + +
    No documentation available
    +
    I
    v
    +
    + CompoundType + +
    No documentation available
    +
    f
    +
    + d + +
    No documentation available
    +
    I
    +
    + EmptyInterface + +
    No documentation available
    +
    E
    +
    + Enum + +
    No documentation available
    +
    E
    +
    + Enum2 + +
    No documentation available
    +
    c
    +
    + Foobar + +

    Foobar docs

    +
    +
    f
    +
    + functionWithOptionalParameters + +
    No documentation available
    +
    I
    +
    + Hello + +
    No documentation available
    +
    I
    +
    + InterfaceWithIndexSignature + +
    No documentation available
    +
    f
    +
    + qaz + +
    No documentation available
    +
    v
    +
    + someVariable + +
    No documentation available
    +
    c
    N
    +
    + Testing + +
    No documentation available
    +
    f
    +
    + Testing.t + +
    No documentation available
    +
    T
    +
    + TypeAlias + +
    No documentation available
    +
    +
    +
    f
    +
    + Testing.x + +
    No documentation available
    +
    f
    +
    + x + +
    No documentation available
    +
    +
    +
    f
    +
    + externalFunction + +
    No documentation available
    +
    f
    +
    + Testing.externalFunction + +
    No documentation available
    +
    +
    +
    v
    +
    + default + +

    The default export item.

    +
    +
    f
    +
    + x + +
    No documentation available
    +
    +
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-10.snap b/tests/snapshots/html_test__html_doc_files_rewrite-10.snap index 75067eff..1664504a 100644 --- a/tests/snapshots/html_test__html_doc_files_rewrite-10.snap +++ b/tests/snapshots/html_test__html_doc_files_rewrite-10.snap @@ -1,36 +1,25 @@ --- source: tests/html_test.rs -expression: "files.get(\"./~/Foo.prototype.foo.html\").unwrap()" +expression: files.get(name).unwrap() --- - Foo.prototype.foo - documentation + B - documentation - - - - - - - - - + + + + + +
    -
    -

    Usage

    import { Foo } from ".";
    -
    -
    -
    +
    + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-11.snap b/tests/snapshots/html_test__html_doc_files_rewrite-11.snap index 2c721a05..f941ad60 100644 --- a/tests/snapshots/html_test__html_doc_files_rewrite-11.snap +++ b/tests/snapshots/html_test__html_doc_files_rewrite-11.snap @@ -1,5 +1,5 @@ --- source: tests/html_test.rs -expression: "files.get(\"./~/Foo.prototype.html\").unwrap()" +expression: files.get(name).unwrap() --- - + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-12.snap b/tests/snapshots/html_test__html_doc_files_rewrite-12.snap index 632025aa..424d5b5d 100644 --- a/tests/snapshots/html_test__html_doc_files_rewrite-12.snap +++ b/tests/snapshots/html_test__html_doc_files_rewrite-12.snap @@ -1,28 +1,25 @@ --- source: tests/html_test.rs -expression: "files.get(\"./~/Foobar.html\").unwrap()" +expression: files.get(name).unwrap() --- - Foobar - documentation + Bar - documentation - - - - - - - - - + + + + + +
    -
    +
    - class Foobar -
    + class Bar +
    + extends Foo<string> +
    +

    Some quote in bar docs +This quote part is ignored +when getting the title of this doc

    +
    +

    Bar docs

    +
    -

    Usage

    import default from ".";
    -
    -
    +
    diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-13.snap b/tests/snapshots/html_test__html_doc_files_rewrite-13.snap index 1747cadc..249b4727 100644 --- a/tests/snapshots/html_test__html_doc_files_rewrite-13.snap +++ b/tests/snapshots/html_test__html_doc_files_rewrite-13.snap @@ -1,5 +1,5 @@ --- source: tests/html_test.rs -expression: "files.get(\"./~/Foobar.prototype.html\").unwrap()" +expression: files.get(name).unwrap() --- - + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-14.snap b/tests/snapshots/html_test__html_doc_files_rewrite-14.snap index a9500a7d..31a8d53f 100644 --- a/tests/snapshots/html_test__html_doc_files_rewrite-14.snap +++ b/tests/snapshots/html_test__html_doc_files_rewrite-14.snap @@ -1,36 +1,25 @@ --- source: tests/html_test.rs -expression: "files.get(\"./~/Hello.html\").unwrap()" +expression: files.get(file_name).unwrap() --- - Hello - documentation + Baz.bar - documentation - - - - - - - - - + + + + + +
    -
    +
    diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-15.snap b/tests/snapshots/html_test__html_doc_files_rewrite-15.snap index 460182df..dceca004 100644 --- a/tests/snapshots/html_test__html_doc_files_rewrite-15.snap +++ b/tests/snapshots/html_test__html_doc_files_rewrite-15.snap @@ -1,28 +1,25 @@ --- source: tests/html_test.rs -expression: "files.get(\"./~/Hello.world.html\").unwrap()" +expression: files.get(file_name).unwrap() --- - Hello.world - documentation + Baz.foo - documentation - - - - - - - - - + + + + + +
    -
    +
    - property Hello.world + property Baz.foo

    -Type

    +Type
    -
    "string" +
    Record<string, T extends string ? 0 : 1>
    @@ -89,17 +78,21 @@ Type
    -

    Usage

    import { type Hello } from ".";
    -
    -
    +
    diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-16.snap b/tests/snapshots/html_test__html_doc_files_rewrite-16.snap index fc498835..cb521110 100644 --- a/tests/snapshots/html_test__html_doc_files_rewrite-16.snap +++ b/tests/snapshots/html_test__html_doc_files_rewrite-16.snap @@ -1,23 +1,20 @@ --- source: tests/html_test.rs -expression: "files.get(\"foo/index.html\").unwrap()" +expression: files.get(file_name).unwrap() --- - Index - documentation + Baz - documentation - + - - - + - - +
    -
    -
    -
    +
    +
    -

    -
    - default +Properties
    -

    The default export item.

    -
    -
    -
    -
    +
    +
    + + + + + + + + + + +foo: Record<string, T extends string ? 0 : 1> + +
    +
    +
    +
    - -
    + +
    -

    Usage

    import * as mod from "foo";
    -
    -
    -
    + + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-17.snap b/tests/snapshots/html_test__html_doc_files_rewrite-17.snap index b6b90334..65b73b3a 100644 --- a/tests/snapshots/html_test__html_doc_files_rewrite-17.snap +++ b/tests/snapshots/html_test__html_doc_files_rewrite-17.snap @@ -1,36 +1,25 @@ --- source: tests/html_test.rs -expression: "files.get(\"foo/~/x.html\").unwrap()" +expression: files.get(file_name).unwrap() --- - x - documentation + EmptyInterface - documentation - - - - - - - - - - + + + + + + +
    -
    -

    Usage

    import { x } from "foo";
    -
    -
    -
    +
    + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-18.snap b/tests/snapshots/html_test__html_doc_files_rewrite-18.snap index cf016dae..b241cae2 100644 --- a/tests/snapshots/html_test__html_doc_files_rewrite-18.snap +++ b/tests/snapshots/html_test__html_doc_files_rewrite-18.snap @@ -1,15 +1,149 @@ --- source: tests/html_test.rs -expression: "files.get(\"fuse.js\").unwrap()" +expression: files.get(file_name).unwrap() --- -// deno-fmt-ignore-file -// deno-lint-ignore-file -/** - * Fuse.js v7.0.0 - Lightweight fuzzy-search (http://fusejs.io) - * - * Copyright (c) 2023 Kiro Risk (http://kiro.me) - * All Rights Reserved. Apache Software License 2.0 - * - * http://www.apache.org/licenses/LICENSE-2.0 - */ -var e,t;e=this,t=function(){"use strict";function e(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function t(t){for(var n=1;ne.length)&&(t=e.length);for(var n=0,r=new Array(t);n0&&void 0!==arguments[0]?arguments[0]:{},n=t.getFn,i=void 0===n?$.getFn:n,o=t.fieldNormWeight,c=void 0===o?$.fieldNormWeight:o;r(this,e),this.norm=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:3,n=new Map,r=Math.pow(10,t);return{get:function(t){var i=t.match(F).length;if(n.has(i))return n.get(i);var o=1/Math.pow(i,.5*e),c=parseFloat(Math.round(o*r)/r);return n.set(i,c),c},clear:function(){n.clear()}}}(c,3),this.getFn=i,this.isCreated=!1,this.setIndexRecords()}return o(e,[{key:"setSources",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.docs=e}},{key:"setIndexRecords",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.records=e}},{key:"setKeys",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.keys=t,this._keysMap={},t.forEach((function(t,n){e._keysMap[t.id]=n}))}},{key:"create",value:function(){var e=this;!this.isCreated&&this.docs.length&&(this.isCreated=!0,m(this.docs[0])?this.docs.forEach((function(t,n){e._addString(t,n)})):this.docs.forEach((function(t,n){e._addObject(t,n)})),this.norm.clear())}},{key:"add",value:function(e){var t=this.size();m(e)?this._addString(e,t):this._addObject(e,t)}},{key:"removeAt",value:function(e){this.records.splice(e,1);for(var t=e,n=this.size();t2&&void 0!==arguments[2]?arguments[2]:{},r=n.getFn,i=void 0===r?$.getFn:r,o=n.fieldNormWeight,c=void 0===o?$.fieldNormWeight:o,a=new R({getFn:i,fieldNormWeight:c});return a.setKeys(e.map(A)),a.setSources(t),a.create(),a}function N(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t.errors,r=void 0===n?0:n,i=t.currentLocation,o=void 0===i?0:i,c=t.expectedLocation,a=void 0===c?0:c,s=t.distance,u=void 0===s?$.distance:s,h=t.ignoreLocation,l=void 0===h?$.ignoreLocation:h,f=r/e.length;if(l)return f;var d=Math.abs(a-o);return u?f+d/u:d?1:f}var W=32;function T(e,t,n){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},i=r.location,o=void 0===i?$.location:i,c=r.distance,a=void 0===c?$.distance:c,s=r.threshold,u=void 0===s?$.threshold:s,h=r.findAllMatches,l=void 0===h?$.findAllMatches:h,f=r.minMatchCharLength,d=void 0===f?$.minMatchCharLength:f,v=r.includeMatches,g=void 0===v?$.includeMatches:v,y=r.ignoreLocation,p=void 0===y?$.ignoreLocation:y;if(t.length>W)throw new Error("Pattern length exceeds max of ".concat(W,"."));for(var m,k=t.length,M=e.length,b=Math.max(0,Math.min(o,M)),x=u,w=b,S=d>1||g,L=S?Array(M):[];(m=e.indexOf(t,w))>-1;){var _=N(t,{currentLocation:m,expectedLocation:b,distance:a,ignoreLocation:p});if(x=Math.min(_,x),w=m+k,S)for(var O=0;O=P;D-=1){var K=D-1,q=n[e.charAt(K)];if(S&&(L[K]=+!!q),z[D]=(z[D+1]<<1|1)&q,E&&(z[D]|=(j[D+1]|j[D])<<1|1|j[D+1]),z[D]&C&&(A=N(t,{errors:E,currentLocation:K,expectedLocation:b,distance:a,ignoreLocation:p}))<=x){if(x=A,(w=K)<=b)break;P=Math.max(1,2*b-w)}}if(N(t,{errors:E+1,currentLocation:b,expectedLocation:b,distance:a,ignoreLocation:p})>x)break;j=z}var B={isMatch:w>=0,score:Math.max(.001,A)};if(S){var J=function(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:$.minMatchCharLength,n=[],r=-1,i=-1,o=0,c=e.length;o=t&&n.push([r,i]),r=-1)}return e[o-1]&&o-r>=t&&n.push([r,o-1]),n}(L,d);J.length?g&&(B.indices=J):B.isMatch=!1}return B}function z(e){for(var t={},n=0,r=e.length;n1&&void 0!==arguments[1]?arguments[1]:{},o=i.location,c=void 0===o?$.location:o,a=i.threshold,s=void 0===a?$.threshold:a,u=i.distance,h=void 0===u?$.distance:u,l=i.includeMatches,f=void 0===l?$.includeMatches:l,d=i.findAllMatches,v=void 0===d?$.findAllMatches:d,g=i.minMatchCharLength,y=void 0===g?$.minMatchCharLength:g,p=i.isCaseSensitive,m=void 0===p?$.isCaseSensitive:p,k=i.ignoreLocation,M=void 0===k?$.ignoreLocation:k;if(r(this,e),this.options={location:c,threshold:s,distance:h,includeMatches:f,findAllMatches:v,minMatchCharLength:y,isCaseSensitive:m,ignoreLocation:M},this.pattern=m?t:t.toLowerCase(),this.chunks=[],this.pattern.length){var b=function(e,t){n.chunks.push({pattern:e,alphabet:z(e),startIndex:t})},x=this.pattern.length;if(x>W){for(var w=0,S=x%W,L=x-S;w1&&void 0!==arguments[1]?arguments[1]:{},c=o.location,a=void 0===c?$.location:c,s=o.threshold,u=void 0===s?$.threshold:s,h=o.distance,l=void 0===h?$.distance:h,f=o.includeMatches,d=void 0===f?$.includeMatches:f,v=o.findAllMatches,g=void 0===v?$.findAllMatches:v,y=o.minMatchCharLength,p=void 0===y?$.minMatchCharLength:y,m=o.isCaseSensitive,k=void 0===m?$.isCaseSensitive:m,M=o.ignoreLocation,b=void 0===M?$.ignoreLocation:M;return r(this,n),(i=t.call(this,e))._bitapSearch=new D(e,{location:a,threshold:u,distance:l,includeMatches:d,findAllMatches:g,minMatchCharLength:p,isCaseSensitive:k,ignoreLocation:b}),i}return o(n,[{key:"search",value:function(e){return this._bitapSearch.searchIn(e)}}],[{key:"type",get:function(){return"fuzzy"}},{key:"multiRegex",get:function(){return/^"(.*)"$/}},{key:"singleRegex",get:function(){return/^(.*)$/}}]),n}(K),X=function(e){a(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return o(n,[{key:"search",value:function(e){for(var t,n=0,r=[],i=this.pattern.length;(t=e.indexOf(this.pattern,n))>-1;)n=t+i,r.push([t,n-1]);var o=!!r.length;return{isMatch:o,score:o?0:1,indices:r}}}],[{key:"type",get:function(){return"include"}},{key:"multiRegex",get:function(){return/^'"(.*)"$/}},{key:"singleRegex",get:function(){return/^'(.*)$/}}]),n}(K),Y=[B,X,U,V,H,G,J,Q],Z=Y.length,ee=/ +(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/,te=new Set([Q.type,X.type]),ne=function(){function e(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=n.isCaseSensitive,o=void 0===i?$.isCaseSensitive:i,c=n.includeMatches,a=void 0===c?$.includeMatches:c,s=n.minMatchCharLength,u=void 0===s?$.minMatchCharLength:s,h=n.ignoreLocation,l=void 0===h?$.ignoreLocation:h,f=n.findAllMatches,d=void 0===f?$.findAllMatches:f,v=n.location,g=void 0===v?$.location:v,y=n.threshold,p=void 0===y?$.threshold:y,m=n.distance,k=void 0===m?$.distance:m;r(this,e),this.query=null,this.options={isCaseSensitive:o,includeMatches:a,minMatchCharLength:u,findAllMatches:d,ignoreLocation:l,location:g,threshold:p,distance:k},this.pattern=o?t:t.toLowerCase(),this.query=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return e.split("|").map((function(e){for(var n=e.trim().split(ee).filter((function(e){return e&&!!e.trim()})),r=[],i=0,o=n.length;i2&&void 0!==arguments[2]?arguments[2]:{}).auto,r=void 0===n||n;return ue(e)||(e=he(e)),function e(n){var i=Object.keys(n),o=function(e){return!!e[ae]}(n);if(!o&&i.length>1&&!ue(n))return e(he(n));if(function(e){return!g(e)&&b(e)&&!ue(e)}(n)){var c=o?n[ae]:i[0],a=o?n[se]:n[c];if(!m(a))throw new Error(function(e){return"Invalid value for key ".concat(e)}(c));var s={keyId:C(c),pattern:a};return r&&(s.searcher=ie(a,t)),s}var u={children:[],operator:i[0]};return i.forEach((function(t){var r=n[t];g(r)&&r.forEach((function(t){u.children.push(e(t))}))})),u}(e)}function fe(e,t){var n=e.matches;t.matches=[],x(n)&&n.forEach((function(e){if(x(e.indices)&&e.indices.length){var n={indices:e.indices,value:e.value};e.key&&(n.key=e.key.src),e.idx>-1&&(n.refIndex=e.idx),t.matches.push(n)}}))}function de(e,t){t.score=e.score}var ve=function(){function e(n){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},o=arguments.length>2?arguments[2]:void 0;r(this,e),this.options=t(t({},$),i),this.options.useExtendedSearch,this._keyStore=new j(this.options.keys),this.setCollection(n,o)}return o(e,[{key:"setCollection",value:function(e,t){if(this._docs=e,t&&!(t instanceof R))throw new Error("Incorrect 'index' type");this._myIndex=t||P(this.options.keys,this._docs,{getFn:this.options.getFn,fieldNormWeight:this.options.fieldNormWeight})}},{key:"add",value:function(e){x(e)&&(this._docs.push(e),this._myIndex.add(e))}},{key:"remove",value:function(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:function(){return!1},t=[],n=0,r=this._docs.length;n1&&void 0!==arguments[1]?arguments[1]:{}).limit,n=void 0===t?-1:t,r=this.options,i=r.includeMatches,o=r.includeScore,c=r.shouldSort,a=r.sortFn,s=r.ignoreFieldNorm,u=m(e)?m(this._docs[0])?this._searchStringList(e):this._searchObjectList(e):this._searchLogical(e);return function(e,t){var n=t.ignoreFieldNorm,r=void 0===n?$.ignoreFieldNorm:n;e.forEach((function(e){var t=1;e.matches.forEach((function(e){var n=e.key,i=e.norm,o=e.score,c=n?n.weight:null;t*=Math.pow(0===o&&c?Number.EPSILON:o,(c||1)*(r?1:i))})),e.score=t}))}(u,{ignoreFieldNorm:s}),c&&u.sort(a),k(n)&&n>-1&&(u=u.slice(0,n)),function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=n.includeMatches,i=void 0===r?$.includeMatches:r,o=n.includeScore,c=void 0===o?$.includeScore:o,a=[];return i&&a.push(fe),c&&a.push(de),e.map((function(e){var n=e.idx,r={item:t[n],refIndex:n};return a.length&&a.forEach((function(t){t(e,r)})),r}))}(u,this._docs,{includeMatches:i,includeScore:o})}},{key:"_searchStringList",value:function(e){var t=ie(e,this.options),n=this._myIndex.records,r=[];return n.forEach((function(e){var n=e.v,i=e.i,o=e.n;if(x(n)){var c=t.searchIn(n),a=c.isMatch,s=c.score,u=c.indices;a&&r.push({item:n,idx:i,matches:[{score:s,value:n,norm:o,indices:u}]})}})),r}},{key:"_searchLogical",value:function(e){var t=this,n=le(e,this.options),r=function e(n,r,i){if(!n.children){var o=n.keyId,c=n.searcher,a=t._findMatches({key:t._keyStore.get(o),value:t._myIndex.getValueForItemAtKeyId(r,o),searcher:c});return a&&a.length?[{idx:i,item:r,matches:a}]:[]}for(var s=[],u=0,h=n.children.length;u1&&void 0!==arguments[1]?arguments[1]:{},n=t.getFn,r=void 0===n?$.getFn:n,i=t.fieldNormWeight,o=void 0===i?$.fieldNormWeight:i,c=e.keys,a=e.records,s=new R({getFn:r,fieldNormWeight:o});return s.setKeys(c),s.setIndexRecords(a),s},ve.config=$,function(){re.push.apply(re,arguments)}(ne),ve},"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Fuse=t(); + + + + Enum - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { Enum } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-19.snap b/tests/snapshots/html_test__html_doc_files_rewrite-19.snap index 89b94021..0e1545c4 100644 --- a/tests/snapshots/html_test__html_doc_files_rewrite-19.snap +++ b/tests/snapshots/html_test__html_doc_files_rewrite-19.snap @@ -1,37 +1,149 @@ --- source: tests/html_test.rs -expression: "files.get(\"script.js\").unwrap()" +expression: files.get(file_name).unwrap() --- -function findParent(el, find) { - do { - if (find(el)) { - return el; - } - } while (el = el.parentElement); -} + + + + Enum2 - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    + enum Enum2 +
    +
    -window.addEventListener("load", () => { - const usageSelector = document.getElementById("usageSelector"); +
    +
    - document.addEventListener("mouseup", (e) => { - if ( - findParent( - e.target, - (el) => - el.parentElement === usageSelector && el instanceof HTMLDivElement, - ) - ) { - usageSelector.open = false; - } - }); -}); +
    +
    +
    +
    +
    +
    +
    +

    Usage

    import { Enum2 } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-2.snap b/tests/snapshots/html_test__html_doc_files_rewrite-2.snap index 00c0aefb..2d062244 100644 --- a/tests/snapshots/html_test__html_doc_files_rewrite-2.snap +++ b/tests/snapshots/html_test__html_doc_files_rewrite-2.snap @@ -1,36 +1,25 @@ --- source: tests/html_test.rs -expression: "files.get(\"./index.html\").unwrap()" +expression: files.get(file_name).unwrap() --- - Index - documentation + documentation - - - - - - - - - + + + + + +
    -
    -
    -

    Some docs

    -
    - - - - - -Note

    -Useful information that users should know, even when skimming content.

    -
    -
    - - - - - -Tip

    -Helpful advice for doing things better or more easily.

    -
    -
    - - - - - -Important

    -Key information users need to know to achieve their goal.

    -
    -
    - - - - - -Warning

    -Urgent info that needs immediate user attention to avoid problems.

    -
    -
    - - - - - -Caution

    -Advises about risks or negative outcomes of certain actions.

    -
    -
    -
    c
    -
    - Bar - -
    No documentation available
    -
    -
    c
    -
    - Foo - -

    some Foo docs

    -
    -
    -
    c
    -
    - Foobar - -
    No documentation available
    -
    -
    -
    -
    -
    f
    -
    - c - -
    No documentation available
    -
    -
    f
    -
    - d - -
    No documentation available
    -
    -
    f
    -
    - qaz - -
    No documentation available
    -
    -
    -
    -
    -
    -

    - - - - - - - - - - -Interfaces

    I
    -
    - Hello - -
    No documentation available
    -
    -
    -
    -
    -
    -

    - - - - - - - - - - -Type Aliases

    T
    -
    - Baz - -
    No documentation available
    -
    -
    -
    -
    +
    +
    +
    diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-20.snap b/tests/snapshots/html_test__html_doc_files_rewrite-20.snap index 3c39d30f..a6d4f579 100644 --- a/tests/snapshots/html_test__html_doc_files_rewrite-20.snap +++ b/tests/snapshots/html_test__html_doc_files_rewrite-20.snap @@ -1,172 +1,99 @@ --- source: tests/html_test.rs -expression: "files.get(\"search.js\").unwrap()" +expression: files.get(file_name).unwrap() --- -const Fuse = window.Fuse; - -const searchInput = document.querySelector("#searchbar"); -const mainContentTags = document.getElementsByTagName("main"); -const searchResultsDiv = document.querySelector("#searchResults"); -const currentFile = - document.querySelector("meta[name='doc-current-file']").attributes - .getNamedItem("content").value; -const pathToRoot = "../".repeat( - currentFile ? (currentFile.split("/").length + 1) : 0, -); -searchInput.removeAttribute("style"); - -const SEARCH_INDEX = window.DENO_DOC_SEARCH_INDEX; - -const fuse = new Fuse(SEARCH_INDEX.nodes, { - keys: [{ - name: "name", - weight: 2, - }], - isCaseSensitive: false, - minMatchCharLength: 2, - threshold: 0.4, -}); - -const loadedUrl = new URL(window.location.href); -const val = loadedUrl.searchParams.get("q"); -if (val) { - searchInput.value = val; - doSearch(val); -} - -window.addEventListener("load", function () { - document.addEventListener("keydown", function (event) { - if (event.key.toLowerCase() === "s") { - if (event.target !== searchInput) { - searchInput.focus(); - event.preventDefault(); - } - } - }); - - const emptyPlaceholder = "Click or press 'S' to search..."; - searchInput.placeholder = emptyPlaceholder; - - searchInput.addEventListener("focus", function () { - searchInput.placeholder = "Type your query here..."; - }); - - searchInput.addEventListener("blur", function () { - searchInput.placeholder = emptyPlaceholder; - }); -}); - -function debounce(func, delay) { - let timerId; - - return function () { - const context = this; - const args = arguments; - - clearTimeout(timerId); - - timerId = setTimeout(function () { - func.apply(context, args); - }, delay); - }; -} - -const debouncedSearch = debounce(doSearch, 250); - -searchInput.addEventListener("input", (e) => { - const val = e.target.value; - debouncedSearch(val); -}); - -function doSearch(val) { - if (!val) { - updateCurrentLocation(val); - showPage(); - } else { - const results = searchInIndex(val); - // console.log("results", results); - updateCurrentLocation(val); - renderResults(results); - showSearchResults(); - } -} - -function updateCurrentLocation(val) { - const url = new URL(window.location.href); - if (val) { - url.searchParams.set("q", val); - } else { - url.searchParams.delete("q"); - } - window.history.replaceState({}, "", url.href); -} - -function showPage() { - for (const mainTag of mainContentTags) { - mainTag.style.display = "block"; - } - searchResultsDiv.style.display = "none"; -} - -function showSearchResults() { - for (const mainTag of mainContentTags) { - mainTag.style.display = "none"; - } - searchResultsDiv.style.display = "block"; -} - -function renderResults(results) { - if (results.length === 0) { - searchResultsDiv.innerHTML = `No result`; - return; - } - - let html = ``; - searchResultsDiv.innerHTML = html; -} - -function searchInIndex(val) { - return fuse.search(val).map((result) => result.item); -} - -function docNodeKindToStringVariants(kind) { - switch (kind) { - case "function": - return ["Function", "Function", "f"]; - case "variable": - return ["Variable", "Variable", "v"]; - case "class": - return ["Class", "Class", "c"]; - case "enum": - return ["Enum", "Enum", "E"]; - case "interface": - return ["Interface", "Interface", "I"]; - case "typeAlias": - return ["TypeAlias", "Type Alias", "T"]; - case "namespace": - return ["Namespace", "Namespace", "N"]; - default: - return []; - } -} +Type
    + +
    +
    "string" + +
    +
    + + + +
    +
    +

    Usage

    import { Foo } from ".";
    +
    +
    +
    + + + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-21.snap b/tests/snapshots/html_test__html_doc_files_rewrite-21.snap index 94375f24..61e44eaf 100644 --- a/tests/snapshots/html_test__html_doc_files_rewrite-21.snap +++ b/tests/snapshots/html_test__html_doc_files_rewrite-21.snap @@ -1,7 +1,814 @@ --- source: tests/html_test.rs -expression: "files.get(\"search_index.js\").unwrap()" +expression: files.get(file_name).unwrap() --- -(function () { - window.DENO_DOC_SEARCH_INDEX = {"nodes":[{"kind":["class"],"name":"A","file":".","doc":"","location":{"filename":".","line":45,"col":0,"byteIndex":741},"url":"././~/A.html","category":"","declarationKind":"private","deprecated":false},{"kind":["class"],"name":"B","file":".","doc":"","location":{"filename":".","line":48,"col":0,"byteIndex":770},"url":"././~/B.html","category":"","declarationKind":"export","deprecated":false},{"kind":["class"],"name":"Bar","file":".","doc":"","location":{"filename":".","line":31,"col":0,"byteIndex":588},"url":"././~/Bar.html","category":"","declarationKind":"export","deprecated":false},{"kind":["typeAlias"],"name":"Baz","file":".","doc":"","location":{"filename":".","line":41,"col":0,"byteIndex":702},"url":"././~/Baz.html","category":"","declarationKind":"export","deprecated":false},{"kind":["class"],"name":"Foo","file":".","doc":"some Foo docs","location":{"filename":".","line":25,"col":0,"byteIndex":488},"url":"././~/Foo.html","category":"","declarationKind":"export","deprecated":false},{"kind":["class"],"name":"Foobar","file":".","doc":"","location":{"filename":".","line":34,"col":0,"byteIndex":622},"url":"././~/Foobar.html","category":"","declarationKind":"export","deprecated":false},{"kind":["interface"],"name":"Hello","file":".","doc":"","location":{"filename":".","line":37,"col":0,"byteIndex":655},"url":"././~/Hello.html","category":"","declarationKind":"export","deprecated":false},{"kind":["function"],"name":"c","file":".","doc":"","location":{"filename":".","line":57,"col":13,"byteIndex":933},"url":"././~/c.html","category":"","declarationKind":"export","deprecated":false},{"kind":["function","function","function"],"name":"qaz","file":".","doc":"","location":{"filename":".","line":53,"col":0,"byteIndex":812},"url":"././~/qaz.html","category":"","declarationKind":"export","deprecated":false},{"kind":["variable"],"name":"default","file":"foo","doc":"The default export item.\n\nThis item reproduces the issue reported in {@link https://github.com/jsr-io/jsr/issues/459}","location":{"filename":"foo","line":7,"col":6,"byteIndex":167},"url":"./foo/~/default.html","category":"","declarationKind":"export","deprecated":false},{"kind":["function"],"name":"x","file":"foo","doc":"","location":{"filename":"foo","line":1,"col":0,"byteIndex":0},"url":"./foo/~/x.html","category":"","declarationKind":"export","deprecated":false}]}; -})() + + + + Foo - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    + class Foo +

    some Foo docs Bar

    +
    +
    + + + + + + + + + + +

    test

    +

    +

    hello

    +

    bar

    +
    foo
    +
    +

    baz

    +
    +
    +
    + + + + + + + + + + +

    test 2

    +

    +

    hello

    +

    bar

    +
    foo
    +
    +

    baz

    +
    +
    +
    +
    +
    +

    + + + + + + + + + + +Constructors

    + +
    +
    new
    +
    + + + + + + + + + + +Foo(value: T) + +
    +
    +
    +
    +

    + + + + + + + + + + +Type Parameters

    + +
    +
    +
    +
    +

    + + + + + + + + + + +Properties

    +
    + +
    +
    abstract
    +
    + + + + + + + + + + +foo: A + +
    +
    + +
    +
    + +
    +
    protected
    +
    readonly
    +
    + + + + + + + + + + +getter + +
    +
    + +
    +
    protected
    +
    + + + + + + + + + + +protectedProperty: boolean + +
    +
    + +
    +
    readonly
    +
    + + + + + + + + + + +readonlyProperty: boolean + +
    +
    + +
    +
    writeonly
    +
    + + + + + + + + + + +setter: string + +
    +
    + +
    +
    +
    +
    +
    + +
    +
    private
    +
    + + + + + + + + + + +methodWithOverloads(s: number): void + +
    +
    + +
    +
    private
    +
    + + + + + + + + + + +methodWithOverloads(s: string): void + +
    +
    + +
    +
    +
    +
    +
    +

    + + + + + + + + + + +Static Properties

    + +
    +
    + + + + + + + + + + +bar: "string" + +
    +
    + +
    +
    writeonly
    +
    + + + + + + + + + + +staticSetter: number + +
    +
    +
    +
    +

    + + + + + + + + + + +Static Methods

    +
    +
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-22.snap b/tests/snapshots/html_test__html_doc_files_rewrite-22.snap index 6e74eec6..83b227bf 100644 --- a/tests/snapshots/html_test__html_doc_files_rewrite-22.snap +++ b/tests/snapshots/html_test__html_doc_files_rewrite-22.snap @@ -1,7 +1,99 @@ --- source: tests/html_test.rs -expression: "files.get(\"search_index.js\").unwrap()" +expression: files.get(file_name).unwrap() --- -(function () { - window.DENO_DOC_SEARCH_INDEX = {"nodes":[{"kind":["class"],"name":"A","file":".","doc":"","location":{"filename":".","line":45,"col":0,"byteIndex":741},"url":"././~/A.html","category":"","declarationKind":"private","deprecated":false},{"kind":["class"],"name":"B","file":".","doc":"","location":{"filename":".","line":48,"col":0,"byteIndex":770},"url":"././~/B.html","category":"","declarationKind":"export","deprecated":false},{"kind":["class"],"name":"Bar","file":".","doc":"","location":{"filename":".","line":31,"col":0,"byteIndex":588},"url":"././~/Bar.html","category":"","declarationKind":"export","deprecated":false},{"kind":["typeAlias"],"name":"Baz","file":".","doc":"","location":{"filename":".","line":41,"col":0,"byteIndex":702},"url":"././~/Baz.html","category":"","declarationKind":"export","deprecated":false},{"kind":["class"],"name":"Foo","file":".","doc":"some Foo docs","location":{"filename":".","line":25,"col":0,"byteIndex":488},"url":"././~/Foo.html","category":"","declarationKind":"export","deprecated":false},{"kind":["class"],"name":"Foobar","file":".","doc":"","location":{"filename":".","line":34,"col":0,"byteIndex":622},"url":"././~/Foobar.html","category":"","declarationKind":"export","deprecated":false},{"kind":["interface"],"name":"Hello","file":".","doc":"","location":{"filename":".","line":37,"col":0,"byteIndex":655},"url":"././~/Hello.html","category":"","declarationKind":"export","deprecated":false},{"kind":["function"],"name":"c","file":".","doc":"","location":{"filename":".","line":57,"col":13,"byteIndex":933},"url":"././~/c.html","category":"","declarationKind":"export","deprecated":false},{"kind":["function"],"name":"d","file":".","doc":"","location":{"filename":".","line":59,"col":0,"byteIndex":961},"url":"././~/d.html","category":"","declarationKind":"export","deprecated":false},{"kind":["function","function","function"],"name":"qaz","file":".","doc":"","location":{"filename":".","line":53,"col":0,"byteIndex":812},"url":"././~/qaz.html","category":"","declarationKind":"export","deprecated":false},{"kind":["variable"],"name":"default","file":"foo","doc":"The default export item.\n\nThis item reproduces the issue reported in {@link https://github.com/jsr-io/jsr/issues/459}","location":{"filename":"foo","line":7,"col":6,"byteIndex":167},"url":"./foo/~/default.html","category":"","declarationKind":"export","deprecated":false},{"kind":["function"],"name":"x","file":"foo","doc":"","location":{"filename":"foo","line":1,"col":0,"byteIndex":0},"url":"./foo/~/x.html","category":"","declarationKind":"export","deprecated":false}]}; -})() + + + + Foo.prototype."><img src=x onerror=alert(1)> - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    + property Foo.prototype."><img src=x onerror=alert(1)> +
    +
    + +
    +
    number + +
    +
    +
    +
    +
    +
    +
    +

    Usage

    import { Foo } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-23.snap b/tests/snapshots/html_test__html_doc_files_rewrite-23.snap index 0b814096..0fb90a6c 100644 --- a/tests/snapshots/html_test__html_doc_files_rewrite-23.snap +++ b/tests/snapshots/html_test__html_doc_files_rewrite-23.snap @@ -1,7 +1,124 @@ --- source: tests/html_test.rs -expression: "files.get(\"search_index.js\").unwrap()" +expression: files.get(file_name).unwrap() --- -(function () { - window.DENO_DOC_SEARCH_INDEX = {"nodes":[{"kind":["class"],"name":"A","file":".","location":{"filename":".","line":45,"col":0,"byteIndex":741},"declarationKind":"private","deprecated":false},{"kind":["class"],"name":"B","file":".","location":{"filename":".","line":48,"col":0,"byteIndex":770},"declarationKind":"export","deprecated":false},{"kind":["class"],"name":"Bar","file":".","location":{"filename":".","line":31,"col":0,"byteIndex":588},"declarationKind":"export","deprecated":false},{"kind":["typeAlias"],"name":"Baz","file":".","location":{"filename":".","line":41,"col":0,"byteIndex":702},"declarationKind":"export","deprecated":false},{"kind":["class"],"name":"Foo","file":".","location":{"filename":".","line":25,"col":0,"byteIndex":488},"declarationKind":"export","deprecated":false},{"kind":["class"],"name":"Foobar","file":".","location":{"filename":".","line":34,"col":0,"byteIndex":622},"declarationKind":"export","deprecated":false},{"kind":["interface"],"name":"Hello","file":".","location":{"filename":".","line":37,"col":0,"byteIndex":655},"declarationKind":"export","deprecated":false},{"kind":["function"],"name":"c","file":".","location":{"filename":".","line":57,"col":13,"byteIndex":933},"declarationKind":"export","deprecated":false},{"kind":["function","function","function"],"name":"qaz","file":".","location":{"filename":".","line":53,"col":0,"byteIndex":812},"declarationKind":"export","deprecated":false},{"kind":["variable"],"name":"default","file":"foo","location":{"filename":"foo","line":7,"col":6,"byteIndex":167},"declarationKind":"export","deprecated":false},{"kind":["function"],"name":"x","file":"foo","location":{"filename":"foo","line":1,"col":0,"byteIndex":0},"declarationKind":"export","deprecated":false}]}; -})() + + + + Foo.prototype.[Symbol.iterator] - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { Foo } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-24.snap b/tests/snapshots/html_test__html_doc_files_rewrite-24.snap new file mode 100644 index 00000000..d08fd059 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-24.snap @@ -0,0 +1,99 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Foo.prototype.foo - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { Foo } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-25.snap b/tests/snapshots/html_test__html_doc_files_rewrite-25.snap new file mode 100644 index 00000000..f9c7c6b1 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-25.snap @@ -0,0 +1,118 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Foo.prototype.getter - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { Foo } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-26.snap b/tests/snapshots/html_test__html_doc_files_rewrite-26.snap new file mode 100644 index 00000000..57f9486e --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-26.snap @@ -0,0 +1,234 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Foo.prototype.getterAndSetter - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { Foo } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-27.snap b/tests/snapshots/html_test__html_doc_files_rewrite-27.snap new file mode 100644 index 00000000..50404116 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-27.snap @@ -0,0 +1,5 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-28.snap b/tests/snapshots/html_test__html_doc_files_rewrite-28.snap new file mode 100644 index 00000000..49a479f6 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-28.snap @@ -0,0 +1,286 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Foo.prototype.methodWithOverloads - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { Foo } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-29.snap b/tests/snapshots/html_test__html_doc_files_rewrite-29.snap new file mode 100644 index 00000000..7a66cb57 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-29.snap @@ -0,0 +1,99 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Foo.prototype.protectedProperty - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    + property Foo.prototype.protectedProperty +
    +
    + +
    +
    boolean + +
    +
    +
    +
    +
    +
    +
    +

    Usage

    import { Foo } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-3.snap b/tests/snapshots/html_test__html_doc_files_rewrite-3.snap index dabc4da9..25eaafcf 100644 --- a/tests/snapshots/html_test__html_doc_files_rewrite-3.snap +++ b/tests/snapshots/html_test__html_doc_files_rewrite-3.snap @@ -1,28 +1,25 @@ --- source: tests/html_test.rs -expression: "files.get(\"./~/Bar.html\").unwrap()" +expression: files.get(name).unwrap() --- - Bar - documentation + A - documentation - - - - - - - - - + + + + + +
    -
    +
    - class Bar -
    - extends Foo -
    + class A +
    Private
    +
    -

    Usage

    import { Bar } from ".";
    -
    -
    +
    diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-30.snap b/tests/snapshots/html_test__html_doc_files_rewrite-30.snap new file mode 100644 index 00000000..02f9a170 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-30.snap @@ -0,0 +1,99 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Foo.prototype.readonlyProperty - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    + property Foo.prototype.readonlyProperty +
    +
    + +
    +
    boolean + +
    +
    +
    +
    +
    +
    +
    +

    Usage

    import { Foo } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-31.snap b/tests/snapshots/html_test__html_doc_files_rewrite-31.snap new file mode 100644 index 00000000..7d967b7c --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-31.snap @@ -0,0 +1,177 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Foo.prototype.setter - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { Foo } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-32.snap b/tests/snapshots/html_test__html_doc_files_rewrite-32.snap new file mode 100644 index 00000000..02eda4c1 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-32.snap @@ -0,0 +1,124 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Foo.prototype.test - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { Foo } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-33.snap b/tests/snapshots/html_test__html_doc_files_rewrite-33.snap new file mode 100644 index 00000000..d9d9637d --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-33.snap @@ -0,0 +1,124 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Foo.staticMethod - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { Foo } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-34.snap b/tests/snapshots/html_test__html_doc_files_rewrite-34.snap new file mode 100644 index 00000000..75cc3c99 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-34.snap @@ -0,0 +1,177 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Foo.staticSetter - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { Foo } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-35.snap b/tests/snapshots/html_test__html_doc_files_rewrite-35.snap new file mode 100644 index 00000000..aa3ef449 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-35.snap @@ -0,0 +1,115 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Foobar - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    + class Foobar +
    // This code block is ignored when getting the title of this doc
    +const foobar = new Foobar();
    +
    +

    Foobar docs

    +

    +heading

    +

    content

    +

    +sub heading

    +
    + +
    +
    +
    +
    +
    +
    +

    Usage

    import Foobar from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-36.snap b/tests/snapshots/html_test__html_doc_files_rewrite-36.snap new file mode 100644 index 00000000..98d0f995 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-36.snap @@ -0,0 +1,5 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-37.snap b/tests/snapshots/html_test__html_doc_files_rewrite-37.snap new file mode 100644 index 00000000..d73bbf86 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-37.snap @@ -0,0 +1,99 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Hello.ab - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { type Hello } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-38.snap b/tests/snapshots/html_test__html_doc_files_rewrite-38.snap new file mode 100644 index 00000000..52f2ab8e --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-38.snap @@ -0,0 +1,177 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Hello.computedMethod - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { type Hello } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-39.snap b/tests/snapshots/html_test__html_doc_files_rewrite-39.snap new file mode 100644 index 00000000..af73f984 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-39.snap @@ -0,0 +1,431 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Hello - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    + interface Hello +
    +
    +

    + + + + + + + + + + +Type Parameters

    + +
    +
    + + + + + + + + + + +T extends string + +
    +
    + +
    +
    + + + + + + + + + + +E extends T + +
    +
    + +
    +
    + + + + + + + + + + +R = number + +
    +
    +
    +
    +

    + + + + + + + + + + +Call Signatures

    + +
    +
    (a: string): string + +
    +
    +
    +
    +

    + + + + + + + + + + +Properties

    + +
    +
    + + + + + + + + + + +world: string = "foo" + +
    +
    + +
    +
    readonly
    +
    optional
    +
    + + + + + + + + + + +test: "test" + +

    Some docs

    +
    +
    + +
    +
    +
    + +
    +
    + + + + + + + + + + +x: { [foo: string]: number; } + +
    +
    +
    +
    + +
    +
    optional
    +
    + + + + + + + + + + +optionalMethod(): [string] + +
    +
    + +
    +
    optional
    +
    + + + + + + + + + + +[computedMethod](a: T extends () => infer R ? R : any): void + +
    +
    +
    +
    +
    +
    +
    +

    Usage

    import { type Hello } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-4.snap b/tests/snapshots/html_test__html_doc_files_rewrite-4.snap index 251b4b6b..70e26278 100644 --- a/tests/snapshots/html_test__html_doc_files_rewrite-4.snap +++ b/tests/snapshots/html_test__html_doc_files_rewrite-4.snap @@ -1,5 +1,5 @@ --- source: tests/html_test.rs -expression: "files.get(\"./~/Bar.prototype.html\").unwrap()" +expression: files.get(name).unwrap() --- - + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-40.snap b/tests/snapshots/html_test__html_doc_files_rewrite-40.snap new file mode 100644 index 00000000..b7edcd5c --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-40.snap @@ -0,0 +1,124 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Hello.optionalMethod - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { type Hello } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-41.snap b/tests/snapshots/html_test__html_doc_files_rewrite-41.snap new file mode 100644 index 00000000..70485176 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-41.snap @@ -0,0 +1,100 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Hello.test - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { type Hello } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-42.snap b/tests/snapshots/html_test__html_doc_files_rewrite-42.snap new file mode 100644 index 00000000..2525d205 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-42.snap @@ -0,0 +1,99 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Hello.world - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { type Hello } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-43.snap b/tests/snapshots/html_test__html_doc_files_rewrite-43.snap new file mode 100644 index 00000000..1cf53b3b --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-43.snap @@ -0,0 +1,116 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Hello.x - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { type Hello } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-44.snap b/tests/snapshots/html_test__html_doc_files_rewrite-44.snap new file mode 100644 index 00000000..9890c4d2 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-44.snap @@ -0,0 +1,116 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + InterfaceWithIndexSignature - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { type InterfaceWithIndexSignature } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-45.snap b/tests/snapshots/html_test__html_doc_files_rewrite-45.snap new file mode 100644 index 00000000..5f1a6613 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-45.snap @@ -0,0 +1,180 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Testing.externalFunction - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { Testing } from ".";
    +const { externalFunction } = Testing;
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-46.snap b/tests/snapshots/html_test__html_doc_files_rewrite-46.snap new file mode 100644 index 00000000..f2b13e57 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-46.snap @@ -0,0 +1,116 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Testing - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    + class Testing +
    +
    +
    +
    +
    +

    Usage

    import { Testing } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-47.snap b/tests/snapshots/html_test__html_doc_files_rewrite-47.snap new file mode 100644 index 00000000..1f543d84 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-47.snap @@ -0,0 +1,5 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-48.snap b/tests/snapshots/html_test__html_doc_files_rewrite-48.snap new file mode 100644 index 00000000..fda35787 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-48.snap @@ -0,0 +1,124 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Testing.t - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { Testing } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-49.snap b/tests/snapshots/html_test__html_doc_files_rewrite-49.snap new file mode 100644 index 00000000..408584c1 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-49.snap @@ -0,0 +1,180 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Testing.x - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { Testing } from ".";
    +const { x } = Testing;
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-5.snap b/tests/snapshots/html_test__html_doc_files_rewrite-5.snap index 8c045305..805a7045 100644 --- a/tests/snapshots/html_test__html_doc_files_rewrite-5.snap +++ b/tests/snapshots/html_test__html_doc_files_rewrite-5.snap @@ -1,28 +1,25 @@ --- source: tests/html_test.rs -expression: "files.get(\"./~/Baz.html\").unwrap()" +expression: files.get(file_name).unwrap() --- - Baz - documentation + AbstractClass - documentation - - - - - - - - - + + + + + +
    -
    -

    Usage

    import { type Baz } from ".";
    -
    -
    +

    Document Navigation

    +
    diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-50.snap b/tests/snapshots/html_test__html_doc_files_rewrite-50.snap new file mode 100644 index 00000000..6f2a08c9 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-50.snap @@ -0,0 +1,99 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + TypeAlias - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { type TypeAlias } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-51.snap b/tests/snapshots/html_test__html_doc_files_rewrite-51.snap new file mode 100644 index 00000000..c14cd630 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-51.snap @@ -0,0 +1,124 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + anotherVariable.bar - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { anotherVariable } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-52.snap b/tests/snapshots/html_test__html_doc_files_rewrite-52.snap new file mode 100644 index 00000000..8055b0af --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-52.snap @@ -0,0 +1,99 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + anotherVariable.foo - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { anotherVariable } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-53.snap b/tests/snapshots/html_test__html_doc_files_rewrite-53.snap new file mode 100644 index 00000000..e93d03d3 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-53.snap @@ -0,0 +1,174 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + anotherVariable - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { anotherVariable } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-54.snap b/tests/snapshots/html_test__html_doc_files_rewrite-54.snap new file mode 100644 index 00000000..6add1e4e --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-54.snap @@ -0,0 +1,124 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + c - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { c } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-55.snap b/tests/snapshots/html_test__html_doc_files_rewrite-55.snap new file mode 100644 index 00000000..308e0759 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-55.snap @@ -0,0 +1,480 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + d - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    + function d +
    + + + + + + + + + + + +d<T = string>(
    foo?: number,
    bar?: string,
    baz?: { hello?: string; },
    qaz: T,
    ...strings: string[],
    ): string
    +
    +
    + + + + + + + + + + +

    test

    +

    +
    d();
    +
    +
    +
    +
    + + + + + + + + + + +

    Example 2

    +

    +
    d();
    +
    +
    +
    +
    +
    +
    +

    + + + + + + + + + + +Type Parameters

    + +
    +
    + + + + + + + + + + +T = string + +
    +
    +
    +
    +

    + + + + + + + + + + +Parameters

    + +
    +
    optional
    +
    + + + + + + + + + + +foo: number = 1 + +

    {number} some parameter

    +
    +
    + +
    +
    optional
    +
    + + + + + + + + + + +bar: string = bar + +
    +
    + +
    +
    optional
    +
    + + + + + + + + + + +baz: { hello?: string; } + +
    +
    + +
    +
    +
    + +
    +
    + + + + + + + + + + +...strings: string[] + +
    +
    +
    +
    +

    + + + + + + + + + + +Return Type

    + +
    +
    string + +

    a new string

    +
    +
    +
    +
    + +
    +
    Foo + +

    bar

    +
    +
    +
    +
    +
    +
    +
    +
    +

    Usage

    import { d } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-56.snap b/tests/snapshots/html_test__html_doc_files_rewrite-56.snap new file mode 100644 index 00000000..fc363a77 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-56.snap @@ -0,0 +1,353 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + functionWithOptionalParameters - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    + function functionWithOptionalParameters +
    + + + + + + + + + + + +functionWithOptionalParameters(
    foo?: number,
    bar?: number,
    baz?: [number],
    unnamed 3?: string[],
    unnamed 4?: { qux: number; },
    ): void
    +
    +
    +

    + + + + + + + + + + +Parameters

    + +
    +
    optional
    +
    + + + + + + + + + + +foo: number = 1 + +
    +
    + +
    +
    optional
    +
    + + + + + + + + + + +bar: number + +
    +
    + +
    +
    optional
    +
    + + + + + + + + + + +baz: [number] + +
    +
    + +
    +
    optional
    +
    + + + + + + + + + + +unnamed 3: string[] + +
    +
    + +
    +
    optional
    +
    + + + + + + + + + + +unnamed 4: { qux: number; } + +
    +
    +
    +
    +

    + + + + + + + + + + +Return Type

    + +
    +
    void + +
    +
    +
    +
    + +
    +
    + +

    bar

    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +

    Usage

    import { functionWithOptionalParameters } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-57.snap b/tests/snapshots/html_test__html_doc_files_rewrite-57.snap new file mode 100644 index 00000000..fd485338 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-57.snap @@ -0,0 +1,277 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + qaz - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { qaz } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-58.snap b/tests/snapshots/html_test__html_doc_files_rewrite-58.snap new file mode 100644 index 00000000..78f462d8 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-58.snap @@ -0,0 +1,67 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + someVariable - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    + variable someVariable +
    +
    +
    +
    +
    +

    Usage

    import { someVariable } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-59.snap b/tests/snapshots/html_test__html_doc_files_rewrite-59.snap new file mode 100644 index 00000000..60770f81 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-59.snap @@ -0,0 +1,178 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + x - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { x } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-6.snap b/tests/snapshots/html_test__html_doc_files_rewrite-6.snap index a1703bbf..dc49a9c3 100644 --- a/tests/snapshots/html_test__html_doc_files_rewrite-6.snap +++ b/tests/snapshots/html_test__html_doc_files_rewrite-6.snap @@ -1,28 +1,25 @@ --- source: tests/html_test.rs -expression: "files.get(\"./~/Baz.foo.html\").unwrap()" +expression: files.get(name).unwrap() --- - Baz.foo - documentation + AbstractClass.prototype.foo - documentation - - - - - - - - - + + + + + +
    -
    +
    - property Baz.foo + property AbstractClass.prototype.foo

    -Type

    +Type
    string @@ -89,17 +78,21 @@ Type
    -

    Usage

    import { type Baz } from ".";
    -
    -
    +
    diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-60.snap b/tests/snapshots/html_test__html_doc_files_rewrite-60.snap new file mode 100644 index 00000000..10da4d46 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-60.snap @@ -0,0 +1,127 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + c - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    f
    +
    + x + +
    No documentation available
    +
    +
    +
    +
    +
    +
    +
    +

    Usage

    import * as c from "c";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-61.snap b/tests/snapshots/html_test__html_doc_files_rewrite-61.snap new file mode 100644 index 00000000..248833ad --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-61.snap @@ -0,0 +1,186 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + x - c - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { x } from "c";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-62.snap b/tests/snapshots/html_test__html_doc_files_rewrite-62.snap new file mode 100644 index 00000000..3d034110 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-62.snap @@ -0,0 +1,127 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + d - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    f
    +
    + externalFunction + +
    No documentation available
    +
    +
    +
    +
    +
    +
    +
    +

    Usage

    import * as mod from "d";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-63.snap b/tests/snapshots/html_test__html_doc_files_rewrite-63.snap new file mode 100644 index 00000000..9fc08737 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-63.snap @@ -0,0 +1,186 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + externalFunction - d - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { externalFunction } from "d";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-64.snap b/tests/snapshots/html_test__html_doc_files_rewrite-64.snap new file mode 100644 index 00000000..b07a8ffd --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-64.snap @@ -0,0 +1,159 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + foo - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    f
    +
    + x + +
    No documentation available
    +
    +
    +
    +
    v
    +
    + default + +

    The default export item.

    +
    +
    +
    +
    +
    +
    +
    +
    +

    Usage

    import * as bar from "foo";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-65.snap b/tests/snapshots/html_test__html_doc_files_rewrite-65.snap new file mode 100644 index 00000000..17abc251 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-65.snap @@ -0,0 +1,109 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + default - foo - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import bar from "foo";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-66.snap b/tests/snapshots/html_test__html_doc_files_rewrite-66.snap new file mode 100644 index 00000000..c5f81334 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-66.snap @@ -0,0 +1,186 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + x - foo - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +

    Usage

    import { x } from "foo";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-67.snap b/tests/snapshots/html_test__html_doc_files_rewrite-67.snap new file mode 100644 index 00000000..4778501f --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-67.snap @@ -0,0 +1,15 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- +// deno-fmt-ignore-file +// deno-lint-ignore-file +/** + * Fuse.js v7.0.0 - Lightweight fuzzy-search (http://fusejs.io) + * + * Copyright (c) 2023 Kiro Risk (http://kiro.me) + * All Rights Reserved. Apache Software License 2.0 + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ +var e,t;e=this,t=function(){"use strict";function e(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function t(t){for(var n=1;ne.length)&&(t=e.length);for(var n=0,r=new Array(t);n0&&void 0!==arguments[0]?arguments[0]:{},n=t.getFn,i=void 0===n?$.getFn:n,o=t.fieldNormWeight,c=void 0===o?$.fieldNormWeight:o;r(this,e),this.norm=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:3,n=new Map,r=Math.pow(10,t);return{get:function(t){var i=t.match(F).length;if(n.has(i))return n.get(i);var o=1/Math.pow(i,.5*e),c=parseFloat(Math.round(o*r)/r);return n.set(i,c),c},clear:function(){n.clear()}}}(c,3),this.getFn=i,this.isCreated=!1,this.setIndexRecords()}return o(e,[{key:"setSources",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.docs=e}},{key:"setIndexRecords",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.records=e}},{key:"setKeys",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.keys=t,this._keysMap={},t.forEach((function(t,n){e._keysMap[t.id]=n}))}},{key:"create",value:function(){var e=this;!this.isCreated&&this.docs.length&&(this.isCreated=!0,m(this.docs[0])?this.docs.forEach((function(t,n){e._addString(t,n)})):this.docs.forEach((function(t,n){e._addObject(t,n)})),this.norm.clear())}},{key:"add",value:function(e){var t=this.size();m(e)?this._addString(e,t):this._addObject(e,t)}},{key:"removeAt",value:function(e){this.records.splice(e,1);for(var t=e,n=this.size();t2&&void 0!==arguments[2]?arguments[2]:{},r=n.getFn,i=void 0===r?$.getFn:r,o=n.fieldNormWeight,c=void 0===o?$.fieldNormWeight:o,a=new R({getFn:i,fieldNormWeight:c});return a.setKeys(e.map(A)),a.setSources(t),a.create(),a}function N(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t.errors,r=void 0===n?0:n,i=t.currentLocation,o=void 0===i?0:i,c=t.expectedLocation,a=void 0===c?0:c,s=t.distance,u=void 0===s?$.distance:s,h=t.ignoreLocation,l=void 0===h?$.ignoreLocation:h,f=r/e.length;if(l)return f;var d=Math.abs(a-o);return u?f+d/u:d?1:f}var W=32;function T(e,t,n){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},i=r.location,o=void 0===i?$.location:i,c=r.distance,a=void 0===c?$.distance:c,s=r.threshold,u=void 0===s?$.threshold:s,h=r.findAllMatches,l=void 0===h?$.findAllMatches:h,f=r.minMatchCharLength,d=void 0===f?$.minMatchCharLength:f,v=r.includeMatches,g=void 0===v?$.includeMatches:v,y=r.ignoreLocation,p=void 0===y?$.ignoreLocation:y;if(t.length>W)throw new Error("Pattern length exceeds max of ".concat(W,"."));for(var m,k=t.length,M=e.length,b=Math.max(0,Math.min(o,M)),x=u,w=b,S=d>1||g,L=S?Array(M):[];(m=e.indexOf(t,w))>-1;){var _=N(t,{currentLocation:m,expectedLocation:b,distance:a,ignoreLocation:p});if(x=Math.min(_,x),w=m+k,S)for(var O=0;O=P;D-=1){var K=D-1,q=n[e.charAt(K)];if(S&&(L[K]=+!!q),z[D]=(z[D+1]<<1|1)&q,E&&(z[D]|=(j[D+1]|j[D])<<1|1|j[D+1]),z[D]&C&&(A=N(t,{errors:E,currentLocation:K,expectedLocation:b,distance:a,ignoreLocation:p}))<=x){if(x=A,(w=K)<=b)break;P=Math.max(1,2*b-w)}}if(N(t,{errors:E+1,currentLocation:b,expectedLocation:b,distance:a,ignoreLocation:p})>x)break;j=z}var B={isMatch:w>=0,score:Math.max(.001,A)};if(S){var J=function(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:$.minMatchCharLength,n=[],r=-1,i=-1,o=0,c=e.length;o=t&&n.push([r,i]),r=-1)}return e[o-1]&&o-r>=t&&n.push([r,o-1]),n}(L,d);J.length?g&&(B.indices=J):B.isMatch=!1}return B}function z(e){for(var t={},n=0,r=e.length;n1&&void 0!==arguments[1]?arguments[1]:{},o=i.location,c=void 0===o?$.location:o,a=i.threshold,s=void 0===a?$.threshold:a,u=i.distance,h=void 0===u?$.distance:u,l=i.includeMatches,f=void 0===l?$.includeMatches:l,d=i.findAllMatches,v=void 0===d?$.findAllMatches:d,g=i.minMatchCharLength,y=void 0===g?$.minMatchCharLength:g,p=i.isCaseSensitive,m=void 0===p?$.isCaseSensitive:p,k=i.ignoreLocation,M=void 0===k?$.ignoreLocation:k;if(r(this,e),this.options={location:c,threshold:s,distance:h,includeMatches:f,findAllMatches:v,minMatchCharLength:y,isCaseSensitive:m,ignoreLocation:M},this.pattern=m?t:t.toLowerCase(),this.chunks=[],this.pattern.length){var b=function(e,t){n.chunks.push({pattern:e,alphabet:z(e),startIndex:t})},x=this.pattern.length;if(x>W){for(var w=0,S=x%W,L=x-S;w1&&void 0!==arguments[1]?arguments[1]:{},c=o.location,a=void 0===c?$.location:c,s=o.threshold,u=void 0===s?$.threshold:s,h=o.distance,l=void 0===h?$.distance:h,f=o.includeMatches,d=void 0===f?$.includeMatches:f,v=o.findAllMatches,g=void 0===v?$.findAllMatches:v,y=o.minMatchCharLength,p=void 0===y?$.minMatchCharLength:y,m=o.isCaseSensitive,k=void 0===m?$.isCaseSensitive:m,M=o.ignoreLocation,b=void 0===M?$.ignoreLocation:M;return r(this,n),(i=t.call(this,e))._bitapSearch=new D(e,{location:a,threshold:u,distance:l,includeMatches:d,findAllMatches:g,minMatchCharLength:p,isCaseSensitive:k,ignoreLocation:b}),i}return o(n,[{key:"search",value:function(e){return this._bitapSearch.searchIn(e)}}],[{key:"type",get:function(){return"fuzzy"}},{key:"multiRegex",get:function(){return/^"(.*)"$/}},{key:"singleRegex",get:function(){return/^(.*)$/}}]),n}(K),X=function(e){a(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return o(n,[{key:"search",value:function(e){for(var t,n=0,r=[],i=this.pattern.length;(t=e.indexOf(this.pattern,n))>-1;)n=t+i,r.push([t,n-1]);var o=!!r.length;return{isMatch:o,score:o?0:1,indices:r}}}],[{key:"type",get:function(){return"include"}},{key:"multiRegex",get:function(){return/^'"(.*)"$/}},{key:"singleRegex",get:function(){return/^'(.*)$/}}]),n}(K),Y=[B,X,U,V,H,G,J,Q],Z=Y.length,ee=/ +(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/,te=new Set([Q.type,X.type]),ne=function(){function e(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=n.isCaseSensitive,o=void 0===i?$.isCaseSensitive:i,c=n.includeMatches,a=void 0===c?$.includeMatches:c,s=n.minMatchCharLength,u=void 0===s?$.minMatchCharLength:s,h=n.ignoreLocation,l=void 0===h?$.ignoreLocation:h,f=n.findAllMatches,d=void 0===f?$.findAllMatches:f,v=n.location,g=void 0===v?$.location:v,y=n.threshold,p=void 0===y?$.threshold:y,m=n.distance,k=void 0===m?$.distance:m;r(this,e),this.query=null,this.options={isCaseSensitive:o,includeMatches:a,minMatchCharLength:u,findAllMatches:d,ignoreLocation:l,location:g,threshold:p,distance:k},this.pattern=o?t:t.toLowerCase(),this.query=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return e.split("|").map((function(e){for(var n=e.trim().split(ee).filter((function(e){return e&&!!e.trim()})),r=[],i=0,o=n.length;i2&&void 0!==arguments[2]?arguments[2]:{}).auto,r=void 0===n||n;return ue(e)||(e=he(e)),function e(n){var i=Object.keys(n),o=function(e){return!!e[ae]}(n);if(!o&&i.length>1&&!ue(n))return e(he(n));if(function(e){return!g(e)&&b(e)&&!ue(e)}(n)){var c=o?n[ae]:i[0],a=o?n[se]:n[c];if(!m(a))throw new Error(function(e){return"Invalid value for key ".concat(e)}(c));var s={keyId:C(c),pattern:a};return r&&(s.searcher=ie(a,t)),s}var u={children:[],operator:i[0]};return i.forEach((function(t){var r=n[t];g(r)&&r.forEach((function(t){u.children.push(e(t))}))})),u}(e)}function fe(e,t){var n=e.matches;t.matches=[],x(n)&&n.forEach((function(e){if(x(e.indices)&&e.indices.length){var n={indices:e.indices,value:e.value};e.key&&(n.key=e.key.src),e.idx>-1&&(n.refIndex=e.idx),t.matches.push(n)}}))}function de(e,t){t.score=e.score}var ve=function(){function e(n){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},o=arguments.length>2?arguments[2]:void 0;r(this,e),this.options=t(t({},$),i),this.options.useExtendedSearch,this._keyStore=new j(this.options.keys),this.setCollection(n,o)}return o(e,[{key:"setCollection",value:function(e,t){if(this._docs=e,t&&!(t instanceof R))throw new Error("Incorrect 'index' type");this._myIndex=t||P(this.options.keys,this._docs,{getFn:this.options.getFn,fieldNormWeight:this.options.fieldNormWeight})}},{key:"add",value:function(e){x(e)&&(this._docs.push(e),this._myIndex.add(e))}},{key:"remove",value:function(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:function(){return!1},t=[],n=0,r=this._docs.length;n1&&void 0!==arguments[1]?arguments[1]:{}).limit,n=void 0===t?-1:t,r=this.options,i=r.includeMatches,o=r.includeScore,c=r.shouldSort,a=r.sortFn,s=r.ignoreFieldNorm,u=m(e)?m(this._docs[0])?this._searchStringList(e):this._searchObjectList(e):this._searchLogical(e);return function(e,t){var n=t.ignoreFieldNorm,r=void 0===n?$.ignoreFieldNorm:n;e.forEach((function(e){var t=1;e.matches.forEach((function(e){var n=e.key,i=e.norm,o=e.score,c=n?n.weight:null;t*=Math.pow(0===o&&c?Number.EPSILON:o,(c||1)*(r?1:i))})),e.score=t}))}(u,{ignoreFieldNorm:s}),c&&u.sort(a),k(n)&&n>-1&&(u=u.slice(0,n)),function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=n.includeMatches,i=void 0===r?$.includeMatches:r,o=n.includeScore,c=void 0===o?$.includeScore:o,a=[];return i&&a.push(fe),c&&a.push(de),e.map((function(e){var n=e.idx,r={item:t[n],refIndex:n};return a.length&&a.forEach((function(t){t(e,r)})),r}))}(u,this._docs,{includeMatches:i,includeScore:o})}},{key:"_searchStringList",value:function(e){var t=ie(e,this.options),n=this._myIndex.records,r=[];return n.forEach((function(e){var n=e.v,i=e.i,o=e.n;if(x(n)){var c=t.searchIn(n),a=c.isMatch,s=c.score,u=c.indices;a&&r.push({item:n,idx:i,matches:[{score:s,value:n,norm:o,indices:u}]})}})),r}},{key:"_searchLogical",value:function(e){var t=this,n=le(e,this.options),r=function e(n,r,i){if(!n.children){var o=n.keyId,c=n.searcher,a=t._findMatches({key:t._keyStore.get(o),value:t._myIndex.getValueForItemAtKeyId(r,o),searcher:c});return a&&a.length?[{idx:i,item:r,matches:a}]:[]}for(var s=[],u=0,h=n.children.length;u1&&void 0!==arguments[1]?arguments[1]:{},n=t.getFn,r=void 0===n?$.getFn:n,i=t.fieldNormWeight,o=void 0===i?$.fieldNormWeight:i,c=e.keys,a=e.records,s=new R({getFn:r,fieldNormWeight:o});return s.setKeys(c),s.setIndexRecords(a),s},ve.config=$,function(){re.push.apply(re,arguments)}(ne),ve},"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Fuse=t(); diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-68.snap b/tests/snapshots/html_test__html_doc_files_rewrite-68.snap new file mode 100644 index 00000000..e67d0c9c --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-68.snap @@ -0,0 +1,39 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- +function findParent(el, find) { + do { + if (find(el)) { + return el; + } + } while (el = el.parentElement); +} + +document.addEventListener("click", (e) => { + const target = findParent( + e.target, + (el) => el instanceof HTMLButtonElement && el.dataset["copy"], + ); + if (target) { + navigator?.clipboard?.writeText(target.dataset["copy"]); + target.classList.add("copied"); + setTimeout(() => target.classList.remove("copied"), 1000); + } +}); + +window.addEventListener("load", () => { + const usageSelector = document.getElementById("usageSelector"); + + document.addEventListener("mouseup", (e) => { + if ( + findParent( + e.target, + (el) => + el.parentElement === usageSelector && el instanceof HTMLDivElement, + ) + ) { + usageSelector.open = false; + } + }); +}); diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-69.snap b/tests/snapshots/html_test__html_doc_files_rewrite-69.snap new file mode 100644 index 00000000..33d6c4a7 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-69.snap @@ -0,0 +1,145 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- +const Fuse = window.Fuse; + +const searchInput = document.querySelector("#searchbar"); +const contentDiv = document.querySelector("#content"); +const searchResultsDiv = document.querySelector("#searchResults"); +const currentFile = + document.querySelector("meta[name='doc-current-file']").attributes + .getNamedItem("content").value; +const pathToRoot = "../".repeat( + currentFile ? (currentFile.split("/").length + 1) : 0, +); +searchInput.removeAttribute("style"); + +const SEARCH_INDEX = window.DENO_DOC_SEARCH_INDEX; + +const fuse = new Fuse(SEARCH_INDEX.nodes, { + keys: [{ + name: "name", + weight: 2, + }], + isCaseSensitive: false, + minMatchCharLength: 2, + threshold: 0.4, +}); + +const loadedUrl = new URL(window.location.href); +const val = loadedUrl.searchParams.get("q"); +if (val) { + searchInput.value = val; + doSearch(val); +} + +window.addEventListener("load", function () { + document.addEventListener("keydown", function (event) { + if (event.key.toLowerCase() === "s") { + if (event.target !== searchInput) { + searchInput.focus(); + event.preventDefault(); + } + } + }); + + const emptyPlaceholder = "Click or press 'S' to search..."; + searchInput.placeholder = emptyPlaceholder; + + searchInput.addEventListener("focus", function () { + searchInput.placeholder = "Type your query here..."; + }); + + searchInput.addEventListener("blur", function () { + searchInput.placeholder = emptyPlaceholder; + }); +}); + +function debounce(func, delay) { + let timerId; + + return function () { + const context = this; + const args = arguments; + + clearTimeout(timerId); + + timerId = setTimeout(function () { + func.apply(context, args); + }, delay); + }; +} + +const debouncedSearch = debounce(doSearch, 250); + +searchInput.addEventListener("input", (e) => { + const val = e.target.value; + debouncedSearch(val); +}); + +function doSearch(val) { + if (!val) { + updateCurrentLocation(val); + showPage(); + } else { + const results = searchInIndex(val); + // console.log("results", results); + updateCurrentLocation(val); + renderResults(results); + showSearchResults(); + } +} + +function updateCurrentLocation(val) { + const url = new URL(window.location.href); + if (val) { + url.searchParams.set("q", val); + } else { + url.searchParams.delete("q"); + } + window.history.replaceState({}, "", url.href); +} + +function showPage() { + contentDiv.style.display = "flex"; + searchResultsDiv.style.display = "none"; +} + +function showSearchResults() { + contentDiv.style.display = "none"; + searchResultsDiv.style.display = "block"; +} + +function renderResults(results) { + if (results.length === 0) { + searchResultsDiv.innerHTML = `No result`; + return; + } + + let html = `
      `; + + for (const result of results) { + const kind = result.kind.map((kind) => { + return `
      ${kind.char}
      `; + }).join(""); + + html += `
    • + +
      +
      + ${kind} +
      + ${result.name} +
      +
      +
    • `; + } + + html += `
    `; + searchResultsDiv.innerHTML = html; +} + +function searchInIndex(val) { + return fuse.search(val).map((result) => result.item); +} diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-7.snap b/tests/snapshots/html_test__html_doc_files_rewrite-7.snap index 9d08efdc..23dd0ed9 100644 --- a/tests/snapshots/html_test__html_doc_files_rewrite-7.snap +++ b/tests/snapshots/html_test__html_doc_files_rewrite-7.snap @@ -1,28 +1,25 @@ --- source: tests/html_test.rs -expression: "files.get(\"./~/Foo.html\").unwrap()" +expression: files.get(file_name).unwrap() --- - Foo - documentation + AbstractClass.prototype.getter - documentation - - - - - - - - - + + + + + +
    -
    -

    Usage

    import { Foo } from ".";
    -
    -
    +

    Document Navigation

    +
    diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-70.snap b/tests/snapshots/html_test__html_doc_files_rewrite-70.snap new file mode 100644 index 00000000..854dae09 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_rewrite-70.snap @@ -0,0 +1,7 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- +(function () { + window.DENO_DOC_SEARCH_INDEX = {"kind":"search","nodes":[{"kind":[{"char":"c","kind":"Class","title":"Class"}],"name":"A","file":".","doc":"","url":"././~/A.html","deprecated":false},{"kind":[{"char":"c","kind":"Class","title":"Class"}],"name":"AbstractClass","file":".","doc":"","url":"././~/AbstractClass.html","deprecated":false},{"kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"AbstractClass.prototype.method","file":".","doc":"","url":"././~/AbstractClass.prototype.method.html","deprecated":false},{"kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"AbstractClass.prototype.getter","file":".","doc":"","url":"././~/AbstractClass.prototype.getter.html","deprecated":false},{"kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"AbstractClass.prototype.foo","file":".","doc":"","url":"././~/AbstractClass.prototype.foo.html","deprecated":false},{"kind":[{"char":"c","kind":"Class","title":"Class"}],"name":"B","file":".","doc":"","url":"././~/B.html","deprecated":false},{"kind":[{"char":"c","kind":"Class","title":"Class"}],"name":"Bar","file":".","doc":"> Some quote in bar docs\n> This quote part is ignored\n> when getting the title of this doc\n\nBar docs","url":"././~/Bar.html","deprecated":false},{"kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"Baz","file":".","doc":"","url":"././~/Baz.html","deprecated":false},{"kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"Baz.bar","file":".","doc":"","url":"././~/Baz.bar.html","deprecated":false},{"kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Baz.foo","file":".","doc":"","url":"././~/Baz.foo.html","deprecated":false},{"kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"EmptyInterface","file":".","doc":"","url":"././~/EmptyInterface.html","deprecated":false},{"kind":[{"char":"E","kind":"Enum","title":"Enum"}],"name":"Enum","file":".","doc":"","url":"././~/Enum.html","deprecated":false},{"kind":[{"char":"E","kind":"Enum","title":"Enum"}],"name":"Enum2","file":".","doc":"","url":"././~/Enum2.html","deprecated":false},{"kind":[{"char":"c","kind":"Class","title":"Class"}],"name":"Foo","file":".","doc":"some Foo docs {@linkcode Bar}\n","url":"././~/Foo.html","deprecated":false},{"kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"Foo.prototype.[Symbol.iterator]","file":".","doc":"","url":"././~/Foo.prototype.[Symbol.iterator].html","deprecated":false},{"kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"Foo.prototype.getter","file":".","doc":"","url":"././~/Foo.prototype.getter.html","deprecated":false},{"kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"Foo.prototype.setter","file":".","doc":"","url":"././~/Foo.prototype.setter.html","deprecated":false},{"kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"Foo.prototype.getterAndSetter","file":".","doc":"","url":"././~/Foo.prototype.getterAndSetter.html","deprecated":false},{"kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"Foo.prototype.getterAndSetter","file":".","doc":"","url":"././~/Foo.prototype.getterAndSetter.html","deprecated":false},{"kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"Foo.staticSetter","file":".","doc":"","url":"././~/Foo.staticSetter.html","deprecated":false},{"kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"Foo.prototype.test","file":".","doc":"","url":"././~/Foo.prototype.test.html","deprecated":false},{"kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"Foo.staticMethod","file":".","doc":"","url":"././~/Foo.staticMethod.html","deprecated":false},{"kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"Foo.prototype.methodWithOverloads","file":".","doc":"","url":"././~/Foo.prototype.methodWithOverloads.html","deprecated":false},{"kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"Foo.prototype.methodWithOverloads","file":".","doc":"","url":"././~/Foo.prototype.methodWithOverloads.html","deprecated":false},{"kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"Foo.prototype.methodWithOverloads","file":".","doc":"","url":"././~/Foo.prototype.methodWithOverloads.html","deprecated":false},{"kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Foo.bar","file":".","doc":"","url":"././~/Foo.bar.html","deprecated":false},{"kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Foo.prototype.protectedProperty","file":".","doc":"","url":"././~/Foo.prototype.protectedProperty.html","deprecated":false},{"kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Foo.prototype.readonlyProperty","file":".","doc":"","url":"././~/Foo.prototype.readonlyProperty.html","deprecated":false},{"kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Foo.prototype.foo","file":".","doc":"","url":"././~/Foo.prototype.foo.html","deprecated":false},{"kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Foo.prototype.\"><img src=x onerror=alert(1)>","file":".","doc":"","url":"././~/Foo.prototype.\">.html","deprecated":false},{"kind":[{"char":"c","kind":"Class","title":"Class"}],"name":"Foobar","file":".","doc":"```ts\n// This code block is ignored when getting the title of this doc\nconst foobar = new Foobar();\n```\n\nFoobar docs\n\n# heading\n\ncontent\n\n## sub heading\n","url":"././~/Foobar.html","deprecated":false},{"kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"Hello","file":".","doc":"","url":"././~/Hello.html","deprecated":false},{"kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"Hello.optionalMethod","file":".","doc":"","url":"././~/Hello.optionalMethod.html","deprecated":false},{"kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"Hello.computedMethod","file":".","doc":"","url":"././~/Hello.computedMethod.html","deprecated":false},{"kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Hello.world","file":".","doc":"","url":"././~/Hello.world.html","deprecated":false},{"kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Hello.test","file":".","doc":"Some docs","url":"././~/Hello.test.html","deprecated":false},{"kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Hello.ab","file":".","doc":"","url":"././~/Hello.ab.html","deprecated":false},{"kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"Hello.x","file":".","doc":"","url":"././~/Hello.x.html","deprecated":false},{"kind":[{"char":"I","kind":"Interface","title":"Interface"}],"name":"InterfaceWithIndexSignature","file":".","doc":"","url":"././~/InterfaceWithIndexSignature.html","deprecated":false},{"kind":[{"char":"c","kind":"Class","title":"Class"},{"char":"N","kind":"Namespace","title":"Namespace"}],"name":"Testing","file":".","doc":"","url":"././~/Testing.html","deprecated":false},{"kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"Testing.t","file":".","doc":"","url":"././~/Testing.t.html","deprecated":false},{"kind":[{"char":"T","kind":"TypeAlias","title":"Type Alias"}],"name":"TypeAlias","file":".","doc":"","url":"././~/TypeAlias.html","deprecated":false},{"kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"anotherVariable","file":".","doc":"","url":"././~/anotherVariable.html","deprecated":false},{"kind":[{"char":"m","kind":"Method","title":"Method"}],"name":"anotherVariable.bar","file":".","doc":"","url":"././~/anotherVariable.bar.html","deprecated":false},{"kind":[{"char":"p","kind":"Property","title":"Property"}],"name":"anotherVariable.foo","file":".","doc":"","url":"././~/anotherVariable.foo.html","deprecated":false},{"kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"c","file":".","doc":"","url":"././~/c.html","deprecated":false},{"kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"d","file":".","doc":"","url":"././~/d.html","deprecated":false},{"kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"functionWithOptionalParameters","file":".","doc":"","url":"././~/functionWithOptionalParameters.html","deprecated":false},{"kind":[{"char":"f","kind":"Function","title":"Function"},{"char":"f","kind":"Function","title":"Function"},{"char":"f","kind":"Function","title":"Function"}],"name":"qaz","file":".","doc":"content\n","url":"././~/qaz.html","deprecated":false},{"kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"someVariable","file":".","doc":"","url":"././~/someVariable.html","deprecated":false},{"kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"Testing.x","file":"c","doc":"","url":"./c/~/Testing.x.html","deprecated":false},{"kind":[{"char":"f","kind":"Function","title":"Function"},{"char":"f","kind":"Function","title":"Function"},{"char":"f","kind":"Function","title":"Function"}],"name":"x","file":"c","doc":"","url":"./c/~/x.html","deprecated":false},{"kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"Testing.externalFunction","file":"d","doc":"","url":"./d/~/Testing.externalFunction.html","deprecated":false},{"kind":[{"char":"f","kind":"Function","title":"Function"}],"name":"externalFunction","file":"d","doc":"","url":"./d/~/externalFunction.html","deprecated":false},{"kind":[{"char":"v","kind":"Variable","title":"Variable"}],"name":"default","file":"foo","doc":"The default export item.\n\nThis item reproduces the issue reported in {@link https://github.com/jsr-io/jsr/issues/459}","url":"./foo/~/default.html","deprecated":false}]}; +})() diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-8.snap b/tests/snapshots/html_test__html_doc_files_rewrite-8.snap index 46ccc69c..57697401 100644 --- a/tests/snapshots/html_test__html_doc_files_rewrite-8.snap +++ b/tests/snapshots/html_test__html_doc_files_rewrite-8.snap @@ -1,106 +1,5 @@ --- source: tests/html_test.rs -expression: "files.get(\"./~/Foo.bar.html\").unwrap()" +expression: files.get(name).unwrap() --- - - - - Foo.bar - documentation - - - - - - - - - - - - - -
    -
    -
    -
    -
    -

    Usage

    import { Foo } from ".";
    -
    -
    -
    -
    -
    - - + diff --git a/tests/snapshots/html_test__html_doc_files_rewrite-9.snap b/tests/snapshots/html_test__html_doc_files_rewrite-9.snap index 28b13461..0ec8d138 100644 --- a/tests/snapshots/html_test__html_doc_files_rewrite-9.snap +++ b/tests/snapshots/html_test__html_doc_files_rewrite-9.snap @@ -1,36 +1,25 @@ --- source: tests/html_test.rs -expression: "files.get(\"./~/Foo.prototype.\\\">.html\").unwrap()" +expression: files.get(file_name).unwrap() --- - Foo.prototype."><img src=x onerror=alert(1)> - documentation + AbstractClass.prototype.method - documentation - - - - - - - - - + + + + + +
    -
    +
    - property Foo.prototype."><img src=x onerror=alert(1)> -
    + method AbstractClass.prototype.method +
    + + + + + + + + + + + +AbstractClass.prototype.method(s: number | string): s is string +
    +
    +

    + + + + + + + + + + +Parameters

    + +
    +
    + + + + + + + + + + +s: number | string + +
    +
    +
    -

    .htm -Type

    +Return Type
    -
    number +
    s is string
    +
    -

    Usage

    import { Foo } from ".";
    -
    -
    +

    Document Navigation

    +
    diff --git a/tests/snapshots/html_test__html_doc_files_rewrite.snap b/tests/snapshots/html_test__html_doc_files_rewrite.snap index 1711f335..471a67d1 100644 --- a/tests/snapshots/html_test__html_doc_files_rewrite.snap +++ b/tests/snapshots/html_test__html_doc_files_rewrite.snap @@ -1,6 +1,6 @@ --- source: tests/html_test.rs -expression: "files.get(\"./all_symbols.html\").unwrap()" +expression: files.get(file_name).unwrap() --- @@ -11,13 +11,10 @@ expression: "files.get(\"./all_symbols.html\").unwrap()" - - - + - - +
    -
    -
    +
    +
    c
    +
    + AbstractClass + +
    No documentation available
    +
    v
    +
    + anotherVariable + +
    No documentation available
    +
    c
    Bar -
    No documentation available
    -
    +

    Bar docs

    +
    T
    Baz -
    No documentation available
    -
    +
    No documentation available
    f
    c -
    No documentation available
    -
    +
    No documentation available
    f
    d -
    No documentation available
    -
    +
    No documentation available
    +
    I
    +
    + EmptyInterface + +
    No documentation available
    +
    E
    +
    + Enum + +
    No documentation available
    +
    E
    +
    + Enum2 + +
    No documentation available
    c
    Foobar -
    No documentation available
    -
    +

    Foobar docs

    +
    +
    f
    +
    + functionWithOptionalParameters + +
    No documentation available
    I
    Hello -
    No documentation available
    -
    +
    No documentation available
    +
    I
    +
    + InterfaceWithIndexSignature + +
    No documentation available
    f
    qaz -
    No documentation available
    -
    +
    No documentation available
    +
    v
    +
    + someVariable + +
    No documentation available
    +
    c
    N
    +
    + Testing + +
    No documentation available
    +
    f
    +
    + Testing.t + +
    No documentation available
    +
    T
    +
    + TypeAlias + +
    No documentation available
    +
    + +
    +
    f
    +
    + Testing.x + +
    No documentation available
    +
    f
    +
    + x + +
    No documentation available
    +
    +
    +
    +
    f
    +
    + externalFunction + +
    No documentation available
    +
    f
    +
    + Testing.externalFunction + +
    No documentation available
    @@ -145,19 +262,18 @@ expression: "files.get(\"./all_symbols.html\").unwrap()"
    default -

    The default export item.

    -
    -
    +

    The default export item.

    +
    f
    x -
    No documentation available
    -
    +
    No documentation available
    -
    + + diff --git a/tests/snapshots/html_test__html_doc_files_single-10.snap b/tests/snapshots/html_test__html_doc_files_single-10.snap new file mode 100644 index 00000000..e67d0c9c --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_single-10.snap @@ -0,0 +1,39 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- +function findParent(el, find) { + do { + if (find(el)) { + return el; + } + } while (el = el.parentElement); +} + +document.addEventListener("click", (e) => { + const target = findParent( + e.target, + (el) => el instanceof HTMLButtonElement && el.dataset["copy"], + ); + if (target) { + navigator?.clipboard?.writeText(target.dataset["copy"]); + target.classList.add("copied"); + setTimeout(() => target.classList.remove("copied"), 1000); + } +}); + +window.addEventListener("load", () => { + const usageSelector = document.getElementById("usageSelector"); + + document.addEventListener("mouseup", (e) => { + if ( + findParent( + e.target, + (el) => + el.parentElement === usageSelector && el instanceof HTMLDivElement, + ) + ) { + usageSelector.open = false; + } + }); +}); diff --git a/tests/snapshots/html_test__html_doc_files_single-11.snap b/tests/snapshots/html_test__html_doc_files_single-11.snap new file mode 100644 index 00000000..33d6c4a7 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_single-11.snap @@ -0,0 +1,145 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- +const Fuse = window.Fuse; + +const searchInput = document.querySelector("#searchbar"); +const contentDiv = document.querySelector("#content"); +const searchResultsDiv = document.querySelector("#searchResults"); +const currentFile = + document.querySelector("meta[name='doc-current-file']").attributes + .getNamedItem("content").value; +const pathToRoot = "../".repeat( + currentFile ? (currentFile.split("/").length + 1) : 0, +); +searchInput.removeAttribute("style"); + +const SEARCH_INDEX = window.DENO_DOC_SEARCH_INDEX; + +const fuse = new Fuse(SEARCH_INDEX.nodes, { + keys: [{ + name: "name", + weight: 2, + }], + isCaseSensitive: false, + minMatchCharLength: 2, + threshold: 0.4, +}); + +const loadedUrl = new URL(window.location.href); +const val = loadedUrl.searchParams.get("q"); +if (val) { + searchInput.value = val; + doSearch(val); +} + +window.addEventListener("load", function () { + document.addEventListener("keydown", function (event) { + if (event.key.toLowerCase() === "s") { + if (event.target !== searchInput) { + searchInput.focus(); + event.preventDefault(); + } + } + }); + + const emptyPlaceholder = "Click or press 'S' to search..."; + searchInput.placeholder = emptyPlaceholder; + + searchInput.addEventListener("focus", function () { + searchInput.placeholder = "Type your query here..."; + }); + + searchInput.addEventListener("blur", function () { + searchInput.placeholder = emptyPlaceholder; + }); +}); + +function debounce(func, delay) { + let timerId; + + return function () { + const context = this; + const args = arguments; + + clearTimeout(timerId); + + timerId = setTimeout(function () { + func.apply(context, args); + }, delay); + }; +} + +const debouncedSearch = debounce(doSearch, 250); + +searchInput.addEventListener("input", (e) => { + const val = e.target.value; + debouncedSearch(val); +}); + +function doSearch(val) { + if (!val) { + updateCurrentLocation(val); + showPage(); + } else { + const results = searchInIndex(val); + // console.log("results", results); + updateCurrentLocation(val); + renderResults(results); + showSearchResults(); + } +} + +function updateCurrentLocation(val) { + const url = new URL(window.location.href); + if (val) { + url.searchParams.set("q", val); + } else { + url.searchParams.delete("q"); + } + window.history.replaceState({}, "", url.href); +} + +function showPage() { + contentDiv.style.display = "flex"; + searchResultsDiv.style.display = "none"; +} + +function showSearchResults() { + contentDiv.style.display = "none"; + searchResultsDiv.style.display = "block"; +} + +function renderResults(results) { + if (results.length === 0) { + searchResultsDiv.innerHTML = `No result`; + return; + } + + let html = `
      `; + + for (const result of results) { + const kind = result.kind.map((kind) => { + return `
      ${kind.char}
      `; + }).join(""); + + html += `
    • + +
      +
      + ${kind} +
      + ${result.name} +
      +
      +
    • `; + } + + html += `
    `; + searchResultsDiv.innerHTML = html; +} + +function searchInIndex(val) { + return fuse.search(val).map((result) => result.item); +} diff --git a/tests/snapshots/html_test__html_doc_files_single-12.snap b/tests/snapshots/html_test__html_doc_files_single-12.snap new file mode 100644 index 00000000..e465acb3 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_single-12.snap @@ -0,0 +1,7 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- +(function () { + window.DENO_DOC_SEARCH_INDEX = {"kind":"search","nodes":[{"kind":[{"char":"c","kind":"Class","title":"Class"}],"name":"Bar","file":".","doc":"","url":"././~/Bar.html","deprecated":false},{"kind":[{"char":"c","kind":"Class","title":"Class"}],"name":"Foo","file":".","doc":"```ts\nusing time = new FakeTime();\n```","url":"././~/Foo.html","deprecated":false},{"kind":[{"char":"c","kind":"Class","title":"Class"}],"name":"Foobar","file":".","doc":"","url":"././~/Foobar.html","deprecated":false}]}; +})() diff --git a/tests/snapshots/html_test__html_doc_files_single-2.snap b/tests/snapshots/html_test__html_doc_files_single-2.snap new file mode 100644 index 00000000..bb76e0ff --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_single-2.snap @@ -0,0 +1,57 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_single-3.snap b/tests/snapshots/html_test__html_doc_files_single-3.snap new file mode 100644 index 00000000..de5a369b --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_single-3.snap @@ -0,0 +1,69 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Bar - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    + class Bar +
    + extends Foo +
    +
    +
    +
    +
    +

    Usage

    import { Bar } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_single-4.snap b/tests/snapshots/html_test__html_doc_files_single-4.snap new file mode 100644 index 00000000..2c441d4e --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_single-4.snap @@ -0,0 +1,5 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + diff --git a/tests/snapshots/html_test__html_doc_files_single-5.snap b/tests/snapshots/html_test__html_doc_files_single-5.snap new file mode 100644 index 00000000..d31210dd --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_single-5.snap @@ -0,0 +1,79 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Foo - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    + class Foo +
    using time = new FakeTime();
    +
    +
    +
    +
    +
    +
    +

    Usage

    import { Foo } from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_single-6.snap b/tests/snapshots/html_test__html_doc_files_single-6.snap new file mode 100644 index 00000000..50404116 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_single-6.snap @@ -0,0 +1,5 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + diff --git a/tests/snapshots/html_test__html_doc_files_single-7.snap b/tests/snapshots/html_test__html_doc_files_single-7.snap new file mode 100644 index 00000000..653ac3f3 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_single-7.snap @@ -0,0 +1,67 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + Foobar - documentation + + + + + + + + + + +
    +
    +
    +
    +
    +
    + class Foobar +
    +
    +
    +
    +
    +

    Usage

    import Foobar from ".";
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__html_doc_files_single-8.snap b/tests/snapshots/html_test__html_doc_files_single-8.snap new file mode 100644 index 00000000..98d0f995 --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_single-8.snap @@ -0,0 +1,5 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + diff --git a/tests/snapshots/html_test__html_doc_files_single-9.snap b/tests/snapshots/html_test__html_doc_files_single-9.snap new file mode 100644 index 00000000..4778501f --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_single-9.snap @@ -0,0 +1,15 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- +// deno-fmt-ignore-file +// deno-lint-ignore-file +/** + * Fuse.js v7.0.0 - Lightweight fuzzy-search (http://fusejs.io) + * + * Copyright (c) 2023 Kiro Risk (http://kiro.me) + * All Rights Reserved. Apache Software License 2.0 + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ +var e,t;e=this,t=function(){"use strict";function e(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function t(t){for(var n=1;ne.length)&&(t=e.length);for(var n=0,r=new Array(t);n0&&void 0!==arguments[0]?arguments[0]:{},n=t.getFn,i=void 0===n?$.getFn:n,o=t.fieldNormWeight,c=void 0===o?$.fieldNormWeight:o;r(this,e),this.norm=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:3,n=new Map,r=Math.pow(10,t);return{get:function(t){var i=t.match(F).length;if(n.has(i))return n.get(i);var o=1/Math.pow(i,.5*e),c=parseFloat(Math.round(o*r)/r);return n.set(i,c),c},clear:function(){n.clear()}}}(c,3),this.getFn=i,this.isCreated=!1,this.setIndexRecords()}return o(e,[{key:"setSources",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.docs=e}},{key:"setIndexRecords",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.records=e}},{key:"setKeys",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.keys=t,this._keysMap={},t.forEach((function(t,n){e._keysMap[t.id]=n}))}},{key:"create",value:function(){var e=this;!this.isCreated&&this.docs.length&&(this.isCreated=!0,m(this.docs[0])?this.docs.forEach((function(t,n){e._addString(t,n)})):this.docs.forEach((function(t,n){e._addObject(t,n)})),this.norm.clear())}},{key:"add",value:function(e){var t=this.size();m(e)?this._addString(e,t):this._addObject(e,t)}},{key:"removeAt",value:function(e){this.records.splice(e,1);for(var t=e,n=this.size();t2&&void 0!==arguments[2]?arguments[2]:{},r=n.getFn,i=void 0===r?$.getFn:r,o=n.fieldNormWeight,c=void 0===o?$.fieldNormWeight:o,a=new R({getFn:i,fieldNormWeight:c});return a.setKeys(e.map(A)),a.setSources(t),a.create(),a}function N(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t.errors,r=void 0===n?0:n,i=t.currentLocation,o=void 0===i?0:i,c=t.expectedLocation,a=void 0===c?0:c,s=t.distance,u=void 0===s?$.distance:s,h=t.ignoreLocation,l=void 0===h?$.ignoreLocation:h,f=r/e.length;if(l)return f;var d=Math.abs(a-o);return u?f+d/u:d?1:f}var W=32;function T(e,t,n){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},i=r.location,o=void 0===i?$.location:i,c=r.distance,a=void 0===c?$.distance:c,s=r.threshold,u=void 0===s?$.threshold:s,h=r.findAllMatches,l=void 0===h?$.findAllMatches:h,f=r.minMatchCharLength,d=void 0===f?$.minMatchCharLength:f,v=r.includeMatches,g=void 0===v?$.includeMatches:v,y=r.ignoreLocation,p=void 0===y?$.ignoreLocation:y;if(t.length>W)throw new Error("Pattern length exceeds max of ".concat(W,"."));for(var m,k=t.length,M=e.length,b=Math.max(0,Math.min(o,M)),x=u,w=b,S=d>1||g,L=S?Array(M):[];(m=e.indexOf(t,w))>-1;){var _=N(t,{currentLocation:m,expectedLocation:b,distance:a,ignoreLocation:p});if(x=Math.min(_,x),w=m+k,S)for(var O=0;O=P;D-=1){var K=D-1,q=n[e.charAt(K)];if(S&&(L[K]=+!!q),z[D]=(z[D+1]<<1|1)&q,E&&(z[D]|=(j[D+1]|j[D])<<1|1|j[D+1]),z[D]&C&&(A=N(t,{errors:E,currentLocation:K,expectedLocation:b,distance:a,ignoreLocation:p}))<=x){if(x=A,(w=K)<=b)break;P=Math.max(1,2*b-w)}}if(N(t,{errors:E+1,currentLocation:b,expectedLocation:b,distance:a,ignoreLocation:p})>x)break;j=z}var B={isMatch:w>=0,score:Math.max(.001,A)};if(S){var J=function(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:$.minMatchCharLength,n=[],r=-1,i=-1,o=0,c=e.length;o=t&&n.push([r,i]),r=-1)}return e[o-1]&&o-r>=t&&n.push([r,o-1]),n}(L,d);J.length?g&&(B.indices=J):B.isMatch=!1}return B}function z(e){for(var t={},n=0,r=e.length;n1&&void 0!==arguments[1]?arguments[1]:{},o=i.location,c=void 0===o?$.location:o,a=i.threshold,s=void 0===a?$.threshold:a,u=i.distance,h=void 0===u?$.distance:u,l=i.includeMatches,f=void 0===l?$.includeMatches:l,d=i.findAllMatches,v=void 0===d?$.findAllMatches:d,g=i.minMatchCharLength,y=void 0===g?$.minMatchCharLength:g,p=i.isCaseSensitive,m=void 0===p?$.isCaseSensitive:p,k=i.ignoreLocation,M=void 0===k?$.ignoreLocation:k;if(r(this,e),this.options={location:c,threshold:s,distance:h,includeMatches:f,findAllMatches:v,minMatchCharLength:y,isCaseSensitive:m,ignoreLocation:M},this.pattern=m?t:t.toLowerCase(),this.chunks=[],this.pattern.length){var b=function(e,t){n.chunks.push({pattern:e,alphabet:z(e),startIndex:t})},x=this.pattern.length;if(x>W){for(var w=0,S=x%W,L=x-S;w1&&void 0!==arguments[1]?arguments[1]:{},c=o.location,a=void 0===c?$.location:c,s=o.threshold,u=void 0===s?$.threshold:s,h=o.distance,l=void 0===h?$.distance:h,f=o.includeMatches,d=void 0===f?$.includeMatches:f,v=o.findAllMatches,g=void 0===v?$.findAllMatches:v,y=o.minMatchCharLength,p=void 0===y?$.minMatchCharLength:y,m=o.isCaseSensitive,k=void 0===m?$.isCaseSensitive:m,M=o.ignoreLocation,b=void 0===M?$.ignoreLocation:M;return r(this,n),(i=t.call(this,e))._bitapSearch=new D(e,{location:a,threshold:u,distance:l,includeMatches:d,findAllMatches:g,minMatchCharLength:p,isCaseSensitive:k,ignoreLocation:b}),i}return o(n,[{key:"search",value:function(e){return this._bitapSearch.searchIn(e)}}],[{key:"type",get:function(){return"fuzzy"}},{key:"multiRegex",get:function(){return/^"(.*)"$/}},{key:"singleRegex",get:function(){return/^(.*)$/}}]),n}(K),X=function(e){a(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return o(n,[{key:"search",value:function(e){for(var t,n=0,r=[],i=this.pattern.length;(t=e.indexOf(this.pattern,n))>-1;)n=t+i,r.push([t,n-1]);var o=!!r.length;return{isMatch:o,score:o?0:1,indices:r}}}],[{key:"type",get:function(){return"include"}},{key:"multiRegex",get:function(){return/^'"(.*)"$/}},{key:"singleRegex",get:function(){return/^'(.*)$/}}]),n}(K),Y=[B,X,U,V,H,G,J,Q],Z=Y.length,ee=/ +(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/,te=new Set([Q.type,X.type]),ne=function(){function e(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=n.isCaseSensitive,o=void 0===i?$.isCaseSensitive:i,c=n.includeMatches,a=void 0===c?$.includeMatches:c,s=n.minMatchCharLength,u=void 0===s?$.minMatchCharLength:s,h=n.ignoreLocation,l=void 0===h?$.ignoreLocation:h,f=n.findAllMatches,d=void 0===f?$.findAllMatches:f,v=n.location,g=void 0===v?$.location:v,y=n.threshold,p=void 0===y?$.threshold:y,m=n.distance,k=void 0===m?$.distance:m;r(this,e),this.query=null,this.options={isCaseSensitive:o,includeMatches:a,minMatchCharLength:u,findAllMatches:d,ignoreLocation:l,location:g,threshold:p,distance:k},this.pattern=o?t:t.toLowerCase(),this.query=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return e.split("|").map((function(e){for(var n=e.trim().split(ee).filter((function(e){return e&&!!e.trim()})),r=[],i=0,o=n.length;i2&&void 0!==arguments[2]?arguments[2]:{}).auto,r=void 0===n||n;return ue(e)||(e=he(e)),function e(n){var i=Object.keys(n),o=function(e){return!!e[ae]}(n);if(!o&&i.length>1&&!ue(n))return e(he(n));if(function(e){return!g(e)&&b(e)&&!ue(e)}(n)){var c=o?n[ae]:i[0],a=o?n[se]:n[c];if(!m(a))throw new Error(function(e){return"Invalid value for key ".concat(e)}(c));var s={keyId:C(c),pattern:a};return r&&(s.searcher=ie(a,t)),s}var u={children:[],operator:i[0]};return i.forEach((function(t){var r=n[t];g(r)&&r.forEach((function(t){u.children.push(e(t))}))})),u}(e)}function fe(e,t){var n=e.matches;t.matches=[],x(n)&&n.forEach((function(e){if(x(e.indices)&&e.indices.length){var n={indices:e.indices,value:e.value};e.key&&(n.key=e.key.src),e.idx>-1&&(n.refIndex=e.idx),t.matches.push(n)}}))}function de(e,t){t.score=e.score}var ve=function(){function e(n){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},o=arguments.length>2?arguments[2]:void 0;r(this,e),this.options=t(t({},$),i),this.options.useExtendedSearch,this._keyStore=new j(this.options.keys),this.setCollection(n,o)}return o(e,[{key:"setCollection",value:function(e,t){if(this._docs=e,t&&!(t instanceof R))throw new Error("Incorrect 'index' type");this._myIndex=t||P(this.options.keys,this._docs,{getFn:this.options.getFn,fieldNormWeight:this.options.fieldNormWeight})}},{key:"add",value:function(e){x(e)&&(this._docs.push(e),this._myIndex.add(e))}},{key:"remove",value:function(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:function(){return!1},t=[],n=0,r=this._docs.length;n1&&void 0!==arguments[1]?arguments[1]:{}).limit,n=void 0===t?-1:t,r=this.options,i=r.includeMatches,o=r.includeScore,c=r.shouldSort,a=r.sortFn,s=r.ignoreFieldNorm,u=m(e)?m(this._docs[0])?this._searchStringList(e):this._searchObjectList(e):this._searchLogical(e);return function(e,t){var n=t.ignoreFieldNorm,r=void 0===n?$.ignoreFieldNorm:n;e.forEach((function(e){var t=1;e.matches.forEach((function(e){var n=e.key,i=e.norm,o=e.score,c=n?n.weight:null;t*=Math.pow(0===o&&c?Number.EPSILON:o,(c||1)*(r?1:i))})),e.score=t}))}(u,{ignoreFieldNorm:s}),c&&u.sort(a),k(n)&&n>-1&&(u=u.slice(0,n)),function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=n.includeMatches,i=void 0===r?$.includeMatches:r,o=n.includeScore,c=void 0===o?$.includeScore:o,a=[];return i&&a.push(fe),c&&a.push(de),e.map((function(e){var n=e.idx,r={item:t[n],refIndex:n};return a.length&&a.forEach((function(t){t(e,r)})),r}))}(u,this._docs,{includeMatches:i,includeScore:o})}},{key:"_searchStringList",value:function(e){var t=ie(e,this.options),n=this._myIndex.records,r=[];return n.forEach((function(e){var n=e.v,i=e.i,o=e.n;if(x(n)){var c=t.searchIn(n),a=c.isMatch,s=c.score,u=c.indices;a&&r.push({item:n,idx:i,matches:[{score:s,value:n,norm:o,indices:u}]})}})),r}},{key:"_searchLogical",value:function(e){var t=this,n=le(e,this.options),r=function e(n,r,i){if(!n.children){var o=n.keyId,c=n.searcher,a=t._findMatches({key:t._keyStore.get(o),value:t._myIndex.getValueForItemAtKeyId(r,o),searcher:c});return a&&a.length?[{idx:i,item:r,matches:a}]:[]}for(var s=[],u=0,h=n.children.length;u1&&void 0!==arguments[1]?arguments[1]:{},n=t.getFn,r=void 0===n?$.getFn:n,i=t.fieldNormWeight,o=void 0===i?$.fieldNormWeight:i,c=e.keys,a=e.records,s=new R({getFn:r,fieldNormWeight:o});return s.setKeys(c),s.setIndexRecords(a),s},ve.config=$,function(){re.push.apply(re,arguments)}(ne),ve},"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Fuse=t(); diff --git a/tests/snapshots/html_test__html_doc_files_single.snap b/tests/snapshots/html_test__html_doc_files_single.snap new file mode 100644 index 00000000..9f8ace5b --- /dev/null +++ b/tests/snapshots/html_test__html_doc_files_single.snap @@ -0,0 +1,87 @@ +--- +source: tests/html_test.rs +expression: files.get(file_name).unwrap() +--- + + + + All Symbols - documentation + + + + + + + + + + +
    +
    +
    +
    c
    +
    + Bar + +
    No documentation available
    +
    c
    +
    + Foo + +
    No documentation available
    +
    c
    +
    + Foobar + +
    No documentation available
    +
    +
    +
    +
    +
    +
    +
    + + diff --git a/tests/snapshots/html_test__module_doc.snap b/tests/snapshots/html_test__module_doc.snap index 7a8cfad4..d2e0e133 100644 --- a/tests/snapshots/html_test__module_doc.snap +++ b/tests/snapshots/html_test__module_doc.snap @@ -7,7 +7,52 @@ expression: module_docs "deprecated": null, "sections": { "id": "module_doc", - "docs": "

    Some docs

    \n
    \n \n \n \n \n\nNote

    \nUseful information that users should know, even when skimming content.

    \n
    \n
    \n \n \n \n \n\nTip

    \nHelpful advice for doing things better or more easily.

    \n
    \n
    \n \n \n \n \n\nImportant

    \nKey information users need to know to achieve their goal.

    \n
    \n
    \n \n \n \n \n\nWarning

    \nUrgent info that needs immediate user attention to avoid problems.

    \n
    \n
    \n \n \n \n \n\nCaution

    \nAdvises about risks or negative outcomes of certain actions.

    \n
    \n
    ", + "docs": null, + "sections": [ + { + "header": { + "title": "Functions", + "anchor": { + "id": "Functions" + }, + "href": null, + "doc": null + }, + "content": { + "kind": "namespace_section", + "content": [ + { + "id": "namespace_externalfunction", + "anchor": { + "id": "namespace_externalfunction" + }, + "tags": [], + "doc_node_kind_ctx": [ + { + "kind": "Function", + "char": "f", + "title": "Function", + "title_lowercase": "function", + "title_plural": "Functions" + } + ], + "href": ".././d/~/externalFunction.html", + "name": "externalFunction", + "docs": null, + "deprecated": false, + "subitems": [] + } + ] + } + } + ] + } + }, + { + "deprecated": null, + "sections": { + "id": "module_doc", + "docs": null, "sections": [] } }, @@ -47,7 +92,8 @@ expression: module_docs "href": ".././foo/~/x.html", "name": "x", "docs": null, - "deprecated": false + "deprecated": false, + "subitems": [] } ] } @@ -82,7 +128,53 @@ expression: module_docs "href": ".././foo/~/default.html", "name": "default", "docs": "

    The default export item.

    \n
    ", - "deprecated": false + "deprecated": false, + "subitems": [] + } + ] + } + } + ] + } + }, + { + "deprecated": null, + "sections": { + "id": "module_doc", + "docs": null, + "sections": [ + { + "header": { + "title": "Functions", + "anchor": { + "id": "Functions" + }, + "href": null, + "doc": null + }, + "content": { + "kind": "namespace_section", + "content": [ + { + "id": "namespace_x", + "anchor": { + "id": "namespace_x" + }, + "tags": [], + "doc_node_kind_ctx": [ + { + "kind": "Function", + "char": "f", + "title": "Function", + "title_lowercase": "function", + "title_plural": "Functions" + } + ], + "href": ".././c/~/x.html", + "name": "x", + "docs": null, + "deprecated": false, + "subitems": [] } ] } diff --git a/tests/snapshots/html_test__symbol_group.snap b/tests/snapshots/html_test__symbol_group.snap index ea29b754..c4ff5ae0 100644 --- a/tests/snapshots/html_test__symbol_group.snap +++ b/tests/snapshots/html_test__symbol_group.snap @@ -4,6 +4,180 @@ expression: files --- [ { + "kind": "SymbolPageCtx", + "html_head_ctx": { + "title": "externalFunction - documentation", + "current_file": "d", + "stylesheet_url": "../../styles.css", + "page_stylesheet_url": "../../page.css", + "reset_stylesheet_url": "../../reset.css", + "url_search_index": "../../search_index.js", + "script_js": "../../script.js", + "fuse_js": "../../fuse.js", + "url_search": "../../search.js", + "head_inject": null, + "disable_search": false + }, + "symbol_group_ctx": { + "name": "externalFunction", + "symbols": [ + { + "kind": { + "kind": "Function", + "char": "f", + "title": "Function", + "title_lowercase": "function", + "title_plural": "Functions" + }, + "usage": null, + "tags": [], + "subtitle": null, + "content": [ + { + "kind": "function", + "value": { + "functions": [ + { + "id": "function_externalFunction_0", + "anchor": { + "id": "function_externalFunction_0" + }, + "name": "externalFunction", + "summary": "(_n?: number): void", + "deprecated": null, + "content": { + "id": "", + "docs": null, + "sections": [ + { + "header": { + "title": "Parameters", + "anchor": { + "id": "parameters" + }, + "href": null, + "doc": null + }, + "content": { + "kind": "doc_entry", + "content": [ + { + "id": "function_externalfunction_0_parameters__n", + "name": "_n", + "name_href": null, + "content": ": number = 0", + "anchor": { + "id": "function_externalfunction_0_parameters__n" + }, + "tags": [ + { + "kind": "optional" + } + ], + "js_doc": null, + "source_href": null + } + ] + } + }, + { + "header": { + "title": "Return Type", + "anchor": { + "id": "return-type" + }, + "href": null, + "doc": null + }, + "content": { + "kind": "doc_entry", + "content": [ + { + "id": "function_externalFunction_0_return", + "name": null, + "name_href": null, + "content": "void", + "anchor": { + "id": "function_externalFunction_0_return" + }, + "tags": [], + "js_doc": null, + "source_href": null + } + ] + } + } + ] + } + } + ] + } + } + ], + "deprecated": null, + "source_href": null + } + ] + }, + "breadcrumbs_ctx": { + "parts": [ + { + "name": "index", + "href": "../../", + "is_symbol": false, + "is_first_symbol": false + }, + { + "name": "d", + "href": "../.././d/index.html", + "is_symbol": false, + "is_first_symbol": false + }, + { + "name": "externalFunction", + "href": "../.././d/~/externalFunction.html", + "is_symbol": true, + "is_first_symbol": true + } + ] + }, + "toc_ctx": { + "usages": { + "usages": [ + { + "name": "", + "content": "
    import { externalFunction } from "d";\n
    \n
    ", + "icon": null, + "additional_css": "" + } + ], + "composed": false + }, + "top_symbols": null, + "document_navigation_str": "", + "document_navigation": [ + { + "level": 1, + "content": "Parameters", + "anchor": "parameters" + }, + { + "level": 2, + "content": "_n", + "anchor": "function_externalfunction_0_parameters__n" + }, + { + "level": 1, + "content": "Return Type", + "anchor": "return-type" + } + ] + }, + "disable_search": false, + "categories_panel": null + }, + { + "kind": "SymbolPageCtx", "html_head_ctx": { "title": "A - documentation", "current_file": ".", @@ -14,6 +188,7 @@ expression: files "script_js": "../script.js", "fuse_js": "../fuse.js", "url_search": "../search.js", + "head_inject": null, "disable_search": false }, "symbol_group_ctx": { @@ -76,7 +251,7 @@ expression: files "usages": [ { "name": "", - "content": "
    import { A } from \".\";\n
    \n
    ", + "content": "
    import { A } from ".";\n
    \n
    ", "icon": null, "additional_css": "" } @@ -84,15 +259,17 @@ expression: files "composed": false }, "top_symbols": null, - "document_navigation": null + "document_navigation_str": null, + "document_navigation": [] }, "disable_search": false, "categories_panel": null }, null, { + "kind": "SymbolPageCtx", "html_head_ctx": { - "title": "B - documentation", + "title": "AbstractClass - documentation", "current_file": ".", "stylesheet_url": "../styles.css", "page_stylesheet_url": "../page.css", @@ -101,10 +278,11 @@ expression: files "script_js": "../script.js", "fuse_js": "../fuse.js", "url_search": "../search.js", + "head_inject": null, "disable_search": false }, "symbol_group_ctx": { - "name": "B", + "name": "AbstractClass", "symbols": [ { "kind": { @@ -115,11 +293,7 @@ expression: files "title_plural": "Classes" }, "usage": null, - "tags": [ - { - "kind": "private" - } - ], + "tags": [], "subtitle": { "kind": "class", "value": { @@ -133,7 +307,92 @@ expression: files "value": { "id": "", "docs": null, - "sections": [] + "sections": [ + { + "header": { + "title": "Properties", + "anchor": { + "id": "properties" + }, + "href": null, + "doc": null + }, + "content": { + "kind": "doc_entry", + "content": [ + { + "id": "property_foo", + "name": "foo", + "name_href": "../././~/AbstractClass.prototype.foo.html", + "content": ": string", + "anchor": { + "id": "property_foo" + }, + "tags": [ + { + "kind": "abstract" + } + ], + "js_doc": null, + "source_href": null + }, + { + "id": "accessor_getter", + "name": "getter", + "name_href": "../././~/AbstractClass.prototype.getter.html", + "content": ": string", + "anchor": { + "id": "accessor_getter" + }, + "tags": [ + { + "kind": "abstract" + }, + { + "kind": "readonly" + } + ], + "js_doc": null, + "source_href": null + } + ] + } + }, + { + "header": { + "title": "Methods", + "anchor": { + "id": "methods" + }, + "href": null, + "doc": null + }, + "content": { + "kind": "doc_entry", + "content": [ + { + "id": "method_method_0", + "name": "method", + "name_href": "../././~/AbstractClass.prototype.method.html", + "content": "(s: number | string): s is string", + "anchor": { + "id": "method_method_0" + }, + "tags": [ + { + "kind": "abstract" + }, + { + "kind": "optional" + } + ], + "js_doc": null, + "source_href": null + } + ] + } + } + ] } } ], @@ -151,8 +410,8 @@ expression: files "is_first_symbol": false }, { - "name": "B", - "href": "../././~/B.html", + "name": "AbstractClass", + "href": "../././~/AbstractClass.html", "is_symbol": true, "is_first_symbol": true } @@ -163,7 +422,7 @@ expression: files "usages": [ { "name": "", - "content": "
    import { B } from \".\";\n
    \n
    ", + "content": "
    import { AbstractClass } from ".";\n
    \n
    ", "icon": null, "additional_css": "" } @@ -171,15 +430,43 @@ expression: files "composed": false }, "top_symbols": null, - "document_navigation": null + "document_navigation_str": "", + "document_navigation": [ + { + "level": 1, + "content": "Properties", + "anchor": "properties" + }, + { + "level": 2, + "content": "foo", + "anchor": "property_foo" + }, + { + "level": 2, + "content": "getter", + "anchor": "accessor_getter" + }, + { + "level": 1, + "content": "Methods", + "anchor": "methods" + }, + { + "level": 2, + "content": "method", + "anchor": "method_method_0" + } + ] }, "disable_search": false, "categories_panel": null }, null, { + "kind": "SymbolPageCtx", "html_head_ctx": { - "title": "Bar - documentation", + "title": "B - documentation", "current_file": ".", "stylesheet_url": "../styles.css", "page_stylesheet_url": "../page.css", @@ -188,10 +475,11 @@ expression: files "script_js": "../script.js", "fuse_js": "../fuse.js", "url_search": "../search.js", + "head_inject": null, "disable_search": false }, "symbol_group_ctx": { - "name": "Bar", + "name": "B", "symbols": [ { "kind": { @@ -202,16 +490,16 @@ expression: files "title_plural": "Classes" }, "usage": null, - "tags": [], + "tags": [ + { + "kind": "private" + } + ], "subtitle": { "kind": "class", "value": { "implements": null, - "extends": { - "href": "../././~/Foo.html", - "symbol": "Foo", - "type_args": "" - } + "extends": null } }, "content": [ @@ -238,8 +526,8 @@ expression: files "is_first_symbol": false }, { - "name": "Bar", - "href": "../././~/Bar.html", + "name": "B", + "href": "../././~/B.html", "is_symbol": true, "is_first_symbol": true } @@ -250,7 +538,7 @@ expression: files "usages": [ { "name": "", - "content": "
    import { Bar } from \".\";\n
    \n
    ", + "content": "
    import { B } from ".";\n
    \n
    ", "icon": null, "additional_css": "" } @@ -258,15 +546,17 @@ expression: files "composed": false }, "top_symbols": null, - "document_navigation": null + "document_navigation_str": null, + "document_navigation": [] }, "disable_search": false, "categories_panel": null }, null, { + "kind": "SymbolPageCtx", "html_head_ctx": { - "title": "Baz - documentation", + "title": "Bar - documentation", "current_file": ".", "stylesheet_url": "../styles.css", "page_stylesheet_url": "../page.css", @@ -275,57 +565,40 @@ expression: files "script_js": "../script.js", "fuse_js": "../fuse.js", "url_search": "../search.js", + "head_inject": null, "disable_search": false }, "symbol_group_ctx": { - "name": "Baz", + "name": "Bar", "symbols": [ { "kind": { - "kind": "TypeAlias", - "char": "T", - "title": "Type Alias", - "title_lowercase": "type alias", - "title_plural": "Type Aliases" + "kind": "Class", + "char": "c", + "title": "Class", + "title_lowercase": "class", + "title_plural": "Classes" }, "usage": null, "tags": [], - "subtitle": null, + "subtitle": { + "kind": "class", + "value": { + "implements": null, + "extends": { + "href": "../././~/Foo.html", + "symbol": "Foo", + "type_args": "<string>" + } + } + }, "content": [ { "kind": "other", "value": { "id": "", - "docs": null, - "sections": [ - { - "header": { - "title": "Properties", - "anchor": { - "id": "properties" - }, - "href": null, - "doc": null - }, - "content": { - "kind": "doc_entry", - "content": [ - { - "id": "property_foo", - "name": "foo", - "name_href": "../././~/Baz.foo.html", - "content": ": string", - "anchor": { - "id": "property_foo" - }, - "tags": [], - "js_doc": null, - "source_href": null - } - ] - } - } - ] + "docs": "
    \n

    Some quote in bar docs\nThis quote part is ignored\nwhen getting the title of this doc

    \n
    \n

    Bar docs

    \n
    ", + "sections": [] } } ], @@ -343,8 +616,8 @@ expression: files "is_first_symbol": false }, { - "name": "Baz", - "href": "../././~/Baz.html", + "name": "Bar", + "href": "../././~/Bar.html", "is_symbol": true, "is_first_symbol": true } @@ -355,7 +628,7 @@ expression: files "usages": [ { "name": "", - "content": "
    import { type Baz } from \".\";\n
    \n
    ", + "content": "
    import { Bar } from ".";\n
    \n
    ", "icon": null, "additional_css": "" } @@ -363,14 +636,17 @@ expression: files "composed": false }, "top_symbols": null, - "document_navigation": "