Merge pull request #874 from napi-rs/tweak

tweaking for node-rs v2 upgrade
This commit is contained in:
LongYinan 2021-11-25 22:55:22 +08:00 committed by GitHub
commit 1af25a57b2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
44 changed files with 800 additions and 458 deletions

View file

@ -35,13 +35,14 @@
"@octokit/rest": "^18.12.0",
"@types/inquirer": "^8.1.3",
"@types/js-yaml": "^4.0.5",
"@types/lodash-es": "^4.17.5",
"chalk": "^4.1.2",
"clipanion": "^3.1.0",
"debug": "^4.3.2",
"fdir": "^5.1.0",
"inquirer": "^8.2.0",
"js-yaml": "^4.1.0",
"putasset": "^5.0.3",
"lodash-es": "4.17.21",
"toml": "^3.0.0",
"tslib": "^2.3.1",
"typanion": "^3.7.1"

View file

@ -4,6 +4,7 @@ import { join, parse, sep } from 'path'
import { Instance } from 'chalk'
import { Command, Option } from 'clipanion'
import { groupBy } from 'lodash-es'
import toml from 'toml'
import { getNapiConfig } from './consts'
@ -327,6 +328,7 @@ interface TypeDef {
kind: 'fn' | 'struct' | 'impl' | 'enum' | 'interface'
name: string
def: string
js_mod?: string
}
async function processIntermediateTypeFile(
@ -344,7 +346,7 @@ async function processIntermediateTypeFile(
.split('\n')
.map((line) => line.trim())
.filter(Boolean)
let dts = `/* eslint-disable */
const dtsHeader = `/* eslint-disable */
export class ExternalObject<T> {
readonly '': {
@ -352,43 +354,75 @@ export class ExternalObject<T> {
[K: symbol]: T
}
}\n`
const classes = new Map<string, string>()
const impls = new Map<string, string>()
lines.forEach((line) => {
const def = JSON.parse(line) as TypeDef
const allDefs = lines.map((line) => JSON.parse(line) as TypeDef)
switch (def.kind) {
case 'struct':
idents.push(def.name)
classes.set(def.name, def.def)
break
case 'impl':
impls.set(def.name, def.def)
break
case 'interface':
dts += `interface ${def.name} {\n${indentLines(def.def, 2)}\n}\n`
break
default:
idents.push(def.name)
dts += def.def + '\n'
function convertDefs(defs: TypeDef[], nested = false): string {
const classes = new Map<string, string>()
const impls = new Map<string, string>()
let dts = ''
const lineStart = nested ? ' ' : ''
defs.forEach((def) => {
switch (def.kind) {
case 'struct':
if (!nested) {
idents.push(def.name)
}
classes.set(def.name, def.def)
break
case 'impl':
impls.set(def.name, def.def)
break
case 'interface':
dts += `${lineStart}interface ${def.name} {\n${indentLines(
def.def,
nested ? 4 : 2,
)}\n}\n`
break
default:
if (!nested) {
idents.push(def.name)
}
dts += lineStart + def.def + '\n'
}
})
for (const [name, classDef] of classes.entries()) {
const implDef = impls.get(name)
dts += `${lineStart}export class ${name} {\n${indentLines(
classDef,
nested ? 4 : 2,
)}`
if (implDef) {
dts += `\n${indentLines(implDef, nested ? 4 : 2)}`
}
dts += `\n${lineStart}}\n`
}
})
for (const [name, classDef] of classes.entries()) {
const implDef = impls.get(name)
dts += `export class ${name} {\n${indentLines(classDef, 2)}`
if (implDef) {
dts += `\n${indentLines(implDef, 2)}`
}
dts += '\n}\n'
return dts
}
const topLevelDef = convertDefs(allDefs.filter((def) => !def.js_mod))
const namespaceDefs = Object.entries(
groupBy(
allDefs.filter((def) => def.js_mod),
'js_mod',
),
).reduce((acc, [mod, defs]) => {
idents.push(mod)
return (
acc +
`export namespace ${mod} {
${convertDefs(defs, true)}
}\n`
)
}, '')
await unlinkAsync(source)
await writeFileAsync(target, dts, 'utf8')
await writeFileAsync(target, dtsHeader + topLevelDef + namespaceDefs, 'utf8')
return idents
}

View file

@ -15,6 +15,7 @@ pub struct NapiFn {
pub vis: syn::Visibility,
pub parent: Option<Ident>,
pub strict: bool,
pub js_mod: Option<String>,
}
#[derive(Debug, Clone)]
@ -54,6 +55,7 @@ pub struct NapiStruct {
pub fields: Vec<NapiStructField>,
pub is_tuple: bool,
pub kind: NapiStructKind,
pub js_mod: Option<String>,
}
#[derive(Debug, Clone, PartialEq)]
@ -78,6 +80,7 @@ pub struct NapiImpl {
pub js_name: String,
pub items: Vec<NapiFn>,
pub task_output_type: Option<Type>,
pub js_mod: Option<String>,
}
#[derive(Debug, Clone)]
@ -85,6 +88,7 @@ pub struct NapiEnum {
pub name: Ident,
pub js_name: String,
pub variants: Vec<NapiEnumVariant>,
pub js_mod: Option<String>,
}
#[derive(Debug, Clone)]
@ -100,4 +104,11 @@ pub struct NapiConst {
pub js_name: String,
pub type_name: Type,
pub value: Expr,
pub js_mod: Option<String>,
}
#[derive(Debug, Clone)]
pub struct NapiMod {
pub name: Ident,
pub js_name: String,
}

View file

@ -5,6 +5,7 @@ use crate::BindgenResult;
mod r#const;
mod r#enum;
mod r#fn;
mod js_mod;
mod r#struct;
pub trait TryToTokens {
@ -27,3 +28,12 @@ fn get_register_ident(name: &str) -> Ident {
let new_name = format!("__napi_register__{}", name);
Ident::new(&new_name, Span::call_site())
}
fn js_mod_to_token_stream(js_mod: Option<&String>) -> TokenStream {
js_mod
.map(|i| {
let i = format!("{}\0", i);
quote! { Some(#i) }
})
.unwrap_or_else(|| quote! { None })
}

View file

@ -1,7 +1,10 @@
use proc_macro2::{Literal, TokenStream};
use proc_macro2::{Ident, Literal, TokenStream};
use quote::ToTokens;
use crate::{codegen::get_register_ident, BindgenResult, NapiConst, TryToTokens};
use crate::{
codegen::{get_register_ident, js_mod_to_token_stream},
BindgenResult, NapiConst, TryToTokens,
};
impl TryToTokens for NapiConst {
fn try_to_tokens(&self, tokens: &mut TokenStream) -> BindgenResult<()> {
@ -19,22 +22,25 @@ impl NapiConst {
fn gen_module_register(&self) -> TokenStream {
let name_str = self.name.to_string();
let name_ident = self.name.clone();
let js_name_lit = Literal::string(&self.js_name);
let js_name_lit = Literal::string(&format!("{}\0", self.name));
let register_name = get_register_ident(&name_str);
let type_name = &self.type_name;
let cb_name = Ident::new(
&format!("__register__const__{}_callback__", register_name),
self.name.span(),
);
let js_mod_ident = js_mod_to_token_stream(self.js_mod.as_ref());
quote! {
#[allow(non_snake_case)]
#[allow(clippy::all)]
unsafe fn #cb_name(env: napi::sys::napi_env) -> napi::Result<napi::sys::napi_value> {
<#type_name as napi::bindgen_prelude::ToNapiValue>::to_napi_value(env, #name_ident)
}
#[allow(non_snake_case)]
#[allow(clippy::all)]
#[napi::bindgen_prelude::ctor]
fn #register_name() {
use std::ffi::CString;
use std::ptr;
unsafe fn cb(env: napi::sys::napi_env) -> napi::Result<napi::sys::napi_value> {
<#type_name as napi::bindgen_prelude::ToNapiValue>::to_napi_value(env, #name_ident)
}
napi::bindgen_prelude::register_module_export(#js_name_lit, cb);
napi::bindgen_prelude::register_module_export(#js_mod_ident, #js_name_lit, #cb_name);
}
}
}

View file

@ -1,7 +1,10 @@
use proc_macro2::{Literal, TokenStream};
use proc_macro2::{Ident, Literal, Span, TokenStream};
use quote::ToTokens;
use crate::{codegen::get_register_ident, BindgenResult, NapiEnum, TryToTokens};
use crate::{
codegen::{get_register_ident, js_mod_to_token_stream},
BindgenResult, NapiEnum, TryToTokens,
};
impl TryToTokens for NapiEnum {
fn try_to_tokens(&self, tokens: &mut TokenStream) -> BindgenResult<()> {
@ -98,18 +101,18 @@ impl NapiEnum {
fn gen_module_register(&self) -> TokenStream {
let name_str = self.name.to_string();
let js_name_lit = Literal::string(&self.js_name);
let js_name_lit = Literal::string(&format!("{}\0", &self.js_name));
let register_name = get_register_ident(&name_str);
let mut define_properties = vec![];
for variant in self.variants.iter() {
let name_lit = Literal::string(&variant.name.to_string());
let name_lit = Literal::string(&format!("{}\0", variant.name.to_string()));
let val_lit = Literal::i32_unsuffixed(variant.val);
define_properties.push(quote! {
{
let name = CString::new(#name_lit)?;
let name = std::ffi::CStr::from_bytes_with_nul_unchecked(#name_lit.as_bytes());
napi::bindgen_prelude::check_status!(
napi::bindgen_prelude::sys::napi_set_named_property(env, obj_ptr, name.as_ptr(), i32::to_napi_value(env, #val_lit)?),
"Failed to defined enum `{}`",
@ -119,28 +122,34 @@ impl NapiEnum {
})
}
let callback_name = Ident::new(
&format!("__register__enum__{}_callback__", name_str),
Span::call_site(),
);
let js_mod_ident = js_mod_to_token_stream(self.js_mod.as_ref());
quote! {
unsafe fn #callback_name(env: napi::bindgen_prelude::sys::napi_env) -> napi::bindgen_prelude::Result<napi::bindgen_prelude::sys::napi_value> {
use std::ffi::CString;
use std::ptr;
let mut obj_ptr = ptr::null_mut();
napi::bindgen_prelude::check_status!(
napi::bindgen_prelude::sys::napi_create_object(env, &mut obj_ptr),
"Failed to create napi object"
)?;
#(#define_properties)*
Ok(obj_ptr)
}
#[allow(non_snake_case)]
#[allow(clippy::all)]
#[napi::bindgen_prelude::ctor]
fn #register_name() {
use std::ffi::CString;
use std::ptr;
unsafe fn cb(env: napi::bindgen_prelude::sys::napi_env) -> napi::bindgen_prelude::Result<napi::bindgen_prelude::sys::napi_value> {
let mut obj_ptr = ptr::null_mut();
napi::bindgen_prelude::check_status!(
napi::bindgen_prelude::sys::napi_create_object(env, &mut obj_ptr),
"Failed to create napi object"
)?;
#(#define_properties)*
Ok(obj_ptr)
}
napi::bindgen_prelude::register_module_export(#js_name_lit, cb);
napi::bindgen_prelude::register_module_export(#js_mod_ident, #js_name_lit, #callback_name);
}
}
}

View file

@ -2,7 +2,7 @@ use proc_macro2::{Ident, Span, TokenStream};
use quote::ToTokens;
use crate::{
codegen::{get_intermediate_ident, get_register_ident},
codegen::{get_intermediate_ident, get_register_ident, js_mod_to_token_stream},
BindgenResult, CallbackArg, FnKind, FnSelf, NapiFn, NapiFnArgKind, TryToTokens,
};
@ -245,6 +245,8 @@ impl NapiFn {
let js_name = &self.js_name;
if let Some(ty) = &self.ret {
let ty_string = ty.into_token_stream().to_string();
let is_return_self = ty_string == "& Self" || ty_string == "&mut Self";
if self.kind == FnKind::Constructor {
if self.is_ret_result {
quote! { cb.construct(#js_name, #ret?) }
@ -263,19 +265,27 @@ impl NapiFn {
<#ty as napi::bindgen_prelude::ToNapiValue>::to_napi_value(env, #ret)
}
} else {
quote! {
match #ret {
Ok(value) => napi::bindgen_prelude::ToNapiValue::to_napi_value(env, value),
Err(err) => {
napi::bindgen_prelude::JsError::from(err).throw_into(env);
Ok(std::ptr::null_mut())
},
if is_return_self {
quote! { #ret.map(|_| cb.this) }
} else {
quote! {
match #ret {
Ok(value) => napi::bindgen_prelude::ToNapiValue::to_napi_value(env, value),
Err(err) => {
napi::bindgen_prelude::JsError::from(err).throw_into(env);
Ok(std::ptr::null_mut())
},
}
}
}
}
} else {
quote! {
<#ty as napi::bindgen_prelude::ToNapiValue>::to_napi_value(env, #ret)
if is_return_self {
quote! { Ok(cb.this) }
} else {
quote! {
<#ty as napi::bindgen_prelude::ToNapiValue>::to_napi_value(env, #ret)
}
}
}
} else {
@ -290,36 +300,40 @@ impl NapiFn {
quote! {}
} else {
let name_str = self.name.to_string();
let js_name = &self.js_name;
let js_name = format!("{}\0", &self.js_name);
let name_len = js_name.len();
let module_register_name = get_register_ident(&name_str);
let intermediate_ident = get_intermediate_ident(&name_str);
let js_mod_ident = js_mod_to_token_stream(self.js_mod.as_ref());
let cb_name = Ident::new(
&format!("__register__fn__{}_callback__", name_str),
Span::call_site(),
);
quote! {
unsafe fn #cb_name(env: napi::bindgen_prelude::sys::napi_env) -> napi::bindgen_prelude::Result<napi::bindgen_prelude::sys::napi_value> {
let mut fn_ptr = std::ptr::null_mut();
napi::bindgen_prelude::check_status!(
napi::bindgen_prelude::sys::napi_create_function(
env,
#js_name.as_ptr() as *const _,
#name_len,
Some(#intermediate_ident),
std::ptr::null_mut(),
&mut fn_ptr,
),
"Failed to register function `{}`",
#name_str,
)?;
Ok(fn_ptr)
}
#[allow(clippy::all)]
#[allow(non_snake_case)]
#[napi::bindgen_prelude::ctor]
fn #module_register_name() {
unsafe fn cb(env: napi::bindgen_prelude::sys::napi_env) -> napi::bindgen_prelude::Result<napi::bindgen_prelude::sys::napi_value> {
let mut fn_ptr = std::ptr::null_mut();
napi::bindgen_prelude::check_status!(
napi::bindgen_prelude::sys::napi_create_function(
env,
#js_name.as_ptr() as *const _,
#name_len,
Some(#intermediate_ident),
std::ptr::null_mut(),
&mut fn_ptr,
),
"Failed to register function `{}`",
#name_str,
)?;
Ok(fn_ptr)
}
napi::bindgen_prelude::register_module_export(#js_name, cb);
napi::bindgen_prelude::register_module_export(#js_mod_ident, #js_name, #cb_name);
}
}
}

View file

@ -0,0 +1,9 @@
use proc_macro2::TokenStream;
use crate::{NapiMod, TryToTokens};
impl TryToTokens for NapiMod {
fn try_to_tokens(&self, _tokens: &mut TokenStream) -> crate::BindgenResult<()> {
Ok(())
}
}

View file

@ -4,7 +4,7 @@ use proc_macro2::{Ident, Literal, Span, TokenStream};
use quote::ToTokens;
use crate::{
codegen::{get_intermediate_ident, get_register_ident},
codegen::{get_intermediate_ident, get_register_ident, js_mod_to_token_stream},
BindgenResult, FnKind, NapiImpl, NapiStruct, NapiStructKind, TryToTokens,
};
@ -378,7 +378,7 @@ impl NapiStruct {
fn gen_register(&self) -> TokenStream {
let name_str = self.name.to_string();
let struct_register_name = get_register_ident(&format!("{}_struct", name_str));
let js_name = &self.js_name;
let js_name = format!("{}\0", self.js_name);
let mut props = vec![];
if self.kind == NapiStructKind::Constructor {
@ -413,13 +413,13 @@ impl NapiStruct {
props.push(prop);
}
let js_mod_ident = js_mod_to_token_stream(self.js_mod.as_ref());
quote! {
#[allow(non_snake_case)]
#[allow(clippy::all)]
#[napi::bindgen_prelude::ctor]
fn #struct_register_name() {
napi::bindgen_prelude::register_class(#name_str, #js_name, vec![#(#props),*]);
napi::bindgen_prelude::register_class(#name_str, #js_mod_ident, #js_name, vec![#(#props),*]);
}
}
}
@ -436,7 +436,7 @@ impl TryToTokens for NapiImpl {
impl NapiImpl {
fn gen_helper_mod(&self) -> BindgenResult<TokenStream> {
let name_str = self.name.to_string();
let js_name = &self.js_name;
let js_name = format!("{}\0", self.js_name);
let mod_name = Ident::new(
&format!("__napi_impl_helper__{}", name_str),
Span::call_site(),
@ -478,7 +478,7 @@ impl NapiImpl {
let mut props: Vec<_> = props.into_iter().collect();
props.sort_by_key(|(_, prop)| prop.to_string());
let props = props.into_iter().map(|(_, prop)| prop);
let js_mod_ident = js_mod_to_token_stream(self.js_mod.as_ref());
Ok(quote! {
#[allow(non_snake_case)]
#[allow(clippy::all)]
@ -488,7 +488,7 @@ impl NapiImpl {
#[napi::bindgen_prelude::ctor]
fn #register_name() {
napi::bindgen_prelude::register_class(#name_str, #js_name, vec![#(#props),*]);
napi::bindgen_prelude::register_class(#name_str, #js_mod_ident, #js_name, vec![#(#props),*]);
}
}
})

View file

@ -54,4 +54,5 @@ napi_ast_impl! {
(Impl, NapiImpl),
(Enum, NapiEnum),
(Const, NapiConst),
(Mod, NapiMod),
}

View file

@ -1,6 +1,7 @@
mod r#const;
mod r#enum;
mod r#fn;
mod js_mod;
pub(crate) mod r#struct;
use std::collections::HashMap;
@ -13,13 +14,19 @@ pub struct TypeDef {
pub kind: String,
pub name: String,
pub def: String,
pub js_mod: Option<String>,
}
impl ToString for TypeDef {
fn to_string(&self) -> String {
let js_mod = if let Some(js_mod) = &self.js_mod {
format!(", \"js_mod\": \"{}\"", js_mod)
} else {
"".to_owned()
};
format!(
r#"{{"kind": "{}", "name": "{}", "def": "{}"}}"#,
self.kind, self.name, self.def,
r#"{{"kind": "{}", "name": "{}", "def": "{}"{}}}"#,
self.kind, self.name, self.def, js_mod,
)
}
}

View file

@ -12,6 +12,7 @@ impl ToTypeDef for NapiConst {
&self.js_name,
ty_to_ts_type(&self.type_name, false).0
),
js_mod: self.js_mod.to_owned(),
}
}
}

View file

@ -11,6 +11,7 @@ impl ToTypeDef for NapiEnum {
js_name = &self.js_name,
variants = self.gen_ts_variants()
),
js_mod: self.js_mod.to_owned(),
}
}
}

View file

@ -19,6 +19,7 @@ impl ToTypeDef for NapiFn {
kind: "fn".to_owned(),
name: self.js_name.clone(),
def,
js_mod: self.js_mod.to_owned(),
}
}
}
@ -111,6 +112,8 @@ impl NapiFn {
let (ts_type, _) = ty_to_ts_type(ret, true);
if ts_type == "undefined" {
"void".to_owned()
} else if ts_type == "Self" {
"this".to_owned()
} else {
ts_type
}

View file

@ -0,0 +1,12 @@
use crate::{NapiMod, ToTypeDef, TypeDef};
impl ToTypeDef for NapiMod {
fn to_type_def(&self) -> TypeDef {
TypeDef {
kind: "mod".to_owned(),
name: self.js_name.clone(),
def: "".to_owned(),
js_mod: None,
}
}
}

View file

@ -23,6 +23,7 @@ impl ToTypeDef for NapiStruct {
}),
name: self.js_name.to_owned(),
def: self.gen_ts_class(),
js_mod: self.js_mod.to_owned(),
}
}
}
@ -44,6 +45,7 @@ impl ToTypeDef for NapiImpl {
.map(|f| f.to_type_def().def)
.collect::<Vec<_>>()
.join("\\n"),
js_mod: self.js_mod.to_owned(),
}
}
}

View file

@ -12,9 +12,10 @@ use napi_derive_backend::{BindgenResult, TryToTokens};
#[cfg(feature = "type-def")]
use napi_derive_backend::{ToTypeDef, TypeDef};
use parser::ParseNapi;
use parser::{attrs::BindgenAttrs, ParseNapi};
use proc_macro::TokenStream as RawStream;
use proc_macro2::TokenStream;
use proc_macro2::{TokenStream, TokenTree};
use quote::ToTokens;
use std::env;
#[cfg(feature = "type-def")]
use std::{
@ -23,6 +24,7 @@ use std::{
};
#[cfg(feature = "compat-mode")]
use syn::{fold::Fold, parse_macro_input, ItemFn};
use syn::{Attribute, Item};
/// ```ignore
/// #[napi]
@ -49,21 +51,78 @@ pub fn napi(attr: RawStream, input: RawStream) -> RawStream {
fn expand(attr: TokenStream, input: TokenStream) -> BindgenResult<TokenStream> {
let mut item = syn::parse2::<syn::Item>(input)?;
let opts = syn::parse2(attr)?;
let opts: BindgenAttrs = syn::parse2(attr)?;
let mut tokens = proc_macro2::TokenStream::new();
let napi = item.parse_napi(&mut tokens, opts)?;
napi.try_to_tokens(&mut tokens)?;
#[cfg(feature = "type-def")]
if let Ok(type_def_file) = env::var("TYPE_DEF_TMP_PATH") {
if let Err(e) = output_type_def(type_def_file, napi.to_type_def()) {
println!("Failed to write type def file: {:?}", e);
if let Item::Mod(mut js_mod) = item {
let js_name = opts.js_name().map_or_else(
|| js_mod.ident.to_string(),
|(js_name, _)| js_name.to_owned(),
);
if let Some((_, mut items)) = js_mod.content.clone() {
for item in items.iter_mut() {
let mut empty_attrs = vec![];
if let Some(item_opts) = replace_napi_attr_in_mod(
js_name.clone(),
match item {
syn::Item::Fn(ref mut function) => &mut function.attrs,
syn::Item::Struct(ref mut struct_) => &mut struct_.attrs,
syn::Item::Enum(ref mut enum_) => &mut enum_.attrs,
syn::Item::Const(ref mut const_) => &mut const_.attrs,
syn::Item::Impl(ref mut impl_) => &mut impl_.attrs,
syn::Item::Mod(mod_) => {
let mod_in_mod = mod_
.attrs
.iter()
.enumerate()
.find(|(_, m)| m.path.segments[0].ident == "napi");
if mod_in_mod.is_some() {
bail_span!(
mod_,
"napi module cannot be nested under another napi module"
);
} else {
&mut empty_attrs
}
}
_ => &mut empty_attrs,
},
) {
let napi = item.parse_napi(&mut tokens, item_opts)?;
napi.try_to_tokens(&mut tokens)?;
#[cfg(feature = "type-def")]
if let Ok(type_def_file) = env::var("TYPE_DEF_TMP_PATH") {
if let Err(e) = output_type_def(type_def_file, napi.to_type_def()) {
println!("Failed to write type def file: {:?}", e);
};
}
} else {
item.to_tokens(&mut tokens);
};
}
js_mod.content = None;
};
}
let js_mod_attrs: Vec<Attribute> = js_mod
.attrs
.clone()
.into_iter()
.filter(|attr| attr.path.segments[0].ident != "napi")
.collect();
let mod_name = js_mod.ident;
let visible = js_mod.vis;
let mod_tokens = quote! { #(#js_mod_attrs)* #visible mod #mod_name { #tokens } };
Ok(mod_tokens)
} else {
let napi = item.parse_napi(&mut tokens, opts)?;
napi.try_to_tokens(&mut tokens)?;
Ok(tokens)
#[cfg(feature = "type-def")]
if let Ok(type_def_file) = env::var("TYPE_DEF_TMP_PATH") {
if let Err(e) = output_type_def(type_def_file, napi.to_type_def()) {
println!("Failed to write type def file: {:?}", e);
};
}
Ok(tokens)
}
}
#[cfg(feature = "type-def")]
@ -213,3 +272,49 @@ pub fn module_exports(_attr: RawStream, input: RawStream) -> RawStream {
})
.into()
}
fn replace_napi_attr_in_mod(
js_namespace: String,
attrs: &mut Vec<syn::Attribute>,
) -> Option<BindgenAttrs> {
let napi_attr = attrs.clone();
let napi_attr = napi_attr
.iter()
.enumerate()
.find(|(_, m)| m.path.segments[0].ident == "napi");
if let Some((index, napi_attr)) = napi_attr {
let attr_token_stream = napi_attr.tokens.clone();
let raw_attr_stream = attr_token_stream.to_string();
let raw_attr_stream = if !raw_attr_stream.is_empty() {
raw_attr_stream
.strip_prefix('(')
.unwrap()
.strip_suffix(')')
.unwrap()
.to_string()
} else {
raw_attr_stream
};
let raw_attr_token_stream = syn::parse_str::<TokenStream>(raw_attr_stream.as_str()).unwrap();
let new_attr: syn::Attribute = if !raw_attr_stream.is_empty() {
syn::parse_quote!(
#[napi(#raw_attr_token_stream, namespace = #js_namespace)]
)
} else {
syn::parse_quote!(
#[napi(namespace = #js_namespace)]
)
};
let struct_opts: BindgenAttrs;
if let Some(TokenTree::Group(g)) = new_attr.tokens.into_iter().next() {
struct_opts = syn::parse2(g.stream()).ok()?;
} else {
struct_opts = syn::parse2(quote! {}).ok()?;
}
attrs.remove(index);
Some(struct_opts)
} else {
None
}
}

View file

@ -27,6 +27,7 @@ struct AttributeParseState {
checks: Cell<usize>,
}
#[derive(Debug)]
/// Parsed attributes from a `#[napi(..)]`.
pub struct BindgenAttrs {
/// Whether `#[napi]` attribute exists
@ -51,7 +52,7 @@ macro_rules! attrgen {
(skip, Skip(Span)),
(strict, Strict(Span)),
(object, Object(Span)),
(task, Task(Span)),
(namespace, Namespace(Span, String, Span)),
// impl later
// (inspectable, Inspectable(Span)),
@ -169,11 +170,11 @@ impl BindgenAttrs {
.enumerate()
.find(|&(_, m)| m.path.segments[0].ident == "napi");
let pos = match &napi_attr {
let pos = match napi_attr {
Some((pos, raw_attr)) => {
ret.exists = true;
ret.span = raw_attr.tokens.span();
*pos
pos
}
None => return Ok(ret),
};
@ -216,6 +217,7 @@ impl Default for BindgenAttrs {
macro_rules! gen_bindgen_attr {
($( ($method:ident, $($variants:tt)*) ,)*) => {
/// The possible attributes in the `#[napi]`.
#[derive(Debug)]
pub enum BindgenAttr {
$($($variants)*,)*
}
@ -243,7 +245,6 @@ pub fn record_struct(ident: &Ident, js_name: String, opts: &BindgenAttrs) {
pub fn check_recorded_struct_for_impl(ident: &Ident, opts: &BindgenAttrs) -> BindgenResult<String> {
STRUCTS.with(|state| {
let struct_name = ident.to_string();
let mut map = state.parsed.borrow_mut();
if let Some(parsed) = map.get_mut(&struct_name) {
if opts.constructor().is_some() && !cfg!(debug_assertions) {

View file

@ -574,6 +574,7 @@ fn napi_fn_from_decl(
parent: parent.cloned(),
attrs,
strict: opts.strict().is_some(),
js_mod: opts.namespace().map(|(m, _)| m.to_owned()),
}
})
}
@ -588,7 +589,7 @@ impl ParseNapi for syn::Item {
syn::Item::Const(c) => c.parse_napi(tokens, opts),
_ => bail_span!(
self,
"#[napi] can only be applied to a function, struct, enum or impl."
"#[napi] can only be applied to a function, struct, enum, const, mod or impl."
),
}
}
@ -735,7 +736,6 @@ impl ConvertToAST for syn::ItemStruct {
setter: !(ignored || readonly),
})
}
record_struct(&struct_name, js_name.clone(), &opts);
Diagnostic::from_vec(errors).map(|()| Napi {
@ -747,13 +747,14 @@ impl ConvertToAST for syn::ItemStruct {
fields,
is_tuple,
kind: struct_kind,
js_mod: opts.namespace().map(|(m, _)| m.to_owned()),
}),
})
}
}
impl ConvertToAST for syn::ItemImpl {
fn convert_to_ast(&mut self, _opts: BindgenAttrs) -> BindgenResult<Napi> {
fn convert_to_ast(&mut self, impl_opts: BindgenAttrs) -> BindgenResult<Napi> {
let struct_name = match get_ty(&self.self_ty) {
syn::Type::Path(syn::TypePath {
ref path,
@ -823,6 +824,7 @@ impl ConvertToAST for syn::ItemImpl {
js_name: struct_js_name,
items,
task_output_type,
js_mod: impl_opts.namespace().map(|(m, _)| m.to_owned()),
}),
})
}
@ -916,6 +918,7 @@ impl ConvertToAST for syn::ItemEnum {
name: self.ident.clone(),
js_name,
variants,
js_mod: opts.namespace().map(|(m, _)| m.to_owned()),
}),
})
}
@ -933,6 +936,7 @@ impl ConvertToAST for syn::ItemConst {
.map_or_else(|| self.ident.to_string(), |(s, _)| s.to_string()),
type_name: *self.ty.clone(),
value: *self.expr.clone(),
js_mod: opts.namespace().map(|(m, _)| m.to_owned()),
}),
}),
_ => bail_span!(self, "only public const allowed"),

View file

@ -1,8 +1,9 @@
use std::ffi::CStr;
use std::mem;
use std::os::raw::c_void;
use std::ptr;
use std::rc::Rc;
use std::sync::atomic::{AtomicU8, Ordering};
use std::{ffi::CString, rc::Rc};
use crate::{
bindgen_runtime::ToNapiValue, check_status, js_values::NapiValue, sys, Env, JsError, JsObject,
@ -59,7 +60,7 @@ pub fn run<T: Task>(
napi_async_work: ptr::null_mut(),
status: task_status.clone(),
}));
let async_work_name = CString::new("napi_rs_async_work")?;
let async_work_name = unsafe { CStr::from_bytes_with_nul_unchecked(b"napi_rs_async_work\0") };
check_status!(unsafe {
sys::napi_create_async_work(
env,

View file

@ -12,7 +12,7 @@ pub static ___CALL_FROM_FACTORY: AtomicBool = AtomicBool::new(false);
pub struct CallbackInfo<const N: usize> {
env: sys::napi_env,
this: sys::napi_value,
pub this: sys::napi_value,
pub args: [sys::napi_value; N],
}

View file

@ -1,6 +1,7 @@
use crate::{bindgen_prelude::*, check_status, sys, ValueType};
use std::ptr;
use crate::{bindgen_prelude::*, check_status, sys, ValueType};
pub struct Array {
env: sys::napi_env,
inner: sys::napi_value,
@ -116,6 +117,20 @@ impl FromNapiValue for Array {
}
}
impl Array {
pub fn from_vec<T>(env: &Env, value: Vec<T>) -> Result<Self>
where
T: ToNapiValue,
{
let mut arr = Array::new(env.0, value.len() as u32)?;
value.into_iter().enumerate().try_for_each(|(index, val)| {
arr.set(index as u32, val)?;
Ok::<(), Error>(())
})?;
Ok(arr)
}
}
impl ValidateNapiValue for Array {
fn type_of() -> Vec<ValueType> {
vec![ValueType::Object]

View file

@ -19,8 +19,9 @@ use super::{FromNapiValue, ToNapiValue, TypeName};
#[allow(non_camel_case_types)]
pub struct i64n(pub i64);
/// https://nodejs.org/api/n-api.html#napi_create_bigint_words
/// The resulting BigInt is calculated as: (1)^sign_bit (words[0] × (2^64)^0 + words[1] × (2^64)^1 + …)
/// <https://nodejs.org/api/n-api.html#napi_create_bigint_words>
/// The resulting BigInt is calculated as: (1)^sign_bit (words\[0\] × (2^64)^0 + words\[1\] × (2^64)^1 + …)
#[derive(Debug, Clone)]
pub struct BigInt {
/// true for negative numbers
pub sign_bit: bool,

View file

@ -1,5 +1,5 @@
use super::{FromNapiValue, ToNapiValue, TypeName};
use crate::{type_of, Status, ValueType};
use crate::{type_of, JsNull, JsUndefined, NapiRaw, Status, ValueType};
const ERROR_MSG: &str = "The return value of typeof(T) should not be equal in Either";
@ -12,6 +12,21 @@ pub enum Either<
B(B),
}
impl<
A: TypeName + FromNapiValue + ToNapiValue + NapiRaw,
B: TypeName + FromNapiValue + ToNapiValue + NapiRaw,
> Either<A, B>
{
/// # Safety
/// Backward compatible with `Either` in **v1**
pub unsafe fn raw(&self) -> napi_sys::napi_value {
match &self {
Self::A(a) => a.raw(),
Self::B(b) => b.raw(),
}
}
}
impl<A: TypeName + FromNapiValue + ToNapiValue, B: TypeName + FromNapiValue + ToNapiValue> TypeName
for Either<A, B>
{
@ -24,6 +39,25 @@ impl<A: TypeName + FromNapiValue + ToNapiValue, B: TypeName + FromNapiValue + To
}
}
// Backwards compatibility with v1
impl<T: TypeName + FromNapiValue + ToNapiValue> From<Either<T, JsUndefined>> for Option<T> {
fn from(value: Either<T, JsUndefined>) -> Option<T> {
match value {
Either::A(v) => Some(v),
Either::B(_) => None,
}
}
}
impl<T: TypeName + FromNapiValue + ToNapiValue> From<Either<T, JsNull>> for Option<T> {
fn from(value: Either<T, JsNull>) -> Option<T> {
match value {
Either::A(v) => Some(v),
Either::B(_) => None,
}
}
}
impl<A: TypeName + FromNapiValue + ToNapiValue, B: TypeName + FromNapiValue + ToNapiValue>
FromNapiValue for Either<A, B>
{

View file

@ -1,4 +1,4 @@
use std::ffi::{c_void, CString};
use std::ffi::{c_void, CStr};
use std::future;
use std::pin::Pin;
use std::ptr;
@ -15,7 +15,6 @@ pub struct Promise<T: FromNapiValue> {
}
unsafe impl<T: FromNapiValue> Send for Promise<T> {}
unsafe impl<T: FromNapiValue> Sync for Promise<T> {}
impl<T: FromNapiValue> FromNapiValue for Promise<T> {
unsafe fn from_napi_value(
@ -23,7 +22,7 @@ impl<T: FromNapiValue> FromNapiValue for Promise<T> {
napi_val: napi_sys::napi_value,
) -> crate::Result<Self> {
let mut then = ptr::null_mut();
let then_c_string = CString::new("then")?;
let then_c_string = CStr::from_bytes_with_nul_unchecked(b"then\0");
check_status!(
napi_sys::napi_get_named_property(env, napi_val, then_c_string.as_ptr(), &mut then,),
"Failed to get then function"
@ -55,7 +54,7 @@ impl<T: FromNapiValue> FromNapiValue for Promise<T> {
"Failed to call then method"
)?;
let mut catch = ptr::null_mut();
let catch_c_string = CString::new("catch")?;
let catch_c_string = CStr::from_bytes_with_nul_unchecked(b"catch\0");
check_status!(
napi_sys::napi_get_named_property(
env,

View file

@ -35,9 +35,16 @@ impl<T: Task> AsyncTask<T> {
abort_signal: Some(signal),
}
}
pub fn with_optional_signal(task: T, signal: Option<AbortSignal>) -> Self {
Self {
inner: task,
abort_signal: signal,
}
}
}
/// https://developer.mozilla.org/zh-CN/docs/Web/API/AbortController
/// <https://developer.mozilla.org/zh-CN/docs/Web/API/AbortController>
pub struct AbortSignal {
raw_work: Rc<AtomicPtr<napi_sys::napi_async_work__>>,
raw_deferred: Rc<AtomicPtr<napi_sys::napi_deferred__>>,

View file

@ -1,4 +1,7 @@
use std::{cell::RefCell, collections::HashMap, ffi::CString, ptr};
use std::cell::RefCell;
use std::collections::HashMap;
use std::ffi::CStr;
use std::ptr;
use crate::{check_status, check_status_or_throw, sys, JsError, Property, Result};
@ -6,9 +9,15 @@ pub type ExportRegisterCallback = unsafe fn(sys::napi_env) -> Result<sys::napi_v
pub type ModuleExportsCallback =
unsafe fn(env: sys::napi_env, exports: sys::napi_value) -> Result<()>;
type ModuleRegisterCallback =
RefCell<Vec<(Option<&'static str>, (&'static str, ExportRegisterCallback))>>;
type ModuleClassProperty =
RefCell<HashMap<&'static str, HashMap<Option<&'static str>, (&'static str, Vec<Property>)>>>;
thread_local! {
static MODULE_REGISTER_CALLBACK: RefCell<Vec<(&'static str, ExportRegisterCallback)>> = Default::default();
static MODULE_CLASS_PROPERTIES: RefCell<HashMap<&'static str, (&'static str, Vec<Property>)>> = Default::default();
static MODULE_REGISTER_CALLBACK: ModuleRegisterCallback = Default::default();
static MODULE_CLASS_PROPERTIES: ModuleClassProperty = Default::default();
static REGISTERED_CLASSES: RefCell<HashMap<
/* export name */ &'static str,
/* constructor */ sys::napi_ref,
@ -31,17 +40,27 @@ pub fn register_module_exports(callback: ModuleExportsCallback) {
MODULE_EXPORTS.with(|cell| cell.set(vec![callback]));
}
pub fn register_module_export(name: &'static str, cb: ExportRegisterCallback) {
pub fn register_module_export(
js_mod: Option<&'static str>,
name: &'static str,
cb: ExportRegisterCallback,
) {
MODULE_REGISTER_CALLBACK.with(|exports| {
let mut list = exports.borrow_mut();
list.push((name, cb));
list.push((js_mod, (name, cb)));
});
}
pub fn register_class(rust_name: &'static str, js_name: &'static str, props: Vec<Property>) {
pub fn register_class(
rust_name: &'static str,
js_mod: Option<&'static str>,
js_name: &'static str,
props: Vec<Property>,
) {
MODULE_CLASS_PROPERTIES.with(|map| {
let mut map = map.borrow_mut();
let val = map.entry(rust_name).or_default();
let val = val.entry(js_mod).or_default();
val.0 = js_name;
val.1.extend(props.into_iter());
@ -53,73 +72,158 @@ unsafe extern "C" fn napi_register_module_v1(
env: sys::napi_env,
exports: sys::napi_value,
) -> sys::napi_value {
let mut exports_objects: HashMap<Option<&'static str>, sys::napi_value> = HashMap::default();
MODULE_REGISTER_CALLBACK.with(|to_register_exports| {
to_register_exports
.take()
.into_iter()
.for_each(|(name, callback)| {
let js_name = CString::new(name).unwrap();
unsafe {
if let Err(e) = callback(env).and_then(|v| {
check_status!(
sys::napi_set_named_property(env, exports, js_name.as_ptr(), v),
"Failed to register export `{}`",
name,
)
}) {
JsError::from(e).throw_into(env)
.iter_mut()
.fold(
HashMap::<Option<&'static str>, Vec<(&'static str, ExportRegisterCallback)>>::new(),
|mut acc, (js_mod, item)| {
if let Some(k) = acc.get_mut(js_mod) {
k.push(*item);
} else {
acc.insert(*js_mod, vec![*item]);
}
acc
},
)
.iter()
.for_each(|(js_mod, items)| {
let mut exports_js_mod = ptr::null_mut();
if let Some(js_mod_str) = js_mod {
if let Some(exports_object) = exports_objects.get(js_mod) {
exports_js_mod = *exports_object;
} else {
check_status_or_throw!(
env,
sys::napi_create_object(env, &mut exports_js_mod),
"Create export JavaScript Object [{}] failed",
js_mod_str
);
check_status_or_throw!(
env,
sys::napi_set_named_property(
env,
exports,
js_mod_str.as_ptr() as *const _,
exports_js_mod
),
"Set exports Object [{}] into exports object failed",
js_mod_str
);
exports_objects.insert(*js_mod, exports_js_mod);
}
}
for (name, callback) in items {
let js_name = CStr::from_bytes_with_nul_unchecked(name.as_bytes());
unsafe {
if let Err(e) = callback(env).and_then(|v| {
check_status!(
sys::napi_set_named_property(
env,
if exports_js_mod.is_null() {
exports
} else {
exports_js_mod
},
js_name.as_ptr(),
v
),
"Failed to register export `{}`",
name,
)
}) {
JsError::from(e).throw_into(env)
}
}
}
})
});
MODULE_CLASS_PROPERTIES.with(|to_register_classes| {
for (rust_name, (js_name, props)) in to_register_classes.take().into_iter() {
unsafe {
let (ctor, props): (Vec<_>, Vec<_>) = props.into_iter().partition(|prop| prop.is_ctor);
// one or more or zero?
// zero is for `#[napi(task)]`
if ctor.is_empty() && props.is_empty() {
continue;
}
let ctor = ctor.get(0).map(|c| c.raw().method.unwrap()).unwrap_or(noop);
let raw_props: Vec<_> = props.iter().map(|prop| prop.raw()).collect();
for (rust_name, js_mods) in to_register_classes.take().iter() {
for (js_mod, (js_name, props)) in js_mods {
let mut exports_js_mod = ptr::null_mut();
unsafe {
if let Some(js_mod_str) = js_mod {
if let Some(exports_object) = exports_objects.get(js_mod) {
exports_js_mod = *exports_object;
} else {
check_status_or_throw!(
env,
sys::napi_create_object(env, &mut exports_js_mod),
"Create export JavaScript Object [{}] failed",
js_mod_str
);
check_status_or_throw!(
env,
sys::napi_set_named_property(
env,
exports,
js_mod_str.as_ptr() as *const _,
exports_js_mod
),
"Set exports Object [{}] into exports object failed",
js_mod_str
);
exports_objects.insert(*js_mod, exports_js_mod);
}
}
let (ctor, props): (Vec<_>, Vec<_>) = props.iter().partition(|prop| prop.is_ctor);
// one or more or zero?
// zero is for `#[napi(task)]`
if ctor.is_empty() && props.is_empty() {
continue;
}
let ctor = ctor.get(0).map(|c| c.raw().method.unwrap()).unwrap_or(noop);
let raw_props: Vec<_> = props.iter().map(|prop| prop.raw()).collect();
let js_class_name = CString::new(js_name).unwrap();
let mut class_ptr = ptr::null_mut();
let js_class_name = CStr::from_bytes_with_nul_unchecked(js_name.as_bytes());
let mut class_ptr = ptr::null_mut();
check_status_or_throw!(
env,
sys::napi_define_class(
check_status_or_throw!(
env,
js_class_name.as_ptr(),
js_name.len(),
Some(ctor),
ptr::null_mut(),
raw_props.len(),
raw_props.as_ptr(),
&mut class_ptr,
),
"Failed to register class `{}` generate by struct `{}`",
&js_name,
&rust_name
);
sys::napi_define_class(
env,
js_class_name.as_ptr(),
js_name.len(),
Some(ctor),
ptr::null_mut(),
raw_props.len(),
raw_props.as_ptr(),
&mut class_ptr,
),
"Failed to register class `{}` generate by struct `{}`",
&js_name,
&rust_name
);
let mut ctor_ref = ptr::null_mut();
sys::napi_create_reference(env, class_ptr, 1, &mut ctor_ref);
let mut ctor_ref = ptr::null_mut();
sys::napi_create_reference(env, class_ptr, 1, &mut ctor_ref);
REGISTERED_CLASSES.with(|registered_classes| {
let mut registered_class = registered_classes.borrow_mut();
registered_class.insert(js_name, ctor_ref);
});
REGISTERED_CLASSES.with(|registered_classes| {
let mut registered_class = registered_classes.borrow_mut();
registered_class.insert(js_name, ctor_ref);
});
check_status_or_throw!(
env,
sys::napi_set_named_property(env, exports, js_class_name.as_ptr(), class_ptr),
"Failed to register class `{}` generate by struct `{}`",
&js_name,
&rust_name
);
check_status_or_throw!(
env,
sys::napi_set_named_property(
env,
if exports_js_mod.is_null() {
exports
} else {
exports_js_mod
},
js_class_name.as_ptr(),
class_ptr
),
"Failed to register class `{}` generate by struct `{}`",
&js_name,
&rust_name
);
}
}
}
});

View file

@ -1,5 +1,6 @@
use std::ptr;
use crate::bindgen_runtime::{FromNapiValue, TypeName};
use crate::check_status;
use crate::{sys, Either, Env, Error, JsUndefined, NapiValue, Result, Status};
@ -45,18 +46,21 @@ impl<'env> CallContext<'env> {
}
}
pub fn get<ArgType: NapiValue>(&self, index: usize) -> Result<ArgType> {
pub fn get<ArgType: FromNapiValue>(&self, index: usize) -> Result<ArgType> {
if index >= self.arg_len() {
Err(Error::new(
Status::GenericFailure,
"Arguments index out of range".to_owned(),
))
} else {
Ok(unsafe { ArgType::from_raw_unchecked(self.env.0, self.args[index]) })
unsafe { ArgType::from_napi_value(self.env.0, self.args[index]) }
}
}
pub fn try_get<ArgType: NapiValue>(&self, index: usize) -> Result<Either<ArgType, JsUndefined>> {
pub fn try_get<ArgType: NapiValue + TypeName + FromNapiValue>(
&self,
index: usize,
) -> Result<Either<ArgType, JsUndefined>> {
if index >= self.arg_len() {
Err(Error::new(
Status::GenericFailure,

View file

@ -1,6 +1,6 @@
use std::convert::{From, TryFrom};
use std::error;
use std::ffi::CString;
use std::ffi::{CStr, CString};
use std::fmt;
#[cfg(feature = "serde-json")]
use std::fmt::Display;
@ -206,11 +206,13 @@ macro_rules! impl_object_methods {
}
pub fn throw(&self, env: sys::napi_env) -> Result<()> {
let error_status = format!("{:?}", self.0.status);
let error_status = format!("{:?}\0", self.0.status);
let status_len = error_status.len();
let error_code_string = CString::new(error_status).unwrap();
let error_code_string =
unsafe { CStr::from_bytes_with_nul_unchecked(error_status.as_bytes()) };
let reason_len = self.0.reason.len();
let reason = CString::new(self.0.reason.clone()).unwrap();
let reason_c_string = format!("{}\0", self.0.reason.clone());
let reason = unsafe { CStr::from_bytes_with_nul_unchecked(reason_c_string.as_bytes()) };
let mut error_code = ptr::null_mut();
let mut reason_string = ptr::null_mut();
let mut js_error = ptr::null_mut();

View file

@ -229,7 +229,7 @@ impl DerefMut for JsArrayBufferValue {
impl JsTypedArray {
/// get TypeArray info
/// https://nodejs.org/api/n-api.html#n_api_napi_get_typedarray_info
/// <https://nodejs.org/api/n-api.html#n_api_napi_get_typedarray_info>
///
/// ***Warning***: Use caution while using this API since the underlying data buffer is managed by the VM.
pub fn into_value(self) -> Result<JsTypedArrayValue> {

View file

@ -196,7 +196,7 @@ impl TryFrom<JsBigInt> for u64 {
}
impl JsBigInt {
/// https://nodejs.org/api/n-api.html#n_api_napi_get_value_bigint_words
/// <https://nodejs.org/api/n-api.html#n_api_napi_get_value_bigint_words>
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;

View file

@ -1,37 +1 @@
use crate::{sys, JsUndefined, NapiRaw, NapiValue, Result};
#[derive(Debug, Clone, Copy)]
pub enum Either<A: NapiValue, B: NapiValue> {
A(A),
B(B),
}
impl<T: NapiValue> From<Either<T, JsUndefined>> for Option<T> {
fn from(value: Either<T, JsUndefined>) -> Option<T> {
match value {
Either::A(v) => Some(v),
Either::B(_) => None,
}
}
}
impl<A: NapiValue, B: NapiValue> NapiValue for Either<A, B> {
unsafe fn from_raw(env: sys::napi_env, value: sys::napi_value) -> Result<Either<A, B>> {
A::from_raw(env, value)
.map(Self::A)
.or_else(|_| B::from_raw(env, value).map(Self::B))
}
unsafe fn from_raw_unchecked(env: sys::napi_env, value: sys::napi_value) -> Either<A, B> {
Self::from_raw(env, value).unwrap()
}
}
impl<A: NapiValue, B: NapiValue> NapiRaw for Either<A, B> {
unsafe fn raw(&self) -> sys::napi_value {
match self {
Either::A(v) => v.raw(),
Either::B(v) => v.raw(),
}
}
}
pub use crate::bindgen_runtime::Either;

View file

@ -94,7 +94,7 @@ impl JsFunction {
unsafe { JsUnknown::from_raw(self.0.env, return_value) }
}
/// https://nodejs.org/api/n-api.html#n_api_napi_new_instance
/// <https://nodejs.org/api/n-api.html#n_api_napi_new_instance>
///
/// This method is used to instantiate a new `JavaScript` value using a given `JsFunction` that represents the constructor for the object.
pub fn new_instance<V>(&self, args: &[V]) -> Result<JsObject>

View file

@ -437,7 +437,7 @@ macro_rules! impl_object_methods {
Ok(unsafe { JsObject::from_raw_unchecked(self.0.env, raw_value) })
}
/// https://nodejs.org/api/n-api.html#n_api_napi_get_all_property_names
/// <https://nodejs.org/api/n-api.html#n_api_napi_get_all_property_names>
/// return `Array` of property names
#[cfg(feature = "napi6")]
pub fn get_all_property_names(

View file

@ -156,7 +156,6 @@ macro_rules! assert_type_of {
}
#[allow(dead_code)]
#[cfg(debug_assertions)]
pub(crate) unsafe fn log_js_value<V: AsRef<[sys::napi_value]>>(
// `info`, `log`, `warning` or `error`
method: &str,

View file

@ -1,4 +1,4 @@
use std::ffi::CString;
use std::ffi::CStr;
use std::future::Future;
use std::marker::PhantomData;
use std::os::raw::c_void;
@ -25,7 +25,7 @@ impl<Data, Resolver: FnOnce(sys::napi_env, Data) -> Result<sys::napi_value>>
{
pub fn new(env: sys::napi_env, deferred: sys::napi_deferred, resolver: Resolver) -> Result<Self> {
let mut async_resource_name = ptr::null_mut();
let s = CString::new("napi_resolve_promise_from_future")?;
let s = unsafe { CStr::from_bytes_with_nul_unchecked(b"napi_resolve_promise_from_future\0") };
check_status!(unsafe {
sys::napi_create_string_utf8(env, s.as_ptr(), 32, &mut async_resource_name)
})?;

View file

@ -42,6 +42,7 @@ Generated by [AVA](https://avajs.dev).
export function createExternalString(content: string): ExternalObject<string>
export function getExternal(external: ExternalObject<number>): number␊
export function mutateExternal(external: ExternalObject<number>, newVal: number): void␊
export function xxh64Alias(input: Buffer): BigInt␊
export function mapOption(val?: number | undefined | null): number | undefined | null␊
export function add(a: number, b: number): number␊
export function fibonacci(n: number): number␊
@ -97,4 +98,21 @@ Generated by [AVA](https://avajs.dev).
name: string␊
static withName(name: string): ClassWithFactory␊
}␊
export namespace xxh3 {␊
export const ALIGNMENT: number␊
export function xxh3_64(input: Buffer): BigInt␊
export function xxh128(input: Buffer): BigInt␊
export class Xxh3 {␊
constructor()␊
update(input: Buffer): void␊
digest(): BigInt␊
}␊
}␊
export namespace xxh2 {␊
export function xxh2Plus(a: number, b: number): number␊
export function xxh3Xxh64Alias(input: Buffer): BigInt␊
}␊
`

View file

@ -52,6 +52,9 @@ import {
getExternal,
mutateExternal,
createExternalString,
xxh2,
xxh3,
xxh64Alias,
} from '../'
test('export const', (t) => {
@ -294,6 +297,18 @@ BigIntTest('create BigInt i64', (t) => {
t.is(createBigIntI64(), BigInt(100))
})
BigIntTest('js mod test', (t) => {
t.is(xxh64Alias(Buffer.from('hello world')), BigInt('1116'))
t.is(xxh3.xxh3_64(Buffer.from('hello world')), BigInt('1116'))
t.is(xxh3.xxh128(Buffer.from('hello world')), BigInt('1116'))
t.is(xxh2.xxh2Plus(1, 2), 3)
t.is(xxh2.xxh3Xxh64Alias(Buffer.from('hello world')), BigInt('1116'))
t.is(xxh3.ALIGNMENT, 16)
const xx3 = new xxh3.Xxh3()
xx3.update(Buffer.from('hello world'))
t.is(xx3.digest(), BigInt('1116'))
})
const Napi4Test = Number(process.versions.napi) >= 4 ? test : test.skip
Napi4Test('call thread safe function', (t) => {

View file

@ -32,6 +32,7 @@ export function createExternal(size: number): ExternalObject<number>
export function createExternalString(content: string): ExternalObject<string>
export function getExternal(external: ExternalObject<number>): number
export function mutateExternal(external: ExternalObject<number>, newVal: number): void
export function xxh64Alias(input: Buffer): BigInt
export function mapOption(val?: number | undefined | null): number | undefined | null
export function add(a: number, b: number): number
export function fibonacci(n: number): number
@ -87,3 +88,20 @@ export class ClassWithFactory {
name: string
static withName(name: string): ClassWithFactory
}
export namespace xxh3 {
export const ALIGNMENT: number
export function xxh3_64(input: Buffer): BigInt
export function xxh128(input: Buffer): BigInt
export class Xxh3 {
constructor()
update(input: Buffer): void
digest(): BigInt
}
}
export namespace xxh2 {
export function xxh2Plus(a: number, b: number): number
export function xxh3Xxh64Alias(input: Buffer): BigInt
}

View file

@ -0,0 +1,79 @@
#[napi]
mod xxh3 {
use napi::bindgen_prelude::{BigInt, Buffer};
#[napi]
pub const ALIGNMENT: u32 = 16;
#[napi(js_name = "xxh3_64")]
pub fn xxh64(input: Buffer) -> u64 {
let mut h: u64 = 0;
for i in input.as_ref() {
h = h.wrapping_add(*i as u64);
}
h
}
#[napi]
pub fn xxh128(input: Buffer) -> u128 {
let mut h: u128 = 0;
for i in input.as_ref() {
h = h.wrapping_add(*i as u128);
}
h
}
#[napi]
pub struct Xxh3 {
inner: BigInt,
}
#[napi]
impl Xxh3 {
#[napi(constructor)]
pub fn new() -> Xxh3 {
Xxh3 {
inner: BigInt {
sign_bit: false,
words: vec![0],
},
}
}
#[napi]
pub fn update(&mut self, input: Buffer) {
for i in input.as_ref() {
self.inner = BigInt {
sign_bit: false,
words: vec![self.inner.get_u64().1.wrapping_add(*i as u64)],
};
}
}
#[napi]
pub fn digest(&self) -> BigInt {
self.inner.clone()
}
}
}
#[napi]
mod xxh2 {
use napi::bindgen_prelude::*;
#[napi]
pub fn xxh2_plus(a: u32, b: u32) -> u32 {
a + b
}
#[napi]
pub fn xxh3_xxh64_alias(input: Buffer) -> u64 {
super::xxh3::xxh64(input)
}
}
use napi::bindgen_prelude::Buffer;
#[napi]
pub fn xxh64_alias(input: Buffer) -> u64 {
xxh3::xxh64(input)
}

View file

@ -16,6 +16,7 @@ mod either;
mod r#enum;
mod error;
mod external;
mod js_mod;
mod nullable;
mod number;
mod object;

View file

@ -5,7 +5,7 @@ use napi::Task;
struct DelaySum(u32, u32);
#[napi(task)]
#[napi]
impl Task for DelaySum {
type Output = u32;
type JsValue = u32;

266
yarn.lock
View file

@ -882,25 +882,13 @@
node-gyp "^7.1.0"
read-package-json-fast "^2.0.1"
"@octokit/auth-token@^2.4.0", "@octokit/auth-token@^2.4.4":
"@octokit/auth-token@^2.4.4":
version "2.5.0"
resolved "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz#27c37ea26c205f28443402477ffd261311f21e36"
integrity sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==
dependencies:
"@octokit/types" "^6.0.3"
"@octokit/core@^2.4.3":
version "2.5.4"
resolved "https://registry.npmjs.org/@octokit/core/-/core-2.5.4.tgz#f7fbf8e4f86c5cc2497a8887ba2561ec8d358054"
integrity sha512-HCp8yKQfTITYK+Nd09MHzAlP1v3Ii/oCohv0/TW9rhSLvzb98BOVs2QmVYuloE6a3l6LsfyGIwb6Pc4ycgWlIQ==
dependencies:
"@octokit/auth-token" "^2.4.0"
"@octokit/graphql" "^4.3.1"
"@octokit/request" "^5.4.0"
"@octokit/types" "^5.0.0"
before-after-hook "^2.1.0"
universal-user-agent "^5.0.0"
"@octokit/core@^3.5.1":
version "3.5.1"
resolved "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz#8601ceeb1ec0e1b1b8217b960a413ed8e947809b"
@ -923,7 +911,7 @@
is-plain-object "^5.0.0"
universal-user-agent "^6.0.0"
"@octokit/graphql@^4.3.1", "@octokit/graphql@^4.5.8":
"@octokit/graphql@^4.5.8":
version "4.8.0"
resolved "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz#664d9b11c0e12112cbf78e10f49a05959aa22cc3"
integrity sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==
@ -942,26 +930,18 @@
resolved "https://registry.npmjs.org/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-6.0.1.tgz#e07896739618dab8da7d4077c658003775f95437"
integrity sha512-93uGjlhUD+iNg1iWhUENAtJata6w5nE+V4urXOAlIXdco6xNZtUSfYY8dzp3Udy74aqO/B5UZL80x/YMa5PKRw==
"@octokit/plugin-paginate-rest@^2.16.8", "@octokit/plugin-paginate-rest@^2.2.0":
"@octokit/plugin-paginate-rest@^2.16.8":
version "2.17.0"
resolved "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.17.0.tgz#32e9c7cab2a374421d3d0de239102287d791bce7"
integrity sha512-tzMbrbnam2Mt4AhuyCHvpRkS0oZ5MvwwcQPYGtMv4tUa5kkzG58SVB0fcsLulOZQeRnOgdkZWkRUiyBlh0Bkyw==
dependencies:
"@octokit/types" "^6.34.0"
"@octokit/plugin-request-log@^1.0.0", "@octokit/plugin-request-log@^1.0.4":
"@octokit/plugin-request-log@^1.0.4":
version "1.0.4"
resolved "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz#5e50ed7083a613816b1e4a28aeec5fb7f1462e85"
integrity sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==
"@octokit/plugin-rest-endpoint-methods@3.17.0":
version "3.17.0"
resolved "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-3.17.0.tgz#d8ba04eb883849dd98666c55bf49d8c9fe7be055"
integrity sha512-NFV3vq7GgoO2TrkyBRUOwflkfTYkFKS0tLAPym7RNpkwLCttqShaEGjthOsPEEL+7LFcYv3mU24+F2yVd3npmg==
dependencies:
"@octokit/types" "^4.1.6"
deprecation "^2.3.1"
"@octokit/plugin-rest-endpoint-methods@^5.12.0":
version "5.13.0"
resolved "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.13.0.tgz#8c46109021a3412233f6f50d28786f8e552427ba"
@ -979,7 +959,7 @@
deprecation "^2.0.0"
once "^1.4.0"
"@octokit/request@^5.4.0", "@octokit/request@^5.6.0":
"@octokit/request@^5.6.0":
version "5.6.2"
resolved "https://registry.npmjs.org/@octokit/request/-/request-5.6.2.tgz#1aa74d5da7b9e04ac60ef232edd9a7438dcf32d8"
integrity sha512-je66CvSEVf0jCpRISxkUcCa0UkxmFs6eGDRSbfJtAVwbLH5ceqF+YEyC8lj8ystKyZTy8adWr0qmkY52EfOeLA==
@ -991,16 +971,6 @@
node-fetch "^2.6.1"
universal-user-agent "^6.0.0"
"@octokit/rest@^17.1.3":
version "17.11.2"
resolved "https://registry.npmjs.org/@octokit/rest/-/rest-17.11.2.tgz#f3dbd46f9f06361c646230fd0ef8598e59183ead"
integrity sha512-4jTmn8WossTUaLfNDfXk4fVJgbz5JgZE8eCs4BvIb52lvIH8rpVMD1fgRCrHbSd6LRPE5JFZSfAEtszrOq3ZFQ==
dependencies:
"@octokit/core" "^2.4.3"
"@octokit/plugin-paginate-rest" "^2.2.0"
"@octokit/plugin-request-log" "^1.0.0"
"@octokit/plugin-rest-endpoint-methods" "3.17.0"
"@octokit/rest@^18.1.0", "@octokit/rest@^18.12.0":
version "18.12.0"
resolved "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz#f06bc4952fc87130308d810ca9d00e79f6988881"
@ -1011,20 +981,6 @@
"@octokit/plugin-request-log" "^1.0.4"
"@octokit/plugin-rest-endpoint-methods" "^5.12.0"
"@octokit/types@^4.1.6":
version "4.1.10"
resolved "https://registry.npmjs.org/@octokit/types/-/types-4.1.10.tgz#e4029c11e2cc1335051775bc1600e7e740e4aca4"
integrity sha512-/wbFy1cUIE5eICcg0wTKGXMlKSbaAxEr00qaBXzscLXpqhcwgXeS6P8O0pkysBhRfyjkKjJaYrvR1ExMO5eOXQ==
dependencies:
"@types/node" ">= 8"
"@octokit/types@^5.0.0":
version "5.5.0"
resolved "https://registry.npmjs.org/@octokit/types/-/types-5.5.0.tgz#e5f06e8db21246ca102aa28444cdb13ae17a139b"
integrity sha512-UZ1pErDue6bZNjYOotCNveTXArOMZQFG6hKJfOnGnulVCMcVVi7YIIuuR4WfBhjo7zgpmzn/BkPDnUXtNx+PcQ==
dependencies:
"@types/node" ">= 8"
"@octokit/types@^6.0.3", "@octokit/types@^6.16.1", "@octokit/types@^6.34.0":
version "6.34.0"
resolved "https://registry.npmjs.org/@octokit/types/-/types-6.34.0.tgz#c6021333334d1ecfb5d370a8798162ddf1ae8218"
@ -1229,9 +1185,9 @@
"@types/lodash" "*"
"@types/lodash@*":
version "4.14.176"
resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.176.tgz#641150fc1cda36fbfa329de603bbb175d7ee20c0"
integrity sha512-xZmuPTa3rlZoIbtDUyJKZQimJV3bxCmzMIO2c9Pz9afyDro6kr7R79GwcB6mRhuoPmV2p1Vb66WOJH7F886WKQ==
version "4.14.177"
resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.177.tgz#f70c0d19c30fab101cad46b52be60363c43c4578"
integrity sha512-0fDwydE2clKe9MNfvXHBHF9WEahRuj+msTuQqOmAApNORFvhMYZKNGGJdCzuhheVjMps/ti0Ak/iJPACMaevvw==
"@types/minimatch@^3.0.3":
version "3.0.5"
@ -1248,7 +1204,7 @@
resolved "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197"
integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==
"@types/node@*", "@types/node@>= 8", "@types/node@^16.11.9":
"@types/node@*", "@types/node@^16.11.9":
version "16.11.9"
resolved "https://registry.npmjs.org/@types/node/-/node-16.11.9.tgz#879be3ad7af29f4c1a5c433421bf99fab7047185"
integrity sha512-MKmdASMf3LtPzwLyRrFjtFFZ48cMf8jmX5VRYrDQiJa8Ybu5VAmkqBWqKU8fdCwD8ysw4mQ9nrEHvzg6gunR7A==
@ -1392,12 +1348,7 @@ acorn-walk@^8.0.0, acorn-walk@^8.1.1:
resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1"
integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==
acorn@^8.0.4, acorn@^8.4.1:
version "8.5.0"
resolved "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz#4512ccb99b3698c752591e9bb4472e38ad43cee2"
integrity sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==
acorn@^8.6.0:
acorn@^8.0.4, acorn@^8.4.1, acorn@^8.6.0:
version "8.6.0"
resolved "https://registry.npmjs.org/acorn/-/acorn-8.6.0.tgz#e3692ba0eb1a0c83eaa4f37f5fa7368dd7142895"
integrity sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw==
@ -1442,9 +1393,9 @@ ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4:
uri-js "^4.2.2"
ajv@^8.0.1:
version "8.7.1"
resolved "https://registry.npmjs.org/ajv/-/ajv-8.7.1.tgz#52be6f1736b076074798124293618f132ad07a7e"
integrity sha512-gPpOObTO1QjbnN1sVMjJcp1TF9nggMfO4MBR5uQl6ZVTOaEPq5i4oq/6R9q2alMMPB3eg53wFv1RuJBLuxf3Hw==
version "8.8.2"
resolved "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz#01b4fef2007a28bf75f0b7fc009f62679de4abbb"
integrity sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==
dependencies:
fast-deep-equal "^3.1.1"
json-schema-traverse "^1.0.0"
@ -1728,7 +1679,7 @@ bcrypt-pbkdf@^1.0.0, bcrypt-pbkdf@^1.0.2:
dependencies:
tweetnacl "^0.14.3"
before-after-hook@^2.1.0, before-after-hook@^2.2.0:
before-after-hook@^2.2.0:
version "2.2.2"
resolved "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz#a6e8ca41028d90ee2c24222f201c90956091613e"
integrity sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==
@ -1914,15 +1865,15 @@ camelcase-keys@^6.2.2:
map-obj "^4.0.0"
quick-lru "^4.0.1"
camelcase@^5.0.0, camelcase@^5.3.1:
camelcase@^5.3.1:
version "5.3.1"
resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
camelcase@^6.2.0:
version "6.2.0"
resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809"
integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==
version "6.2.1"
resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.2.1.tgz#250fd350cfd555d0d2160b1d51510eaf8326e86e"
integrity sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA==
caseless@~0.12.0:
version "0.12.0"
@ -1951,11 +1902,6 @@ chardet@^0.7.0:
resolved "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
checkup@^1.3.0:
version "1.3.0"
resolved "https://registry.npmjs.org/checkup/-/checkup-1.3.0.tgz#d3800276fea5d0f247ffc951be78c8b02f8e0d76"
integrity sha1-04ACdv6l0PJH/8lRvnjIsC+ODXY=
chokidar@^3.4.3:
version "3.5.2"
resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75"
@ -2081,11 +2027,6 @@ clone@^1.0.2:
resolved "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4=
clone@^2.1.2:
version "2.1.2"
resolved "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f"
integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=
cmd-shim@^4.1.0:
version "4.1.0"
resolved "https://registry.npmjs.org/cmd-shim/-/cmd-shim-4.1.0.tgz#b3a904a6743e9fede4148c6f3800bf2a08135bdd"
@ -2165,9 +2106,9 @@ common-path-prefix@^3.0.0:
integrity sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==
common-tags@^1.8.0:
version "1.8.0"
resolved "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937"
integrity sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==
version "1.8.2"
resolved "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz#94ebb3c076d26032745fd54face7f688ef5ac9c6"
integrity sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==
commondir@^1.0.1:
version "1.0.1"
@ -2370,7 +2311,7 @@ cross-env@^7.0.3:
dependencies:
cross-spawn "^7.0.1"
cross-spawn@^6.0.0, cross-spawn@^6.0.5:
cross-spawn@^6.0.5:
version "6.0.5"
resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
@ -2460,7 +2401,7 @@ decamelize-keys@^1.1.0:
decamelize "^1.1.0"
map-obj "^1.0.0"
decamelize@^1.1.0, decamelize@^1.2.0:
decamelize@^1.1.0:
version "1.2.0"
resolved "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=
@ -3063,19 +3004,6 @@ eventemitter3@^4.0.4:
resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
execa@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8"
integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==
dependencies:
cross-spawn "^6.0.0"
get-stream "^4.0.0"
is-stream "^1.1.0"
npm-run-path "^2.0.0"
p-finally "^1.0.0"
signal-exit "^3.0.0"
strip-eof "^1.0.0"
execa@^5.0.0, execa@^5.1.1:
version "5.1.1"
resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd"
@ -3223,9 +3151,9 @@ flat-cache@^3.0.4:
rimraf "^3.0.2"
flatted@^3.1.0:
version "3.2.2"
resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz#64bfed5cb68fe3ca78b3eb214ad97b63bedce561"
integrity sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==
version "3.2.4"
resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.4.tgz#28d9969ea90661b5134259f312ab6aa7929ac5e2"
integrity sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==
foreground-child@^2.0.0:
version "2.0.0"
@ -3350,7 +3278,7 @@ get-port@^5.1.1:
resolved "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz#0469ed07563479de6efb986baf053dcd7d4e3193"
integrity sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==
get-stream@^4.0.0, get-stream@^4.1.0:
get-stream@^4.1.0:
version "4.1.0"
resolved "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5"
integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==
@ -4023,11 +3951,6 @@ is-ssh@^1.3.0:
dependencies:
protocols "^1.1.0"
is-stream@^1.1.0:
version "1.1.0"
resolved "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
is-stream@^2.0.0:
version "2.0.1"
resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077"
@ -4123,11 +4046,6 @@ istanbul-reports@^3.0.2:
html-escaper "^2.0.0"
istanbul-lib-report "^3.0.0"
jju@^1.4.0:
version "1.4.0"
resolved "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz#a3abe2718af241a2b2904f84a625970f389ae32a"
integrity sha1-o6vicYryQaKykE+EpiWXDzia4yo=
js-string-escape@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef"
@ -4326,9 +4244,9 @@ lilconfig@2.0.4:
integrity sha512-bfTIN7lEsiooCocSISTWXkiWJkRqtL9wYtYy+8EK3Y41qh3mpwPU0ycTOgjdY9ErwXCc8QyrQp82bdL0Xkm9yA==
lines-and-columns@^1.1.6:
version "1.1.6"
resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00"
integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=
version "1.2.4"
resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
lint-staged@^12.1.2:
version "12.1.2"
@ -4351,15 +4269,15 @@ lint-staged@^12.1.2:
yaml "^1.10.2"
listr2@^3.13.3:
version "3.13.3"
resolved "https://registry.npmjs.org/listr2/-/listr2-3.13.3.tgz#d8f6095c9371b382c9b1c2bc33c5941d8e177f11"
integrity sha512-VqAgN+XVfyaEjSaFewGPcDs5/3hBbWVaX1VgWv2f52MF7US45JuARlArULctiB44IIcEk3JF7GtoFCLqEdeuPA==
version "3.13.5"
resolved "https://registry.npmjs.org/listr2/-/listr2-3.13.5.tgz#105a813f2eb2329c4aae27373a281d610ee4985f"
integrity sha512-3n8heFQDSk+NcwBn3CgxEibZGaRzx+pC64n3YjpMD1qguV4nWus3Al+Oo3KooqFKTQEJ1v7MmnbnyyNspgx3NA==
dependencies:
cli-truncate "^2.1.0"
clone "^2.1.2"
colorette "^2.0.16"
log-update "^4.0.0"
p-map "^4.0.0"
rfdc "^1.3.0"
rxjs "^7.4.0"
through "^2.3.8"
wrap-ansi "^7.0.0"
@ -4425,6 +4343,11 @@ locate-path@^6.0.0:
dependencies:
p-locate "^5.0.0"
lodash-es@4.17.21:
version "4.17.21"
resolved "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee"
integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==
lodash._reinterpolate@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
@ -4505,11 +4428,6 @@ lru-cache@^6.0.0:
dependencies:
yallist "^4.0.0"
macos-release@^2.2.0:
version "2.5.0"
resolved "https://registry.npmjs.org/macos-release/-/macos-release-2.5.0.tgz#067c2c88b5f3fb3c56a375b2ec93826220fa1ff2"
integrity sha512-EIgv+QZ9r+814gjJj0Bt5vSLJLzswGmSUbUpbi9AIr/fsN2IWFBl2NucV9PAiek+U1STK468tEkxmVYUtuAN3g==
magic-string@^0.25.7:
version "0.25.7"
resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051"
@ -4664,7 +4582,7 @@ mime-db@1.51.0:
resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c"
integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==
mime-types@^2.1.12, mime-types@^2.1.21, mime-types@~2.1.19:
mime-types@^2.1.12, mime-types@~2.1.19:
version "2.1.34"
resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24"
integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==
@ -5080,13 +4998,6 @@ npm-run-all@^4.1.5:
shell-quote "^1.6.1"
string.prototype.padend "^3.0.0"
npm-run-path@^2.0.0:
version "2.0.2"
resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=
dependencies:
path-key "^2.0.0"
npm-run-path@^4.0.1:
version "4.0.1"
resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea"
@ -5203,14 +5114,6 @@ os-homedir@^1.0.0:
resolved "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M=
os-name@^3.1.0:
version "3.1.0"
resolved "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz#dec19d966296e1cd62d701a5a66ee1ddeae70801"
integrity sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==
dependencies:
macos-release "^2.2.0"
windows-release "^3.1.0"
os-tmpdir@^1.0.0, os-tmpdir@~1.0.2:
version "1.0.2"
resolved "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
@ -5449,7 +5352,7 @@ path-is-absolute@^1.0.0:
resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
path-key@^2.0.0, path-key@^2.0.1:
path-key@^2.0.1:
version "2.0.1"
resolved "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=
@ -5651,19 +5554,6 @@ pupa@^2.1.1:
dependencies:
escape-goat "^2.0.0"
putasset@^5.0.3:
version "5.0.3"
resolved "https://registry.npmjs.org/putasset/-/putasset-5.0.3.tgz#2fa82a8fc5e2333869df8ffb0e1f8618b1c87b9b"
integrity sha512-LGRp0SLOC4PDP/BawMaG3/hw6iKgQPRXcBF7WIzx2XTYwHVk2sS3gpvZqz6bf9GhKMal2phs+DF7J6eIAXEL4w==
dependencies:
"@octokit/rest" "^17.1.3"
checkup "^1.3.0"
mime-types "^2.1.21"
readjson "^2.0.1"
try-catch "^3.0.0"
try-to-catch "^3.0.0"
yargs-parser "^18.1.1"
q@^1.5.1:
version "1.5.1"
resolved "https://registry.npmjs.org/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
@ -5845,14 +5735,6 @@ readdirp@~3.6.0:
dependencies:
picomatch "^2.2.1"
readjson@^2.0.1:
version "2.2.2"
resolved "https://registry.npmjs.org/readjson/-/readjson-2.2.2.tgz#ed940ebdd72b88b383e02db7117402f980158959"
integrity sha512-PdeC9tsmLWBiL8vMhJvocq+OezQ3HhsH2HrN7YkhfYcTjQSa/iraB15A7Qvt7Xpr0Yd2rDNt6GbFwVQDg3HcAw==
dependencies:
jju "^1.4.0"
try-catch "^3.0.0"
rechoir@^0.6.2:
version "0.6.2"
resolved "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
@ -5973,6 +5855,11 @@ reusify@^1.0.4:
resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
rfdc@^1.3.0:
version "1.3.0"
resolved "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b"
integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==
rimraf@^2.6.3:
version "2.7.1"
resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
@ -6134,9 +6021,9 @@ side-channel@^1.0.4:
object-inspect "^1.9.0"
signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3:
version "3.0.5"
resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz#9e3e8cc0c75a99472b44321033a7702e7738252f"
integrity sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==
version "3.0.6"
resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af"
integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==
sinon@^12.0.1:
version "12.0.1"
@ -6201,9 +6088,9 @@ socks-proxy-agent@^5.0.0:
socks "^2.3.3"
socks-proxy-agent@^6.0.0:
version "6.1.0"
resolved "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.1.0.tgz#869cf2d7bd10fea96c7ad3111e81726855e285c3"
integrity sha512-57e7lwCN4Tzt3mXz25VxOErJKXlPfXmkMLnk310v/jwW20jWRVcgsOit+xNkN3eIEdB47GwnfAEBLacZ/wVIKg==
version "6.1.1"
resolved "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.1.1.tgz#e664e8f1aaf4e1fb3df945f09e3d94f911137f87"
integrity sha512-t8J0kG3csjA4g6FTbsMOWws+7R7vuRC8aQ/wy3/1OWmsgwA68zs/+cExQ0koSitUDXqhufF/YJr9wtNMZHw5Ew==
dependencies:
agent-base "^6.0.2"
debug "^4.3.1"
@ -6276,9 +6163,9 @@ spdx-expression-parse@^3.0.0:
spdx-license-ids "^3.0.0"
spdx-license-ids@^3.0.0:
version "3.0.10"
resolved "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz#0d9becccde7003d6c658d487dd48a32f0bf3014b"
integrity sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==
version "3.0.11"
resolved "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz#50c0d8c40a14ec1bf449bae69a0ea4685a9d9f95"
integrity sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==
split-ca@^1.0.1:
version "1.0.1"
@ -6456,11 +6343,6 @@ strip-bom@^4.0.0:
resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878"
integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==
strip-eof@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=
strip-final-newline@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad"
@ -6698,16 +6580,6 @@ trim-off-newlines@^1.0.1:
resolved "https://registry.npmjs.org/trim-off-newlines/-/trim-off-newlines-1.0.3.tgz#8df24847fcb821b0ab27d58ab6efec9f2fe961a1"
integrity sha512-kh6Tu6GbeSNMGfrrZh6Bb/4ZEHV1QlB4xNDBeog8Y9/QwFlKTRyWvY3Fs9tRDAMZliVUwieMgEdIeL/FtqjkJg==
try-catch@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/try-catch/-/try-catch-3.0.0.tgz#7996d8b89895e2e8ae62cbdbeb4fe17470f8131b"
integrity sha512-3uAqUnoemzca1ENvZ72EVimR+E8lqBbzwZ9v4CEbLjkaV3Q+FtdmPUt7jRtoSoTiYjyIMxEkf6YgUpe/voJ1ng==
try-to-catch@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/try-to-catch/-/try-to-catch-3.0.0.tgz#a1903b44d13d5124c54d14a461d22ec1f52ea14b"
integrity sha512-eIm6ZXwR35jVF8By/HdbbkcaCDTBI5PpCPkejRKrYp0jyf/DbCCcRhHD7/O9jtFI3ewsqo9WctFEiJTS6i+CQA==
ts-node@^10.4.0:
version "10.4.0"
resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz#680f88945885f4e6cf450e7f0d6223dd404895f7"
@ -6727,9 +6599,9 @@ ts-node@^10.4.0:
yn "3.1.1"
tsconfig-paths@^3.11.0:
version "3.11.0"
resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz#954c1fe973da6339c78e06b03ce2e48810b65f36"
integrity sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==
version "3.12.0"
resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz#19769aca6ee8f6a1a341e38c8fa45dd9fb18899b"
integrity sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==
dependencies:
"@types/json5" "^0.0.29"
json5 "^1.0.1"
@ -6890,13 +6762,6 @@ unique-string@^2.0.0:
dependencies:
crypto-random-string "^2.0.0"
universal-user-agent@^5.0.0:
version "5.0.0"
resolved "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-5.0.0.tgz#a3182aa758069bf0e79952570ca757de3579c1d9"
integrity sha512-B5TPtzZleXyPrUMKCpEHFmVhMN6EhmJYjG5PQna9s7mXeSqGTLap4OpqLl5FCEFUI3UBmllkETwKf/db66Y54Q==
dependencies:
os-name "^3.1.0"
universal-user-agent@^6.0.0:
version "6.0.0"
resolved "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee"
@ -7079,13 +6944,6 @@ widest-line@^3.1.0:
dependencies:
string-width "^4.0.0"
windows-release@^3.1.0:
version "3.3.3"
resolved "https://registry.npmjs.org/windows-release/-/windows-release-3.3.3.tgz#1c10027c7225743eec6b89df160d64c2e0293999"
integrity sha512-OSOGH1QYiW5yVor9TtmXKQvt2vjQqbYS+DqmsZw+r7xDwLXEeT3JGW0ZppFmHx4diyXmxt238KFR3N9jzevBRg==
dependencies:
execa "^1.0.0"
word-wrap@^1.2.3:
version "1.2.3"
resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
@ -7206,14 +7064,6 @@ yargs-parser@20.2.4:
resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54"
integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==
yargs-parser@^18.1.1:
version "18.1.3"
resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0"
integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==
dependencies:
camelcase "^5.0.0"
decamelize "^1.2.0"
yargs-parser@^20.2.2, yargs-parser@^20.2.3, yargs-parser@^20.2.7:
version "20.2.9"
resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee"