├── .gitignore ├── .vscode └── settings.json ├── tests ├── local.ts ├── remote.ts └── util.ts ├── test_plugin ├── Cargo.toml ├── src │ └── lib.rs └── Cargo.lock ├── deps.ts ├── test_deps.ts ├── LICENSE ├── .github └── workflows │ └── ci.yml ├── test.ts ├── mod.ts └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | .deno_plugins/ -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "deno.enable": true, 3 | "deno.unstable": true 4 | } 5 | -------------------------------------------------------------------------------- /tests/local.ts: -------------------------------------------------------------------------------- 1 | import { testPrepare } from "./util.ts"; 2 | await testPrepare("file://./test_plugin/target/debug"); 3 | -------------------------------------------------------------------------------- /tests/remote.ts: -------------------------------------------------------------------------------- 1 | import { testPrepare } from "./util.ts"; 2 | import { assert } from "../test_deps.ts"; 3 | 4 | const address = Deno.args[0]; 5 | assert(address && address.length > 0, "no address"); 6 | 7 | await testPrepare(`http://${address}/test_plugin/target/debug`); 8 | -------------------------------------------------------------------------------- /test_plugin/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "test_plugin" 3 | version = "0.0.1" 4 | authors = ["the deno authors"] 5 | edition = "2018" 6 | publish = false 7 | 8 | [lib] 9 | crate-type = ["cdylib"] 10 | 11 | [dependencies] 12 | futures = "0.3.5" 13 | deno_core = "0.63.0" 14 | -------------------------------------------------------------------------------- /deps.ts: -------------------------------------------------------------------------------- 1 | export { exists } from "https://deno.land/std@0.69.0/fs/exists.ts"; 2 | export * as log from "https://deno.land/std@0.69.0/log/mod.ts"; 3 | export * as path from "https://deno.land/std@0.69.0/path/mod.ts"; 4 | export { createHash } from "https://deno.land/std@0.69.0/hash/mod.ts"; 5 | -------------------------------------------------------------------------------- /test_deps.ts: -------------------------------------------------------------------------------- 1 | export { 2 | assert, 3 | assertEquals, 4 | } from "https://deno.land/std@0.69.0/testing/asserts.ts"; 5 | 6 | export { serve } from "https://deno.land/std@0.69.0/http/server.ts"; 7 | export { serveFile } from "https://deno.land/std@0.69.0/http/file_server.ts"; 8 | export { resolve } from "https://deno.land/std@0.69.0/path/posix.ts"; 9 | -------------------------------------------------------------------------------- /tests/util.ts: -------------------------------------------------------------------------------- 1 | import { PrepareOptions, prepare } from "../mod.ts"; 2 | import { assertEquals } from "../test_deps.ts"; 3 | 4 | const textDecoder = new TextDecoder(); 5 | 6 | export async function testPrepare(releaseUrl: string) { 7 | const pluginOptions: PrepareOptions = { 8 | name: "test_plugin", 9 | printLog: true, 10 | urls: { 11 | darwin: `${releaseUrl}/libtest_plugin.dylib`, 12 | windows: `${releaseUrl}/test_plugin.dll`, 13 | linux: `${releaseUrl}/libtest_plugin.so`, 14 | }, 15 | }; 16 | 17 | const pluginId = await prepare(pluginOptions); 18 | 19 | // @ts-ignore 20 | const { testSync } = Deno.core.ops(); 21 | 22 | //@ts-ignore 23 | const response = Deno.core.dispatch( 24 | testSync, 25 | new Uint8Array([116, 101, 115, 116]), 26 | new Uint8Array([116, 101, 115, 116]), 27 | )!; 28 | 29 | assertEquals(textDecoder.decode(response), "test"); 30 | 31 | Deno.close(pluginId); 32 | } 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 EnokMan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | name: ${{ matrix.os }} 8 | runs-on: ${{ matrix.os }} 9 | timeout-minutes: 30 10 | 11 | strategy: 12 | matrix: 13 | os: [macOS-latest, windows-latest, ubuntu-latest] 14 | 15 | env: 16 | DENO_VERSION: 1.4.0 17 | RUST_VERSION: 1.46.0 18 | RUST_BACKTRACE: full 19 | 20 | steps: 21 | - name: Clone repository 22 | uses: actions/checkout@v1 23 | 24 | - name: Install rust 25 | uses: hecrj/setup-rust-action@v1 26 | with: 27 | rust-version: ${{ env.RUST_VERSION }} 28 | 29 | - name: Install Deno 30 | uses: denolib/setup-deno@master 31 | with: 32 | deno-version: ${{ env.DENO_VERSION }} 33 | 34 | - name: Log versions 35 | run: | 36 | deno --version 37 | rustc --version 38 | cargo --version 39 | 40 | - name: Cache 41 | uses: actions/cache@v2 42 | with: 43 | path: |- 44 | ~/.cargo/registry 45 | ~/.cargo/git 46 | test_plugin/target/*/.* 47 | test_plugin/target/*/build 48 | test_plugin/target/*/deps 49 | key: ${{ matrix.os }}-${{ hashFiles('test_plugin//Cargo.lock') }} 50 | restore-keys: | 51 | ${{ matrix.os }}- 52 | 53 | - name: Build test_plugin 54 | working-directory: test_plugin 55 | run: cargo build 56 | 57 | - name: Test 58 | run: deno test -A --unstable 59 | 60 | - name: Test 61 | run: deno test -A --unstable --no-check 62 | -------------------------------------------------------------------------------- /test_plugin/src/lib.rs: -------------------------------------------------------------------------------- 1 | use deno_core::plugin_api::Interface; 2 | use deno_core::plugin_api::Op; 3 | use deno_core::plugin_api::ZeroCopyBuf; 4 | use futures::future::FutureExt; 5 | 6 | #[no_mangle] 7 | pub fn deno_plugin_init(interface: &mut dyn Interface) { 8 | interface.register_op("testSync", op_test_sync); 9 | interface.register_op("testAsync", op_test_async); 10 | } 11 | 12 | fn op_test_sync( 13 | _interface: &mut dyn Interface, 14 | zero_copy: &mut [ZeroCopyBuf], 15 | ) -> Op { 16 | if !zero_copy.is_empty() { 17 | println!("Hello from plugin."); 18 | } 19 | let zero_copy = zero_copy.to_vec(); 20 | for (idx, buf) in zero_copy.iter().enumerate() { 21 | let buf_str = std::str::from_utf8(&buf[..]).unwrap(); 22 | println!("zero_copy[{}]: {}", idx, buf_str); 23 | } 24 | let result = b"test"; 25 | let result_box: Box<[u8]> = Box::new(*result); 26 | Op::Sync(result_box) 27 | } 28 | 29 | fn op_test_async( 30 | _interface: &mut dyn Interface, 31 | zero_copy: &mut [ZeroCopyBuf], 32 | ) -> Op { 33 | if !zero_copy.is_empty() { 34 | println!("Hello from plugin."); 35 | } 36 | let zero_copy = zero_copy.to_vec(); 37 | let fut = async move { 38 | for (idx, buf) in zero_copy.iter().enumerate() { 39 | let buf_str = std::str::from_utf8(&buf[..]).unwrap(); 40 | println!("zero_copy[{}]: {}", idx, buf_str); 41 | } 42 | let (tx, rx) = futures::channel::oneshot::channel::>(); 43 | std::thread::spawn(move || { 44 | std::thread::sleep(std::time::Duration::from_secs(1)); 45 | tx.send(Ok(())).unwrap(); 46 | }); 47 | assert!(rx.await.is_ok()); 48 | let result = b"test"; 49 | let result_box: Box<[u8]> = Box::new(*result); 50 | result_box 51 | }; 52 | 53 | Op::Async(fut.boxed()) 54 | } 55 | -------------------------------------------------------------------------------- /test.ts: -------------------------------------------------------------------------------- 1 | import { exists } from "./deps.ts"; 2 | import { assert, resolve, serve, serveFile } from "./test_deps.ts"; 3 | 4 | const pluginDir = ".deno_plugins"; 5 | 6 | async function cleanCache() { 7 | if (await exists(pluginDir)) { 8 | return Deno.remove(pluginDir, { recursive: true }); 9 | } 10 | } 11 | 12 | async function pluginIsCached(): Promise { 13 | if (!await exists(pluginDir)) { 14 | return false; 15 | } 16 | for (const _ of Deno.readDirSync(pluginDir)) { 17 | return true; 18 | } 19 | return false; 20 | } 21 | 22 | Deno.test("testPrepareLocal", async () => { 23 | await cleanCache(); 24 | 25 | let p = Deno.run({ 26 | cmd: [ 27 | "deno", 28 | "run", 29 | "--allow-read", 30 | "--allow-write", 31 | "--allow-env", 32 | "--allow-plugin", 33 | "--unstable", 34 | "./tests/local.ts", 35 | ], 36 | }); 37 | 38 | let status = await p.status(); 39 | assert(status.success); 40 | assert(await pluginIsCached()); 41 | p.close(); 42 | 43 | p = Deno.run({ 44 | cmd: [ 45 | "deno", 46 | "run", 47 | "--allow-read", 48 | "--allow-write", 49 | "--allow-env", 50 | "--allow-plugin", 51 | "--unstable", 52 | "./tests/local.ts", 53 | ], 54 | }); 55 | 56 | status = await p.status(); 57 | assert(status.success); 58 | 59 | p.close(); 60 | }); 61 | 62 | function startServer(addr: string) { 63 | const server = serve("127.0.0.1:4500"); 64 | 65 | (async () => { 66 | for await (const request of server) { 67 | const response = await serveFile( 68 | request, 69 | resolve(`.${request.url}`), 70 | ); 71 | await request.respond(response); 72 | } 73 | })(); 74 | 75 | return server; 76 | } 77 | 78 | Deno.test("testPrepareRemote", async () => { 79 | await cleanCache(); 80 | 81 | const address = "localhost:4500"; 82 | const server = startServer(address); 83 | 84 | let p = Deno.run({ 85 | cmd: [ 86 | "deno", 87 | "run", 88 | "--allow-read", 89 | "--allow-env", 90 | "--allow-write", 91 | "--allow-plugin", 92 | "--allow-net", 93 | "--unstable", 94 | "./tests/remote.ts", 95 | address, 96 | ], 97 | }); 98 | 99 | let status = await p.status(); 100 | assert(status.success); 101 | assert(await pluginIsCached()); 102 | p.close(); 103 | 104 | p = Deno.run({ 105 | cmd: [ 106 | "deno", 107 | "run", 108 | "--allow-read", 109 | "--allow-env", 110 | "--allow-write", 111 | "--allow-plugin", 112 | "--allow-net", 113 | "--unstable", 114 | "./tests/remote.ts", 115 | address, 116 | ], 117 | }); 118 | 119 | status = await p.status(); 120 | assert(status.success); 121 | 122 | p.close(); 123 | server.close(); 124 | }); 125 | -------------------------------------------------------------------------------- /mod.ts: -------------------------------------------------------------------------------- 1 | import { createHash, exists, log, path } from "./deps.ts"; 2 | 3 | const os = Deno.build.os; 4 | 5 | const PLUGIN_SUFFIX_MAP: { [os in typeof Deno.build.os]: string } = { 6 | darwin: ".dylib", 7 | linux: ".so", 8 | windows: ".dll", 9 | }; 10 | 11 | const pluginSuffix = PLUGIN_SUFFIX_MAP[os]; 12 | 13 | export interface PrepareOptions { 14 | name: string; 15 | printLog?: boolean; 16 | checkCache?: boolean; 17 | cacheDir?: string; 18 | urls: { 19 | darwin?: string; 20 | linux?: string; 21 | windows?: string; 22 | }; 23 | } 24 | 25 | const defaultCacheDir = Deno.env.get("DENO_PLUGIN_DIR") ?? ".deno_plugins"; 26 | 27 | export async function download(options: PrepareOptions): Promise { 28 | const { name, urls, checkCache = true } = options; 29 | 30 | const cacheDir = options.cacheDir ?? defaultCacheDir; 31 | const remoteUrl = urls[os]; 32 | const md5 = createHash("md5"); 33 | md5.update(remoteUrl + pluginSuffix); 34 | const remoteHash = md5.toString("hex"); 35 | const cacheFileName = `${name}_${remoteHash}${pluginSuffix}`; 36 | const localPath = path.resolve(cacheDir, cacheFileName); 37 | 38 | if (!(await exists(localPath)) || !checkCache) { 39 | if (!remoteUrl) { 40 | throw Error( 41 | `"${name}" plugin does not provide binaries suitable for the current system`, 42 | ); 43 | } 44 | 45 | await Deno.mkdir(cacheDir, { recursive: true }); 46 | 47 | if (remoteUrl.startsWith("file://")) { 48 | const fromPath = path.resolve(remoteUrl.slice(7)); 49 | await copyFromLocal(name, fromPath, localPath); 50 | } else { 51 | await downloadFromRemote(name, remoteUrl, localPath); 52 | } 53 | } 54 | 55 | return localPath; 56 | } 57 | 58 | export async function prepare(options: PrepareOptions): Promise { 59 | const { name, printLog = true } = options; 60 | 61 | if (printLog) { 62 | await log.setup({}); 63 | } 64 | 65 | const localPath = await download(options); 66 | 67 | log.info(`load deno plugin "${name}" from local "${localPath}"`); 68 | 69 | return Deno.openPlugin(localPath); 70 | } 71 | 72 | async function downloadFromRemote( 73 | name: string, 74 | remoteUrl: string, 75 | savePath: string, 76 | ) { 77 | log.info(`downloading deno plugin "${name}" from "${remoteUrl}"`); 78 | const download = await fetch(remoteUrl); 79 | 80 | if (download.status !== 200) { 81 | throw Error(`downloading plugin "${name}" from "${remoteUrl}" failed.`); 82 | } 83 | 84 | const pluginFileData = await download.arrayBuffer(); 85 | await Deno.writeFile(savePath, new Uint8Array(pluginFileData)); 86 | } 87 | 88 | async function copyFromLocal(name: string, from: string, to: string) { 89 | log.info(`copy deno plugin "${name}" from "${from}"`); 90 | 91 | if (!(await exists(from))) { 92 | throw Error( 93 | `copy plugin "${name}" from "${from}" failed, ${from} does not exist.`, 94 | ); 95 | } 96 | 97 | await Deno.copyFile(from, to); 98 | } 99 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # deno-plugin-prepare 2 | 3 | A library for managing deno native plugin dependencies 4 | 5 | [![tag](https://img.shields.io/github/tag/manyuanrong/deno-plugin-prepare.svg)](https://github.com/manyuanrong/deno-plugin-prepare) 6 | [![Build Status](https://github.com/manyuanrong/deno-plugin-prepare/workflows/ci/badge.svg?branch=master)](https://github.com/manyuanrong/deno-plugin-prepare/actions) 7 | [![license](https://img.shields.io/github/license/manyuanrong/deno-plugin-prepare.svg)](https://github.com/manyuanrong/deno-plugin-prepare) 8 | [![tag](https://img.shields.io/badge/deno-v1.4.0-green.svg)](https://github.com/denoland/deno) 9 | 10 | ### Why do you need this module? 11 | 12 | Because Deno's plugin is not a first-class citizen, it cannot be loaded directly using `import` like `js`, `ts`, and `json`. 13 | 14 | Deno's plugin is compiled with other system-level languages, and cannot be compiled into one target result across multiple platforms, usually compiled into multiple platform target binaries. These binary files are usually much larger than scripts such as `js/ts`, so they should not be downloaded all, need to be dynamically loaded according to the platform. 15 | 16 | ### API 17 | 18 | #### prepare 19 | 20 | The API needs to provide some plug-in information, including the name of the plugin, and the remote url of the binary file for different platforms. It is similar to an asynchronous version of `Deno.openPlugin`, which will automatically download the corresponding binary file according to the platform and cache it in the `.deno_plugins` directory of the current working directory. 21 | 22 | ### Usage 23 | 24 | ```ts 25 | import { 26 | prepare, 27 | PrepareOptions, 28 | } from "https://deno.land/x/plugin_prepare@v0.8.0/mod.ts"; 29 | 30 | const releaseUrl = 31 | "https://github.com/manyuanrong/deno-plugin-prepare/releases/download/plugin_bins"; 32 | 33 | const pluginOptions: PrepareOptions = { 34 | name: "test_plugin", 35 | 36 | // Whether to output log. Optional, default is true 37 | // printLog: true, 38 | 39 | // Whether to use locally cached files. Optional, default is true 40 | // checkCache: true, 41 | 42 | // Support "http://", "https://", "file://" 43 | urls: { 44 | darwin: `${releaseUrl}/libtest_plugin.dylib`, 45 | windows: `${releaseUrl}/test_plugin.dll`, 46 | linux: `${releaseUrl}/libtest_plugin.so`, 47 | }, 48 | }; 49 | const rid = await prepare(pluginOptions); 50 | //@ts-ignore 51 | const { testSync } = Deno.core.ops(); 52 | //@ts-ignore 53 | const response = Deno.core.dispatch( 54 | testSync, 55 | new Uint8Array([116, 101, 115, 116]) 56 | )!; 57 | 58 | console.log(response); 59 | Deno.close(rid); 60 | ``` 61 | 62 | ### Custom cache path 63 | 64 | By default, binary files will be cached in the `.deno_plugins` directory. In some cases, we need to store in other locations, you can set the `DENO_PLUGIN_DIR` environment variable 65 | 66 | ### TODOs 67 | 68 | - [x] Caching binary files with URL hash (multi-version coexistence) 69 | - [ ] Supports downloading and decompressing .GZ files 70 | -------------------------------------------------------------------------------- /test_plugin/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "anyhow" 5 | version = "1.0.33" 6 | source = "registry+https://github.com/rust-lang/crates.io-index" 7 | checksum = "a1fd36ffbb1fb7c834eac128ea8d0e310c5aeb635548f9d58861e1308d46e71c" 8 | 9 | [[package]] 10 | name = "autocfg" 11 | version = "1.0.1" 12 | source = "registry+https://github.com/rust-lang/crates.io-index" 13 | checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" 14 | 15 | [[package]] 16 | name = "bitflags" 17 | version = "1.2.1" 18 | source = "registry+https://github.com/rust-lang/crates.io-index" 19 | checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" 20 | 21 | [[package]] 22 | name = "cargo_gn" 23 | version = "0.0.15" 24 | source = "registry+https://github.com/rust-lang/crates.io-index" 25 | checksum = "5ba7d7f7b201dfcbc314b14f2176c92f8ba521dab538b40e426ffed25ed7cd80" 26 | 27 | [[package]] 28 | name = "cfg-if" 29 | version = "0.1.10" 30 | source = "registry+https://github.com/rust-lang/crates.io-index" 31 | checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 32 | 33 | [[package]] 34 | name = "deno_core" 35 | version = "0.63.0" 36 | source = "registry+https://github.com/rust-lang/crates.io-index" 37 | checksum = "9c16226d3b09f47e251adf56faccc17c823e702e0a2079efbdd541d620cfc4b5" 38 | dependencies = [ 39 | "anyhow", 40 | "futures", 41 | "indexmap", 42 | "lazy_static", 43 | "libc", 44 | "log", 45 | "rusty_v8", 46 | "serde", 47 | "serde_json", 48 | "smallvec", 49 | "url", 50 | ] 51 | 52 | [[package]] 53 | name = "futures" 54 | version = "0.3.5" 55 | source = "registry+https://github.com/rust-lang/crates.io-index" 56 | checksum = "1e05b85ec287aac0dc34db7d4a569323df697f9c55b99b15d6b4ef8cde49f613" 57 | dependencies = [ 58 | "futures-channel", 59 | "futures-core", 60 | "futures-executor", 61 | "futures-io", 62 | "futures-sink", 63 | "futures-task", 64 | "futures-util", 65 | ] 66 | 67 | [[package]] 68 | name = "futures-channel" 69 | version = "0.3.5" 70 | source = "registry+https://github.com/rust-lang/crates.io-index" 71 | checksum = "f366ad74c28cca6ba456d95e6422883cfb4b252a83bed929c83abfdbbf2967d5" 72 | dependencies = [ 73 | "futures-core", 74 | "futures-sink", 75 | ] 76 | 77 | [[package]] 78 | name = "futures-core" 79 | version = "0.3.5" 80 | source = "registry+https://github.com/rust-lang/crates.io-index" 81 | checksum = "59f5fff90fd5d971f936ad674802482ba441b6f09ba5e15fd8b39145582ca399" 82 | 83 | [[package]] 84 | name = "futures-executor" 85 | version = "0.3.5" 86 | source = "registry+https://github.com/rust-lang/crates.io-index" 87 | checksum = "10d6bb888be1153d3abeb9006b11b02cf5e9b209fda28693c31ae1e4e012e314" 88 | dependencies = [ 89 | "futures-core", 90 | "futures-task", 91 | "futures-util", 92 | ] 93 | 94 | [[package]] 95 | name = "futures-io" 96 | version = "0.3.5" 97 | source = "registry+https://github.com/rust-lang/crates.io-index" 98 | checksum = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789" 99 | 100 | [[package]] 101 | name = "futures-macro" 102 | version = "0.3.5" 103 | source = "registry+https://github.com/rust-lang/crates.io-index" 104 | checksum = "d0b5a30a4328ab5473878237c447333c093297bded83a4983d10f4deea240d39" 105 | dependencies = [ 106 | "proc-macro-hack", 107 | "proc-macro2", 108 | "quote", 109 | "syn", 110 | ] 111 | 112 | [[package]] 113 | name = "futures-sink" 114 | version = "0.3.5" 115 | source = "registry+https://github.com/rust-lang/crates.io-index" 116 | checksum = "3f2032893cb734c7a05d85ce0cc8b8c4075278e93b24b66f9de99d6eb0fa8acc" 117 | 118 | [[package]] 119 | name = "futures-task" 120 | version = "0.3.5" 121 | source = "registry+https://github.com/rust-lang/crates.io-index" 122 | checksum = "bdb66b5f09e22019b1ab0830f7785bcea8e7a42148683f99214f73f8ec21a626" 123 | dependencies = [ 124 | "once_cell", 125 | ] 126 | 127 | [[package]] 128 | name = "futures-util" 129 | version = "0.3.5" 130 | source = "registry+https://github.com/rust-lang/crates.io-index" 131 | checksum = "8764574ff08b701a084482c3c7031349104b07ac897393010494beaa18ce32c6" 132 | dependencies = [ 133 | "futures-channel", 134 | "futures-core", 135 | "futures-io", 136 | "futures-macro", 137 | "futures-sink", 138 | "futures-task", 139 | "memchr", 140 | "pin-project", 141 | "pin-utils", 142 | "proc-macro-hack", 143 | "proc-macro-nested", 144 | "slab", 145 | ] 146 | 147 | [[package]] 148 | name = "hashbrown" 149 | version = "0.9.0" 150 | source = "registry+https://github.com/rust-lang/crates.io-index" 151 | checksum = "00d63df3d41950fb462ed38308eea019113ad1508da725bbedcd0fa5a85ef5f7" 152 | 153 | [[package]] 154 | name = "idna" 155 | version = "0.2.0" 156 | source = "registry+https://github.com/rust-lang/crates.io-index" 157 | checksum = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" 158 | dependencies = [ 159 | "matches", 160 | "unicode-bidi", 161 | "unicode-normalization", 162 | ] 163 | 164 | [[package]] 165 | name = "indexmap" 166 | version = "1.6.0" 167 | source = "registry+https://github.com/rust-lang/crates.io-index" 168 | checksum = "55e2e4c765aa53a0424761bf9f41aa7a6ac1efa87238f59560640e27fca028f2" 169 | dependencies = [ 170 | "autocfg", 171 | "hashbrown", 172 | ] 173 | 174 | [[package]] 175 | name = "itoa" 176 | version = "0.4.6" 177 | source = "registry+https://github.com/rust-lang/crates.io-index" 178 | checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" 179 | 180 | [[package]] 181 | name = "lazy_static" 182 | version = "1.4.0" 183 | source = "registry+https://github.com/rust-lang/crates.io-index" 184 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 185 | 186 | [[package]] 187 | name = "libc" 188 | version = "0.2.77" 189 | source = "registry+https://github.com/rust-lang/crates.io-index" 190 | checksum = "f2f96b10ec2560088a8e76961b00d47107b3a625fecb76dedb29ee7ccbf98235" 191 | 192 | [[package]] 193 | name = "log" 194 | version = "0.4.11" 195 | source = "registry+https://github.com/rust-lang/crates.io-index" 196 | checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" 197 | dependencies = [ 198 | "cfg-if", 199 | ] 200 | 201 | [[package]] 202 | name = "matches" 203 | version = "0.1.8" 204 | source = "registry+https://github.com/rust-lang/crates.io-index" 205 | checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" 206 | 207 | [[package]] 208 | name = "memchr" 209 | version = "2.3.3" 210 | source = "registry+https://github.com/rust-lang/crates.io-index" 211 | checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" 212 | 213 | [[package]] 214 | name = "once_cell" 215 | version = "1.4.1" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | checksum = "260e51e7efe62b592207e9e13a68e43692a7a279171d6ba57abd208bf23645ad" 218 | 219 | [[package]] 220 | name = "percent-encoding" 221 | version = "2.1.0" 222 | source = "registry+https://github.com/rust-lang/crates.io-index" 223 | checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" 224 | 225 | [[package]] 226 | name = "pin-project" 227 | version = "0.4.23" 228 | source = "registry+https://github.com/rust-lang/crates.io-index" 229 | checksum = "ca4433fff2ae79342e497d9f8ee990d174071408f28f726d6d83af93e58e48aa" 230 | dependencies = [ 231 | "pin-project-internal", 232 | ] 233 | 234 | [[package]] 235 | name = "pin-project-internal" 236 | version = "0.4.23" 237 | source = "registry+https://github.com/rust-lang/crates.io-index" 238 | checksum = "2c0e815c3ee9a031fdf5af21c10aa17c573c9c6a566328d99e3936c34e36461f" 239 | dependencies = [ 240 | "proc-macro2", 241 | "quote", 242 | "syn", 243 | ] 244 | 245 | [[package]] 246 | name = "pin-utils" 247 | version = "0.1.0" 248 | source = "registry+https://github.com/rust-lang/crates.io-index" 249 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 250 | 251 | [[package]] 252 | name = "proc-macro-hack" 253 | version = "0.5.18" 254 | source = "registry+https://github.com/rust-lang/crates.io-index" 255 | checksum = "99c605b9a0adc77b7211c6b1f722dcb613d68d66859a44f3d485a6da332b0598" 256 | 257 | [[package]] 258 | name = "proc-macro-nested" 259 | version = "0.1.6" 260 | source = "registry+https://github.com/rust-lang/crates.io-index" 261 | checksum = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a" 262 | 263 | [[package]] 264 | name = "proc-macro2" 265 | version = "1.0.21" 266 | source = "registry+https://github.com/rust-lang/crates.io-index" 267 | checksum = "36e28516df94f3dd551a587da5357459d9b36d945a7c37c3557928c1c2ff2a2c" 268 | dependencies = [ 269 | "unicode-xid", 270 | ] 271 | 272 | [[package]] 273 | name = "quote" 274 | version = "1.0.7" 275 | source = "registry+https://github.com/rust-lang/crates.io-index" 276 | checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" 277 | dependencies = [ 278 | "proc-macro2", 279 | ] 280 | 281 | [[package]] 282 | name = "rusty_v8" 283 | version = "0.11.0" 284 | source = "registry+https://github.com/rust-lang/crates.io-index" 285 | checksum = "8c11463988ec37b3f8cb84e4c2fe8f63058c46e07348b6d1d27b114a2b981304" 286 | dependencies = [ 287 | "bitflags", 288 | "cargo_gn", 289 | "lazy_static", 290 | "libc", 291 | "which", 292 | ] 293 | 294 | [[package]] 295 | name = "ryu" 296 | version = "1.0.5" 297 | source = "registry+https://github.com/rust-lang/crates.io-index" 298 | checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" 299 | 300 | [[package]] 301 | name = "serde" 302 | version = "1.0.116" 303 | source = "registry+https://github.com/rust-lang/crates.io-index" 304 | checksum = "96fe57af81d28386a513cbc6858332abc6117cfdb5999647c6444b8f43a370a5" 305 | dependencies = [ 306 | "serde_derive", 307 | ] 308 | 309 | [[package]] 310 | name = "serde_derive" 311 | version = "1.0.116" 312 | source = "registry+https://github.com/rust-lang/crates.io-index" 313 | checksum = "f630a6370fd8e457873b4bd2ffdae75408bc291ba72be773772a4c2a065d9ae8" 314 | dependencies = [ 315 | "proc-macro2", 316 | "quote", 317 | "syn", 318 | ] 319 | 320 | [[package]] 321 | name = "serde_json" 322 | version = "1.0.57" 323 | source = "registry+https://github.com/rust-lang/crates.io-index" 324 | checksum = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c" 325 | dependencies = [ 326 | "indexmap", 327 | "itoa", 328 | "ryu", 329 | "serde", 330 | ] 331 | 332 | [[package]] 333 | name = "slab" 334 | version = "0.4.2" 335 | source = "registry+https://github.com/rust-lang/crates.io-index" 336 | checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" 337 | 338 | [[package]] 339 | name = "smallvec" 340 | version = "1.4.2" 341 | source = "registry+https://github.com/rust-lang/crates.io-index" 342 | checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252" 343 | 344 | [[package]] 345 | name = "syn" 346 | version = "1.0.40" 347 | source = "registry+https://github.com/rust-lang/crates.io-index" 348 | checksum = "963f7d3cc59b59b9325165add223142bbf1df27655d07789f109896d353d8350" 349 | dependencies = [ 350 | "proc-macro2", 351 | "quote", 352 | "unicode-xid", 353 | ] 354 | 355 | [[package]] 356 | name = "test_plugin" 357 | version = "0.0.1" 358 | dependencies = [ 359 | "deno_core", 360 | "futures", 361 | ] 362 | 363 | [[package]] 364 | name = "thiserror" 365 | version = "1.0.20" 366 | source = "registry+https://github.com/rust-lang/crates.io-index" 367 | checksum = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08" 368 | dependencies = [ 369 | "thiserror-impl", 370 | ] 371 | 372 | [[package]] 373 | name = "thiserror-impl" 374 | version = "1.0.20" 375 | source = "registry+https://github.com/rust-lang/crates.io-index" 376 | checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793" 377 | dependencies = [ 378 | "proc-macro2", 379 | "quote", 380 | "syn", 381 | ] 382 | 383 | [[package]] 384 | name = "tinyvec" 385 | version = "0.3.4" 386 | source = "registry+https://github.com/rust-lang/crates.io-index" 387 | checksum = "238ce071d267c5710f9d31451efec16c5ee22de34df17cc05e56cbc92e967117" 388 | 389 | [[package]] 390 | name = "unicode-bidi" 391 | version = "0.3.4" 392 | source = "registry+https://github.com/rust-lang/crates.io-index" 393 | checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" 394 | dependencies = [ 395 | "matches", 396 | ] 397 | 398 | [[package]] 399 | name = "unicode-normalization" 400 | version = "0.1.13" 401 | source = "registry+https://github.com/rust-lang/crates.io-index" 402 | checksum = "6fb19cf769fa8c6a80a162df694621ebeb4dafb606470b2b2fce0be40a98a977" 403 | dependencies = [ 404 | "tinyvec", 405 | ] 406 | 407 | [[package]] 408 | name = "unicode-xid" 409 | version = "0.2.1" 410 | source = "registry+https://github.com/rust-lang/crates.io-index" 411 | checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" 412 | 413 | [[package]] 414 | name = "url" 415 | version = "2.1.1" 416 | source = "registry+https://github.com/rust-lang/crates.io-index" 417 | checksum = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb" 418 | dependencies = [ 419 | "idna", 420 | "matches", 421 | "percent-encoding", 422 | "serde", 423 | ] 424 | 425 | [[package]] 426 | name = "which" 427 | version = "4.0.2" 428 | source = "registry+https://github.com/rust-lang/crates.io-index" 429 | checksum = "87c14ef7e1b8b8ecfc75d5eca37949410046e66f15d185c01d70824f1f8111ef" 430 | dependencies = [ 431 | "libc", 432 | "thiserror", 433 | ] 434 | --------------------------------------------------------------------------------