commit
5a040872e3
27 changed files with 1842 additions and 335 deletions
|
@ -12,6 +12,7 @@ edition = "2018"
|
|||
[features]
|
||||
libuv = ["futures"]
|
||||
tokio_rt = ["futures", "tokio", "once_cell"]
|
||||
serde-json = ["serde", "serde_json"]
|
||||
|
||||
[dependencies]
|
||||
napi-sys = { version = "0.4", path = "../sys" }
|
||||
|
@ -29,6 +30,13 @@ optional = true
|
|||
version = "1.4"
|
||||
optional = true
|
||||
|
||||
[dependencies.serde]
|
||||
version = "1"
|
||||
optional = true
|
||||
|
||||
[dependencies.serde_json]
|
||||
version = "1"
|
||||
optional = true
|
||||
|
||||
[build-dependencies]
|
||||
napi-build = { version = "0.2", path = "../build" }
|
||||
|
|
|
@ -11,12 +11,18 @@ use crate::js_values::*;
|
|||
use crate::task::Task;
|
||||
use crate::{sys, Error, NodeVersion, Result, Status};
|
||||
|
||||
#[cfg(all(feature = "serde-json"))]
|
||||
use crate::js_values::{De, Ser};
|
||||
#[cfg(all(any(feature = "libuv", feature = "tokio_rt"), napi4))]
|
||||
use crate::promise;
|
||||
#[cfg(all(feature = "tokio_rt", napi4))]
|
||||
use crate::tokio_rt::{get_tokio_sender, Message};
|
||||
#[cfg(all(feature = "libuv", napi4))]
|
||||
use crate::uv;
|
||||
#[cfg(all(feature = "serde-json"))]
|
||||
use serde::de::DeserializeOwned;
|
||||
#[cfg(all(feature = "serde-json"))]
|
||||
use serde::Serialize;
|
||||
#[cfg(all(feature = "libuv", napi4))]
|
||||
use std::future::Future;
|
||||
#[cfg(all(feature = "tokio_rt", napi4))]
|
||||
|
@ -98,7 +104,7 @@ impl Env {
|
|||
pub fn create_bigint_from_i64(&self, value: i64) -> Result<JsBigint> {
|
||||
let mut raw_value = ptr::null_mut();
|
||||
check_status(unsafe { sys::napi_create_bigint_int64(self.0, value, &mut raw_value) })?;
|
||||
Ok(JsBigint::from_raw_unchecked(self.0, raw_value))
|
||||
Ok(JsBigint::from_raw_unchecked(self.0, raw_value, 1))
|
||||
}
|
||||
|
||||
#[cfg(napi6)]
|
||||
|
@ -107,7 +113,7 @@ impl Env {
|
|||
pub fn create_bigint_from_u64(&self, value: u64) -> Result<JsBigint> {
|
||||
let mut raw_value = ptr::null_mut();
|
||||
check_status(unsafe { sys::napi_create_bigint_uint64(self.0, value, &mut raw_value) })?;
|
||||
Ok(JsBigint::from_raw_unchecked(self.0, raw_value))
|
||||
Ok(JsBigint::from_raw_unchecked(self.0, raw_value, 1))
|
||||
}
|
||||
|
||||
#[cfg(napi6)]
|
||||
|
@ -116,6 +122,7 @@ impl Env {
|
|||
/// The resulting BigInt will be negative when sign_bit is true.
|
||||
pub fn create_bigint_from_words(&self, sign_bit: bool, words: Vec<u64>) -> Result<JsBigint> {
|
||||
let mut raw_value = ptr::null_mut();
|
||||
let len = words.len();
|
||||
check_status(unsafe {
|
||||
sys::napi_create_bigint_words(
|
||||
self.0,
|
||||
|
@ -123,12 +130,12 @@ impl Env {
|
|||
true => 1,
|
||||
false => 0,
|
||||
},
|
||||
words.len() as u64,
|
||||
len as u64,
|
||||
words.as_ptr(),
|
||||
&mut raw_value,
|
||||
)
|
||||
})?;
|
||||
Ok(JsBigint::from_raw_unchecked(self.0, raw_value))
|
||||
Ok(JsBigint::from_raw_unchecked(self.0, raw_value, len as _))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -608,6 +615,32 @@ impl Env {
|
|||
Ok(JsObject::from_raw_unchecked(self.0, raw_promise))
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde-json")]
|
||||
#[inline]
|
||||
pub fn to_js_value<T>(&self, node: &T) -> Result<JsUnknown>
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
let s = Ser(self);
|
||||
node.serialize(s).map(JsUnknown)
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde-json")]
|
||||
#[inline]
|
||||
pub fn from_js_value<T, V>(&self, value: V) -> Result<T>
|
||||
where
|
||||
T: DeserializeOwned + ?Sized,
|
||||
V: NapiValue,
|
||||
{
|
||||
let value = Value {
|
||||
env: self.0,
|
||||
value: value.raw_value(),
|
||||
value_type: ValueType::Unknown,
|
||||
};
|
||||
let mut de = De(&value);
|
||||
T::deserialize(&mut de)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn strict_equals<A: NapiValue, B: NapiValue>(&self, a: A, b: B) -> Result<bool> {
|
||||
let mut result = false;
|
||||
|
|
|
@ -1,7 +1,14 @@
|
|||
use std::convert::From;
|
||||
use std::error::Error as StdError;
|
||||
use std::fmt;
|
||||
#[cfg(feature = "serde-json")]
|
||||
use std::fmt::Display;
|
||||
use std::os::raw::c_char;
|
||||
use std::ptr;
|
||||
|
||||
#[cfg(feature = "serde-json")]
|
||||
use serde::{de, ser};
|
||||
|
||||
use crate::{sys, Status};
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
@ -12,6 +19,22 @@ pub struct Error {
|
|||
pub reason: String,
|
||||
}
|
||||
|
||||
impl StdError for Error {}
|
||||
|
||||
#[cfg(feature = "serde-json")]
|
||||
impl ser::Error for Error {
|
||||
fn custom<T: Display>(msg: T) -> Self {
|
||||
Error::new(Status::InvalidArg, msg.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde-json")]
|
||||
impl de::Error for Error {
|
||||
fn custom<T: Display>(msg: T) -> Self {
|
||||
Error::new(Status::InvalidArg, msg.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{:?}: {}", self.status, self.reason)
|
||||
|
@ -82,6 +105,6 @@ pub fn check_status(code: sys::napi_status) -> Result<()> {
|
|||
let status = Status::from(code);
|
||||
match status {
|
||||
Status::Ok => Ok(()),
|
||||
_ => Err(Error::from_status(status)),
|
||||
_ => Err(Error::new(status, "".to_owned())),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use std::convert::TryFrom;
|
||||
use std::ptr;
|
||||
|
||||
use super::{JsObject, NapiValue, Value, ValueType};
|
||||
use super::{JsObject, JsUnknown, NapiValue, Value, ValueType};
|
||||
use crate::error::check_status;
|
||||
use crate::{sys, Result};
|
||||
use crate::{sys, Error, Result};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct JsArrayBuffer {
|
||||
|
@ -46,3 +47,10 @@ impl NapiValue for JsArrayBuffer {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<JsUnknown> for JsArrayBuffer {
|
||||
type Error = Error;
|
||||
fn try_from(value: JsUnknown) -> Result<JsArrayBuffer> {
|
||||
JsArrayBuffer::from_raw(value.0.env, value.0.value)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,146 @@
|
|||
use std::convert::TryFrom;
|
||||
use std::ptr;
|
||||
|
||||
use super::{Error, Value};
|
||||
use super::*;
|
||||
use crate::error::check_status;
|
||||
use crate::{sys, Result};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct JsBigint(pub(crate) Value);
|
||||
pub struct JsBigint {
|
||||
pub(crate) raw: Value,
|
||||
pub word_count: u64,
|
||||
}
|
||||
|
||||
impl JsBigint {
|
||||
pub(crate) fn from_raw_unchecked(
|
||||
env: sys::napi_env,
|
||||
value: sys::napi_value,
|
||||
word_count: u64,
|
||||
) -> Self {
|
||||
Self {
|
||||
raw: Value {
|
||||
env,
|
||||
value,
|
||||
value_type: ValueType::Object,
|
||||
},
|
||||
word_count,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn into_unknown(self) -> Result<JsUnknown> {
|
||||
JsUnknown::from_raw(self.raw.env, self.raw.value)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn coerce_to_number(self) -> Result<JsNumber> {
|
||||
let mut new_raw_value = ptr::null_mut();
|
||||
let status =
|
||||
unsafe { sys::napi_coerce_to_number(self.raw.env, self.raw.value, &mut new_raw_value) };
|
||||
check_status(status)?;
|
||||
Ok(JsNumber(Value {
|
||||
env: self.raw.env,
|
||||
value: new_raw_value,
|
||||
value_type: ValueType::Number,
|
||||
}))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn coerce_to_string(self) -> Result<JsString> {
|
||||
let mut new_raw_value = ptr::null_mut();
|
||||
let status =
|
||||
unsafe { sys::napi_coerce_to_string(self.raw.env, self.raw.value, &mut new_raw_value) };
|
||||
check_status(status)?;
|
||||
Ok(JsString(Value {
|
||||
env: self.raw.env,
|
||||
value: new_raw_value,
|
||||
value_type: ValueType::String,
|
||||
}))
|
||||
}
|
||||
#[inline]
|
||||
pub fn coerce_to_object(self) -> Result<JsObject> {
|
||||
let mut new_raw_value = ptr::null_mut();
|
||||
let status =
|
||||
unsafe { sys::napi_coerce_to_object(self.raw.env, self.raw.value, &mut new_raw_value) };
|
||||
check_status(status)?;
|
||||
Ok(JsObject(Value {
|
||||
env: self.raw.env,
|
||||
value: new_raw_value,
|
||||
value_type: ValueType::Object,
|
||||
}))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(napi5)]
|
||||
pub fn is_date(&self) -> Result<bool> {
|
||||
let mut is_date = true;
|
||||
let status = unsafe { sys::napi_is_date(self.raw.env, self.raw.value, &mut is_date) };
|
||||
check_status(status)?;
|
||||
Ok(is_date)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_error(&self) -> Result<bool> {
|
||||
let mut result = false;
|
||||
check_status(unsafe { sys::napi_is_error(self.raw.env, self.raw.value, &mut result) })?;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_typedarray(&self) -> Result<bool> {
|
||||
let mut result = false;
|
||||
check_status(unsafe { sys::napi_is_typedarray(self.raw.env, self.raw.value, &mut result) })?;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_dataview(&self) -> Result<bool> {
|
||||
let mut result = false;
|
||||
check_status(unsafe { sys::napi_is_dataview(self.raw.env, self.raw.value, &mut result) })?;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn instanceof<Constructor: NapiValue>(&self, constructor: Constructor) -> Result<bool> {
|
||||
let mut result = false;
|
||||
check_status(unsafe {
|
||||
sys::napi_instanceof(
|
||||
self.raw.env,
|
||||
self.raw.value,
|
||||
constructor.raw_value(),
|
||||
&mut result,
|
||||
)
|
||||
})?;
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
|
||||
impl NapiValue for JsBigint {
|
||||
fn raw_value(&self) -> sys::napi_value {
|
||||
self.raw.value
|
||||
}
|
||||
|
||||
fn from_raw(env: sys::napi_env, value: sys::napi_value) -> Result<Self> {
|
||||
let mut word_count: u64 = 0;
|
||||
check_status(unsafe {
|
||||
sys::napi_get_value_bigint_words(
|
||||
env,
|
||||
value,
|
||||
ptr::null_mut(),
|
||||
&mut word_count,
|
||||
ptr::null_mut(),
|
||||
)
|
||||
})?;
|
||||
Ok(JsBigint {
|
||||
raw: Value {
|
||||
env,
|
||||
value,
|
||||
value_type: ValueType::Bigint,
|
||||
},
|
||||
word_count,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// The BigInt will be converted losslessly when the value is over what an int64 could hold.
|
||||
impl TryFrom<JsBigint> for i64 {
|
||||
|
@ -28,38 +162,26 @@ impl TryFrom<JsBigint> for u64 {
|
|||
|
||||
impl JsBigint {
|
||||
/// https://nodejs.org/api/n-api.html#n_api_napi_get_value_bigint_words
|
||||
pub fn get_words(&self, sign_bit: bool) -> Result<Vec<u64>> {
|
||||
let mut word_count: u64 = 0;
|
||||
#[inline]
|
||||
pub fn get_words(&mut self) -> Result<(bool, Vec<u64>)> {
|
||||
let mut words: Vec<u64> = Vec::with_capacity(self.word_count as usize);
|
||||
let word_count = &mut self.word_count;
|
||||
let mut sign_bit = 0;
|
||||
check_status(unsafe {
|
||||
sys::napi_get_value_bigint_words(
|
||||
self.0.env,
|
||||
self.0.value,
|
||||
ptr::null_mut(),
|
||||
&mut word_count,
|
||||
ptr::null_mut(),
|
||||
)
|
||||
})?;
|
||||
|
||||
let mut words: Vec<u64> = Vec::with_capacity(word_count as usize);
|
||||
let mut sign_bit = match sign_bit {
|
||||
true => 1,
|
||||
false => 0,
|
||||
};
|
||||
check_status(unsafe {
|
||||
sys::napi_get_value_bigint_words(
|
||||
self.0.env,
|
||||
self.0.value,
|
||||
self.raw.env,
|
||||
self.raw.value,
|
||||
&mut sign_bit,
|
||||
&mut word_count,
|
||||
word_count,
|
||||
words.as_mut_ptr(),
|
||||
)
|
||||
})?;
|
||||
|
||||
unsafe {
|
||||
words.set_len(word_count as usize);
|
||||
words.set_len(self.word_count as usize);
|
||||
};
|
||||
|
||||
Ok(words)
|
||||
Ok((sign_bit == 1, words))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -67,7 +189,7 @@ impl JsBigint {
|
|||
let mut val: u64 = 0;
|
||||
let mut loss = false;
|
||||
check_status(unsafe {
|
||||
sys::napi_get_value_bigint_uint64(self.0.env, self.0.value, &mut val, &mut loss)
|
||||
sys::napi_get_value_bigint_uint64(self.raw.env, self.raw.value, &mut val, &mut loss)
|
||||
})?;
|
||||
|
||||
Ok((val, loss))
|
||||
|
@ -78,8 +200,29 @@ impl JsBigint {
|
|||
let mut val: i64 = 0;
|
||||
let mut loss: bool = false;
|
||||
check_status(unsafe {
|
||||
sys::napi_get_value_bigint_int64(self.0.env, self.0.value, &mut val, &mut loss)
|
||||
sys::napi_get_value_bigint_int64(self.raw.env, self.raw.value, &mut val, &mut loss)
|
||||
})?;
|
||||
Ok((val, loss))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_i128(&mut self) -> Result<(i128, bool)> {
|
||||
let (signed, words) = self.get_words()?;
|
||||
let len = words.len();
|
||||
let i128_words: [i64; 2] = [words[0] as _, words[1] as _];
|
||||
let mut val = unsafe { ptr::read(i128_words.as_ptr() as *const i128) };
|
||||
if signed {
|
||||
val = -val;
|
||||
}
|
||||
Ok((val, len > 2))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_u128(&mut self) -> Result<(bool, u128, bool)> {
|
||||
let (signed, words) = self.get_words()?;
|
||||
let len = words.len();
|
||||
let u128_words: [u64; 2] = [words[0], words[1]];
|
||||
let val = unsafe { ptr::read(u128_words.as_ptr() as *const u128) };
|
||||
Ok((signed, val, len > 2))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
use std::convert::TryFrom;
|
||||
use std::ops::Deref;
|
||||
use std::ptr;
|
||||
use std::slice;
|
||||
|
||||
use super::{JsObject, JsUnknown, NapiValue, Value, ValueType};
|
||||
use crate::error::check_status;
|
||||
use crate::{sys, Result};
|
||||
use crate::{sys, Error, Result};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct JsBuffer {
|
||||
|
@ -42,8 +43,7 @@ impl NapiValue for JsBuffer {
|
|||
fn from_raw(env: sys::napi_env, value: sys::napi_value) -> Result<Self> {
|
||||
let mut data = ptr::null_mut();
|
||||
let mut len: u64 = 0;
|
||||
let status = unsafe { sys::napi_get_buffer_info(env, value, &mut data, &mut len) };
|
||||
check_status(status)?;
|
||||
check_status(unsafe { sys::napi_get_buffer_info(env, value, &mut data, &mut len) })?;
|
||||
Ok(JsBuffer {
|
||||
value: JsObject(Value {
|
||||
env,
|
||||
|
@ -68,3 +68,10 @@ impl Deref for JsBuffer {
|
|||
self.data
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<JsUnknown> for JsBuffer {
|
||||
type Error = Error;
|
||||
fn try_from(value: JsUnknown) -> Result<JsBuffer> {
|
||||
JsBuffer::from_raw(value.0.env, value.0.value)
|
||||
}
|
||||
}
|
||||
|
|
358
napi/src/js_values/de.rs
Normal file
358
napi/src/js_values/de.rs
Normal file
|
@ -0,0 +1,358 @@
|
|||
use std::convert::TryInto;
|
||||
|
||||
use serde::de::Visitor;
|
||||
use serde::de::{DeserializeSeed, EnumAccess, MapAccess, SeqAccess, Unexpected, VariantAccess};
|
||||
|
||||
use super::{type_of, NapiValue, Value, ValueType};
|
||||
#[cfg(napi6)]
|
||||
use crate::JsBigint;
|
||||
use crate::{Error, JsBoolean, JsBuffer, JsNumber, JsObject, JsString, JsUnknown, Result, Status};
|
||||
|
||||
pub(crate) struct De<'env>(pub(crate) &'env Value);
|
||||
|
||||
#[doc(hidden)]
|
||||
impl<'x, 'de, 'env> serde::de::Deserializer<'x> for &'de mut De<'env> {
|
||||
type Error = Error;
|
||||
|
||||
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
|
||||
where
|
||||
V: Visitor<'x>,
|
||||
{
|
||||
let js_value_type = type_of(self.0.env, self.0.value)?;
|
||||
match js_value_type {
|
||||
ValueType::Null | ValueType::Undefined => visitor.visit_unit(),
|
||||
ValueType::Boolean => {
|
||||
let js_boolean = JsBoolean::from_raw_unchecked(self.0.env, self.0.value);
|
||||
visitor.visit_bool(js_boolean.get_value()?)
|
||||
}
|
||||
ValueType::Number => {
|
||||
let js_number: f64 = JsNumber::from_raw_unchecked(self.0.env, self.0.value).try_into()?;
|
||||
if js_number.trunc() == js_number {
|
||||
visitor.visit_i64(js_number as i64)
|
||||
} else {
|
||||
visitor.visit_f64(js_number)
|
||||
}
|
||||
}
|
||||
ValueType::String => {
|
||||
let js_string = JsString::from_raw_unchecked(self.0.env, self.0.value);
|
||||
visitor.visit_str(js_string.as_str()?)
|
||||
}
|
||||
ValueType::Object => {
|
||||
let js_object = JsObject::from_raw_unchecked(self.0.env, self.0.value);
|
||||
if js_object.is_array()? {
|
||||
let mut deserializer =
|
||||
JsArrayAccess::new(&js_object, js_object.get_array_length_unchecked()?);
|
||||
visitor.visit_seq(&mut deserializer)
|
||||
} else if js_object.is_buffer()? {
|
||||
visitor.visit_bytes(JsBuffer::from_raw(self.0.env, self.0.value)?.data)
|
||||
} else {
|
||||
let mut deserializer = JsObjectAccess::new(&js_object)?;
|
||||
visitor.visit_map(&mut deserializer)
|
||||
}
|
||||
}
|
||||
#[cfg(napi6)]
|
||||
ValueType::Bigint => {
|
||||
let mut js_bigint = JsBigint::from_raw(self.0.env, self.0.value)?;
|
||||
let (signed, v, _loss) = js_bigint.get_u128()?;
|
||||
if signed {
|
||||
visitor.visit_i128(-(v as i128))
|
||||
} else {
|
||||
visitor.visit_u128(v)
|
||||
}
|
||||
}
|
||||
ValueType::External | ValueType::Function | ValueType::Symbol => Err(Error::new(
|
||||
Status::InvalidArg,
|
||||
format!("typeof {:?} value could not be deserialized", js_value_type),
|
||||
)),
|
||||
ValueType::Unknown => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
|
||||
where
|
||||
V: Visitor<'x>,
|
||||
{
|
||||
visitor.visit_bytes(JsBuffer::from_raw(self.0.env, self.0.value)?.data)
|
||||
}
|
||||
|
||||
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
|
||||
where
|
||||
V: Visitor<'x>,
|
||||
{
|
||||
visitor.visit_bytes(JsBuffer::from_raw(self.0.env, self.0.value)?.data)
|
||||
}
|
||||
|
||||
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
|
||||
where
|
||||
V: Visitor<'x>,
|
||||
{
|
||||
match type_of(self.0.env, self.0.value)? {
|
||||
ValueType::Undefined | ValueType::Null => visitor.visit_none(),
|
||||
_ => visitor.visit_some(self),
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_enum<V>(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_variants: &'static [&'static str],
|
||||
visitor: V,
|
||||
) -> Result<V::Value>
|
||||
where
|
||||
V: Visitor<'x>,
|
||||
{
|
||||
let js_value_type = type_of(self.0.env, self.0.value)?;
|
||||
match js_value_type {
|
||||
ValueType::String => visitor.visit_enum(JsEnumAccess::new(
|
||||
JsString::from_raw_unchecked(self.0.env, self.0.value)
|
||||
.as_str()?
|
||||
.to_owned(),
|
||||
None,
|
||||
)),
|
||||
ValueType::Object => {
|
||||
let js_object = JsObject::from_raw_unchecked(self.0.env, self.0.value);
|
||||
let properties = js_object.get_property_names::<JsObject>()?;
|
||||
let property_len = properties.get_array_length_unchecked()?;
|
||||
if property_len != 1 {
|
||||
Err(Error::new(
|
||||
Status::InvalidArg,
|
||||
format!(
|
||||
"object key length: {}, can not deserialize to Enum",
|
||||
property_len
|
||||
),
|
||||
))
|
||||
} else {
|
||||
let key = properties.get_index::<JsString>(0)?;
|
||||
let value: JsUnknown = js_object.get_property(&key)?;
|
||||
visitor.visit_enum(JsEnumAccess::new(key.as_str()?.to_owned(), Some(&value.0)))
|
||||
}
|
||||
}
|
||||
_ => Err(Error::new(
|
||||
Status::InvalidArg,
|
||||
format!(
|
||||
"{:?} type could not deserialize to Enum type",
|
||||
js_value_type
|
||||
),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
|
||||
where
|
||||
V: Visitor<'x>,
|
||||
{
|
||||
visitor.visit_unit()
|
||||
}
|
||||
|
||||
forward_to_deserialize_any! {
|
||||
<V: Visitor<'x>>
|
||||
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
|
||||
unit unit_struct seq tuple tuple_struct map struct identifier
|
||||
newtype_struct
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(crate) struct JsEnumAccess<'env> {
|
||||
variant: String,
|
||||
value: Option<&'env Value>,
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
impl<'env> JsEnumAccess<'env> {
|
||||
fn new(variant: String, value: Option<&'env Value>) -> Self {
|
||||
Self { variant, value }
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
impl<'de, 'env> EnumAccess<'de> for JsEnumAccess<'env> {
|
||||
type Error = Error;
|
||||
type Variant = JsVariantAccess<'env>;
|
||||
|
||||
fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
|
||||
where
|
||||
V: DeserializeSeed<'de>,
|
||||
{
|
||||
use serde::de::IntoDeserializer;
|
||||
let variant = self.variant.into_deserializer();
|
||||
let variant_access = JsVariantAccess { value: self.value };
|
||||
seed.deserialize(variant).map(|v| (v, variant_access))
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(crate) struct JsVariantAccess<'env> {
|
||||
value: Option<&'env Value>,
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
impl<'de, 'env> VariantAccess<'de> for JsVariantAccess<'env> {
|
||||
type Error = Error;
|
||||
fn unit_variant(self) -> Result<()> {
|
||||
match self.value {
|
||||
Some(val) => {
|
||||
let mut deserializer = De(val);
|
||||
serde::de::Deserialize::deserialize(&mut deserializer)
|
||||
}
|
||||
None => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
|
||||
where
|
||||
T: DeserializeSeed<'de>,
|
||||
{
|
||||
match self.value {
|
||||
Some(val) => {
|
||||
let mut deserializer = De(val);
|
||||
seed.deserialize(&mut deserializer)
|
||||
}
|
||||
None => Err(serde::de::Error::invalid_type(
|
||||
Unexpected::UnitVariant,
|
||||
&"newtype variant",
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
match self.value {
|
||||
Some(js_value) => {
|
||||
let js_object = JsObject::from_raw(js_value.env, js_value.value)?;
|
||||
if js_object.is_array()? {
|
||||
let mut deserializer =
|
||||
JsArrayAccess::new(&js_object, js_object.get_array_length_unchecked()?);
|
||||
visitor.visit_seq(&mut deserializer)
|
||||
} else {
|
||||
Err(serde::de::Error::invalid_type(
|
||||
Unexpected::Other("JsValue"),
|
||||
&"tuple variant",
|
||||
))
|
||||
}
|
||||
}
|
||||
None => Err(serde::de::Error::invalid_type(
|
||||
Unexpected::UnitVariant,
|
||||
&"tuple variant",
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
match self.value {
|
||||
Some(js_value) => {
|
||||
if let Ok(val) = JsObject::from_raw(js_value.env, js_value.value) {
|
||||
let mut deserializer = JsObjectAccess::new(&val)?;
|
||||
visitor.visit_map(&mut deserializer)
|
||||
} else {
|
||||
Err(serde::de::Error::invalid_type(
|
||||
Unexpected::Other("JsValue"),
|
||||
&"struct variant",
|
||||
))
|
||||
}
|
||||
}
|
||||
_ => Err(serde::de::Error::invalid_type(
|
||||
Unexpected::UnitVariant,
|
||||
&"struct variant",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
struct JsArrayAccess<'env> {
|
||||
input: &'env JsObject,
|
||||
idx: u32,
|
||||
len: u32,
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
impl<'env> JsArrayAccess<'env> {
|
||||
fn new(input: &'env JsObject, len: u32) -> Self {
|
||||
Self { input, idx: 0, len }
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
impl<'de, 'env> SeqAccess<'de> for JsArrayAccess<'env> {
|
||||
type Error = Error;
|
||||
|
||||
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
|
||||
where
|
||||
T: DeserializeSeed<'de>,
|
||||
{
|
||||
if self.idx >= self.len {
|
||||
return Ok(None);
|
||||
}
|
||||
let v = self.input.get_index::<JsUnknown>(self.idx)?;
|
||||
self.idx += 1;
|
||||
|
||||
let mut de = De(&v.0);
|
||||
seed.deserialize(&mut de).map(Some)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(crate) struct JsObjectAccess<'env> {
|
||||
value: &'env JsObject,
|
||||
properties: JsObject,
|
||||
idx: u32,
|
||||
property_len: u32,
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
impl<'env> JsObjectAccess<'env> {
|
||||
fn new(value: &'env JsObject) -> Result<Self> {
|
||||
let properties = value.get_property_names::<JsObject>()?;
|
||||
let property_len = properties.get_array_length_unchecked()?;
|
||||
Ok(Self {
|
||||
value,
|
||||
properties,
|
||||
idx: 0,
|
||||
property_len,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
impl<'de, 'env> MapAccess<'de> for JsObjectAccess<'env> {
|
||||
type Error = Error;
|
||||
|
||||
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
|
||||
where
|
||||
K: DeserializeSeed<'de>,
|
||||
{
|
||||
if self.idx >= self.property_len {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let prop_name = self.properties.get_index::<JsUnknown>(self.idx)?;
|
||||
|
||||
let mut de = De(&prop_name.0);
|
||||
seed.deserialize(&mut de).map(Some)
|
||||
}
|
||||
|
||||
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
|
||||
where
|
||||
V: DeserializeSeed<'de>,
|
||||
{
|
||||
if self.idx >= self.property_len {
|
||||
return Err(Error::new(
|
||||
Status::InvalidArg,
|
||||
format!("Index:{} out of range: {}", self.property_len, self.idx),
|
||||
));
|
||||
}
|
||||
let prop_name = self.properties.get_index::<JsString>(self.idx)?;
|
||||
let value: JsUnknown = self.value.get_property(&prop_name)?;
|
||||
|
||||
self.idx += 1;
|
||||
let mut de = De(&value.0);
|
||||
let res = seed.deserialize(&mut de)?;
|
||||
Ok(res)
|
||||
}
|
||||
}
|
|
@ -1,9 +1,14 @@
|
|||
use std::convert::From;
|
||||
use std::convert::{From, TryFrom};
|
||||
use std::ptr;
|
||||
|
||||
use crate::error::check_status;
|
||||
use crate::{sys, Error, Result, Status};
|
||||
|
||||
#[cfg(feature = "serde-json")]
|
||||
mod de;
|
||||
#[cfg(feature = "serde-json")]
|
||||
mod ser;
|
||||
|
||||
mod arraybuffer;
|
||||
#[cfg(napi6)]
|
||||
mod bigint;
|
||||
|
@ -27,10 +32,14 @@ pub use bigint::JsBigint;
|
|||
pub use boolean::JsBoolean;
|
||||
pub use buffer::JsBuffer;
|
||||
pub use class_property::Property;
|
||||
#[cfg(feature = "serde-json")]
|
||||
pub(crate) use de::De;
|
||||
pub use either::Either;
|
||||
pub use function::JsFunction;
|
||||
pub use number::JsNumber;
|
||||
pub use object::JsObject;
|
||||
#[cfg(feature = "serde-json")]
|
||||
pub(crate) use ser::Ser;
|
||||
pub use string::JsString;
|
||||
pub(crate) use tagged_object::TaggedObject;
|
||||
pub use undefined::JsUndefined;
|
||||
|
@ -94,6 +103,13 @@ macro_rules! impl_napi_value_trait {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<JsUnknown> for $js_value {
|
||||
type Error = Error;
|
||||
fn try_from(value: JsUnknown) -> Result<$js_value> {
|
||||
$js_value::from_raw(value.0.env, value.0.value)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -204,8 +220,6 @@ impl_js_value_methods!(JsString);
|
|||
impl_js_value_methods!(JsObject);
|
||||
impl_js_value_methods!(JsFunction);
|
||||
impl_js_value_methods!(JsExternal);
|
||||
#[cfg(napi6)]
|
||||
impl_js_value_methods!(JsBigint);
|
||||
impl_js_value_methods!(JsSymbol);
|
||||
|
||||
use ValueType::*;
|
||||
|
@ -218,8 +232,6 @@ impl_napi_value_trait!(JsString, String);
|
|||
impl_napi_value_trait!(JsObject, Object);
|
||||
impl_napi_value_trait!(JsFunction, Function);
|
||||
impl_napi_value_trait!(JsExternal, External);
|
||||
#[cfg(napi6)]
|
||||
impl_napi_value_trait!(JsBigint, Bigint);
|
||||
impl_napi_value_trait!(JsSymbol, Symbol);
|
||||
|
||||
impl NapiValue for JsUnknown {
|
||||
|
|
|
@ -21,28 +21,32 @@ impl JsObject {
|
|||
key: JsNumber,
|
||||
value: V,
|
||||
) -> Result<()> {
|
||||
let status =
|
||||
unsafe { sys::napi_set_property(self.0.env, self.0.value, key.0.value, value.raw_value()) };
|
||||
check_status(status)?;
|
||||
Ok(())
|
||||
check_status(unsafe {
|
||||
sys::napi_set_property(self.0.env, self.0.value, key.0.value, value.raw_value())
|
||||
})
|
||||
}
|
||||
|
||||
pub fn set_named_property<T: NapiValue>(&mut self, name: &str, value: T) -> Result<()> {
|
||||
let key = CString::new(name)?;
|
||||
let status = unsafe {
|
||||
check_status(unsafe {
|
||||
sys::napi_set_named_property(self.0.env, self.0.value, key.as_ptr(), value.raw_value())
|
||||
};
|
||||
check_status(status)?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_named_property<T: NapiValue>(&self, name: &str) -> Result<T> {
|
||||
let key = CString::new(name)?;
|
||||
let mut raw_value = ptr::null_mut();
|
||||
let status = unsafe {
|
||||
check_status(unsafe {
|
||||
sys::napi_get_named_property(self.0.env, self.0.value, key.as_ptr(), &mut raw_value)
|
||||
};
|
||||
check_status(status)?;
|
||||
})?;
|
||||
T::from_raw(self.0.env, raw_value)
|
||||
}
|
||||
|
||||
pub fn get_property<K: NapiValue, T: NapiValue>(&self, key: &K) -> Result<T> {
|
||||
let mut raw_value = ptr::null_mut();
|
||||
check_status(unsafe {
|
||||
sys::napi_get_property(self.0.env, self.0.value, key.raw_value(), &mut raw_value)
|
||||
})?;
|
||||
T::from_raw(self.0.env, raw_value)
|
||||
}
|
||||
|
||||
|
@ -59,22 +63,21 @@ impl JsObject {
|
|||
|
||||
pub fn get_index<T: NapiValue>(&self, index: u32) -> Result<T> {
|
||||
let mut raw_value = ptr::null_mut();
|
||||
let status = unsafe { sys::napi_get_element(self.0.env, self.0.value, index, &mut raw_value) };
|
||||
check_status(status)?;
|
||||
check_status(unsafe {
|
||||
sys::napi_get_element(self.0.env, self.0.value, index, &mut raw_value)
|
||||
})?;
|
||||
T::from_raw(self.0.env, raw_value)
|
||||
}
|
||||
|
||||
pub fn is_array(&self) -> Result<bool> {
|
||||
let mut is_array = false;
|
||||
let status = unsafe { sys::napi_is_array(self.0.env, self.0.value, &mut is_array) };
|
||||
check_status(status)?;
|
||||
check_status(unsafe { sys::napi_is_array(self.0.env, self.0.value, &mut is_array) })?;
|
||||
Ok(is_array)
|
||||
}
|
||||
|
||||
pub fn is_buffer(&self) -> Result<bool> {
|
||||
let mut is_buffer = false;
|
||||
let status = unsafe { sys::napi_is_buffer(self.0.env, self.0.value, &mut is_buffer) };
|
||||
check_status(status)?;
|
||||
check_status(unsafe { sys::napi_is_buffer(self.0.env, self.0.value, &mut is_buffer) })?;
|
||||
Ok(is_buffer)
|
||||
}
|
||||
|
||||
|
@ -89,9 +92,13 @@ impl JsObject {
|
|||
"Object is not array".to_owned(),
|
||||
));
|
||||
}
|
||||
self.get_array_length_unchecked()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_array_length_unchecked(&self) -> Result<u32> {
|
||||
let mut length: u32 = 0;
|
||||
let status = unsafe { sys::napi_get_array_length(self.0.env, self.raw_value(), &mut length) };
|
||||
check_status(status)?;
|
||||
check_status(unsafe { sys::napi_get_array_length(self.0.env, self.raw_value(), &mut length) })?;
|
||||
Ok(length)
|
||||
}
|
||||
}
|
||||
|
|
510
napi/src/js_values/ser.rs
Normal file
510
napi/src/js_values/ser.rs
Normal file
|
@ -0,0 +1,510 @@
|
|||
use std::result::Result as StdResult;
|
||||
#[cfg(napi6)]
|
||||
use std::slice;
|
||||
|
||||
use serde::{ser, Serialize, Serializer};
|
||||
|
||||
use super::*;
|
||||
use crate::{Env, Error, Result};
|
||||
|
||||
pub(crate) struct Ser<'env>(pub(crate) &'env Env);
|
||||
|
||||
impl<'env> Ser<'env> {
|
||||
fn new(env: &'env Env) -> Self {
|
||||
Self(&env)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'env> Serializer for Ser<'env> {
|
||||
type Ok = Value;
|
||||
type Error = Error;
|
||||
|
||||
type SerializeSeq = SeqSerializer;
|
||||
type SerializeTuple = SeqSerializer;
|
||||
type SerializeTupleStruct = SeqSerializer;
|
||||
type SerializeTupleVariant = SeqSerializer;
|
||||
type SerializeMap = MapSerializer;
|
||||
type SerializeStruct = StructSerializer;
|
||||
type SerializeStructVariant = StructSerializer;
|
||||
|
||||
#[inline]
|
||||
fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
|
||||
self.0.get_boolean(v).map(|js_value| js_value.0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok> {
|
||||
self
|
||||
.0
|
||||
.create_buffer_with_data(v.to_owned())
|
||||
.map(|js_value| js_value.value.0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn serialize_char(self, v: char) -> Result<Self::Ok> {
|
||||
let mut b = [0; 4];
|
||||
let result = v.encode_utf8(&mut b);
|
||||
self.0.create_string(result).map(|js_string| js_string.0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn serialize_f32(self, v: f32) -> Result<Self::Ok> {
|
||||
self.0.create_double(v as _).map(|js_number| js_number.0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn serialize_f64(self, v: f64) -> Result<Self::Ok> {
|
||||
self.0.create_double(v).map(|js_number| js_number.0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn serialize_i16(self, v: i16) -> Result<Self::Ok> {
|
||||
self.0.create_int32(v as _).map(|js_number| js_number.0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn serialize_i32(self, v: i32) -> Result<Self::Ok> {
|
||||
self.0.create_int32(v).map(|js_number| js_number.0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn serialize_i64(self, v: i64) -> Result<Self::Ok> {
|
||||
self.0.create_int64(v).map(|js_number| js_number.0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn serialize_i8(self, v: i8) -> Result<Self::Ok> {
|
||||
self.0.create_int32(v as _).map(|js_number| js_number.0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn serialize_u8(self, v: u8) -> Result<Self::Ok> {
|
||||
self.0.create_uint32(v as _).map(|js_number| js_number.0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn serialize_u16(self, v: u16) -> Result<Self::Ok> {
|
||||
self.0.create_uint32(v as _).map(|js_number| js_number.0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn serialize_u32(self, v: u32) -> Result<Self::Ok> {
|
||||
self.0.create_uint32(v).map(|js_number| js_number.0)
|
||||
}
|
||||
|
||||
#[cfg(all(any(napi2, napi3, napi4, napi5), not(napi6)))]
|
||||
#[inline]
|
||||
fn serialize_u64(self, v: u64) -> Result<Self::Ok> {
|
||||
self.0.create_int64(v as _).map(|js_number| js_number.0)
|
||||
}
|
||||
|
||||
#[cfg(napi6)]
|
||||
#[inline]
|
||||
fn serialize_u64(self, v: u64) -> Result<Self::Ok> {
|
||||
self
|
||||
.0
|
||||
.create_bigint_from_u64(v)
|
||||
.map(|js_number| js_number.raw)
|
||||
}
|
||||
|
||||
#[cfg(all(any(napi2, napi3, napi4, napi5), not(napi6)))]
|
||||
#[inline]
|
||||
fn serialize_u128(self, v: u128) -> Result<Self::Ok> {
|
||||
self.0.create_string(v.to_string().as_str()).map(|v| v.0)
|
||||
}
|
||||
|
||||
#[cfg(napi6)]
|
||||
#[inline]
|
||||
fn serialize_u128(self, v: u128) -> Result<Self::Ok> {
|
||||
let words_ref = &v as *const _;
|
||||
let words = unsafe { slice::from_raw_parts(words_ref as *const u64, 2) };
|
||||
self
|
||||
.0
|
||||
.create_bigint_from_words(false, words.to_vec())
|
||||
.map(|v| v.raw)
|
||||
}
|
||||
|
||||
#[cfg(all(any(napi2, napi3, napi4, napi5), not(napi6)))]
|
||||
#[inline]
|
||||
fn serialize_i128(self, v: i128) -> Result<Self::Ok> {
|
||||
self.0.create_string(v.to_string().as_str()).map(|v| v.0)
|
||||
}
|
||||
|
||||
#[cfg(napi6)]
|
||||
#[inline]
|
||||
fn serialize_i128(self, v: i128) -> Result<Self::Ok> {
|
||||
let words_ref = &(v as u128) as *const _;
|
||||
let words = unsafe { slice::from_raw_parts(words_ref as *const u64, 2) };
|
||||
self
|
||||
.0
|
||||
.create_bigint_from_words(v < 0, words.to_vec())
|
||||
.map(|v| v.raw)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn serialize_unit(self) -> Result<Self::Ok> {
|
||||
self.0.get_null().map(|null| null.0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn serialize_none(self) -> Result<Self::Ok> {
|
||||
self.0.get_null().map(|null| null.0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn serialize_str(self, v: &str) -> Result<Self::Ok> {
|
||||
self.0.create_string(v).map(|string| string.0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Self::Ok>
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
value.serialize(self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
|
||||
let env = self.0;
|
||||
let key = env.create_string("")?;
|
||||
let obj = env.create_object()?;
|
||||
Ok(MapSerializer { key, obj })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
|
||||
let array = self.0.create_array_with_length(len.unwrap_or(0))?;
|
||||
Ok(SeqSerializer {
|
||||
current_index: 0,
|
||||
array,
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn serialize_tuple_variant(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_variant_index: u32,
|
||||
variant: &'static str,
|
||||
len: usize,
|
||||
) -> Result<Self::SerializeTupleVariant> {
|
||||
let env = self.0;
|
||||
let array = env.create_array_with_length(len)?;
|
||||
let mut object = env.create_object()?;
|
||||
object.set_named_property(
|
||||
variant,
|
||||
JsObject(Value {
|
||||
value: array.0.value,
|
||||
env: array.0.env,
|
||||
value_type: ValueType::Object,
|
||||
}),
|
||||
)?;
|
||||
Ok(SeqSerializer {
|
||||
current_index: 0,
|
||||
array,
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok> {
|
||||
self.0.get_null().map(|null| null.0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn serialize_unit_variant(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_variant_index: u32,
|
||||
variant: &'static str,
|
||||
) -> Result<Self::Ok> {
|
||||
self.0.create_string(variant).map(|string| string.0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn serialize_newtype_struct<T: ?Sized>(self, _name: &'static str, value: &T) -> Result<Self::Ok>
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
value.serialize(self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn serialize_newtype_variant<T: ?Sized>(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_variant_index: u32,
|
||||
variant: &'static str,
|
||||
value: &T,
|
||||
) -> Result<Self::Ok>
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
let mut obj = self.0.create_object()?;
|
||||
obj.set_named_property(variant, JsUnknown(value.serialize(self)?))?;
|
||||
Ok(obj.0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
|
||||
Ok(SeqSerializer {
|
||||
array: self.0.create_array_with_length(len)?,
|
||||
current_index: 0,
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn serialize_tuple_struct(
|
||||
self,
|
||||
_name: &'static str,
|
||||
len: usize,
|
||||
) -> Result<Self::SerializeTupleStruct> {
|
||||
Ok(SeqSerializer {
|
||||
array: self.0.create_array_with_length(len)?,
|
||||
current_index: 0,
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
|
||||
Ok(StructSerializer {
|
||||
obj: self.0.create_object()?,
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn serialize_struct_variant(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_variant_index: u32,
|
||||
variant: &'static str,
|
||||
_len: usize,
|
||||
) -> Result<Self::SerializeStructVariant> {
|
||||
let mut outer = self.0.create_object()?;
|
||||
let inner = self.0.create_object()?;
|
||||
outer.set_named_property(
|
||||
variant,
|
||||
JsObject(Value {
|
||||
env: inner.0.env,
|
||||
value: inner.0.value,
|
||||
value_type: ValueType::Object,
|
||||
}),
|
||||
)?;
|
||||
Ok(StructSerializer {
|
||||
obj: self.0.create_object()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SeqSerializer {
|
||||
array: JsObject,
|
||||
current_index: usize,
|
||||
}
|
||||
|
||||
impl ser::SerializeSeq for SeqSerializer {
|
||||
type Ok = Value;
|
||||
type Error = Error;
|
||||
|
||||
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> StdResult<(), Self::Error>
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
let env = Env::from_raw(self.array.0.env);
|
||||
self.array.set_index(
|
||||
self.current_index,
|
||||
JsUnknown(value.serialize(Ser::new(&env))?),
|
||||
)?;
|
||||
self.current_index = self.current_index + 1;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn end(self) -> Result<Self::Ok> {
|
||||
Ok(self.array.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
impl ser::SerializeTuple for SeqSerializer {
|
||||
type Ok = Value;
|
||||
type Error = Error;
|
||||
|
||||
#[inline]
|
||||
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> StdResult<(), Self::Error>
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
let env = Env::from_raw(self.array.0.env);
|
||||
self.array.set_index(
|
||||
self.current_index,
|
||||
JsUnknown(value.serialize(Ser::new(&env))?),
|
||||
)?;
|
||||
self.current_index = self.current_index + 1;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn end(self) -> StdResult<Self::Ok, Self::Error> {
|
||||
Ok(self.array.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
impl ser::SerializeTupleStruct for SeqSerializer {
|
||||
type Ok = Value;
|
||||
type Error = Error;
|
||||
|
||||
#[inline]
|
||||
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> StdResult<(), Self::Error>
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
let env = Env::from_raw(self.array.0.env);
|
||||
self.array.set_index(
|
||||
self.current_index,
|
||||
JsUnknown(value.serialize(Ser::new(&env))?),
|
||||
)?;
|
||||
self.current_index = self.current_index + 1;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn end(self) -> StdResult<Self::Ok, Self::Error> {
|
||||
Ok(self.array.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
impl ser::SerializeTupleVariant for SeqSerializer {
|
||||
type Ok = Value;
|
||||
type Error = Error;
|
||||
|
||||
#[inline]
|
||||
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> StdResult<(), Self::Error>
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
let env = Env::from_raw(self.array.0.env);
|
||||
self.array.set_index(
|
||||
self.current_index,
|
||||
JsUnknown(value.serialize(Ser::new(&env))?),
|
||||
)?;
|
||||
self.current_index = self.current_index + 1;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn end(self) -> Result<Self::Ok> {
|
||||
Ok(self.array.0)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MapSerializer {
|
||||
key: JsString,
|
||||
obj: JsObject,
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
impl ser::SerializeMap for MapSerializer {
|
||||
type Ok = Value;
|
||||
type Error = Error;
|
||||
|
||||
#[inline]
|
||||
fn serialize_key<T: ?Sized>(&mut self, key: &T) -> StdResult<(), Self::Error>
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
let env = Env::from_raw(self.obj.0.env);
|
||||
self.key = JsString(key.serialize(Ser::new(&env))?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn serialize_value<T: ?Sized>(&mut self, value: &T) -> StdResult<(), Self::Error>
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
let env = Env::from_raw(self.obj.0.env);
|
||||
self.obj.set_property(
|
||||
JsString(Value {
|
||||
env: self.key.0.env,
|
||||
value: self.key.0.value,
|
||||
value_type: ValueType::String,
|
||||
}),
|
||||
JsUnknown(value.serialize(Ser::new(&env))?),
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn serialize_entry<K: ?Sized, V: ?Sized>(
|
||||
&mut self,
|
||||
key: &K,
|
||||
value: &V,
|
||||
) -> StdResult<(), Self::Error>
|
||||
where
|
||||
K: Serialize,
|
||||
V: Serialize,
|
||||
{
|
||||
let env = Env::from_raw(self.obj.0.env);
|
||||
self.obj.set_property(
|
||||
JsString(key.serialize(Ser::new(&env))?),
|
||||
JsUnknown(value.serialize(Ser::new(&env))?),
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn end(self) -> Result<Self::Ok> {
|
||||
Ok(self.obj.0)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct StructSerializer {
|
||||
obj: JsObject,
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
impl ser::SerializeStruct for StructSerializer {
|
||||
type Ok = Value;
|
||||
type Error = Error;
|
||||
|
||||
#[inline]
|
||||
fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> StdResult<(), Error>
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
let env = Env::from_raw(self.obj.0.env);
|
||||
self
|
||||
.obj
|
||||
.set_named_property(key, JsUnknown(value.serialize(Ser::new(&env))?))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn end(self) -> Result<Self::Ok> {
|
||||
Ok(self.obj.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
impl ser::SerializeStructVariant for StructSerializer {
|
||||
type Ok = Value;
|
||||
type Error = Error;
|
||||
|
||||
#[inline]
|
||||
fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> StdResult<(), Error>
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
let env = Env::from_raw(self.obj.0.env);
|
||||
self
|
||||
.obj
|
||||
.set_named_property(key, JsUnknown(value.serialize(Ser::new(&env))?))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn end(self) -> Result<Self::Ok> {
|
||||
Ok(self.obj.0)
|
||||
}
|
||||
}
|
|
@ -47,6 +47,30 @@ impl JsString {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn chars(&self) -> Result<&[char]> {
|
||||
let mut written_char_count: u64 = 0;
|
||||
let len = self.len()? + 1;
|
||||
let mut result = Vec::with_capacity(len);
|
||||
unsafe {
|
||||
let status = sys::napi_get_value_string_utf8(
|
||||
self.0.env,
|
||||
self.0.value,
|
||||
result.as_mut_ptr(),
|
||||
len as u64,
|
||||
&mut written_char_count,
|
||||
);
|
||||
|
||||
check_status(status)?;
|
||||
let ptr = result.as_ptr();
|
||||
mem::forget(result);
|
||||
Ok(slice::from_raw_parts(
|
||||
ptr as *const char,
|
||||
written_char_count as usize,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_str(&self) -> Result<&str> {
|
||||
str::from_utf8(self.get_ref()?)
|
||||
.map_err(|e| Error::new(Status::GenericFailure, format!("{:?}", e)))
|
||||
|
|
|
@ -2,7 +2,7 @@ use crate::sys;
|
|||
|
||||
use super::ValueType;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Value {
|
||||
pub env: sys::napi_env,
|
||||
pub value: sys::napi_value,
|
||||
|
|
|
@ -88,6 +88,10 @@ pub use version::NodeVersion;
|
|||
#[cfg(all(feature = "tokio_rt", napi4))]
|
||||
pub use tokio_rt::shutdown as shutdown_tokio_rt;
|
||||
|
||||
#[cfg(feature = "serde-json")]
|
||||
#[macro_use]
|
||||
extern crate serde;
|
||||
|
||||
/// register nodejs module
|
||||
///
|
||||
/// ## Example
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use std::convert::Into;
|
||||
use std::os::raw::{c_char, c_void};
|
||||
use std::ptr;
|
||||
|
||||
|
@ -7,6 +8,44 @@ use crate::{sys, Env, JsFunction, JsUnknown, Result};
|
|||
use sys::napi_threadsafe_function_call_mode;
|
||||
use sys::napi_threadsafe_function_release_mode;
|
||||
|
||||
#[repr(u8)]
|
||||
pub enum ThreadsafeFunctionCallMode {
|
||||
NonBlocking,
|
||||
Blocking,
|
||||
}
|
||||
|
||||
#[repr(u8)]
|
||||
pub enum ThreadsafeFunctionReleaseMode {
|
||||
Release,
|
||||
Abort,
|
||||
}
|
||||
|
||||
impl Into<napi_threadsafe_function_call_mode> for ThreadsafeFunctionCallMode {
|
||||
fn into(self) -> napi_threadsafe_function_call_mode {
|
||||
match self {
|
||||
ThreadsafeFunctionCallMode::Blocking => {
|
||||
napi_threadsafe_function_call_mode::napi_tsfn_blocking
|
||||
}
|
||||
ThreadsafeFunctionCallMode::NonBlocking => {
|
||||
napi_threadsafe_function_call_mode::napi_tsfn_nonblocking
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<napi_threadsafe_function_release_mode> for ThreadsafeFunctionReleaseMode {
|
||||
fn into(self) -> napi_threadsafe_function_release_mode {
|
||||
match self {
|
||||
ThreadsafeFunctionReleaseMode::Release => {
|
||||
napi_threadsafe_function_release_mode::napi_tsfn_release
|
||||
}
|
||||
ThreadsafeFunctionReleaseMode::Abort => {
|
||||
napi_threadsafe_function_release_mode::napi_tsfn_abort
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ToJs: Copy + Clone {
|
||||
type Output;
|
||||
|
||||
|
@ -25,17 +64,9 @@ pub trait ToJs: Copy + Clone {
|
|||
/// use std::thread;
|
||||
/// use napi::{
|
||||
/// Number, Result, Env, CallContext, JsUndefined, JsFunction,
|
||||
/// sys::{
|
||||
/// napi_threadsafe_function_call_mode::{
|
||||
/// napi_tsfn_blocking,
|
||||
/// },
|
||||
/// napi_threadsafe_function_release_mode::{
|
||||
/// napi_tsfn_release,
|
||||
/// }
|
||||
/// }
|
||||
/// };
|
||||
/// use napi::threadsafe_function::{
|
||||
/// ToJs, ThreadsafeFunction,
|
||||
/// ToJs, ThreadsafeFunction, ThreadsafeFunctionCallMode, ThreadsafeFunctionReleaseMode,
|
||||
/// };
|
||||
///
|
||||
/// // Define a struct for handling the data passed from `ThreadsafeFunction::call`
|
||||
|
@ -67,12 +98,12 @@ pub trait ToJs: Copy + Clone {
|
|||
/// thread::spawn(move || {
|
||||
/// let output: u8 = 42;
|
||||
/// // It's okay to call a threadsafe function multiple times.
|
||||
/// tsfn.call(Ok(output), napi_tsfn_blocking).unwrap();
|
||||
/// tsfn.call(Ok(output), napi_tsfn_blocking).unwrap();
|
||||
/// tsfn.call(Ok(output), ThreadsafeFunctionCallMode::Blocking).unwrap();
|
||||
/// tsfn.call(Ok(output), ThreadsafeFunctionCallMode::Blocking).unwrap();
|
||||
/// // We should call `ThreadsafeFunction::release` manually when we don't
|
||||
/// // need the instance anymore, or it will prevent Node.js from exiting
|
||||
/// // automatically and possibly cause memory leaks.
|
||||
/// tsfn.release(napi_tsfn_release).unwrap();
|
||||
/// tsfn.release(ThreadsafeFunctionReleaseMode::Release).unwrap();
|
||||
/// });
|
||||
///
|
||||
/// ctx.env.get_undefined()
|
||||
|
@ -137,16 +168,12 @@ impl<T: ToJs> ThreadsafeFunction<T> {
|
|||
|
||||
/// See [napi_call_threadsafe_function](https://nodejs.org/api/n-api.html#n_api_napi_call_threadsafe_function)
|
||||
/// for more information.
|
||||
pub fn call(
|
||||
&self,
|
||||
value: Result<T::Output>,
|
||||
mode: napi_threadsafe_function_call_mode,
|
||||
) -> Result<()> {
|
||||
pub fn call(&self, value: Result<T::Output>, mode: ThreadsafeFunctionCallMode) -> Result<()> {
|
||||
check_status(unsafe {
|
||||
sys::napi_call_threadsafe_function(
|
||||
self.raw_value,
|
||||
Box::into_raw(Box::from(value)) as *mut _ as *mut c_void,
|
||||
mode,
|
||||
mode.into(),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
@ -159,8 +186,8 @@ impl<T: ToJs> ThreadsafeFunction<T> {
|
|||
|
||||
/// See [napi_release_threadsafe_function](https://nodejs.org/api/n-api.html#n_api_napi_release_threadsafe_function)
|
||||
/// for more information.
|
||||
pub fn release(&self, mode: napi_threadsafe_function_release_mode) -> Result<()> {
|
||||
check_status(unsafe { sys::napi_release_threadsafe_function(self.raw_value, mode) })
|
||||
pub fn release(&self, mode: ThreadsafeFunctionReleaseMode) -> Result<()> {
|
||||
check_status(unsafe { sys::napi_release_threadsafe_function(self.raw_value, mode.into()) })
|
||||
}
|
||||
|
||||
/// See [napi_ref_threadsafe_function](https://nodejs.org/api/n-api.html#n_api_napi_ref_threadsafe_function)
|
||||
|
|
14
package.json
14
package.json
|
@ -33,7 +33,7 @@
|
|||
},
|
||||
"homepage": "https://github.com/napi-rs/napi-rs#readme",
|
||||
"dependencies": {
|
||||
"clipanion": "^2.4.4",
|
||||
"clipanion": "^2.5.0",
|
||||
"inquirer": "^7.3.3",
|
||||
"toml": "^3.0.0"
|
||||
},
|
||||
|
@ -58,13 +58,13 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@istanbuljs/nyc-config-typescript": "^1.0.1",
|
||||
"@swc-node/register": "^0.4.2",
|
||||
"@swc-node/register": "^0.4.5",
|
||||
"@types/inquirer": "^7.3.1",
|
||||
"@types/node": "^14.6.0",
|
||||
"@typescript-eslint/eslint-plugin": "^4.0.0",
|
||||
"@typescript-eslint/parser": "^3.10.1",
|
||||
"@types/node": "^14.6.2",
|
||||
"@typescript-eslint/eslint-plugin": "^4.0.1",
|
||||
"@typescript-eslint/parser": "^4.0.1",
|
||||
"ava": "^3.12.1",
|
||||
"eslint": "^7.7.0",
|
||||
"eslint": "^7.8.0",
|
||||
"eslint-config-prettier": "^6.11.0",
|
||||
"eslint-plugin-import": "^2.22.0",
|
||||
"eslint-plugin-prettier": "^3.1.4",
|
||||
|
@ -78,7 +78,7 @@
|
|||
"typescript": "^4.0.2"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@swc-node/core-linux-musl": "^0.6.0",
|
||||
"@swc-node/core-linux-musl": "^0.6.1",
|
||||
"tslib": "^2.0.1"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,12 @@ crate-type = ["cdylib"]
|
|||
|
||||
[dependencies]
|
||||
futures = "0.3"
|
||||
napi = { path = "../napi", features = ["libuv", "tokio_rt"] }
|
||||
napi = { path = "../napi", features = ["libuv", "tokio_rt", "serde-json"] }
|
||||
napi-derive = { path = "../napi-derive" }
|
||||
serde = "1"
|
||||
serde_bytes = "0.11"
|
||||
serde_derive = "1"
|
||||
serde_json = "1"
|
||||
tokio = { version = "0.2", features = ["default", "fs"]}
|
||||
|
||||
[build-dependencies]
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
// @ts-expect-error
|
||||
export const napiVersion = parseInt(process.versions.napi || '1', 10)
|
||||
export const napiVersion = parseInt(process.versions.napi ?? '1', 10)
|
||||
|
|
39
test_module/__test__/serde/de.spec.ts
Normal file
39
test_module/__test__/serde/de.spec.ts
Normal file
|
@ -0,0 +1,39 @@
|
|||
import test from 'ava'
|
||||
|
||||
import { napiVersion } from '../napi-version'
|
||||
|
||||
const bindings = require('../../index.node')
|
||||
|
||||
test('deserialize string', (t) => {
|
||||
t.notThrows(() => bindings.expect_hello_world('hello world'))
|
||||
})
|
||||
|
||||
test('deserialize object', (t) => {
|
||||
if (napiVersion < 6) {
|
||||
t.throws(() => {
|
||||
bindings.expect_obj({})
|
||||
})
|
||||
} else {
|
||||
t.notThrows(() =>
|
||||
bindings.expect_obj({
|
||||
a: 1,
|
||||
b: [1, 2],
|
||||
c: 'abc',
|
||||
d: false,
|
||||
e: null,
|
||||
f: null,
|
||||
g: [9, false, 'efg'],
|
||||
h: '🤷',
|
||||
i: 'Empty',
|
||||
j: { Tuple: [27, 'hij'] },
|
||||
k: { Struct: { a: 128, b: [9, 8, 7] } },
|
||||
l: 'jkl',
|
||||
m: [0, 1, 2, 3, 4],
|
||||
o: { Value: ['z', 'y', 'x'] },
|
||||
p: [1, 2, 3.5],
|
||||
q: BigInt('9998881288248882845242411222333'),
|
||||
r: BigInt('-3332323888900001232323022221345'),
|
||||
}),
|
||||
)
|
||||
}
|
||||
})
|
26
test_module/__test__/serde/ser.spec.ts
Normal file
26
test_module/__test__/serde/ser.spec.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
import test from 'ava'
|
||||
|
||||
import { napiVersion } from '../napi-version'
|
||||
|
||||
const bindings = require('../../index.node')
|
||||
|
||||
const testFunc = [
|
||||
'make_num_77',
|
||||
'make_num_32',
|
||||
'make_str_hello',
|
||||
'make_num_array',
|
||||
'make_buff',
|
||||
'make_obj',
|
||||
'make_map',
|
||||
]
|
||||
|
||||
if (napiVersion >= 6) {
|
||||
// bigint inside
|
||||
testFunc.push('make_object')
|
||||
}
|
||||
|
||||
for (const func of testFunc) {
|
||||
test(`serialize ${func} from bindings`, (t) => {
|
||||
t.snapshot(bindings[func]())
|
||||
})
|
||||
}
|
130
test_module/__test__/serde/ser.spec.ts.md
Normal file
130
test_module/__test__/serde/ser.spec.ts.md
Normal file
|
@ -0,0 +1,130 @@
|
|||
# Snapshot report for `test_module/__test__/serde/ser.spec.ts`
|
||||
|
||||
The actual snapshot is saved in `ser.spec.ts.snap`.
|
||||
|
||||
Generated by [AVA](https://avajs.dev).
|
||||
|
||||
## serialize make_buff from bindings
|
||||
|
||||
> Snapshot 1
|
||||
|
||||
Buffer @Uint8Array [
|
||||
fffefd
|
||||
]
|
||||
|
||||
## serialize make_map from bindings
|
||||
|
||||
> Snapshot 1
|
||||
|
||||
{
|
||||
a: 1,
|
||||
b: 2,
|
||||
c: 3,
|
||||
}
|
||||
|
||||
## serialize make_num_32 from bindings
|
||||
|
||||
> Snapshot 1
|
||||
|
||||
32
|
||||
|
||||
## serialize make_num_77 from bindings
|
||||
|
||||
> Snapshot 1
|
||||
|
||||
77
|
||||
|
||||
## serialize make_num_array from bindings
|
||||
|
||||
> Snapshot 1
|
||||
|
||||
[
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
]
|
||||
|
||||
## serialize make_obj from bindings
|
||||
|
||||
> Snapshot 1
|
||||
|
||||
{
|
||||
a: 1,
|
||||
b: [
|
||||
0.1,
|
||||
1.1,
|
||||
2.2,
|
||||
3.3,
|
||||
],
|
||||
c: 'Hi',
|
||||
}
|
||||
|
||||
## serialize make_object from bindings
|
||||
|
||||
> Snapshot 1
|
||||
|
||||
{
|
||||
a: 1,
|
||||
b: [
|
||||
1,
|
||||
2,
|
||||
],
|
||||
c: 'abc',
|
||||
d: false,
|
||||
e: null,
|
||||
f: null,
|
||||
g: [
|
||||
9,
|
||||
false,
|
||||
'efg',
|
||||
],
|
||||
h: '🤷',
|
||||
i: 'Empty',
|
||||
j: [
|
||||
27,
|
||||
'hij',
|
||||
],
|
||||
k: {
|
||||
a: 128,
|
||||
b: [
|
||||
9,
|
||||
8,
|
||||
7,
|
||||
],
|
||||
},
|
||||
l: 'jkl',
|
||||
m: [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
],
|
||||
o: {
|
||||
Value: [
|
||||
'z',
|
||||
'y',
|
||||
'x',
|
||||
],
|
||||
},
|
||||
p: [
|
||||
1,
|
||||
2,
|
||||
3.5,
|
||||
],
|
||||
q: 9998881288248882845242411222333n,
|
||||
r: -340282363588614574563373375108745990111n,
|
||||
}
|
||||
|
||||
## serialize make_str_hello from bindings
|
||||
|
||||
> Snapshot 1
|
||||
|
||||
'Hello World'
|
BIN
test_module/__test__/serde/ser.spec.ts.snap
Normal file
BIN
test_module/__test__/serde/ser.spec.ts.snap
Normal file
Binary file not shown.
|
@ -2,6 +2,8 @@
|
|||
extern crate napi;
|
||||
#[macro_use]
|
||||
extern crate napi_derive;
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
use napi::{CallContext, Error, JsBoolean, JsString, JsUnknown, Module, Result, Status};
|
||||
|
||||
|
@ -11,10 +13,10 @@ mod libuv;
|
|||
mod napi4;
|
||||
#[cfg(napi5)]
|
||||
mod napi5;
|
||||
#[cfg(napi4)]
|
||||
mod tokio_rt;
|
||||
#[cfg(napi6)]
|
||||
mod napi6;
|
||||
#[cfg(napi4)]
|
||||
mod tokio_rt;
|
||||
|
||||
mod buffer;
|
||||
mod class;
|
||||
|
@ -22,6 +24,7 @@ mod either;
|
|||
mod external;
|
||||
mod function;
|
||||
mod napi_version;
|
||||
mod serde;
|
||||
mod string;
|
||||
mod symbol;
|
||||
mod task;
|
||||
|
@ -36,24 +39,21 @@ use libuv::read_file::uv_read_file;
|
|||
use napi4::{test_threadsafe_function, test_tokio_readfile, test_tsfn_error};
|
||||
#[cfg(napi5)]
|
||||
use napi5::is_date::test_object_is_date;
|
||||
#[cfg(napi6)]
|
||||
use napi6::bigint::{
|
||||
test_create_bigint_from_i64, test_create_bigint_from_u64, test_create_bigint_from_words,
|
||||
test_get_bigint_i64, test_get_bigint_u64, test_get_bigint_words,
|
||||
};
|
||||
use napi_version::get_napi_version;
|
||||
use symbol::{create_named_symbol, create_symbol_from_js_string, create_unnamed_symbol};
|
||||
use task::test_spawn_thread;
|
||||
#[cfg(napi4)]
|
||||
use tokio_rt::{error_from_tokio_future, test_execute_tokio_readfile};
|
||||
#[cfg(napi6)]
|
||||
use napi6::bigint::{
|
||||
test_create_bigint_from_i64,
|
||||
test_create_bigint_from_u64,
|
||||
test_create_bigint_from_words,
|
||||
test_get_bigint_i64,
|
||||
test_get_bigint_u64,
|
||||
test_get_bigint_words,
|
||||
};
|
||||
|
||||
register_module!(test_module, init);
|
||||
|
||||
fn init(module: &mut Module) -> Result<()> {
|
||||
serde::register_serde_func(module)?;
|
||||
module.create_named_method("testThrow", test_throw)?;
|
||||
module.create_named_method("testThrowWithReason", test_throw_with_reason)?;
|
||||
module.create_named_method("testSpawnThread", test_spawn_thread)?;
|
||||
|
|
|
@ -1,15 +1,10 @@
|
|||
use std::path::Path;
|
||||
use std::thread;
|
||||
|
||||
use napi::sys::{
|
||||
napi_threadsafe_function_call_mode::napi_tsfn_blocking,
|
||||
napi_threadsafe_function_release_mode::napi_tsfn_release,
|
||||
};
|
||||
use napi::threadsafe_function::{ThreadsafeFunction, ToJs};
|
||||
use napi::{
|
||||
CallContext, Env, Error, JsFunction, JsString, JsUndefined, Result, Status,
|
||||
JsUnknown,
|
||||
use napi::threadsafe_function::{
|
||||
ThreadsafeFunction, ThreadsafeFunctionCallMode, ThreadsafeFunctionReleaseMode, ToJs,
|
||||
};
|
||||
use napi::{CallContext, Env, Error, JsFunction, JsString, JsUndefined, JsUnknown, Result, Status};
|
||||
use tokio;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
|
@ -38,9 +33,15 @@ pub fn test_threadsafe_function(ctx: CallContext) -> Result<JsUndefined> {
|
|||
thread::spawn(move || {
|
||||
let output: Vec<u8> = vec![42, 1, 2, 3];
|
||||
// It's okay to call a threadsafe function multiple times.
|
||||
tsfn.call(Ok(output.clone()), napi_tsfn_blocking).unwrap();
|
||||
tsfn.call(Ok(output.clone()), napi_tsfn_blocking).unwrap();
|
||||
tsfn.release(napi_tsfn_release).unwrap();
|
||||
tsfn
|
||||
.call(Ok(output.clone()), ThreadsafeFunctionCallMode::Blocking)
|
||||
.unwrap();
|
||||
tsfn
|
||||
.call(Ok(output.clone()), ThreadsafeFunctionCallMode::Blocking)
|
||||
.unwrap();
|
||||
tsfn
|
||||
.release(ThreadsafeFunctionReleaseMode::Release)
|
||||
.unwrap();
|
||||
});
|
||||
|
||||
ctx.env.get_undefined()
|
||||
|
@ -56,10 +57,12 @@ pub fn test_tsfn_error(ctx: CallContext) -> Result<JsUndefined> {
|
|||
tsfn
|
||||
.call(
|
||||
Err(Error::new(Status::Unknown, "invalid".to_owned())),
|
||||
napi_tsfn_blocking,
|
||||
ThreadsafeFunctionCallMode::Blocking,
|
||||
)
|
||||
.unwrap();
|
||||
tsfn.release(napi_tsfn_release).unwrap();
|
||||
tsfn
|
||||
.release(ThreadsafeFunctionReleaseMode::Release)
|
||||
.unwrap();
|
||||
});
|
||||
|
||||
ctx.env.get_undefined()
|
||||
|
@ -72,7 +75,9 @@ impl ToJs for HandleBuffer {
|
|||
type Output = Vec<u8>;
|
||||
|
||||
fn resolve(&self, env: &mut Env, output: Self::Output) -> Result<Vec<JsUnknown>> {
|
||||
let value = env.create_buffer_with_data(output.to_vec())?.into_unknown()?;
|
||||
let value = env
|
||||
.create_buffer_with_data(output.to_vec())?
|
||||
.into_unknown()?;
|
||||
Ok(vec![value])
|
||||
}
|
||||
}
|
||||
|
@ -96,8 +101,10 @@ pub fn test_tokio_readfile(ctx: CallContext) -> Result<JsUndefined> {
|
|||
rt.block_on(async move {
|
||||
let mut filepath = Path::new(path_str);
|
||||
let ret = read_file_content(&mut filepath).await;
|
||||
let _ = tsfn.call(ret, napi_tsfn_blocking);
|
||||
tsfn.release(napi_tsfn_release).unwrap();
|
||||
let _ = tsfn.call(ret, ThreadsafeFunctionCallMode::Blocking);
|
||||
tsfn
|
||||
.release(ThreadsafeFunctionReleaseMode::Release)
|
||||
.unwrap();
|
||||
});
|
||||
|
||||
ctx.env.get_undefined()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use napi::{CallContext, JsBigint, JsNumber, JsObject, Result};
|
||||
use std::convert::TryFrom;
|
||||
use napi::{CallContext, JsBigint, Result, JsNumber, JsObject};
|
||||
|
||||
#[js_function(0)]
|
||||
pub fn test_create_bigint_from_i64(ctx: CallContext) -> Result<JsBigint> {
|
||||
|
@ -13,7 +13,9 @@ pub fn test_create_bigint_from_u64(ctx: CallContext) -> Result<JsBigint> {
|
|||
|
||||
#[js_function(0)]
|
||||
pub fn test_create_bigint_from_words(ctx: CallContext) -> Result<JsBigint> {
|
||||
ctx.env.create_bigint_from_words(true, vec![u64::max_value(), u64::max_value()])
|
||||
ctx
|
||||
.env
|
||||
.create_bigint_from_words(true, vec![u64::max_value(), u64::max_value()])
|
||||
}
|
||||
|
||||
#[js_function(1)]
|
||||
|
@ -32,16 +34,18 @@ pub fn test_get_bigint_u64(ctx: CallContext) -> Result<JsNumber> {
|
|||
|
||||
#[js_function(0)]
|
||||
pub fn test_get_bigint_words(ctx: CallContext) -> Result<JsObject> {
|
||||
let js_bigint = ctx.env.create_bigint_from_words(true, vec![i64::max_value() as u64, i64::max_value() as u64])?;
|
||||
let mut js_bigint = ctx
|
||||
.env
|
||||
.create_bigint_from_words(true, vec![i64::max_value() as u64, i64::max_value() as u64])?;
|
||||
let mut js_arr = ctx.env.create_array_with_length(2)?;
|
||||
let words = js_bigint.get_words(true)?;
|
||||
let (_signed, words) = js_bigint.get_words()?;
|
||||
js_arr.set_number_indexed_property(
|
||||
ctx.env.create_int64(0)?,
|
||||
ctx.env.create_bigint_from_u64(words[0])?
|
||||
ctx.env.create_bigint_from_u64(words[0])?,
|
||||
)?;
|
||||
js_arr.set_number_indexed_property(
|
||||
ctx.env.create_int64(1)?,
|
||||
ctx.env.create_bigint_from_u64(words[1])?
|
||||
ctx.env.create_bigint_from_u64(words[1])?,
|
||||
)?;
|
||||
Ok(js_arr)
|
||||
}
|
||||
|
|
182
test_module/src/serde.rs
Normal file
182
test_module/src/serde.rs
Normal file
|
@ -0,0 +1,182 @@
|
|||
use napi::{CallContext, JsObject, JsUndefined, JsUnknown, Module, Result};
|
||||
|
||||
#[derive(Serialize, Debug, Deserialize)]
|
||||
struct AnObject {
|
||||
a: u32,
|
||||
b: Vec<f64>,
|
||||
c: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Debug, Deserialize, Eq, PartialEq)]
|
||||
struct Inner;
|
||||
|
||||
#[derive(Serialize, Debug, Deserialize, Eq, PartialEq)]
|
||||
struct Inner2(i32, bool, String);
|
||||
|
||||
#[derive(Serialize, Debug, Deserialize, Eq, PartialEq)]
|
||||
enum TypeEnum {
|
||||
Empty,
|
||||
Tuple(u32, String),
|
||||
Struct { a: u8, b: Vec<u8> },
|
||||
Value(Vec<char>),
|
||||
}
|
||||
|
||||
#[derive(Serialize, Debug, Deserialize, PartialEq)]
|
||||
struct AnObjectTwo {
|
||||
a: u32,
|
||||
b: Vec<i64>,
|
||||
c: String,
|
||||
d: Option<bool>,
|
||||
e: Option<bool>,
|
||||
f: Inner,
|
||||
g: Inner2,
|
||||
h: char,
|
||||
i: TypeEnum,
|
||||
j: TypeEnum,
|
||||
k: TypeEnum,
|
||||
l: String,
|
||||
m: Vec<u8>,
|
||||
o: TypeEnum,
|
||||
p: Vec<f64>,
|
||||
q: u128,
|
||||
r: i128,
|
||||
}
|
||||
|
||||
macro_rules! make_test {
|
||||
($name:ident, $val:expr) => {
|
||||
#[js_function]
|
||||
fn $name(ctx: CallContext) -> Result<JsUnknown> {
|
||||
let value = $val;
|
||||
ctx.env.to_js_value(&value)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
make_test!(make_num_77, 77i32);
|
||||
make_test!(make_num_32, 32u8);
|
||||
make_test!(make_str_hello, "Hello World");
|
||||
make_test!(make_num_array, vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
|
||||
make_test!(
|
||||
make_obj,
|
||||
AnObject {
|
||||
a: 1,
|
||||
b: vec![0.1f64, 1.1, 2.2, 3.3],
|
||||
c: "Hi".into(),
|
||||
}
|
||||
);
|
||||
make_test!(make_map, {
|
||||
use std::collections::HashMap;
|
||||
let mut map = HashMap::new();
|
||||
map.insert("a", 1);
|
||||
map.insert("b", 2);
|
||||
map.insert("c", 3);
|
||||
map
|
||||
});
|
||||
|
||||
make_test!(make_object, {
|
||||
let value = AnObjectTwo {
|
||||
a: 1,
|
||||
b: vec![1, 2],
|
||||
c: "abc".into(),
|
||||
d: Some(false),
|
||||
e: None,
|
||||
f: Inner,
|
||||
g: Inner2(9, false, "efg".into()),
|
||||
h: '🤷',
|
||||
i: TypeEnum::Empty,
|
||||
j: TypeEnum::Tuple(27, "hij".into()),
|
||||
k: TypeEnum::Struct {
|
||||
a: 128,
|
||||
b: vec![9, 8, 7],
|
||||
},
|
||||
l: "jkl".into(),
|
||||
m: vec![0, 1, 2, 3, 4],
|
||||
o: TypeEnum::Value(vec!['z', 'y', 'x']),
|
||||
p: vec![1., 2., 3.5],
|
||||
q: 9998881288248882845242411222333,
|
||||
r: -3332323888900001232323022221345,
|
||||
};
|
||||
value
|
||||
});
|
||||
|
||||
const NUMBER_BYTES: &'static [u8] = &[255u8, 254, 253];
|
||||
|
||||
make_test!(make_buff, { serde_bytes::Bytes::new(NUMBER_BYTES) });
|
||||
|
||||
macro_rules! make_expect {
|
||||
($name:ident, $val:expr, $val_type:ty) => {
|
||||
#[js_function(1)]
|
||||
fn $name(ctx: CallContext) -> Result<JsUndefined> {
|
||||
let value = $val;
|
||||
let arg0 = ctx.get::<JsUnknown>(0)?;
|
||||
|
||||
let de_serialized: $val_type = ctx.env.from_js_value(arg0)?;
|
||||
assert_eq!(value, de_serialized);
|
||||
ctx.env.get_undefined()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
make_expect!(expect_hello_world, "hello world", String);
|
||||
|
||||
make_expect!(
|
||||
expect_obj,
|
||||
AnObjectTwo {
|
||||
a: 1,
|
||||
b: vec![1, 2],
|
||||
c: "abc".into(),
|
||||
d: Some(false),
|
||||
e: None,
|
||||
f: Inner,
|
||||
g: Inner2(9, false, "efg".into()),
|
||||
h: '🤷',
|
||||
i: TypeEnum::Empty,
|
||||
j: TypeEnum::Tuple(27, "hij".into()),
|
||||
k: TypeEnum::Struct {
|
||||
a: 128,
|
||||
b: vec![9, 8, 7],
|
||||
},
|
||||
l: "jkl".into(),
|
||||
m: vec![0, 1, 2, 3, 4],
|
||||
o: TypeEnum::Value(vec!['z', 'y', 'x']),
|
||||
p: vec![1., 2., 3.5],
|
||||
q: 9998881288248882845242411222333,
|
||||
r: -3332323888900001232323022221345,
|
||||
},
|
||||
AnObjectTwo
|
||||
);
|
||||
|
||||
make_expect!(expect_num_array, vec![0, 1, 2, 3], Vec<i32>);
|
||||
|
||||
make_expect!(
|
||||
expect_buffer,
|
||||
serde_bytes::ByteBuf::from(vec![252u8, 251, 250]),
|
||||
serde_bytes::ByteBuf
|
||||
);
|
||||
|
||||
#[js_function(1)]
|
||||
fn roundtrip_object(ctx: CallContext) -> Result<JsUnknown> {
|
||||
let arg0 = ctx.get::<JsObject>(0)?;
|
||||
|
||||
let de_serialized: AnObjectTwo = ctx.env.from_js_value(arg0)?;
|
||||
ctx.env.to_js_value(&de_serialized)
|
||||
}
|
||||
|
||||
pub fn register_serde_func(m: &mut Module) -> Result<()> {
|
||||
m.create_named_method("make_num_77", make_num_77)?;
|
||||
m.create_named_method("make_num_32", make_num_32)?;
|
||||
m.create_named_method("make_str_hello", make_str_hello)?;
|
||||
m.create_named_method("make_num_array", make_num_array)?;
|
||||
m.create_named_method("make_buff", make_buff)?;
|
||||
m.create_named_method("make_obj", make_obj)?;
|
||||
m.create_named_method("make_object", make_object)?;
|
||||
m.create_named_method("make_map", make_map)?;
|
||||
|
||||
m.create_named_method("expect_hello_world", expect_hello_world)?;
|
||||
m.create_named_method("expect_obj", expect_obj)?;
|
||||
m.create_named_method("expect_num_array", expect_num_array)?;
|
||||
m.create_named_method("expect_buffer", expect_buffer)?;
|
||||
|
||||
m.create_named_method("roundtrip_object", roundtrip_object)?;
|
||||
Ok(())
|
||||
}
|
|
@ -20,25 +20,14 @@
|
|||
"suppressExcessPropertyErrors": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"preserveSymlinks": true,
|
||||
"target": "ES2015",
|
||||
"target": "ES2018",
|
||||
"sourceMap": true,
|
||||
"esModuleInterop": true,
|
||||
"stripInternal": true,
|
||||
"resolveJsonModule": true,
|
||||
"importsNotUsedAsValues": "remove",
|
||||
"outDir": "./scripts",
|
||||
"lib": [
|
||||
"dom",
|
||||
"DOM.Iterable",
|
||||
"ES5",
|
||||
"ES2015",
|
||||
"ES2016",
|
||||
"ES2017",
|
||||
"ES2018",
|
||||
"ES2019",
|
||||
"ES2020",
|
||||
"esnext"
|
||||
]
|
||||
"lib": ["dom", "DOM.Iterable", "ES2019", "ES2020", "esnext"]
|
||||
},
|
||||
"include": ["./src"],
|
||||
"exclude": ["node_modules"]
|
||||
|
|
359
yarn.lock
359
yarn.lock
|
@ -10,18 +10,18 @@
|
|||
"@babel/highlight" "^7.10.4"
|
||||
|
||||
"@babel/core@^7.7.5":
|
||||
version "7.11.4"
|
||||
resolved "https://registry.npmjs.org/@babel/core/-/core-7.11.4.tgz#4301dfdfafa01eeb97f1896c5501a3f0655d4229"
|
||||
integrity sha512-5deljj5HlqRXN+5oJTY7Zs37iH3z3b++KjiKtIsJy1NrjOOVSEaJHEetLBhyu0aQOSNNZ/0IuEAan9GzRuDXHg==
|
||||
version "7.11.5"
|
||||
resolved "https://registry.npmjs.org/@babel/core/-/core-7.11.5.tgz#6ad96e2f71899ea3f9b651f0a911e85205d1ff6d"
|
||||
integrity sha512-fsEANVOcZHzrsV6dMVWqpSeXClq3lNbYrfFGme6DE25FQWe7pyeYpXyx9guqUnpy466JLzZ8z4uwSr2iv60V5Q==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.10.4"
|
||||
"@babel/generator" "^7.11.4"
|
||||
"@babel/generator" "^7.11.5"
|
||||
"@babel/helper-module-transforms" "^7.11.0"
|
||||
"@babel/helpers" "^7.10.4"
|
||||
"@babel/parser" "^7.11.4"
|
||||
"@babel/parser" "^7.11.5"
|
||||
"@babel/template" "^7.10.4"
|
||||
"@babel/traverse" "^7.11.0"
|
||||
"@babel/types" "^7.11.0"
|
||||
"@babel/traverse" "^7.11.5"
|
||||
"@babel/types" "^7.11.5"
|
||||
convert-source-map "^1.7.0"
|
||||
debug "^4.1.0"
|
||||
gensync "^1.0.0-beta.1"
|
||||
|
@ -29,16 +29,16 @@
|
|||
lodash "^4.17.19"
|
||||
resolve "^1.3.2"
|
||||
semver "^5.4.1"
|
||||
source-map "^0.5.0"
|
||||
source-map "^0.6.1"
|
||||
|
||||
"@babel/generator@^7.11.0", "@babel/generator@^7.11.4":
|
||||
version "7.11.4"
|
||||
resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.11.4.tgz#1ec7eec00defba5d6f83e50e3ee72ae2fee482be"
|
||||
integrity sha512-Rn26vueFx0eOoz7iifCN2UHT6rGtnkSGWSoDRIy8jZN3B91PzeSULbswfLoOWuTuAcNwpG/mxy+uCTDnZ9Mp1g==
|
||||
"@babel/generator@^7.11.5":
|
||||
version "7.11.5"
|
||||
resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.11.5.tgz#a5582773425a468e4ba269d9a1f701fbca6a7a82"
|
||||
integrity sha512-9UqHWJ4IwRTy4l0o8gq2ef8ws8UPzvtMkVKjTLAiRmza9p9V6Z+OfuNd9fB1j5Q67F+dVJtPC2sZXI8NM9br4g==
|
||||
dependencies:
|
||||
"@babel/types" "^7.11.0"
|
||||
"@babel/types" "^7.11.5"
|
||||
jsesc "^2.5.1"
|
||||
source-map "^0.5.0"
|
||||
source-map "^0.6.1"
|
||||
|
||||
"@babel/helper-function-name@^7.10.4":
|
||||
version "7.10.4"
|
||||
|
@ -138,10 +138,10 @@
|
|||
chalk "^2.0.0"
|
||||
js-tokens "^4.0.0"
|
||||
|
||||
"@babel/parser@^7.10.4", "@babel/parser@^7.11.0", "@babel/parser@^7.11.4":
|
||||
version "7.11.4"
|
||||
resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.11.4.tgz#6fa1a118b8b0d80d0267b719213dc947e88cc0ca"
|
||||
integrity sha512-MggwidiH+E9j5Sh8pbrX5sJvMcsqS5o+7iB42M9/k0CD63MjYbdP4nhSh7uB5wnv2/RVzTZFTxzF/kIa5mrCqA==
|
||||
"@babel/parser@^7.10.4", "@babel/parser@^7.11.5":
|
||||
version "7.11.5"
|
||||
resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.11.5.tgz#c7ff6303df71080ec7a4f5b8c003c58f1cf51037"
|
||||
integrity sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q==
|
||||
|
||||
"@babel/template@^7.10.4":
|
||||
version "7.10.4"
|
||||
|
@ -152,25 +152,25 @@
|
|||
"@babel/parser" "^7.10.4"
|
||||
"@babel/types" "^7.10.4"
|
||||
|
||||
"@babel/traverse@^7.10.4", "@babel/traverse@^7.11.0":
|
||||
version "7.11.0"
|
||||
resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.0.tgz#9b996ce1b98f53f7c3e4175115605d56ed07dd24"
|
||||
integrity sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==
|
||||
"@babel/traverse@^7.10.4", "@babel/traverse@^7.11.5":
|
||||
version "7.11.5"
|
||||
resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.5.tgz#be777b93b518eb6d76ee2e1ea1d143daa11e61c3"
|
||||
integrity sha512-EjiPXt+r7LiCZXEfRpSJd+jUMnBd4/9OUv7Nx3+0u9+eimMwJmG0Q98lw4/289JCoxSE8OolDMNZaaF/JZ69WQ==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.10.4"
|
||||
"@babel/generator" "^7.11.0"
|
||||
"@babel/generator" "^7.11.5"
|
||||
"@babel/helper-function-name" "^7.10.4"
|
||||
"@babel/helper-split-export-declaration" "^7.11.0"
|
||||
"@babel/parser" "^7.11.0"
|
||||
"@babel/types" "^7.11.0"
|
||||
"@babel/parser" "^7.11.5"
|
||||
"@babel/types" "^7.11.5"
|
||||
debug "^4.1.0"
|
||||
globals "^11.1.0"
|
||||
lodash "^4.17.19"
|
||||
|
||||
"@babel/types@^7.10.4", "@babel/types@^7.11.0":
|
||||
version "7.11.0"
|
||||
resolved "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz#2ae6bf1ba9ae8c3c43824e5861269871b206e90d"
|
||||
integrity sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==
|
||||
"@babel/types@^7.10.4", "@babel/types@^7.11.0", "@babel/types@^7.11.5":
|
||||
version "7.11.5"
|
||||
resolved "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz#d9de577d01252d77c6800cee039ee64faf75662d"
|
||||
integrity sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==
|
||||
dependencies:
|
||||
"@babel/helper-validator-identifier" "^7.10.4"
|
||||
lodash "^4.17.19"
|
||||
|
@ -183,6 +183,16 @@
|
|||
dependencies:
|
||||
arrify "^1.0.1"
|
||||
|
||||
"@eslint/eslintrc@^0.1.0":
|
||||
version "0.1.0"
|
||||
resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.1.0.tgz#3d1f19fb797d42fb1c85458c1c73541eeb1d9e76"
|
||||
integrity sha512-bfL5365QSCmH6cPeFT7Ywclj8C7LiF7sO6mUGzZhtAMV7iID1Euq6740u/SRi4C80NOnVz/CEfK8/HO+nCAPJg==
|
||||
dependencies:
|
||||
ajv "^6.12.4"
|
||||
debug "^4.1.1"
|
||||
import-fresh "^3.2.1"
|
||||
strip-json-comments "^3.1.1"
|
||||
|
||||
"@istanbuljs/load-nyc-config@^1.0.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced"
|
||||
|
@ -206,12 +216,12 @@
|
|||
resolved "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd"
|
||||
integrity sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==
|
||||
|
||||
"@node-rs/helper@^0.3.0":
|
||||
version "0.3.0"
|
||||
resolved "https://registry.npmjs.org/@node-rs/helper/-/helper-0.3.0.tgz#6ab53f3842086f56df92f4990dda642afba84f10"
|
||||
integrity sha512-1p67WcdFAtz5jVGpzpqJL2W+JKmoW4jmPD2cIJOAU4U+Fl5G9QsoFTa07ctiNosSsjYqnvgyE0KWV75YdpDqDg==
|
||||
"@node-rs/helper@^0.3.1":
|
||||
version "0.3.1"
|
||||
resolved "https://registry.npmjs.org/@node-rs/helper/-/helper-0.3.1.tgz#605d3fafb344a4b7b664236c9219ac3e1d72361b"
|
||||
integrity sha512-3X6SJOcyFRYv1mjrjtSHiziJuzAsqaz2pFD3uuLxu4qJo4TH6H0gaUb1Bdxl/VtiDy2yR+eMyBOQFCvr/G2oLA==
|
||||
dependencies:
|
||||
tslib "^2.0.0"
|
||||
tslib "^2.0.1"
|
||||
|
||||
"@nodelib/fs.scandir@2.1.3":
|
||||
version "2.1.3"
|
||||
|
@ -239,51 +249,51 @@
|
|||
resolved "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea"
|
||||
integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==
|
||||
|
||||
"@swc-node/core-darwin@^0.4.2":
|
||||
version "0.4.2"
|
||||
resolved "https://registry.npmjs.org/@swc-node/core-darwin/-/core-darwin-0.4.2.tgz#d41fff560d20e1dc0bf1d077e3ad9eebe1f83862"
|
||||
integrity sha512-PKQZs5Cd1zD0D8KUz2vKGfQET7b19TcIuJ3M5fffosCLo0PV39bi6jrRiILiyP8DPGhOHysOMYkpJh0suVV2uA==
|
||||
"@swc-node/core-darwin@^0.6.1":
|
||||
version "0.6.1"
|
||||
resolved "https://registry.npmjs.org/@swc-node/core-darwin/-/core-darwin-0.6.1.tgz#ad20762202eb25523bb6bdde81e6f6cb5e909bd9"
|
||||
integrity sha512-tMWzyFhq4zPKnqq7yhUknFQWIishokFMMaqaptXq8w3wnidOhUCr83GhVggnj8r8LnUtNB8pegEj17Kl/20qjQ==
|
||||
|
||||
"@swc-node/core-linux-musl@^0.6.0":
|
||||
version "0.6.0"
|
||||
resolved "https://registry.npmjs.org/@swc-node/core-linux-musl/-/core-linux-musl-0.6.0.tgz#b657cce9fc35dddbfb84305a52546d0ece327201"
|
||||
integrity sha512-gOB6PxKs26ZWt4JHIvU4Le8Sht9Ob7t7n2UF7uWwsJ6idDE89SybvZBGfi8B/AKrP2ZQPMi1wNOJABTu8O7ZUw==
|
||||
"@swc-node/core-linux-musl@^0.6.1":
|
||||
version "0.6.1"
|
||||
resolved "https://registry.npmjs.org/@swc-node/core-linux-musl/-/core-linux-musl-0.6.1.tgz#45e2e0b695f594df944f892e9f82a2ce77266bf1"
|
||||
integrity sha512-VcQ1kdeRw1D8/uMk90wHSMJmT41Tex8iytuGKBl/bVOZ5wPD9wA3Sz5ieMgt4CNiUtVITTlpyTJuQgO526W7Ug==
|
||||
|
||||
"@swc-node/core-linux@^0.4.2":
|
||||
version "0.4.2"
|
||||
resolved "https://registry.npmjs.org/@swc-node/core-linux/-/core-linux-0.4.2.tgz#e65750d1bcde9f153ec5e2b418e9b56365c94691"
|
||||
integrity sha512-DOgOclLtbAOA0oJqxjOk6ziYLJ9JeTE/b9GJQm2GLB2jZgMcAPp+u1Dj/cBWEek77YErMeLyD0sYxE4E56KpvQ==
|
||||
"@swc-node/core-linux@^0.6.1":
|
||||
version "0.6.1"
|
||||
resolved "https://registry.npmjs.org/@swc-node/core-linux/-/core-linux-0.6.1.tgz#b17ad7a8dcc1e2c17951e871cfa5c535f1e74145"
|
||||
integrity sha512-oeE50kwZ8FgmP+MDFWi5aQpi4A+xUsqBQphTI4Cth7IdNqWbCq+sKU1dMn5FBFpyrp9KxXX9zrWOZYN6dtlwcg==
|
||||
|
||||
"@swc-node/core-win32@^0.4.2":
|
||||
version "0.4.2"
|
||||
resolved "https://registry.npmjs.org/@swc-node/core-win32/-/core-win32-0.4.2.tgz#26b1a2a2c33da75d5e3b2876f61dfa81188fcfc8"
|
||||
integrity sha512-GopRvIP/m2uJFaEEz3IuCEKBWjZxu/mW53fWjCrib5tU/Vs3bYu2oRs7u2n6XwCDMfPw8RNNutGtbYeWQWYklw==
|
||||
"@swc-node/core-win32@^0.6.1":
|
||||
version "0.6.1"
|
||||
resolved "https://registry.npmjs.org/@swc-node/core-win32/-/core-win32-0.6.1.tgz#7c2c09a1d713166a7d86bc4ac74fdfdcd0901314"
|
||||
integrity sha512-6t8wbrbrY28nLP0rPY6nAuz6wUAZRVwkuEVt6QDrz44eo8wJkPqmZBHhYubDgdiofnxHNOveR9i9sdH2Z7xOSg==
|
||||
|
||||
"@swc-node/core@^0.4.2":
|
||||
version "0.4.2"
|
||||
resolved "https://registry.npmjs.org/@swc-node/core/-/core-0.4.2.tgz#4216cb176fc352d7df09b1cf2579274931dc5644"
|
||||
integrity sha512-32YeSm2Q4YClpKIA2ZJzdZDLvLcv3nyg6pyoupy/cJjLpojGg+Laigo310wkQaCt8Y0NYOOheI/o58TV8xtgYg==
|
||||
"@swc-node/core@^0.6.1":
|
||||
version "0.6.1"
|
||||
resolved "https://registry.npmjs.org/@swc-node/core/-/core-0.6.1.tgz#f3cf3b669f094f6b3d6f78ade54224aaa62a3362"
|
||||
integrity sha512-5DXGG7u1lawiZuqv2MDgKgXNpjXu08uxg89bPU8PJATGeP+EQtJDgHwM7uF1hmRM1wsOsIy4o1t10w6NUWKCxQ==
|
||||
dependencies:
|
||||
"@node-rs/helper" "^0.3.0"
|
||||
"@node-rs/helper" "^0.3.1"
|
||||
optionalDependencies:
|
||||
"@swc-node/core-darwin" "^0.4.2"
|
||||
"@swc-node/core-linux" "^0.4.2"
|
||||
"@swc-node/core-win32" "^0.4.2"
|
||||
"@swc-node/core-darwin" "^0.6.1"
|
||||
"@swc-node/core-linux" "^0.6.1"
|
||||
"@swc-node/core-win32" "^0.6.1"
|
||||
|
||||
"@swc-node/register@^0.4.2":
|
||||
version "0.4.2"
|
||||
resolved "https://registry.npmjs.org/@swc-node/register/-/register-0.4.2.tgz#5d07e1c16fca102a27490d3ec5eeafcdd22a8b33"
|
||||
integrity sha512-F0kD0gOWu2t8br8UZeAfrUFvab7iLs678DoVQrDseqZWSNtqF43F7upQBBKlDRO+mVOCtwdRxGanm/R0Y+aqOA==
|
||||
"@swc-node/register@^0.4.5":
|
||||
version "0.4.5"
|
||||
resolved "https://registry.npmjs.org/@swc-node/register/-/register-0.4.5.tgz#3e80f7f901cc45d17b88a6ee626016cafd30fbe5"
|
||||
integrity sha512-7wY7i19u0ISfR4vmuzPh8XDwum31kiCvQEzkZ55EjzeUVBXhNm280as81jqsGiVW3dN2mlTHfQNLB9WwOLkEnQ==
|
||||
dependencies:
|
||||
"@swc-node/core" "^0.4.2"
|
||||
"@swc-node/sourcemap-support" "^0.1.7"
|
||||
"@swc-node/core" "^0.6.1"
|
||||
"@swc-node/sourcemap-support" "^0.1.8"
|
||||
debug "^4.1.1"
|
||||
pirates "^4.0.1"
|
||||
|
||||
"@swc-node/sourcemap-support@^0.1.7":
|
||||
version "0.1.7"
|
||||
resolved "https://registry.npmjs.org/@swc-node/sourcemap-support/-/sourcemap-support-0.1.7.tgz#2e9b94e0bb7735f4b1ce0f0a464325dd0ad25465"
|
||||
integrity sha512-tC/h/JJi5WJuLbDbWt2aKFLyafUrbSnRwcpO89jmQIVtQUssbfoXGupoGrPThzCfrJyXUNNflWxl3SxIdCvPMA==
|
||||
"@swc-node/sourcemap-support@^0.1.8":
|
||||
version "0.1.8"
|
||||
resolved "https://registry.npmjs.org/@swc-node/sourcemap-support/-/sourcemap-support-0.1.8.tgz#8cf74175ae5e3374612011e7e75c03637019db4c"
|
||||
integrity sha512-AOH32yNN8UJh6Ayc+r3mnPdrjqqEjtXr9wsEiEhh3OqJWFXqkMOHC+18FYhHdTzGzhaYqUshQONjqOTC38yx7Q==
|
||||
dependencies:
|
||||
source-map-support "^0.5.19"
|
||||
|
||||
|
@ -299,11 +309,6 @@
|
|||
resolved "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
|
||||
integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==
|
||||
|
||||
"@types/eslint-visitor-keys@^1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d"
|
||||
integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==
|
||||
|
||||
"@types/glob@^7.1.1":
|
||||
version "7.1.3"
|
||||
resolved "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183"
|
||||
|
@ -321,9 +326,9 @@
|
|||
rxjs "^6.4.0"
|
||||
|
||||
"@types/json-schema@^7.0.3":
|
||||
version "7.0.5"
|
||||
resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd"
|
||||
integrity sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==
|
||||
version "7.0.6"
|
||||
resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0"
|
||||
integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==
|
||||
|
||||
"@types/json5@^0.0.29":
|
||||
version "0.0.29"
|
||||
|
@ -335,10 +340,10 @@
|
|||
resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
|
||||
integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
|
||||
|
||||
"@types/node@*", "@types/node@^14.6.0":
|
||||
version "14.6.0"
|
||||
resolved "https://registry.npmjs.org/@types/node/-/node-14.6.0.tgz#7d4411bf5157339337d7cff864d9ff45f177b499"
|
||||
integrity sha512-mikldZQitV94akrc4sCcSjtJfsTKt4p+e/s0AGscVA6XArQ9kFclP+ZiYUMnq987rc6QlYxXv/EivqlfSLxpKA==
|
||||
"@types/node@*", "@types/node@^14.6.2":
|
||||
version "14.6.2"
|
||||
resolved "https://registry.npmjs.org/@types/node/-/node-14.6.2.tgz#264b44c5a28dfa80198fc2f7b6d3c8a054b9491f"
|
||||
integrity sha512-onlIwbaeqvZyniGPfdw/TEhKIh79pz66L1q06WUQqJLnAb6wbjvOtepLYTGHTqzdXgBYIE3ZdmqHDGsRsbBz7A==
|
||||
|
||||
"@types/normalize-package-data@^2.4.0":
|
||||
version "2.4.0"
|
||||
|
@ -357,92 +362,61 @@
|
|||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@typescript-eslint/eslint-plugin@^4.0.0":
|
||||
version "4.0.0"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.0.0.tgz#99349a501447fed91de18346705c0c65cf603bee"
|
||||
integrity sha512-5e6q1TR7gS2P+8W2xndCu7gBh3BzmYEo70OyIdsmCmknHha/yNbz2vdevl+tP1uoaMOcrzg4gyrAijuV3DDBHA==
|
||||
"@typescript-eslint/eslint-plugin@^4.0.1":
|
||||
version "4.0.1"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.0.1.tgz#88bde9239e29d688315718552cf80a3490491017"
|
||||
integrity sha512-pQZtXupCn11O4AwpYVUX4PDFfmIJl90ZgrEBg0CEcqlwvPiG0uY81fimr1oMFblZnpKAq6prrT9a59pj1x58rw==
|
||||
dependencies:
|
||||
"@typescript-eslint/experimental-utils" "4.0.0"
|
||||
"@typescript-eslint/scope-manager" "4.0.0"
|
||||
"@typescript-eslint/experimental-utils" "4.0.1"
|
||||
"@typescript-eslint/scope-manager" "4.0.1"
|
||||
debug "^4.1.1"
|
||||
functional-red-black-tree "^1.0.1"
|
||||
regexpp "^3.0.0"
|
||||
semver "^7.3.2"
|
||||
tsutils "^3.17.1"
|
||||
|
||||
"@typescript-eslint/experimental-utils@3.10.1":
|
||||
version "3.10.1"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.10.1.tgz#e179ffc81a80ebcae2ea04e0332f8b251345a686"
|
||||
integrity sha512-DewqIgscDzmAfd5nOGe4zm6Bl7PKtMG2Ad0KG8CUZAHlXfAKTF9Ol5PXhiMh39yRL2ChRH1cuuUGOcVyyrhQIw==
|
||||
"@typescript-eslint/experimental-utils@4.0.1":
|
||||
version "4.0.1"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.0.1.tgz#7d9a3ab6821ad5274dad2186c1aa0d93afd696eb"
|
||||
integrity sha512-gAqOjLiHoED79iYTt3F4uSHrYmg/GPz/zGezdB0jAdr6S6gwNiR/j7cTZ8nREKVzMVKLd9G3xbg1sV9GClW3sw==
|
||||
dependencies:
|
||||
"@types/json-schema" "^7.0.3"
|
||||
"@typescript-eslint/types" "3.10.1"
|
||||
"@typescript-eslint/typescript-estree" "3.10.1"
|
||||
"@typescript-eslint/scope-manager" "4.0.1"
|
||||
"@typescript-eslint/types" "4.0.1"
|
||||
"@typescript-eslint/typescript-estree" "4.0.1"
|
||||
eslint-scope "^5.0.0"
|
||||
eslint-utils "^2.0.0"
|
||||
|
||||
"@typescript-eslint/experimental-utils@4.0.0":
|
||||
version "4.0.0"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.0.0.tgz#fbec21a3b5ab59127edb6ce2e139ed378cc50eb5"
|
||||
integrity sha512-hbX6zR+a/vcpFVNJYN/Nbd7gmaMosDTxHEKcvmhWeWcq/0UDifrqmCfkkodbAKL46Fn4ekSBMTyq2zlNDzcQxw==
|
||||
"@typescript-eslint/parser@^4.0.1":
|
||||
version "4.0.1"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.0.1.tgz#73772080db7a7a4534a35d719e006f503e664dc3"
|
||||
integrity sha512-1+qLmXHNAWSQ7RB6fdSQszAiA7JTwzakj5cNYjBTUmpH2cqilxMZEIV+DRKjVZs8NzP3ALmKexB0w/ExjcK9Iw==
|
||||
dependencies:
|
||||
"@types/json-schema" "^7.0.3"
|
||||
"@typescript-eslint/scope-manager" "4.0.0"
|
||||
"@typescript-eslint/types" "4.0.0"
|
||||
"@typescript-eslint/typescript-estree" "4.0.0"
|
||||
eslint-scope "^5.0.0"
|
||||
eslint-utils "^2.0.0"
|
||||
|
||||
"@typescript-eslint/parser@^3.10.1":
|
||||
version "3.10.1"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-3.10.1.tgz#1883858e83e8b442627e1ac6f408925211155467"
|
||||
integrity sha512-Ug1RcWcrJP02hmtaXVS3axPPTTPnZjupqhgj+NnZ6BCkwSImWk/283347+x9wN+lqOdK9Eo3vsyiyDHgsmiEJw==
|
||||
dependencies:
|
||||
"@types/eslint-visitor-keys" "^1.0.0"
|
||||
"@typescript-eslint/experimental-utils" "3.10.1"
|
||||
"@typescript-eslint/types" "3.10.1"
|
||||
"@typescript-eslint/typescript-estree" "3.10.1"
|
||||
eslint-visitor-keys "^1.1.0"
|
||||
|
||||
"@typescript-eslint/scope-manager@4.0.0":
|
||||
version "4.0.0"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.0.0.tgz#8c9e3b3b8cdf5a1fbe671d9fad73ff67bc027ea8"
|
||||
integrity sha512-9gcWUPoWo7gk/+ZQPg7L1ySRmR5HLIy3Vu6/LfhQbuzIkGm6v2CGIjpVRISoDLFRovNRDImd4aP/sa8O4yIEBg==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "4.0.0"
|
||||
"@typescript-eslint/visitor-keys" "4.0.0"
|
||||
|
||||
"@typescript-eslint/types@3.10.1":
|
||||
version "3.10.1"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-3.10.1.tgz#1d7463fa7c32d8a23ab508a803ca2fe26e758727"
|
||||
integrity sha512-+3+FCUJIahE9q0lDi1WleYzjCwJs5hIsbugIgnbB+dSCYUxl8L6PwmsyOPFZde2hc1DlTo/xnkOgiTLSyAbHiQ==
|
||||
|
||||
"@typescript-eslint/types@4.0.0":
|
||||
version "4.0.0"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.0.0.tgz#ec1f9fc06b8558a1d5afa6e337182d08beece7f5"
|
||||
integrity sha512-bK+c2VLzznX2fUWLK6pFDv3cXGTp7nHIuBMq1B9klA+QCsqLHOOqe5TQReAQDl7DN2RfH+neweo0oC5hYlG7Rg==
|
||||
|
||||
"@typescript-eslint/typescript-estree@3.10.1":
|
||||
version "3.10.1"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.10.1.tgz#fd0061cc38add4fad45136d654408569f365b853"
|
||||
integrity sha512-QbcXOuq6WYvnB3XPsZpIwztBoquEYLXh2MtwVU+kO8jgYCiv4G5xrSP/1wg4tkvrEE+esZVquIPX/dxPlePk1w==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "3.10.1"
|
||||
"@typescript-eslint/visitor-keys" "3.10.1"
|
||||
"@typescript-eslint/scope-manager" "4.0.1"
|
||||
"@typescript-eslint/types" "4.0.1"
|
||||
"@typescript-eslint/typescript-estree" "4.0.1"
|
||||
debug "^4.1.1"
|
||||
glob "^7.1.6"
|
||||
is-glob "^4.0.1"
|
||||
lodash "^4.17.15"
|
||||
semver "^7.3.2"
|
||||
tsutils "^3.17.1"
|
||||
|
||||
"@typescript-eslint/typescript-estree@4.0.0":
|
||||
version "4.0.0"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.0.0.tgz#2244c63de2f2190bc5718eb0fb3fd2c437d42097"
|
||||
integrity sha512-ewFMPi2pMLDNIXGMPdf8r7El2oPSZw9PEYB0j+WcpKd7AX2ARmajGa7RUHTukllWX2bj4vWX6JLE1Oih2BMokA==
|
||||
"@typescript-eslint/scope-manager@4.0.1":
|
||||
version "4.0.1"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.0.1.tgz#24d93c3000bdfcc5a157dc4d32b742405a8631b5"
|
||||
integrity sha512-u3YEXVJ8jsj7QCJk3om0Y457fy2euEOkkzxIB/LKU3MdyI+FJ2gI0M4aKEaXzwCSfNDiZ13a3lDo5DVozc+XLQ==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "4.0.0"
|
||||
"@typescript-eslint/visitor-keys" "4.0.0"
|
||||
"@typescript-eslint/types" "4.0.1"
|
||||
"@typescript-eslint/visitor-keys" "4.0.1"
|
||||
|
||||
"@typescript-eslint/types@4.0.1":
|
||||
version "4.0.1"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.0.1.tgz#1cf72582f764931f085cb8230ff215980fe467b2"
|
||||
integrity sha512-S+gD3fgbkZYW2rnbjugNMqibm9HpEjqZBZkTiI3PwbbNGWmAcxolWIUwZ0SKeG4Dy2ktpKKaI/6+HGYVH8Qrlg==
|
||||
|
||||
"@typescript-eslint/typescript-estree@4.0.1":
|
||||
version "4.0.1"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.0.1.tgz#29a43c7060641ec51c902d9f50ac7c5866ec479f"
|
||||
integrity sha512-zGzleORFXrRWRJAMLTB2iJD1IZbCPkg4hsI8mGdpYlKaqzvKYSEWVAYh14eauaR+qIoZVWrXgYSXqLtTlxotiw==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "4.0.1"
|
||||
"@typescript-eslint/visitor-keys" "4.0.1"
|
||||
debug "^4.1.1"
|
||||
globby "^11.0.1"
|
||||
is-glob "^4.0.1"
|
||||
|
@ -450,19 +424,12 @@
|
|||
semver "^7.3.2"
|
||||
tsutils "^3.17.1"
|
||||
|
||||
"@typescript-eslint/visitor-keys@3.10.1":
|
||||
version "3.10.1"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-3.10.1.tgz#cd4274773e3eb63b2e870ac602274487ecd1e931"
|
||||
integrity sha512-9JgC82AaQeglebjZMgYR5wgmfUdUc+EitGUUMW8u2nDckaeimzW+VsoLV6FoimPv2id3VQzfjwBxEMVz08ameQ==
|
||||
"@typescript-eslint/visitor-keys@4.0.1":
|
||||
version "4.0.1"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.0.1.tgz#d4e8de62775f2a6db71c7e8539633680039fdd6c"
|
||||
integrity sha512-yBSqd6FjnTzbg5RUy9J+9kJEyQjTI34JdGMJz+9ttlJzLCnGkBikxw+N5n2VDcc3CesbIEJ0MnZc5uRYnrEnCw==
|
||||
dependencies:
|
||||
eslint-visitor-keys "^1.1.0"
|
||||
|
||||
"@typescript-eslint/visitor-keys@4.0.0":
|
||||
version "4.0.0"
|
||||
resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.0.0.tgz#e2bbb69d98076d6a3f06abcb2048225a74362c33"
|
||||
integrity sha512-sTouJbv6rjVJeTE4lpSBVYXq/u5K3gbB6LKt7ccFEZPTZB/VeQ0ssUz9q5Hx++sCqBbdF8PzrrgvEnicXAR6NQ==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "4.0.0"
|
||||
"@typescript-eslint/types" "4.0.1"
|
||||
eslint-visitor-keys "^2.0.0"
|
||||
|
||||
acorn-jsx@^5.2.0:
|
||||
|
@ -493,7 +460,7 @@ aggregate-error@^3.0.0:
|
|||
clean-stack "^2.0.0"
|
||||
indent-string "^4.0.0"
|
||||
|
||||
ajv@^6.10.0, ajv@^6.10.2:
|
||||
ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.4:
|
||||
version "6.12.4"
|
||||
resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.4.tgz#0614facc4522127fa713445c6bfd3ebd376e2234"
|
||||
integrity sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ==
|
||||
|
@ -850,9 +817,9 @@ clean-yaml-object@^0.1.0:
|
|||
integrity sha1-Y/sRDcLOGoTcIfbZM0h20BCui2g=
|
||||
|
||||
cli-boxes@^2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.0.tgz#538ecae8f9c6ca508e3c3c95b453fe93cb4c168d"
|
||||
integrity sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w==
|
||||
version "2.2.1"
|
||||
resolved "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f"
|
||||
integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==
|
||||
|
||||
cli-cursor@^3.1.0:
|
||||
version "3.1.0"
|
||||
|
@ -879,10 +846,10 @@ cli-width@^3.0.0:
|
|||
resolved "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6"
|
||||
integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==
|
||||
|
||||
clipanion@^2.4.4:
|
||||
version "2.4.4"
|
||||
resolved "https://registry.npmjs.org/clipanion/-/clipanion-2.4.4.tgz#d70244c6f60feb3f4cbd509d2fcbe829fc619061"
|
||||
integrity sha512-KjyCBz8xplftHjIK/nOqq/9b3hPlXbAAo/AxoITrO4yySpQ6a9QSJDAfOx9PfcRUHteeqbdNxZKSPfeFqQ7plg==
|
||||
clipanion@^2.5.0:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.npmjs.org/clipanion/-/clipanion-2.5.0.tgz#eb9c85a6b52a46979b7eb1e79534b23c44a52971"
|
||||
integrity sha512-VYOMl0h/mZXQC2BWq7oBto1zY1SkPWUaJjt+cuIred1HrmrcX1I2N+LNyNoRy8Iwu9r6vUxJwS/tWLwhQW4tPw==
|
||||
|
||||
cliui@^6.0.0:
|
||||
version "6.0.0"
|
||||
|
@ -1351,12 +1318,13 @@ eslint-visitor-keys@^2.0.0:
|
|||
resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8"
|
||||
integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==
|
||||
|
||||
eslint@^7.7.0:
|
||||
version "7.7.0"
|
||||
resolved "https://registry.npmjs.org/eslint/-/eslint-7.7.0.tgz#18beba51411927c4b64da0a8ceadefe4030d6073"
|
||||
integrity sha512-1KUxLzos0ZVsyL81PnRN335nDtQ8/vZUD6uMtWbF+5zDtjKcsklIi78XoE0MVL93QvWTu+E5y44VyyCsOMBrIg==
|
||||
eslint@^7.8.0:
|
||||
version "7.8.0"
|
||||
resolved "https://registry.npmjs.org/eslint/-/eslint-7.8.0.tgz#9a3e2e6e4d0a3f8c42686073c25ebf2e91443e8a"
|
||||
integrity sha512-qgtVyLZqKd2ZXWnLQA4NtVbOyH56zivOAdBFWE54RFkSZjokzNrcP4Z0eVWsZ+84ByXv+jL9k/wE1ENYe8xRFw==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.0.0"
|
||||
"@eslint/eslintrc" "^0.1.0"
|
||||
ajv "^6.10.0"
|
||||
chalk "^4.0.0"
|
||||
cross-spawn "^7.0.2"
|
||||
|
@ -1366,7 +1334,7 @@ eslint@^7.7.0:
|
|||
eslint-scope "^5.1.0"
|
||||
eslint-utils "^2.1.0"
|
||||
eslint-visitor-keys "^1.3.0"
|
||||
espree "^7.2.0"
|
||||
espree "^7.3.0"
|
||||
esquery "^1.2.0"
|
||||
esutils "^2.0.2"
|
||||
file-entry-cache "^5.0.1"
|
||||
|
@ -1393,7 +1361,7 @@ eslint@^7.7.0:
|
|||
text-table "^0.2.0"
|
||||
v8-compile-cache "^2.0.3"
|
||||
|
||||
espree@^7.2.0:
|
||||
espree@^7.3.0:
|
||||
version "7.3.0"
|
||||
resolved "https://registry.npmjs.org/espree/-/espree-7.3.0.tgz#dc30437cf67947cf576121ebd780f15eeac72348"
|
||||
integrity sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw==
|
||||
|
@ -1415,18 +1383,18 @@ esquery@^1.2.0:
|
|||
estraverse "^5.1.0"
|
||||
|
||||
esrecurse@^4.1.0:
|
||||
version "4.2.1"
|
||||
resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf"
|
||||
integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==
|
||||
version "4.3.0"
|
||||
resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921"
|
||||
integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==
|
||||
dependencies:
|
||||
estraverse "^4.1.0"
|
||||
estraverse "^5.2.0"
|
||||
|
||||
estraverse@^4.1.0, estraverse@^4.1.1:
|
||||
estraverse@^4.1.1:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d"
|
||||
integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
|
||||
|
||||
estraverse@^5.1.0:
|
||||
estraverse@^5.1.0, estraverse@^5.2.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880"
|
||||
integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==
|
||||
|
@ -2374,9 +2342,9 @@ md5-hex@^3.0.1:
|
|||
blueimp-md5 "^2.10.0"
|
||||
|
||||
mem@^6.1.0:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.npmjs.org/mem/-/mem-6.1.0.tgz#846eca0bd4708a8f04b9c3f3cd769e194ae63c5c"
|
||||
integrity sha512-RlbnLQgRHk5lwqTtpEkBTQ2ll/CG/iB+J4Hy2Wh97PjgZgXgWJWrFF+XXujh3UUVLvR4OOTgZzcWMMwnehlEUg==
|
||||
version "6.1.1"
|
||||
resolved "https://registry.npmjs.org/mem/-/mem-6.1.1.tgz#ea110c2ebc079eca3022e6b08c85a795e77f6318"
|
||||
integrity sha512-Ci6bIfq/UgcxPTYa8dQQ5FY3BzKkT894bwXWXxC/zqs0XgMO2cT20CGkOqda7gZNkmK5VP4x89IGZ6K7hfbn3Q==
|
||||
dependencies:
|
||||
map-age-cleaner "^0.1.3"
|
||||
mimic-fn "^3.0.0"
|
||||
|
@ -3224,11 +3192,6 @@ source-map-support@^0.5.17, source-map-support@^0.5.19:
|
|||
buffer-from "^1.0.0"
|
||||
source-map "^0.6.0"
|
||||
|
||||
source-map@^0.5.0:
|
||||
version "0.5.7"
|
||||
resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
|
||||
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
|
||||
|
||||
source-map@^0.6.0, source-map@^0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
|
||||
|
@ -3376,7 +3339,7 @@ strip-final-newline@^2.0.0:
|
|||
resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad"
|
||||
integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==
|
||||
|
||||
strip-json-comments@^3.1.0:
|
||||
strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
|
||||
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
|
||||
|
@ -3405,9 +3368,9 @@ supports-color@^5.3.0:
|
|||
has-flag "^3.0.0"
|
||||
|
||||
supports-color@^7.1.0:
|
||||
version "7.1.0"
|
||||
resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1"
|
||||
integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==
|
||||
version "7.2.0"
|
||||
resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
|
||||
integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
|
||||
dependencies:
|
||||
has-flag "^4.0.0"
|
||||
|
||||
|
@ -3515,7 +3478,7 @@ tslib@^1.8.1, tslib@^1.9.0:
|
|||
resolved "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043"
|
||||
integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==
|
||||
|
||||
tslib@^2.0.0, tslib@^2.0.1:
|
||||
tslib@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.npmjs.org/tslib/-/tslib-2.0.1.tgz#410eb0d113e5b6356490eec749603725b021b43e"
|
||||
integrity sha512-SgIkNheinmEBgx1IUNirK0TUD4X9yjjBRTqqjggWCU3pUEqIk3/Uwl3yRixYKT6WjQuGiwDv4NomL3wqRCj+CQ==
|
||||
|
@ -3593,9 +3556,9 @@ update-notifier@^4.1.1:
|
|||
xdg-basedir "^4.0.0"
|
||||
|
||||
uri-js@^4.2.2:
|
||||
version "4.2.2"
|
||||
resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0"
|
||||
integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==
|
||||
version "4.4.0"
|
||||
resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz#aa714261de793e8a82347a7bcc9ce74e86f28602"
|
||||
integrity sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==
|
||||
dependencies:
|
||||
punycode "^2.1.0"
|
||||
|
||||
|
|
Loading…
Reference in a new issue