From 1fe39ff66dceaacca7b99207e13ae1ab8f7bdf39 Mon Sep 17 00:00:00 2001 From: LongYinan Date: Tue, 23 Nov 2021 19:00:31 +0800 Subject: [PATCH] feat(napi): support export rust mod as ts namespace --- cli/package.json | 15 +- cli/src/build.ts | 98 ++++--- crates/backend/src/ast.rs | 11 + crates/backend/src/codegen.rs | 10 + crates/backend/src/codegen/const.rs | 8 +- crates/backend/src/codegen/enum.rs | 9 +- crates/backend/src/codegen/fn.rs | 7 +- crates/backend/src/codegen/js_mod.rs | 9 + crates/backend/src/codegen/struct.rs | 10 +- crates/backend/src/lib.rs | 1 + crates/backend/src/typegen.rs | 11 +- crates/backend/src/typegen/const.rs | 1 + crates/backend/src/typegen/enum.rs | 1 + crates/backend/src/typegen/fn.rs | 1 + crates/backend/src/typegen/js_mod.rs | 12 + crates/backend/src/typegen/struct.rs | 2 + crates/macro/src/lib.rs | 133 ++++++++- crates/macro/src/parser/attrs.rs | 9 +- crates/macro/src/parser/mod.rs | 10 +- .../src/bindgen_runtime/js_values/bigint.rs | 1 + .../src/bindgen_runtime/module_register.rs | 213 ++++++++++---- examples/napi/__test__/typegen.spec.ts.md | 20 ++ examples/napi/__test__/typegen.spec.ts.snap | Bin 1251 -> 1369 bytes examples/napi/__test__/values.spec.ts | 15 + examples/napi/index.d.ts | 20 ++ examples/napi/src/js_mod.rs | 79 ++++++ examples/napi/src/lib.rs | 1 + examples/napi/src/task.rs | 2 +- yarn.lock | 266 ++++-------------- 29 files changed, 639 insertions(+), 336 deletions(-) create mode 100644 crates/backend/src/codegen/js_mod.rs create mode 100644 crates/backend/src/typegen/js_mod.rs create mode 100644 examples/napi/src/js_mod.rs diff --git a/cli/package.json b/cli/package.json index 9b24d5cd..82db2b85 100644 --- a/cli/package.json +++ b/cli/package.json @@ -2,14 +2,22 @@ "name": "@napi-rs/cli", "version": "2.0.0-alpha.10", "description": "Cli tools for napi-rs", - "keywords": ["cli", "rust", "napi", "n-api", "neon"], + "keywords": [ + "cli", + "rust", + "napi", + "n-api", + "neon" + ], "author": "LongYinan ", "homepage": "https://github.com/napi-rs/napi-rs", "license": "MIT", "bin": { "napi": "./scripts/index.js" }, - "files": ["scripts"], + "files": [ + "scripts" + ], "engines": { "node": ">= 10" }, @@ -35,13 +43,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" diff --git a/cli/src/build.ts b/cli/src/build.ts index dd9cae6a..0b0d9010 100644 --- a/cli/src/build.ts +++ b/cli/src/build.ts @@ -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 { readonly '': { @@ -352,43 +354,75 @@ export class ExternalObject { [K: symbol]: T } }\n` - const classes = new Map() - const impls = new Map() - 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() + const impls = new Map() + 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 } diff --git a/crates/backend/src/ast.rs b/crates/backend/src/ast.rs index 3c17d872..7d5c1e0c 100644 --- a/crates/backend/src/ast.rs +++ b/crates/backend/src/ast.rs @@ -15,6 +15,7 @@ pub struct NapiFn { pub vis: syn::Visibility, pub parent: Option, pub strict: bool, + pub js_mod: Option, } #[derive(Debug, Clone)] @@ -54,6 +55,7 @@ pub struct NapiStruct { pub fields: Vec, pub is_tuple: bool, pub kind: NapiStructKind, + pub js_mod: Option, } #[derive(Debug, Clone, PartialEq)] @@ -78,6 +80,7 @@ pub struct NapiImpl { pub js_name: String, pub items: Vec, pub task_output_type: Option, + pub js_mod: Option, } #[derive(Debug, Clone)] @@ -85,6 +88,7 @@ pub struct NapiEnum { pub name: Ident, pub js_name: String, pub variants: Vec, + pub js_mod: Option, } #[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, +} + +#[derive(Debug, Clone)] +pub struct NapiMod { + pub name: Ident, + pub js_name: String, } diff --git a/crates/backend/src/codegen.rs b/crates/backend/src/codegen.rs index ccbddca8..a5d47c82 100644 --- a/crates/backend/src/codegen.rs +++ b/crates/backend/src/codegen.rs @@ -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 }) +} diff --git a/crates/backend/src/codegen/const.rs b/crates/backend/src/codegen/const.rs index 698abbd5..b520603f 100644 --- a/crates/backend/src/codegen/const.rs +++ b/crates/backend/src/codegen/const.rs @@ -1,7 +1,10 @@ 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<()> { @@ -26,6 +29,7 @@ impl NapiConst { &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)] @@ -36,7 +40,7 @@ impl NapiConst { #[allow(clippy::all)] #[napi::bindgen_prelude::ctor] fn #register_name() { - napi::bindgen_prelude::register_module_export(#js_name_lit, #cb_name); + napi::bindgen_prelude::register_module_export(#js_mod_ident, #js_name_lit, #cb_name); } } } diff --git a/crates/backend/src/codegen/enum.rs b/crates/backend/src/codegen/enum.rs index bb1664aa..3d950436 100644 --- a/crates/backend/src/codegen/enum.rs +++ b/crates/backend/src/codegen/enum.rs @@ -1,7 +1,10 @@ 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<()> { @@ -124,6 +127,8 @@ impl NapiEnum { 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 { use std::ffi::CString; @@ -144,7 +149,7 @@ impl NapiEnum { #[allow(clippy::all)] #[napi::bindgen_prelude::ctor] fn #register_name() { - napi::bindgen_prelude::register_module_export(#js_name_lit, #callback_name); + napi::bindgen_prelude::register_module_export(#js_mod_ident, #js_name_lit, #callback_name); } } } diff --git a/crates/backend/src/codegen/fn.rs b/crates/backend/src/codegen/fn.rs index 3261d32b..5f962137 100644 --- a/crates/backend/src/codegen/fn.rs +++ b/crates/backend/src/codegen/fn.rs @@ -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, }; @@ -294,12 +294,11 @@ impl NapiFn { 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 { let mut fn_ptr = std::ptr::null_mut(); @@ -324,7 +323,7 @@ impl NapiFn { #[allow(non_snake_case)] #[napi::bindgen_prelude::ctor] fn #module_register_name() { - napi::bindgen_prelude::register_module_export(#js_name, #cb_name); + napi::bindgen_prelude::register_module_export(#js_mod_ident, #js_name, #cb_name); } } } diff --git a/crates/backend/src/codegen/js_mod.rs b/crates/backend/src/codegen/js_mod.rs new file mode 100644 index 00000000..b215993d --- /dev/null +++ b/crates/backend/src/codegen/js_mod.rs @@ -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(()) + } +} diff --git a/crates/backend/src/codegen/struct.rs b/crates/backend/src/codegen/struct.rs index b24cb6f7..dc2efb75 100644 --- a/crates/backend/src/codegen/struct.rs +++ b/crates/backend/src/codegen/struct.rs @@ -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, }; @@ -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),*]); } } } @@ -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),*]); } } }) diff --git a/crates/backend/src/lib.rs b/crates/backend/src/lib.rs index d9242d21..c7567372 100644 --- a/crates/backend/src/lib.rs +++ b/crates/backend/src/lib.rs @@ -54,4 +54,5 @@ napi_ast_impl! { (Impl, NapiImpl), (Enum, NapiEnum), (Const, NapiConst), + (Mod, NapiMod), } diff --git a/crates/backend/src/typegen.rs b/crates/backend/src/typegen.rs index 38bb14d5..1d7ca257 100644 --- a/crates/backend/src/typegen.rs +++ b/crates/backend/src/typegen.rs @@ -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, } 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, ) } } diff --git a/crates/backend/src/typegen/const.rs b/crates/backend/src/typegen/const.rs index 94fc81c6..46bad1c1 100644 --- a/crates/backend/src/typegen/const.rs +++ b/crates/backend/src/typegen/const.rs @@ -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(), } } } diff --git a/crates/backend/src/typegen/enum.rs b/crates/backend/src/typegen/enum.rs index edaf9f8c..59b060df 100644 --- a/crates/backend/src/typegen/enum.rs +++ b/crates/backend/src/typegen/enum.rs @@ -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(), } } } diff --git a/crates/backend/src/typegen/fn.rs b/crates/backend/src/typegen/fn.rs index 733e303c..7b05c5f5 100644 --- a/crates/backend/src/typegen/fn.rs +++ b/crates/backend/src/typegen/fn.rs @@ -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(), } } } diff --git a/crates/backend/src/typegen/js_mod.rs b/crates/backend/src/typegen/js_mod.rs new file mode 100644 index 00000000..ec08dbf0 --- /dev/null +++ b/crates/backend/src/typegen/js_mod.rs @@ -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, + } + } +} diff --git a/crates/backend/src/typegen/struct.rs b/crates/backend/src/typegen/struct.rs index e871ce08..5493ca0f 100644 --- a/crates/backend/src/typegen/struct.rs +++ b/crates/backend/src/typegen/struct.rs @@ -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::>() .join("\\n"), + js_mod: self.js_mod.to_owned(), } } } diff --git a/crates/macro/src/lib.rs b/crates/macro/src/lib.rs index 026ab1f3..a073eb6a 100644 --- a/crates/macro/src/lib.rs +++ b/crates/macro/src/lib.rs @@ -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 { let mut item = syn::parse2::(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 = 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, +) -> Option { + 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::(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 + } +} diff --git a/crates/macro/src/parser/attrs.rs b/crates/macro/src/parser/attrs.rs index a8660405..a53e8272 100644 --- a/crates/macro/src/parser/attrs.rs +++ b/crates/macro/src/parser/attrs.rs @@ -27,6 +27,7 @@ struct AttributeParseState { checks: Cell, } +#[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 { 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) { diff --git a/crates/macro/src/parser/mod.rs b/crates/macro/src/parser/mod.rs index 4f864247..9d6a2b65 100644 --- a/crates/macro/src/parser/mod.rs +++ b/crates/macro/src/parser/mod.rs @@ -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 { + fn convert_to_ast(&mut self, impl_opts: BindgenAttrs) -> BindgenResult { 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"), diff --git a/crates/napi/src/bindgen_runtime/js_values/bigint.rs b/crates/napi/src/bindgen_runtime/js_values/bigint.rs index 5252e0b9..861f69ef 100644 --- a/crates/napi/src/bindgen_runtime/js_values/bigint.rs +++ b/crates/napi/src/bindgen_runtime/js_values/bigint.rs @@ -21,6 +21,7 @@ pub struct i64n(pub i64); /// /// 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, diff --git a/crates/napi/src/bindgen_runtime/module_register.rs b/crates/napi/src/bindgen_runtime/module_register.rs index 89413ce7..07e86dcf 100644 --- a/crates/napi/src/bindgen_runtime/module_register.rs +++ b/crates/napi/src/bindgen_runtime/module_register.rs @@ -9,9 +9,15 @@ pub type ExportRegisterCallback = unsafe fn(sys::napi_env) -> Result Result<()>; +type ModuleRegisterCallback = + RefCell, (&'static str, ExportRegisterCallback))>>; + +type ModuleClassProperty = + RefCell, (&'static str, Vec)>>>; + thread_local! { - static MODULE_REGISTER_CALLBACK: RefCell> = Default::default(); - static MODULE_CLASS_PROPERTIES: RefCell)>> = Default::default(); + static MODULE_REGISTER_CALLBACK: ModuleRegisterCallback = Default::default(); + static MODULE_CLASS_PROPERTIES: ModuleClassProperty = Default::default(); static REGISTERED_CLASSES: RefCell, + 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) { +pub fn register_class( + rust_name: &'static str, + js_mod: Option<&'static str>, + js_name: &'static str, + props: Vec, +) { 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()); @@ -56,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, sys::napi_value> = HashMap::default(); MODULE_REGISTER_CALLBACK.with(|to_register_exports| { to_register_exports .take() + .iter_mut() + .fold( + HashMap::, 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(|(name, callback)| { - 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, exports, js_name.as_ptr(), v), - "Failed to register export `{}`", - name, - ) - }) { - JsError::from(e).throw_into(env) + .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 = CStr::from_bytes_with_nul_unchecked(js_name.as_bytes()); - 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 + ); + } } } }); diff --git a/examples/napi/__test__/typegen.spec.ts.md b/examples/napi/__test__/typegen.spec.ts.md index a4bbe485..a3ded7ea 100644 --- a/examples/napi/__test__/typegen.spec.ts.md +++ b/examples/napi/__test__/typegen.spec.ts.md @@ -42,6 +42,9 @@ Generated by [AVA](https://avajs.dev). export function createExternalString(content: string): ExternalObject␊ export function getExternal(external: ExternalObject): number␊ export function mutateExternal(external: ExternalObject, 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 +100,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␊ + ␊ + }␊ ` diff --git a/examples/napi/__test__/typegen.spec.ts.snap b/examples/napi/__test__/typegen.spec.ts.snap index 1f203965fd0ddd087c2edd1c9813617fa118fbf3..304ae7be5172ac0ee132e55e494f8fe2623e1c92 100644 GIT binary patch literal 1369 zcmV-f1*ZBzRzVCjZgy8mI94|@H2%^!;h00000000B6 zSHW%@HxQK*6a{=rPQCJ$Rj_d^*>%%}V?(y3)UhoawcMl#f`Gd_k{GW@b;-4?y8ey+ zLi-WD6$N_lxxdh3&mD5L5~ba>jG#WqLvrTLaAr6&ODdJhO6B3tU;OpwKi~iM%a>pM z`}ZHe|GHAqe~%wkDi1548+zrl%HszQ9zB0bKt_zKXCaf+kAOUVzPbw6LlG+yL{v)B zyjBo%8lCzdAyC_$9dffuNDMR-JQ|ZHPdu}+u$6H3LjpvO2fm2R@w+2$vV8B64sPA9 z-cB_ME)_Xwwi*}5oe%q`=N*smWZ*-badZaH4sLc9mCiTcT)lsUoBhH+NgWB{^a|Bsb(h^vFxH?vj0~kf^!jAPFv!s*~F} z{{2KMp~rwp`L=y}s7)!X<5HWWPoc z;2LC|6xs%tjIGMdpdpBsP67GH9=5yU{hURK ztgWv*!(7WLXhO46bcU6h_TaTd99@z)9YB`VxAZ(IW9s7sKWZ;NQ=8%9Wr02Zf)!S?8j6wUb_#!1a)p^w?nRzIi2IOd9FOQ z)AUazwbv)(;3C@yJC;aP!^hoy^jj>V2s>=adtNpmX|(%5xkR#_DT0Rk+$`>aujdur z&1fiT7h02TdyH9ITf-ouTQNo7y*IN7Qf2Q|<*+)lP8In7173?N8l8v`J_QbwH7)68 z6g1TQ2SS6h0gdLr3NCSe@XQo}yJotNlR)8pW(V$E>8K)~#2&>06F<#h@#;Ejv>+GS zV6~)(su8H8xJt>PKZC&3!muF8UUYN zX!&N*8vXkQVOms!kBjQPrL3Lvzn6oUsnCpas5=Ud5E}-1?qjfVeE6z;(rnMZ1g8x4 z@Uih>YqM?A6xpPx5Nc?+Xc44 bb=|0!%r?cYdAoErLtFj>McZ0EF%SR%7uJ}F literal 1251 zcmV<91RVQ8RzV5LYJ6;Xh{1IT3P2?mtWV7o;#9@V2E7UVnwtLg=Hr+jOOvr2S z3h)rz5E6IJyaGqgRQGtC@%+TmiX5Dp?y9f4{);pkjg`iupFjEQ&wsxA?U&C!|M%}d ze*bl)VgI_18;wVej~u=7VdLWu_8&icN#RLKM(g3O*%Io&@foaFhu4LjpukN1^2I`pro&`+OUa9vtoe!og1wL-5FZdh+3 zJ*ozonw)IiYeP1`c(vl#qX9W!gJWTQ5@uvGBT8}+zSux|={=0?cxU?_PW12LB=#c8 zc}SznfLKG;=UyPs_sErGF#_0swGJ!;w3U*I{De6aL!SwVeS#Mo`x$ip3TcsWzEm49 zGX!<+K!Q=`tt#C5nKsAnT;U zMpV<2$6K2o1dGb+qi2RnPF!wzby<=of7bCl&3=SjgbSUpu0R(-(vH z3b@|3tT6j5l!8VP^Tcvy&a^>uPhhG&8NLgMbha;@Cuv+!(xy);Qx&bRxD3(7$YZ8s zkbN?62UV;WnI~!!(#%kF4w)}Z ze`Dw2>@TTdV&ftF8qB%d!;Xbb=5!~^cC-4_PSZb?v|gXBc15-cP9K?=R*0vE=r<)f z$7xwp&&!q_i}nyGpJ+C44b5?%yN?Ip+ug%XCK_wnhtBLczmlx2tznSSt(c;3-nu;l zsk(YKC9K}v)QQ6X0k1<1<*#H6?*oU)ny#d7t#j1kvfmPHMET-|e~G(5;5Gt0b(^|M zB7^qaUHA*FqltVP=M9To{47I`*Y;Vb1-bA&PSR`UnvBj4i { @@ -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) => { diff --git a/examples/napi/index.d.ts b/examples/napi/index.d.ts index 7bbbe23e..81363e0f 100644 --- a/examples/napi/index.d.ts +++ b/examples/napi/index.d.ts @@ -32,6 +32,9 @@ export function createExternal(size: number): ExternalObject export function createExternalString(content: string): ExternalObject export function getExternal(external: ExternalObject): number export function mutateExternal(external: ExternalObject, 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 +90,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 + +} diff --git a/examples/napi/src/js_mod.rs b/examples/napi/src/js_mod.rs new file mode 100644 index 00000000..b0037b9a --- /dev/null +++ b/examples/napi/src/js_mod.rs @@ -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) +} diff --git a/examples/napi/src/lib.rs b/examples/napi/src/lib.rs index 22e44b66..751d16c9 100644 --- a/examples/napi/src/lib.rs +++ b/examples/napi/src/lib.rs @@ -16,6 +16,7 @@ mod either; mod r#enum; mod error; mod external; +mod js_mod; mod nullable; mod number; mod object; diff --git a/examples/napi/src/task.rs b/examples/napi/src/task.rs index 0292c1fc..fbbd2492 100644 --- a/examples/napi/src/task.rs +++ b/examples/napi/src/task.rs @@ -5,7 +5,7 @@ use napi::Task; struct DelaySum(u32, u32); -#[napi(task)] +#[napi] impl Task for DelaySum { type Output = u32; type JsValue = u32; diff --git a/yarn.lock b/yarn.lock index 2621ef84..6e50fcb4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -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"