diff --git a/.gitignore b/.gitignore index a78e8b2..678f458 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /Cargo.lock wasi-sdk *.wasm +.venv diff --git a/Cargo.toml b/Cargo.toml index dfd27d3..1dc30dd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ members = [ ] [workspace.package] -version = "1.0.0-rc6" +version = "1.0.0-rc7" edition = "2021" authors = ["The Extism Authors"] license = "BSD-Clause-3" diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 1735d19..0437a4b 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -12,13 +12,13 @@ path = "src/main.rs" [dependencies] anyhow = { workspace = true } -wizer = "4.0.0" +wizer = "4" structopt = "0.3" swc_atoms = "0.6.5" swc_common = "0.33.10" swc_ecma_ast = "0.112" swc_ecma_parser = "0.143" wagen = "0.1" -log = "0.4.20" -tempfile = "3.8.1" +log = "0.4" +tempfile = "3" env_logger = "0.11" diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index 7691154..f7a00cb 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -8,10 +8,11 @@ license.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -extism-pdk = "1.0.0" +extism-pdk = "1" once_cell = "1.16" anyhow = { workspace = true } quickjs-wasm-rs = "3" +chrono = { version = "0.4", default_features = false, features = ["clock"]} [lib] crate_type = ["cdylib"] diff --git a/crates/core/src/globals.rs b/crates/core/src/globals.rs index f1eb9f7..63eb40e 100644 --- a/crates/core/src/globals.rs +++ b/crates/core/src/globals.rs @@ -1,6 +1,7 @@ use std::{borrow::Cow, collections::HashMap, str::from_utf8}; use anyhow::{anyhow, bail, Context}; +use chrono::{SecondsFormat, Utc}; use extism_pdk::extism::load_input; use extism_pdk::*; use quickjs_wasm_rs::{JSContextRef, JSError, JSValue, JSValueRef}; @@ -15,6 +16,7 @@ pub fn inject_globals(context: &JSContextRef) -> anyhow::Result<()> { let cfg = build_config_object(context)?; let decoder = build_decoder(context)?; let encoder = build_encoder(context)?; + let clock = build_clock(context)?; let mem = build_memory(context)?; let host = build_host_object(context)?; @@ -28,6 +30,7 @@ pub fn inject_globals(context: &JSContextRef) -> anyhow::Result<()> { global.set_property("Memory", mem)?; global.set_property("__decodeUtf8BufferToString", decoder)?; global.set_property("__encodeStringToUtf8Buffer", encoder)?; + global.set_property("__getTime", clock)?; add_host_functions(context)?; @@ -483,6 +486,10 @@ fn build_memory(context: &JSContextRef) -> anyhow::Result { Ok(mem_obj) } +fn build_clock(context: &JSContextRef) -> anyhow::Result { + context.wrap_callback(get_time()) +} + fn build_decoder(context: &JSContextRef) -> anyhow::Result { context.wrap_callback(decode_utf8_buffer_to_js_string()) } @@ -491,6 +498,15 @@ fn build_encoder(context: &JSContextRef) -> anyhow::Result { context.wrap_callback(encode_js_string_to_utf8_buffer()) } +fn get_time() -> impl FnMut(&JSContextRef, JSValueRef, &[JSValueRef]) -> anyhow::Result { + move |_ctx: &JSContextRef, _this: JSValueRef, _args: &[JSValueRef]| { + let now = Utc::now(); + // This format is compatible with JavaScript's Date constructor + let formatted = now.to_rfc3339_opts(SecondsFormat::Millis, true); + Ok(formatted.into()) + } +} + fn decode_utf8_buffer_to_js_string( ) -> impl FnMut(&JSContextRef, JSValueRef, &[JSValueRef]) -> anyhow::Result { move |_ctx: &JSContextRef, _this: JSValueRef, args: &[JSValueRef]| { diff --git a/crates/core/src/prelude/src/index.js b/crates/core/src/prelude/src/index.js index bc88bc6..11f29fe 100644 --- a/crates/core/src/prelude/src/index.js +++ b/crates/core/src/prelude/src/index.js @@ -7,6 +7,19 @@ globalThis.URLPattern = URLPattern; const __decodeUtf8BufferToString = globalThis.__decodeUtf8BufferToString; const __encodeStringToUtf8Buffer = globalThis.__encodeStringToUtf8Buffer; +const __getTime = globalThis.__getTime + +class __ExtismDate extends Date { + constructor(arg) { + if (arg) { + super(arg) + } else { + super(__getTime()) + } + } +} + +globalThis.Date = __ExtismDate class TextDecoder { constructor(label = "utf-8", options = {}) { @@ -85,7 +98,7 @@ class MemoryHandle { const arr = new BigUint64Array(bytes); return arr[0]; } - + readFloat32() { const bytes = this.readBytes(); const arr = new Float32Array(bytes);