├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── fn.js └── src └── main.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "ahash" 7 | version = "0.7.6" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" 10 | dependencies = [ 11 | "getrandom", 12 | "once_cell", 13 | "version_check", 14 | ] 15 | 16 | [[package]] 17 | name = "aho-corasick" 18 | version = "0.7.19" 19 | source = "registry+https://github.com/rust-lang/crates.io-index" 20 | checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" 21 | dependencies = [ 22 | "memchr", 23 | ] 24 | 25 | [[package]] 26 | name = "ansi_term" 27 | version = "0.12.1" 28 | source = "registry+https://github.com/rust-lang/crates.io-index" 29 | checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" 30 | dependencies = [ 31 | "winapi", 32 | ] 33 | 34 | [[package]] 35 | name = "anyhow" 36 | version = "1.0.65" 37 | source = "registry+https://github.com/rust-lang/crates.io-index" 38 | checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602" 39 | 40 | [[package]] 41 | name = "async-trait" 42 | version = "0.1.57" 43 | source = "registry+https://github.com/rust-lang/crates.io-index" 44 | checksum = "76464446b8bc32758d7e88ee1a804d9914cd9b1cb264c029899680b0be29826f" 45 | dependencies = [ 46 | "proc-macro2", 47 | "quote", 48 | "syn", 49 | ] 50 | 51 | [[package]] 52 | name = "autocfg" 53 | version = "1.1.0" 54 | source = "registry+https://github.com/rust-lang/crates.io-index" 55 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 56 | 57 | [[package]] 58 | name = "axum" 59 | version = "0.6.0-rc.1" 60 | source = "registry+https://github.com/rust-lang/crates.io-index" 61 | checksum = "d49958d54e0bab71947eb00a33175eb9164ccc0ea4c262d2139c5f8899a3616e" 62 | dependencies = [ 63 | "async-trait", 64 | "axum-core", 65 | "bitflags", 66 | "bytes", 67 | "futures-util", 68 | "http", 69 | "http-body", 70 | "hyper", 71 | "itoa", 72 | "matchit", 73 | "memchr", 74 | "mime", 75 | "percent-encoding", 76 | "pin-project-lite", 77 | "serde", 78 | "serde_json", 79 | "serde_urlencoded", 80 | "sync_wrapper", 81 | "tokio", 82 | "tower", 83 | "tower-http", 84 | "tower-layer", 85 | "tower-service", 86 | ] 87 | 88 | [[package]] 89 | name = "axum-core" 90 | version = "0.3.0-rc.1" 91 | source = "registry+https://github.com/rust-lang/crates.io-index" 92 | checksum = "5e52ebadfce2f1e7fec9b2dd920952477ffeac9f07a5c492c0cbba2bb22cd294" 93 | dependencies = [ 94 | "async-trait", 95 | "bytes", 96 | "futures-util", 97 | "http", 98 | "http-body", 99 | "mime", 100 | ] 101 | 102 | [[package]] 103 | name = "base64" 104 | version = "0.11.0" 105 | source = "registry+https://github.com/rust-lang/crates.io-index" 106 | checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" 107 | 108 | [[package]] 109 | name = "bitflags" 110 | version = "1.3.2" 111 | source = "registry+https://github.com/rust-lang/crates.io-index" 112 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 113 | 114 | [[package]] 115 | name = "bytes" 116 | version = "1.2.1" 117 | source = "registry+https://github.com/rust-lang/crates.io-index" 118 | checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" 119 | 120 | [[package]] 121 | name = "cc" 122 | version = "1.0.73" 123 | source = "registry+https://github.com/rust-lang/crates.io-index" 124 | checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" 125 | 126 | [[package]] 127 | name = "cfg-if" 128 | version = "1.0.0" 129 | source = "registry+https://github.com/rust-lang/crates.io-index" 130 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 131 | 132 | [[package]] 133 | name = "convert_case" 134 | version = "0.4.0" 135 | source = "registry+https://github.com/rust-lang/crates.io-index" 136 | checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" 137 | 138 | [[package]] 139 | name = "deno_core" 140 | version = "0.149.0" 141 | source = "registry+https://github.com/rust-lang/crates.io-index" 142 | checksum = "79b0fbe1787762b87506922f9b4f3493c28c5f67fd71391bbdeeb11c77e2c8e2" 143 | dependencies = [ 144 | "anyhow", 145 | "deno_ops", 146 | "futures", 147 | "indexmap", 148 | "libc", 149 | "log", 150 | "once_cell", 151 | "parking_lot", 152 | "pin-project", 153 | "serde", 154 | "serde_json", 155 | "serde_v8", 156 | "sourcemap", 157 | "url", 158 | "v8", 159 | ] 160 | 161 | [[package]] 162 | name = "deno_ops" 163 | version = "0.27.0" 164 | source = "registry+https://github.com/rust-lang/crates.io-index" 165 | checksum = "27aa39afc249c59dabc4f207278380502012afcbac7aff13cfa879f794402dbd" 166 | dependencies = [ 167 | "once_cell", 168 | "proc-macro-crate", 169 | "proc-macro2", 170 | "quote", 171 | "regex", 172 | "syn", 173 | ] 174 | 175 | [[package]] 176 | name = "derive_more" 177 | version = "0.99.17" 178 | source = "registry+https://github.com/rust-lang/crates.io-index" 179 | checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" 180 | dependencies = [ 181 | "convert_case", 182 | "proc-macro2", 183 | "quote", 184 | "rustc_version 0.4.0", 185 | "syn", 186 | ] 187 | 188 | [[package]] 189 | name = "either" 190 | version = "1.8.0" 191 | source = "registry+https://github.com/rust-lang/crates.io-index" 192 | checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" 193 | 194 | [[package]] 195 | name = "fallible-iterator" 196 | version = "0.2.0" 197 | source = "registry+https://github.com/rust-lang/crates.io-index" 198 | checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" 199 | 200 | [[package]] 201 | name = "fallible-streaming-iterator" 202 | version = "0.1.9" 203 | source = "registry+https://github.com/rust-lang/crates.io-index" 204 | checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" 205 | 206 | [[package]] 207 | name = "fnv" 208 | version = "1.0.7" 209 | source = "registry+https://github.com/rust-lang/crates.io-index" 210 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 211 | 212 | [[package]] 213 | name = "form_urlencoded" 214 | version = "1.1.0" 215 | source = "registry+https://github.com/rust-lang/crates.io-index" 216 | checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" 217 | dependencies = [ 218 | "percent-encoding", 219 | ] 220 | 221 | [[package]] 222 | name = "fslock" 223 | version = "0.1.8" 224 | source = "registry+https://github.com/rust-lang/crates.io-index" 225 | checksum = "57eafdd0c16f57161105ae1b98a1238f97645f2f588438b2949c99a2af9616bf" 226 | dependencies = [ 227 | "libc", 228 | "winapi", 229 | ] 230 | 231 | [[package]] 232 | name = "futures" 233 | version = "0.3.24" 234 | source = "registry+https://github.com/rust-lang/crates.io-index" 235 | checksum = "7f21eda599937fba36daeb58a22e8f5cee2d14c4a17b5b7739c7c8e5e3b8230c" 236 | dependencies = [ 237 | "futures-channel", 238 | "futures-core", 239 | "futures-executor", 240 | "futures-io", 241 | "futures-sink", 242 | "futures-task", 243 | "futures-util", 244 | ] 245 | 246 | [[package]] 247 | name = "futures-channel" 248 | version = "0.3.24" 249 | source = "registry+https://github.com/rust-lang/crates.io-index" 250 | checksum = "30bdd20c28fadd505d0fd6712cdfcb0d4b5648baf45faef7f852afb2399bb050" 251 | dependencies = [ 252 | "futures-core", 253 | "futures-sink", 254 | ] 255 | 256 | [[package]] 257 | name = "futures-core" 258 | version = "0.3.24" 259 | source = "registry+https://github.com/rust-lang/crates.io-index" 260 | checksum = "4e5aa3de05362c3fb88de6531e6296e85cde7739cccad4b9dfeeb7f6ebce56bf" 261 | 262 | [[package]] 263 | name = "futures-executor" 264 | version = "0.3.24" 265 | source = "registry+https://github.com/rust-lang/crates.io-index" 266 | checksum = "9ff63c23854bee61b6e9cd331d523909f238fc7636290b96826e9cfa5faa00ab" 267 | dependencies = [ 268 | "futures-core", 269 | "futures-task", 270 | "futures-util", 271 | ] 272 | 273 | [[package]] 274 | name = "futures-io" 275 | version = "0.3.24" 276 | source = "registry+https://github.com/rust-lang/crates.io-index" 277 | checksum = "bbf4d2a7a308fd4578637c0b17c7e1c7ba127b8f6ba00b29f717e9655d85eb68" 278 | 279 | [[package]] 280 | name = "futures-macro" 281 | version = "0.3.24" 282 | source = "registry+https://github.com/rust-lang/crates.io-index" 283 | checksum = "42cd15d1c7456c04dbdf7e88bcd69760d74f3a798d6444e16974b505b0e62f17" 284 | dependencies = [ 285 | "proc-macro2", 286 | "quote", 287 | "syn", 288 | ] 289 | 290 | [[package]] 291 | name = "futures-sink" 292 | version = "0.3.24" 293 | source = "registry+https://github.com/rust-lang/crates.io-index" 294 | checksum = "21b20ba5a92e727ba30e72834706623d94ac93a725410b6a6b6fbc1b07f7ba56" 295 | 296 | [[package]] 297 | name = "futures-task" 298 | version = "0.3.24" 299 | source = "registry+https://github.com/rust-lang/crates.io-index" 300 | checksum = "a6508c467c73851293f390476d4491cf4d227dbabcd4170f3bb6044959b294f1" 301 | 302 | [[package]] 303 | name = "futures-util" 304 | version = "0.3.24" 305 | source = "registry+https://github.com/rust-lang/crates.io-index" 306 | checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90" 307 | dependencies = [ 308 | "futures-channel", 309 | "futures-core", 310 | "futures-io", 311 | "futures-macro", 312 | "futures-sink", 313 | "futures-task", 314 | "memchr", 315 | "pin-project-lite", 316 | "pin-utils", 317 | "slab", 318 | ] 319 | 320 | [[package]] 321 | name = "getrandom" 322 | version = "0.2.7" 323 | source = "registry+https://github.com/rust-lang/crates.io-index" 324 | checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" 325 | dependencies = [ 326 | "cfg-if", 327 | "libc", 328 | "wasi", 329 | ] 330 | 331 | [[package]] 332 | name = "hashbrown" 333 | version = "0.12.3" 334 | source = "registry+https://github.com/rust-lang/crates.io-index" 335 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 336 | dependencies = [ 337 | "ahash", 338 | ] 339 | 340 | [[package]] 341 | name = "hashlink" 342 | version = "0.8.0" 343 | source = "registry+https://github.com/rust-lang/crates.io-index" 344 | checksum = "d452c155cb93fecdfb02a73dd57b5d8e442c2063bd7aac72f1bc5e4263a43086" 345 | dependencies = [ 346 | "hashbrown", 347 | ] 348 | 349 | [[package]] 350 | name = "hermit-abi" 351 | version = "0.1.19" 352 | source = "registry+https://github.com/rust-lang/crates.io-index" 353 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" 354 | dependencies = [ 355 | "libc", 356 | ] 357 | 358 | [[package]] 359 | name = "http" 360 | version = "0.2.8" 361 | source = "registry+https://github.com/rust-lang/crates.io-index" 362 | checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" 363 | dependencies = [ 364 | "bytes", 365 | "fnv", 366 | "itoa", 367 | ] 368 | 369 | [[package]] 370 | name = "http-body" 371 | version = "0.4.5" 372 | source = "registry+https://github.com/rust-lang/crates.io-index" 373 | checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" 374 | dependencies = [ 375 | "bytes", 376 | "http", 377 | "pin-project-lite", 378 | ] 379 | 380 | [[package]] 381 | name = "http-range-header" 382 | version = "0.3.0" 383 | source = "registry+https://github.com/rust-lang/crates.io-index" 384 | checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29" 385 | 386 | [[package]] 387 | name = "httparse" 388 | version = "1.8.0" 389 | source = "registry+https://github.com/rust-lang/crates.io-index" 390 | checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" 391 | 392 | [[package]] 393 | name = "httpdate" 394 | version = "1.0.2" 395 | source = "registry+https://github.com/rust-lang/crates.io-index" 396 | checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" 397 | 398 | [[package]] 399 | name = "hyper" 400 | version = "0.14.20" 401 | source = "registry+https://github.com/rust-lang/crates.io-index" 402 | checksum = "02c929dc5c39e335a03c405292728118860721b10190d98c2a0f0efd5baafbac" 403 | dependencies = [ 404 | "bytes", 405 | "futures-channel", 406 | "futures-core", 407 | "futures-util", 408 | "http", 409 | "http-body", 410 | "httparse", 411 | "httpdate", 412 | "itoa", 413 | "pin-project-lite", 414 | "socket2", 415 | "tokio", 416 | "tower-service", 417 | "tracing", 418 | "want", 419 | ] 420 | 421 | [[package]] 422 | name = "idna" 423 | version = "0.3.0" 424 | source = "registry+https://github.com/rust-lang/crates.io-index" 425 | checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" 426 | dependencies = [ 427 | "unicode-bidi", 428 | "unicode-normalization", 429 | ] 430 | 431 | [[package]] 432 | name = "if_chain" 433 | version = "1.0.2" 434 | source = "registry+https://github.com/rust-lang/crates.io-index" 435 | checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" 436 | 437 | [[package]] 438 | name = "indexmap" 439 | version = "1.9.1" 440 | source = "registry+https://github.com/rust-lang/crates.io-index" 441 | checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" 442 | dependencies = [ 443 | "autocfg", 444 | "hashbrown", 445 | ] 446 | 447 | [[package]] 448 | name = "itoa" 449 | version = "1.0.3" 450 | source = "registry+https://github.com/rust-lang/crates.io-index" 451 | checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" 452 | 453 | [[package]] 454 | name = "lazy_static" 455 | version = "1.4.0" 456 | source = "registry+https://github.com/rust-lang/crates.io-index" 457 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 458 | 459 | [[package]] 460 | name = "libc" 461 | version = "0.2.132" 462 | source = "registry+https://github.com/rust-lang/crates.io-index" 463 | checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" 464 | 465 | [[package]] 466 | name = "libsqlite3-sys" 467 | version = "0.25.1" 468 | source = "registry+https://github.com/rust-lang/crates.io-index" 469 | checksum = "9f0455f2c1bc9a7caa792907026e469c1d91761fb0ea37cbb16427c77280cf35" 470 | dependencies = [ 471 | "cc", 472 | "pkg-config", 473 | "vcpkg", 474 | ] 475 | 476 | [[package]] 477 | name = "lock_api" 478 | version = "0.4.8" 479 | source = "registry+https://github.com/rust-lang/crates.io-index" 480 | checksum = "9f80bf5aacaf25cbfc8210d1cfb718f2bf3b11c4c54e5afe36c236853a8ec390" 481 | dependencies = [ 482 | "autocfg", 483 | "scopeguard", 484 | ] 485 | 486 | [[package]] 487 | name = "log" 488 | version = "0.4.17" 489 | source = "registry+https://github.com/rust-lang/crates.io-index" 490 | checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" 491 | dependencies = [ 492 | "cfg-if", 493 | ] 494 | 495 | [[package]] 496 | name = "matchers" 497 | version = "0.1.0" 498 | source = "registry+https://github.com/rust-lang/crates.io-index" 499 | checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" 500 | dependencies = [ 501 | "regex-automata", 502 | ] 503 | 504 | [[package]] 505 | name = "matchit" 506 | version = "0.6.0" 507 | source = "registry+https://github.com/rust-lang/crates.io-index" 508 | checksum = "3dfc802da7b1cf80aefffa0c7b2f77247c8b32206cc83c270b61264f5b360a80" 509 | 510 | [[package]] 511 | name = "memchr" 512 | version = "2.5.0" 513 | source = "registry+https://github.com/rust-lang/crates.io-index" 514 | checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" 515 | 516 | [[package]] 517 | name = "mime" 518 | version = "0.3.16" 519 | source = "registry+https://github.com/rust-lang/crates.io-index" 520 | checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" 521 | 522 | [[package]] 523 | name = "mio" 524 | version = "0.8.4" 525 | source = "registry+https://github.com/rust-lang/crates.io-index" 526 | checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" 527 | dependencies = [ 528 | "libc", 529 | "log", 530 | "wasi", 531 | "windows-sys", 532 | ] 533 | 534 | [[package]] 535 | name = "num_cpus" 536 | version = "1.13.1" 537 | source = "registry+https://github.com/rust-lang/crates.io-index" 538 | checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" 539 | dependencies = [ 540 | "hermit-abi", 541 | "libc", 542 | ] 543 | 544 | [[package]] 545 | name = "num_threads" 546 | version = "0.1.6" 547 | source = "registry+https://github.com/rust-lang/crates.io-index" 548 | checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" 549 | dependencies = [ 550 | "libc", 551 | ] 552 | 553 | [[package]] 554 | name = "once_cell" 555 | version = "1.14.0" 556 | source = "registry+https://github.com/rust-lang/crates.io-index" 557 | checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0" 558 | 559 | [[package]] 560 | name = "parking_lot" 561 | version = "0.12.1" 562 | source = "registry+https://github.com/rust-lang/crates.io-index" 563 | checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" 564 | dependencies = [ 565 | "lock_api", 566 | "parking_lot_core", 567 | ] 568 | 569 | [[package]] 570 | name = "parking_lot_core" 571 | version = "0.9.3" 572 | source = "registry+https://github.com/rust-lang/crates.io-index" 573 | checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" 574 | dependencies = [ 575 | "cfg-if", 576 | "libc", 577 | "redox_syscall", 578 | "smallvec", 579 | "windows-sys", 580 | ] 581 | 582 | [[package]] 583 | name = "percent-encoding" 584 | version = "2.2.0" 585 | source = "registry+https://github.com/rust-lang/crates.io-index" 586 | checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" 587 | 588 | [[package]] 589 | name = "pin-project" 590 | version = "1.0.12" 591 | source = "registry+https://github.com/rust-lang/crates.io-index" 592 | checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" 593 | dependencies = [ 594 | "pin-project-internal", 595 | ] 596 | 597 | [[package]] 598 | name = "pin-project-internal" 599 | version = "1.0.12" 600 | source = "registry+https://github.com/rust-lang/crates.io-index" 601 | checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" 602 | dependencies = [ 603 | "proc-macro2", 604 | "quote", 605 | "syn", 606 | ] 607 | 608 | [[package]] 609 | name = "pin-project-lite" 610 | version = "0.2.9" 611 | source = "registry+https://github.com/rust-lang/crates.io-index" 612 | checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" 613 | 614 | [[package]] 615 | name = "pin-utils" 616 | version = "0.1.0" 617 | source = "registry+https://github.com/rust-lang/crates.io-index" 618 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 619 | 620 | [[package]] 621 | name = "pkg-config" 622 | version = "0.3.25" 623 | source = "registry+https://github.com/rust-lang/crates.io-index" 624 | checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" 625 | 626 | [[package]] 627 | name = "proc-macro-crate" 628 | version = "1.2.1" 629 | source = "registry+https://github.com/rust-lang/crates.io-index" 630 | checksum = "eda0fc3b0fb7c975631757e14d9049da17374063edb6ebbcbc54d880d4fe94e9" 631 | dependencies = [ 632 | "once_cell", 633 | "thiserror", 634 | "toml", 635 | ] 636 | 637 | [[package]] 638 | name = "proc-macro2" 639 | version = "1.0.43" 640 | source = "registry+https://github.com/rust-lang/crates.io-index" 641 | checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" 642 | dependencies = [ 643 | "unicode-ident", 644 | ] 645 | 646 | [[package]] 647 | name = "quote" 648 | version = "1.0.21" 649 | source = "registry+https://github.com/rust-lang/crates.io-index" 650 | checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" 651 | dependencies = [ 652 | "proc-macro2", 653 | ] 654 | 655 | [[package]] 656 | name = "redox_syscall" 657 | version = "0.2.16" 658 | source = "registry+https://github.com/rust-lang/crates.io-index" 659 | checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" 660 | dependencies = [ 661 | "bitflags", 662 | ] 663 | 664 | [[package]] 665 | name = "regex" 666 | version = "1.6.0" 667 | source = "registry+https://github.com/rust-lang/crates.io-index" 668 | checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" 669 | dependencies = [ 670 | "aho-corasick", 671 | "memchr", 672 | "regex-syntax", 673 | ] 674 | 675 | [[package]] 676 | name = "regex-automata" 677 | version = "0.1.10" 678 | source = "registry+https://github.com/rust-lang/crates.io-index" 679 | checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" 680 | dependencies = [ 681 | "regex-syntax", 682 | ] 683 | 684 | [[package]] 685 | name = "regex-syntax" 686 | version = "0.6.27" 687 | source = "registry+https://github.com/rust-lang/crates.io-index" 688 | checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" 689 | 690 | [[package]] 691 | name = "rusqlite" 692 | version = "0.28.0" 693 | source = "registry+https://github.com/rust-lang/crates.io-index" 694 | checksum = "01e213bc3ecb39ac32e81e51ebe31fd888a940515173e3a18a35f8c6e896422a" 695 | dependencies = [ 696 | "bitflags", 697 | "fallible-iterator", 698 | "fallible-streaming-iterator", 699 | "hashlink", 700 | "libsqlite3-sys", 701 | "smallvec", 702 | ] 703 | 704 | [[package]] 705 | name = "rustc_version" 706 | version = "0.2.3" 707 | source = "registry+https://github.com/rust-lang/crates.io-index" 708 | checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" 709 | dependencies = [ 710 | "semver 0.9.0", 711 | ] 712 | 713 | [[package]] 714 | name = "rustc_version" 715 | version = "0.4.0" 716 | source = "registry+https://github.com/rust-lang/crates.io-index" 717 | checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" 718 | dependencies = [ 719 | "semver 1.0.13", 720 | ] 721 | 722 | [[package]] 723 | name = "ryu" 724 | version = "1.0.11" 725 | source = "registry+https://github.com/rust-lang/crates.io-index" 726 | checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" 727 | 728 | [[package]] 729 | name = "scopeguard" 730 | version = "1.1.0" 731 | source = "registry+https://github.com/rust-lang/crates.io-index" 732 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 733 | 734 | [[package]] 735 | name = "semver" 736 | version = "0.9.0" 737 | source = "registry+https://github.com/rust-lang/crates.io-index" 738 | checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" 739 | dependencies = [ 740 | "semver-parser", 741 | ] 742 | 743 | [[package]] 744 | name = "semver" 745 | version = "1.0.13" 746 | source = "registry+https://github.com/rust-lang/crates.io-index" 747 | checksum = "93f6841e709003d68bb2deee8c343572bf446003ec20a583e76f7b15cebf3711" 748 | 749 | [[package]] 750 | name = "semver-parser" 751 | version = "0.7.0" 752 | source = "registry+https://github.com/rust-lang/crates.io-index" 753 | checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" 754 | 755 | [[package]] 756 | name = "serde" 757 | version = "1.0.144" 758 | source = "registry+https://github.com/rust-lang/crates.io-index" 759 | checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860" 760 | dependencies = [ 761 | "serde_derive", 762 | ] 763 | 764 | [[package]] 765 | name = "serde_bytes" 766 | version = "0.11.7" 767 | source = "registry+https://github.com/rust-lang/crates.io-index" 768 | checksum = "cfc50e8183eeeb6178dcb167ae34a8051d63535023ae38b5d8d12beae193d37b" 769 | dependencies = [ 770 | "serde", 771 | ] 772 | 773 | [[package]] 774 | name = "serde_derive" 775 | version = "1.0.144" 776 | source = "registry+https://github.com/rust-lang/crates.io-index" 777 | checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00" 778 | dependencies = [ 779 | "proc-macro2", 780 | "quote", 781 | "syn", 782 | ] 783 | 784 | [[package]] 785 | name = "serde_json" 786 | version = "1.0.85" 787 | source = "registry+https://github.com/rust-lang/crates.io-index" 788 | checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" 789 | dependencies = [ 790 | "indexmap", 791 | "itoa", 792 | "ryu", 793 | "serde", 794 | ] 795 | 796 | [[package]] 797 | name = "serde_urlencoded" 798 | version = "0.7.1" 799 | source = "registry+https://github.com/rust-lang/crates.io-index" 800 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 801 | dependencies = [ 802 | "form_urlencoded", 803 | "itoa", 804 | "ryu", 805 | "serde", 806 | ] 807 | 808 | [[package]] 809 | name = "serde_v8" 810 | version = "0.60.0" 811 | source = "registry+https://github.com/rust-lang/crates.io-index" 812 | checksum = "7248a65d40bbc0326da39fba39f91b23b84a855fc24bd1917de980cf2ec5f07d" 813 | dependencies = [ 814 | "bytes", 815 | "derive_more", 816 | "serde", 817 | "serde_bytes", 818 | "smallvec", 819 | "v8", 820 | ] 821 | 822 | [[package]] 823 | name = "serverless" 824 | version = "0.1.0" 825 | dependencies = [ 826 | "axum", 827 | "deno_core", 828 | "rusqlite", 829 | "serde", 830 | "tokio", 831 | "tracing", 832 | "tracing-subscriber", 833 | ] 834 | 835 | [[package]] 836 | name = "sharded-slab" 837 | version = "0.1.4" 838 | source = "registry+https://github.com/rust-lang/crates.io-index" 839 | checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" 840 | dependencies = [ 841 | "lazy_static", 842 | ] 843 | 844 | [[package]] 845 | name = "signal-hook-registry" 846 | version = "1.4.0" 847 | source = "registry+https://github.com/rust-lang/crates.io-index" 848 | checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" 849 | dependencies = [ 850 | "libc", 851 | ] 852 | 853 | [[package]] 854 | name = "slab" 855 | version = "0.4.7" 856 | source = "registry+https://github.com/rust-lang/crates.io-index" 857 | checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" 858 | dependencies = [ 859 | "autocfg", 860 | ] 861 | 862 | [[package]] 863 | name = "smallvec" 864 | version = "1.9.0" 865 | source = "registry+https://github.com/rust-lang/crates.io-index" 866 | checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" 867 | 868 | [[package]] 869 | name = "socket2" 870 | version = "0.4.7" 871 | source = "registry+https://github.com/rust-lang/crates.io-index" 872 | checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" 873 | dependencies = [ 874 | "libc", 875 | "winapi", 876 | ] 877 | 878 | [[package]] 879 | name = "sourcemap" 880 | version = "6.0.1" 881 | source = "registry+https://github.com/rust-lang/crates.io-index" 882 | checksum = "6e031f2463ecbdd5f34c950f89f5c1e1032f22c0f8e3dc4bdb2e8b6658cf61eb" 883 | dependencies = [ 884 | "base64", 885 | "if_chain", 886 | "lazy_static", 887 | "regex", 888 | "rustc_version 0.2.3", 889 | "serde", 890 | "serde_json", 891 | "url", 892 | ] 893 | 894 | [[package]] 895 | name = "syn" 896 | version = "1.0.99" 897 | source = "registry+https://github.com/rust-lang/crates.io-index" 898 | checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13" 899 | dependencies = [ 900 | "proc-macro2", 901 | "quote", 902 | "unicode-ident", 903 | ] 904 | 905 | [[package]] 906 | name = "sync_wrapper" 907 | version = "0.1.1" 908 | source = "registry+https://github.com/rust-lang/crates.io-index" 909 | checksum = "20518fe4a4c9acf048008599e464deb21beeae3d3578418951a189c235a7a9a8" 910 | 911 | [[package]] 912 | name = "thiserror" 913 | version = "1.0.34" 914 | source = "registry+https://github.com/rust-lang/crates.io-index" 915 | checksum = "8c1b05ca9d106ba7d2e31a9dab4a64e7be2cce415321966ea3132c49a656e252" 916 | dependencies = [ 917 | "thiserror-impl", 918 | ] 919 | 920 | [[package]] 921 | name = "thiserror-impl" 922 | version = "1.0.34" 923 | source = "registry+https://github.com/rust-lang/crates.io-index" 924 | checksum = "e8f2591983642de85c921015f3f070c665a197ed69e417af436115e3a1407487" 925 | dependencies = [ 926 | "proc-macro2", 927 | "quote", 928 | "syn", 929 | ] 930 | 931 | [[package]] 932 | name = "thread_local" 933 | version = "1.1.4" 934 | source = "registry+https://github.com/rust-lang/crates.io-index" 935 | checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" 936 | dependencies = [ 937 | "once_cell", 938 | ] 939 | 940 | [[package]] 941 | name = "time" 942 | version = "0.3.14" 943 | source = "registry+https://github.com/rust-lang/crates.io-index" 944 | checksum = "3c3f9a28b618c3a6b9251b6908e9c99e04b9e5c02e6581ccbb67d59c34ef7f9b" 945 | dependencies = [ 946 | "itoa", 947 | "libc", 948 | "num_threads", 949 | ] 950 | 951 | [[package]] 952 | name = "tinyvec" 953 | version = "1.6.0" 954 | source = "registry+https://github.com/rust-lang/crates.io-index" 955 | checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" 956 | dependencies = [ 957 | "tinyvec_macros", 958 | ] 959 | 960 | [[package]] 961 | name = "tinyvec_macros" 962 | version = "0.1.0" 963 | source = "registry+https://github.com/rust-lang/crates.io-index" 964 | checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" 965 | 966 | [[package]] 967 | name = "tokio" 968 | version = "1.21.0" 969 | source = "registry+https://github.com/rust-lang/crates.io-index" 970 | checksum = "89797afd69d206ccd11fb0ea560a44bbb87731d020670e79416d442919257d42" 971 | dependencies = [ 972 | "autocfg", 973 | "bytes", 974 | "libc", 975 | "memchr", 976 | "mio", 977 | "num_cpus", 978 | "once_cell", 979 | "parking_lot", 980 | "pin-project-lite", 981 | "signal-hook-registry", 982 | "socket2", 983 | "tokio-macros", 984 | "winapi", 985 | ] 986 | 987 | [[package]] 988 | name = "tokio-macros" 989 | version = "1.8.0" 990 | source = "registry+https://github.com/rust-lang/crates.io-index" 991 | checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" 992 | dependencies = [ 993 | "proc-macro2", 994 | "quote", 995 | "syn", 996 | ] 997 | 998 | [[package]] 999 | name = "toml" 1000 | version = "0.5.9" 1001 | source = "registry+https://github.com/rust-lang/crates.io-index" 1002 | checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" 1003 | dependencies = [ 1004 | "serde", 1005 | ] 1006 | 1007 | [[package]] 1008 | name = "tower" 1009 | version = "0.4.13" 1010 | source = "registry+https://github.com/rust-lang/crates.io-index" 1011 | checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" 1012 | dependencies = [ 1013 | "futures-core", 1014 | "futures-util", 1015 | "pin-project", 1016 | "pin-project-lite", 1017 | "tokio", 1018 | "tower-layer", 1019 | "tower-service", 1020 | "tracing", 1021 | ] 1022 | 1023 | [[package]] 1024 | name = "tower-http" 1025 | version = "0.3.4" 1026 | source = "registry+https://github.com/rust-lang/crates.io-index" 1027 | checksum = "3c530c8675c1dbf98facee631536fa116b5fb6382d7dd6dc1b118d970eafe3ba" 1028 | dependencies = [ 1029 | "bitflags", 1030 | "bytes", 1031 | "futures-core", 1032 | "futures-util", 1033 | "http", 1034 | "http-body", 1035 | "http-range-header", 1036 | "pin-project-lite", 1037 | "tower", 1038 | "tower-layer", 1039 | "tower-service", 1040 | ] 1041 | 1042 | [[package]] 1043 | name = "tower-layer" 1044 | version = "0.3.1" 1045 | source = "registry+https://github.com/rust-lang/crates.io-index" 1046 | checksum = "343bc9466d3fe6b0f960ef45960509f84480bf4fd96f92901afe7ff3df9d3a62" 1047 | 1048 | [[package]] 1049 | name = "tower-service" 1050 | version = "0.3.2" 1051 | source = "registry+https://github.com/rust-lang/crates.io-index" 1052 | checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" 1053 | 1054 | [[package]] 1055 | name = "tracing" 1056 | version = "0.1.36" 1057 | source = "registry+https://github.com/rust-lang/crates.io-index" 1058 | checksum = "2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307" 1059 | dependencies = [ 1060 | "cfg-if", 1061 | "log", 1062 | "pin-project-lite", 1063 | "tracing-attributes", 1064 | "tracing-core", 1065 | ] 1066 | 1067 | [[package]] 1068 | name = "tracing-attributes" 1069 | version = "0.1.22" 1070 | source = "registry+https://github.com/rust-lang/crates.io-index" 1071 | checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2" 1072 | dependencies = [ 1073 | "proc-macro2", 1074 | "quote", 1075 | "syn", 1076 | ] 1077 | 1078 | [[package]] 1079 | name = "tracing-core" 1080 | version = "0.1.29" 1081 | source = "registry+https://github.com/rust-lang/crates.io-index" 1082 | checksum = "5aeea4303076558a00714b823f9ad67d58a3bbda1df83d8827d21193156e22f7" 1083 | dependencies = [ 1084 | "once_cell", 1085 | "valuable", 1086 | ] 1087 | 1088 | [[package]] 1089 | name = "tracing-log" 1090 | version = "0.1.3" 1091 | source = "registry+https://github.com/rust-lang/crates.io-index" 1092 | checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" 1093 | dependencies = [ 1094 | "lazy_static", 1095 | "log", 1096 | "tracing-core", 1097 | ] 1098 | 1099 | [[package]] 1100 | name = "tracing-subscriber" 1101 | version = "0.3.15" 1102 | source = "registry+https://github.com/rust-lang/crates.io-index" 1103 | checksum = "60db860322da191b40952ad9affe65ea23e7dd6a5c442c2c42865810c6ab8e6b" 1104 | dependencies = [ 1105 | "ansi_term", 1106 | "matchers", 1107 | "once_cell", 1108 | "regex", 1109 | "sharded-slab", 1110 | "smallvec", 1111 | "thread_local", 1112 | "time", 1113 | "tracing", 1114 | "tracing-core", 1115 | "tracing-log", 1116 | ] 1117 | 1118 | [[package]] 1119 | name = "try-lock" 1120 | version = "0.2.3" 1121 | source = "registry+https://github.com/rust-lang/crates.io-index" 1122 | checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" 1123 | 1124 | [[package]] 1125 | name = "unicode-bidi" 1126 | version = "0.3.8" 1127 | source = "registry+https://github.com/rust-lang/crates.io-index" 1128 | checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" 1129 | 1130 | [[package]] 1131 | name = "unicode-ident" 1132 | version = "1.0.3" 1133 | source = "registry+https://github.com/rust-lang/crates.io-index" 1134 | checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf" 1135 | 1136 | [[package]] 1137 | name = "unicode-normalization" 1138 | version = "0.1.21" 1139 | source = "registry+https://github.com/rust-lang/crates.io-index" 1140 | checksum = "854cbdc4f7bc6ae19c820d44abdc3277ac3e1b2b93db20a636825d9322fb60e6" 1141 | dependencies = [ 1142 | "tinyvec", 1143 | ] 1144 | 1145 | [[package]] 1146 | name = "url" 1147 | version = "2.3.1" 1148 | source = "registry+https://github.com/rust-lang/crates.io-index" 1149 | checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" 1150 | dependencies = [ 1151 | "form_urlencoded", 1152 | "idna", 1153 | "percent-encoding", 1154 | "serde", 1155 | ] 1156 | 1157 | [[package]] 1158 | name = "v8" 1159 | version = "0.49.0" 1160 | source = "registry+https://github.com/rust-lang/crates.io-index" 1161 | checksum = "5a1cbad73336d67babcbe5e3b03c907c8d2ff77fc6f997570af219bbd9fdb6ce" 1162 | dependencies = [ 1163 | "bitflags", 1164 | "fslock", 1165 | "lazy_static", 1166 | "libc", 1167 | "which", 1168 | ] 1169 | 1170 | [[package]] 1171 | name = "valuable" 1172 | version = "0.1.0" 1173 | source = "registry+https://github.com/rust-lang/crates.io-index" 1174 | checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" 1175 | 1176 | [[package]] 1177 | name = "vcpkg" 1178 | version = "0.2.15" 1179 | source = "registry+https://github.com/rust-lang/crates.io-index" 1180 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 1181 | 1182 | [[package]] 1183 | name = "version_check" 1184 | version = "0.9.4" 1185 | source = "registry+https://github.com/rust-lang/crates.io-index" 1186 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 1187 | 1188 | [[package]] 1189 | name = "want" 1190 | version = "0.3.0" 1191 | source = "registry+https://github.com/rust-lang/crates.io-index" 1192 | checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" 1193 | dependencies = [ 1194 | "log", 1195 | "try-lock", 1196 | ] 1197 | 1198 | [[package]] 1199 | name = "wasi" 1200 | version = "0.11.0+wasi-snapshot-preview1" 1201 | source = "registry+https://github.com/rust-lang/crates.io-index" 1202 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1203 | 1204 | [[package]] 1205 | name = "which" 1206 | version = "4.3.0" 1207 | source = "registry+https://github.com/rust-lang/crates.io-index" 1208 | checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b" 1209 | dependencies = [ 1210 | "either", 1211 | "libc", 1212 | "once_cell", 1213 | ] 1214 | 1215 | [[package]] 1216 | name = "winapi" 1217 | version = "0.3.9" 1218 | source = "registry+https://github.com/rust-lang/crates.io-index" 1219 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1220 | dependencies = [ 1221 | "winapi-i686-pc-windows-gnu", 1222 | "winapi-x86_64-pc-windows-gnu", 1223 | ] 1224 | 1225 | [[package]] 1226 | name = "winapi-i686-pc-windows-gnu" 1227 | version = "0.4.0" 1228 | source = "registry+https://github.com/rust-lang/crates.io-index" 1229 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1230 | 1231 | [[package]] 1232 | name = "winapi-x86_64-pc-windows-gnu" 1233 | version = "0.4.0" 1234 | source = "registry+https://github.com/rust-lang/crates.io-index" 1235 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1236 | 1237 | [[package]] 1238 | name = "windows-sys" 1239 | version = "0.36.1" 1240 | source = "registry+https://github.com/rust-lang/crates.io-index" 1241 | checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" 1242 | dependencies = [ 1243 | "windows_aarch64_msvc", 1244 | "windows_i686_gnu", 1245 | "windows_i686_msvc", 1246 | "windows_x86_64_gnu", 1247 | "windows_x86_64_msvc", 1248 | ] 1249 | 1250 | [[package]] 1251 | name = "windows_aarch64_msvc" 1252 | version = "0.36.1" 1253 | source = "registry+https://github.com/rust-lang/crates.io-index" 1254 | checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" 1255 | 1256 | [[package]] 1257 | name = "windows_i686_gnu" 1258 | version = "0.36.1" 1259 | source = "registry+https://github.com/rust-lang/crates.io-index" 1260 | checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" 1261 | 1262 | [[package]] 1263 | name = "windows_i686_msvc" 1264 | version = "0.36.1" 1265 | source = "registry+https://github.com/rust-lang/crates.io-index" 1266 | checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" 1267 | 1268 | [[package]] 1269 | name = "windows_x86_64_gnu" 1270 | version = "0.36.1" 1271 | source = "registry+https://github.com/rust-lang/crates.io-index" 1272 | checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" 1273 | 1274 | [[package]] 1275 | name = "windows_x86_64_msvc" 1276 | version = "0.36.1" 1277 | source = "registry+https://github.com/rust-lang/crates.io-index" 1278 | checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" 1279 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "serverless" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | # v8 wrapper 8 | deno_core = "0.149.0" 9 | # serialisation 10 | serde = { version = "1.0", features = ["derive"] } 11 | # multithreaded runtime 12 | tokio = { version = "1.21", features = ["full"] } 13 | # sqlite 14 | rusqlite = { version = "0.28", features = ["bundled"] } 15 | # http server 16 | axum = "0.6.0-rc.1" 17 | # tracing 18 | tracing = "0.1.36" 19 | # traces to stdout 20 | tracing-subscriber = { version = "0.3.15", features = ["env-filter", "local-time", "time"] } 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This repo is a demonstration of how you could build your own "serverless" platform with data persistence in only 200~ lines of simple, safe code. 2 | 3 | It combines [deno](https://deno.land/) (rust v8 runtime), [axum](https://github.com/tokio-rs/axum/) (http library), and [rusqlite](https://github.com/rusqlite/rusqlite) (sqlite) to build a Function as a Service (FaaS)-like application with file-system backed storage. 4 | 5 | A user submits javascript code with a HTTP POST request, then is able to invoke their function via GET requests. 6 | 7 | The js environment the code is executed within has access to 3 operations implemented in rust. `console.log` emits messages via stdout on the server, `set` inserts into a sqlite backed key-value store, and `get` retrieves from the same store. 8 | 9 | The last evaluated expression from an invoked js function will be returned in the HTTP GET response body. 10 | 11 | ### Example 12 | 13 | https://user-images.githubusercontent.com/2771466/190379404-8c45ff20-c7f9-4215-b18a-cd3926bc0e1f.mov 14 | 15 | In your first terminal 16 | 17 | ``` 18 | cargo run 19 | ``` 20 | 21 | In your second terminal 22 | ```bash 23 | # Submit the contents of fn.js as the function "raccoon" 24 | curl -d @fn.js localhost:8080/fn/raccoon 25 | 26 | # Invoke the function by it's name 27 | curl localhost:8080/fn/raccoon 28 | 29 | # And a couple more times... just in case 30 | curl localhost:8080/fn/raccoon 31 | curl localhost:8080/fn/raccoon 32 | curl localhost:8080/fn/raccoon 33 | ``` 34 | -------------------------------------------------------------------------------- /fn.js: -------------------------------------------------------------------------------- 1 | const raccoons = get("count") * 2 || 2; 2 | console.log("There are now", raccoons, "raccoons 🦝"); 3 | set("count", raccoons); 4 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use std::{ 2 | collections::HashMap, 3 | sync::{Arc, Mutex}, 4 | }; 5 | 6 | use axum::{ 7 | async_trait, 8 | extract::{FromRequestParts, Path, State}, 9 | http::{request::Parts, StatusCode}, 10 | response::IntoResponse, 11 | routing::get, 12 | Router, 13 | }; 14 | use deno_core::{ 15 | error::{AnyError, JsError}, 16 | op, serde_json, serde_v8, v8, JsRuntime, OpState, RuntimeOptions, 17 | }; 18 | use rusqlite::{Connection, OptionalExtension}; 19 | use tracing::{error, info}; 20 | use tracing_subscriber::prelude::*; 21 | 22 | async fn handle_root() -> &'static str { 23 | "Hello rustau!" 24 | } 25 | 26 | // HTTP POST /fn/:name curl -d @fn.js localhost:8080/fn/hello 27 | async fn handle_fn_submit( 28 | State(state): State, 29 | FunctionName(name): FunctionName, 30 | body: String, 31 | ) -> Result<(), AppError> { 32 | let db_file = format!("{name}.db"); 33 | let db = Connection::open(&db_file)?; 34 | 35 | db.execute("create table if not exists kv (key unique, value)", [])?; 36 | 37 | state 38 | .lock()? 39 | .insert(name.clone(), (body, Arc::new(Mutex::new(db)))); 40 | 41 | info!("added new function: {name}"); 42 | 43 | Ok(()) 44 | } 45 | 46 | // HTTP GET /fn/:name curl localhost:8080/fn/hello 47 | async fn handle_fn_execute( 48 | State(state): State, 49 | FunctionName(name): FunctionName, 50 | ) -> Result { 51 | let (fn_body, db) = state 52 | .lock()? 53 | .get(&name) 54 | .cloned() 55 | .ok_or_else(|| AppError::UnknownFunction(name.clone()))?; 56 | 57 | info!("invoking stored fn: {name}"); 58 | 59 | run_js(&name, &fn_body, db) 60 | } 61 | 62 | #[op] 63 | fn op_log(state: &mut OpState, msg: String) { 64 | // emit the log message prefixed with the name of the function 65 | info!("[{}]: {}", state.borrow::(), msg); 66 | } 67 | 68 | #[op] 69 | fn op_kv_set(state: &mut OpState, key: String, value: String) -> Result<(), AnyError> { 70 | let db = state 71 | .borrow_mut::() 72 | .lock() 73 | // the error from a poisoned lock can't be sent between threads 74 | // so we take it's msg contents and wrap them in an error that is Send 75 | .map_err(|err| AnyError::msg(err.to_string()))?; 76 | 77 | db.execute("replace into kv (key, value) values (?1, ?2)", [key, value])?; 78 | 79 | Ok(()) 80 | } 81 | 82 | #[op] 83 | fn op_kv_get(state: &mut OpState, key: String) -> Result, AnyError> { 84 | let db = state 85 | .borrow_mut::() 86 | .lock() 87 | // the error from a poisoned lock can't be sent between threads 88 | // so we take it's msg contents and wrap them in an error that is Send 89 | .map_err(|err| AnyError::msg(err.to_string()))?; 90 | 91 | let result = db 92 | .prepare("select value from kv where key = ?1")? 93 | .query_row([key], |row| row.get(0)) 94 | .optional()?; 95 | 96 | Ok(result) 97 | } 98 | 99 | const RUNTIME_BOOTSTRAP: &str = r#" 100 | globalThis.console = { 101 | log: (...args) => Deno.core.opSync("op_log", args.join(", ")) 102 | } 103 | globalThis.set = (key, value) => (Deno.core.opSync("op_kv_set", key, JSON.stringify(value)), value) 104 | globalThis.get = (key) => JSON.parse(Deno.core.opSync("op_kv_get", key)) 105 | "#; 106 | 107 | fn run_js(name: &str, body: &str, db: DB) -> Result { 108 | let mut runtime = JsRuntime::new(RuntimeOptions { 109 | extensions: vec![deno_core::Extension::builder() 110 | .ops(vec![op_log::decl(), op_kv_set::decl(), op_kv_get::decl()]) 111 | .js(vec![("[runtime]", RUNTIME_BOOTSTRAP)]) 112 | .build()], 113 | ..Default::default() 114 | }); 115 | 116 | let state = runtime.op_state(); 117 | 118 | // inject the name of the function and access to the DB so ops have access 119 | state.borrow_mut().put::(name.to_owned()); 120 | state.borrow_mut().put(db); 121 | 122 | let last_value = runtime.execute_script(name, body)?; 123 | 124 | // parse out the last evaluated expression from the function execution 125 | let scope = &mut runtime.handle_scope(); 126 | let local = v8::Local::new(scope, last_value); 127 | let deserialized_value = serde_v8::from_v8::(scope, local)?; 128 | 129 | info!("result from \"{name}\": {deserialized_value:#?}"); 130 | 131 | Ok(deserialized_value.to_string()) 132 | } 133 | 134 | /// Threadsafe lock around a sqlite database connection 135 | type DB = Arc>; 136 | /// Threadsafe lock around a map of function name -> body & db connection 137 | type AppState = Arc>>; 138 | 139 | #[tokio::main] 140 | async fn main() { 141 | register_trace_stdout_listener(); 142 | 143 | let state: AppState = Default::default(); 144 | 145 | let app = Router::with_state(state) 146 | .route("/", get(handle_root)) 147 | .route("/fn/:name", get(handle_fn_execute).post(handle_fn_submit)); 148 | 149 | let addr = std::net::SocketAddr::from((std::net::Ipv4Addr::UNSPECIFIED, 8080)); 150 | info!("listening on {addr}"); 151 | axum::Server::bind(&addr) 152 | .serve(app.into_make_service()) 153 | .await 154 | .unwrap(); 155 | } 156 | 157 | /// Register logging provider and emit to stdout anything matching INFO or above 158 | fn register_trace_stdout_listener() { 159 | let env_filter = tracing_subscriber::EnvFilter::builder() 160 | .with_default_directive(tracing::metadata::LevelFilter::INFO.into()) 161 | .from_env_lossy(); 162 | let filter_layer = tracing_subscriber::fmt::layer().with_filter(env_filter); 163 | tracing_subscriber::registry().with(filter_layer).init(); 164 | } 165 | 166 | /// Type for all errors that can bubble up to the http level 167 | /// 168 | /// Implements From for various error types, and IntoResponse to build an HTTP response 169 | #[derive(Debug)] 170 | enum AppError { 171 | SqliteError(String), 172 | LockPoisoned(String), 173 | UnknownFunction(String), 174 | JsError(JsError), 175 | DenoError(String), 176 | V8SerialisationError(String), 177 | } 178 | 179 | impl IntoResponse for AppError { 180 | fn into_response(self) -> axum::response::Response { 181 | match self { 182 | AppError::JsError(js_error) => { 183 | format!("error evaluating function: {js_error}").into_response() 184 | } 185 | AppError::UnknownFunction(name) => { 186 | (StatusCode::BAD_REQUEST, format!("unknown function: {name}")).into_response() 187 | } 188 | err => { 189 | error!("internal error: {err:?}"); 190 | (StatusCode::INTERNAL_SERVER_ERROR, "internal server error").into_response() 191 | } 192 | } 193 | } 194 | } 195 | 196 | impl From for AppError { 197 | fn from(err: rusqlite::Error) -> Self { 198 | AppError::SqliteError(err.to_string()) 199 | } 200 | } 201 | 202 | impl From> for AppError { 203 | fn from(e: std::sync::PoisonError) -> Self { 204 | AppError::LockPoisoned(e.to_string()) 205 | } 206 | } 207 | 208 | impl From for AppError { 209 | fn from(err: deno_core::anyhow::Error) -> Self { 210 | match err.downcast::() { 211 | Ok(js_error) => AppError::JsError(js_error), 212 | Err(err) => AppError::DenoError(err.to_string()), 213 | } 214 | } 215 | } 216 | 217 | impl From for AppError { 218 | fn from(err: serde_v8::Error) -> Self { 219 | AppError::V8SerialisationError(err.to_string()) 220 | } 221 | } 222 | 223 | /// Extractor that also validates a function name from the URL 224 | struct FunctionName(String); 225 | 226 | #[async_trait] 227 | impl FromRequestParts for FunctionName 228 | where 229 | S: Send + Sync, 230 | { 231 | type Rejection = axum::response::Response; 232 | 233 | async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { 234 | let Path(name) = Path::::from_request_parts(parts, state) 235 | .await 236 | .map_err(IntoResponse::into_response)?; 237 | 238 | if name.chars().any(|c| !c.is_ascii_alphabetic()) { 239 | let error_msg = format!( 240 | "invalid function name: \"{name}\", only a-z and A-Z characters are allowed" 241 | ); 242 | 243 | return Err((StatusCode::BAD_REQUEST, error_msg).into_response()); 244 | } 245 | 246 | Ok(FunctionName(name)) 247 | } 248 | } 249 | --------------------------------------------------------------------------------